mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-06-07 01:48:20 +02:00
[gl] Convert fill_rectangles to the new GLSL core/arb wrapper.
This commit is contained in:
parent
416273db34
commit
672973caa0
3 changed files with 48 additions and 109 deletions
|
|
@ -91,12 +91,13 @@ typedef struct _cairo_gl_context {
|
|||
cairo_device_t base;
|
||||
|
||||
GLuint dummy_tex;
|
||||
GLint fill_rectangles_shader;
|
||||
GLint fill_rectangles_color_uniform;
|
||||
GLint max_framebuffer_size;
|
||||
GLint max_texture_size;
|
||||
cairo_bool_t using_glsl;
|
||||
|
||||
cairo_bool_t using_shaders;
|
||||
cairo_gl_shader_program_t fill_rectangles_shader;
|
||||
|
||||
cairo_gl_surface_t *current_target;
|
||||
cairo_gl_surface_t *glyphs_temporary_mask;
|
||||
cairo_gl_glyph_cache_t glyph_cache[2];
|
||||
|
|
@ -236,10 +237,6 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
|
|||
cairo_private void
|
||||
_cairo_gl_glyph_cache_fini (cairo_gl_glyph_cache_t *cache);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gl_load_glsl (GLint *shader,
|
||||
const char *vs_source, const char *fs_source);
|
||||
|
||||
static inline int
|
||||
_cairo_gl_y_flip (cairo_gl_surface_t *surface, int y)
|
||||
{
|
||||
|
|
@ -290,6 +287,9 @@ bind_matrix_to_shader (GLuint program, const char *name, cairo_matrix_t* m);
|
|||
cairo_status_t
|
||||
bind_texture_to_shader (GLuint program, const char *name, GLuint tex_unit);
|
||||
|
||||
void
|
||||
_cairo_gl_use_program (cairo_gl_shader_program_t *shader);
|
||||
|
||||
slim_hidden_proto (cairo_gl_surface_create);
|
||||
|
||||
#endif /* CAIRO_GL_PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -35,89 +35,6 @@
|
|||
#include "cairo-gl-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
static GLint
|
||||
_cairo_gl_compile_glsl(GLenum type, GLint *shader_out, const char *source)
|
||||
{
|
||||
GLint ok;
|
||||
GLint shader;
|
||||
|
||||
shader = glCreateShaderObjectARB (type);
|
||||
glShaderSourceARB (shader, 1, (const GLchar **)&source, NULL);
|
||||
glCompileShaderARB (shader);
|
||||
glGetObjectParameterivARB (shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
|
||||
if (!ok) {
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetObjectParameterivARB (shader, GL_OBJECT_INFO_LOG_LENGTH_ARB,
|
||||
&size);
|
||||
info = malloc (size);
|
||||
|
||||
if (info)
|
||||
glGetInfoLogARB (shader, size, NULL, info);
|
||||
fprintf (stderr, "Failed to compile %s: %s\n",
|
||||
type == GL_FRAGMENT_SHADER ? "FS" : "VS",
|
||||
info);
|
||||
fprintf (stderr, "Shader source:\n%s", source);
|
||||
fprintf (stderr, "GLSL compile failure\n");
|
||||
|
||||
glDeleteObjectARB (shader);
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*shader_out = shader;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gl_load_glsl (GLint *shader_out,
|
||||
const char *vs_source, const char *fs_source)
|
||||
{
|
||||
GLint ok;
|
||||
GLint shader, vs, fs;
|
||||
cairo_status_t status;
|
||||
|
||||
shader = glCreateProgramObjectARB ();
|
||||
|
||||
status = _cairo_gl_compile_glsl (GL_VERTEX_SHADER_ARB, &vs, vs_source);
|
||||
if (_cairo_status_is_error (status))
|
||||
goto fail;
|
||||
status = _cairo_gl_compile_glsl (GL_FRAGMENT_SHADER_ARB, &fs, fs_source);
|
||||
if (_cairo_status_is_error (status))
|
||||
goto fail;
|
||||
|
||||
glAttachObjectARB (shader, vs);
|
||||
glAttachObjectARB (shader, fs);
|
||||
glLinkProgram (shader);
|
||||
glGetObjectParameterivARB (shader, GL_OBJECT_LINK_STATUS_ARB, &ok);
|
||||
if (!ok) {
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetObjectParameterivARB (shader, GL_OBJECT_INFO_LOG_LENGTH_ARB,
|
||||
&size);
|
||||
info = malloc (size);
|
||||
|
||||
if (info)
|
||||
glGetInfoLogARB (shader, size, NULL, info);
|
||||
fprintf (stderr, "Failed to link: %s\n", info);
|
||||
free (info);
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
*shader_out = shader;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
glDeleteObjectARB (shader);
|
||||
return status;
|
||||
}
|
||||
|
||||
typedef struct _shader_impl {
|
||||
cairo_status_t
|
||||
(*compile_shader) (GLuint *shader, GLenum type, const char *text);
|
||||
|
|
@ -157,6 +74,9 @@ typedef struct _shader_impl {
|
|||
|
||||
cairo_status_t
|
||||
(*bind_texture_to_shader) (GLuint program, const char *name, GLuint tex_unit);
|
||||
|
||||
void
|
||||
(*use_program) (cairo_gl_shader_program_t *program);
|
||||
} shader_impl_t;
|
||||
|
||||
static const shader_impl_t*
|
||||
|
|
@ -394,6 +314,12 @@ bind_texture_to_shader_arb (GLuint program, const char *name, GLuint tex_unit)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
use_program_arb (cairo_gl_shader_program_t *program)
|
||||
{
|
||||
glUseProgramObjectARB (program->program);
|
||||
}
|
||||
|
||||
/* OpenGL Core 2.0 API. */
|
||||
static cairo_status_t
|
||||
compile_shader_core_2_0 (GLuint *shader, GLenum type, const char *text)
|
||||
|
|
@ -559,6 +485,12 @@ bind_texture_to_shader_core_2_0 (GLuint program, const char *name, GLuint tex_un
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
use_program_core_2_0 (cairo_gl_shader_program_t *program)
|
||||
{
|
||||
glUseProgram (program->program);
|
||||
}
|
||||
|
||||
static const shader_impl_t shader_impl_core_2_0 = {
|
||||
compile_shader_core_2_0,
|
||||
link_shader_core_2_0,
|
||||
|
|
@ -571,6 +503,7 @@ static const shader_impl_t shader_impl_core_2_0 = {
|
|||
bind_vec4_to_shader_core_2_0,
|
||||
bind_matrix_to_shader_core_2_0,
|
||||
bind_texture_to_shader_core_2_0,
|
||||
use_program_core_2_0,
|
||||
};
|
||||
|
||||
static const shader_impl_t shader_impl_arb = {
|
||||
|
|
@ -585,6 +518,7 @@ static const shader_impl_t shader_impl_arb = {
|
|||
bind_vec4_to_shader_arb,
|
||||
bind_matrix_to_shader_arb,
|
||||
bind_texture_to_shader_arb,
|
||||
use_program_arb,
|
||||
};
|
||||
|
||||
static const shader_impl_t*
|
||||
|
|
@ -713,3 +647,9 @@ bind_texture_to_shader (GLuint program, const char *name, GLuint tex_unit)
|
|||
{
|
||||
return get_impl()->bind_texture_to_shader(program, name, tex_unit);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_use_program (cairo_gl_shader_program_t *program)
|
||||
{
|
||||
get_impl()->use_program (program);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,12 +114,15 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
|
|||
return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
|
||||
}
|
||||
|
||||
if (GLEW_ARB_fragment_shader &&
|
||||
GLEW_ARB_vertex_shader &&
|
||||
GLEW_ARB_shader_objects) {
|
||||
if (GLEW_VERSION_2_0 ||
|
||||
(GLEW_ARB_fragment_shader &&
|
||||
GLEW_ARB_vertex_shader &&
|
||||
GLEW_ARB_shader_objects)) {
|
||||
ctx->using_glsl = TRUE;
|
||||
}
|
||||
|
||||
init_shader_program (&ctx->fill_rectangles_shader);
|
||||
|
||||
/* Set up the dummy texture for tex_env_combine with constant color. */
|
||||
glGenTextures (1, &ctx->dummy_tex);
|
||||
glBindTexture (GL_TEXTURE_2D, ctx->dummy_tex);
|
||||
|
|
@ -1889,7 +1892,6 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
|
|||
#define N_STACK_RECTS 4
|
||||
cairo_gl_surface_t *surface = abstract_surface;
|
||||
GLfloat vertices_stack[N_STACK_RECTS*4*2];
|
||||
GLfloat gl_color[4];
|
||||
cairo_gl_context_t *ctx;
|
||||
int i;
|
||||
GLfloat *vertices;
|
||||
|
|
@ -1913,16 +1915,12 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (ctx->fill_rectangles_shader == 0) {
|
||||
status = _cairo_gl_load_glsl (&ctx->fill_rectangles_shader,
|
||||
fill_vs_source, fill_fs_source);
|
||||
if (_cairo_status_is_error (status)) {
|
||||
_cairo_gl_context_release (ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
ctx->fill_rectangles_color_uniform =
|
||||
glGetUniformLocationARB (ctx->fill_rectangles_shader, "color");
|
||||
status = create_shader_program (&ctx->fill_rectangles_shader,
|
||||
fill_vs_source,
|
||||
fill_fs_source);
|
||||
if (unlikely (status)) {
|
||||
_cairo_gl_context_release (ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (num_rects > N_STACK_RECTS) {
|
||||
|
|
@ -1936,16 +1934,17 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
|
|||
vertices = vertices_stack;
|
||||
}
|
||||
|
||||
glUseProgramObjectARB (ctx->fill_rectangles_shader);
|
||||
_cairo_gl_use_program (&ctx->fill_rectangles_shader);
|
||||
|
||||
_cairo_gl_set_destination (surface);
|
||||
_cairo_gl_set_operator (surface, op, FALSE);
|
||||
|
||||
gl_color[0] = color->red * color->alpha;
|
||||
gl_color[1] = color->green * color->alpha;
|
||||
gl_color[2] = color->blue * color->alpha;
|
||||
gl_color[3] = color->alpha;
|
||||
glUniform4fvARB (ctx->fill_rectangles_color_uniform, 1, gl_color);
|
||||
bind_vec4_to_shader (ctx->fill_rectangles_shader.program,
|
||||
"color",
|
||||
color->red * color->alpha,
|
||||
color->green * color->alpha,
|
||||
color->blue * color->alpha,
|
||||
color->alpha);
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
vertices[i * 8 + 0] = rects[i].x;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue