From 672973caa0c3877b3b9f1c5f5966449ce0d7e239 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 2 Feb 2010 11:17:43 -0800 Subject: [PATCH] [gl] Convert fill_rectangles to the new GLSL core/arb wrapper. --- src/cairo-gl-private.h | 12 ++--- src/cairo-gl-shaders.c | 106 +++++++++-------------------------------- src/cairo-gl-surface.c | 39 ++++++++------- 3 files changed, 48 insertions(+), 109 deletions(-) diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index e4fe0006b..927595a65 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -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 */ diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c index cff051810..7e6026378 100644 --- a/src/cairo-gl-shaders.c +++ b/src/cairo-gl-shaders.c @@ -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); +} diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 9d6e416d3..41a9bbc2e 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -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;