[cairo] [PATCH] gl: Bind samplers just once at program compile time.

Eric Anholt eric at anholt.net
Mon Feb 21 14:55:20 PST 2011


We never bound any other value to the sampler uniforms, so why bother
resetting them all the time?

[  0]   before      firefox-talos-gfx   29.972   30.493   0.89%    3/3
[  0]   after       firefox-talos-gfx   29.397   29.599   1.27%    3/3

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 src/cairo-gl-composite.c |    6 +----
 src/cairo-gl-private.h   |    5 ----
 src/cairo-gl-shaders.c   |   58 +++++++++++++++++++++++++++-------------------
 3 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index d5b3c5c..c8f84a9 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -401,13 +401,9 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
 	_cairo_gl_shader_bind_float  (ctx,
 				      uniform_name,
 				      operand->gradient.radius_0);
-	/* fall through */
+        break;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_TEXTURE:
-        strcpy (custom_part, "_sampler");
-	_cairo_gl_shader_bind_texture(ctx,
-                                      uniform_name,
-                                      tex_unit);
         break;
     }
 }
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 475f14a..73818b1 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -548,11 +548,6 @@ _cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
 				GLfloat* gl_m);
 
 cairo_private void
-_cairo_gl_shader_bind_texture (cairo_gl_context_t *ctx,
-			       const char *name,
-			       GLuint tex_unit);
-
-cairo_private void
 _cairo_gl_set_shader (cairo_gl_context_t *ctx,
 		      cairo_gl_shader_t *shader);
 
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index a17491e..39e4e30 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -99,12 +99,6 @@ typedef struct cairo_gl_shader_impl {
 		      GLfloat* gl_m);
 
     void
-    (*bind_texture) (cairo_gl_context_t *ctx,
-		     cairo_gl_shader_t *shader,
-		     const char *name,
-		     cairo_gl_tex_t tex_unit);
-
-    void
     (*use) (cairo_gl_context_t *ctx,
 	    cairo_gl_shader_t *shader);
 } shader_impl_t;
@@ -291,16 +285,6 @@ bind_matrix4f_core_2_0 (cairo_gl_context_t *ctx,
 }
 
 static void
-bind_texture_core_2_0 (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader,
-		       const char *name, cairo_gl_tex_t tex_unit)
-{
-    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
-    GLint location = dispatch->GetUniformLocation (shader->program, name);
-    assert (location != -1);
-    dispatch->Uniform1i (location, tex_unit);
-}
-
-static void
 use_program_core_2_0 (cairo_gl_context_t *ctx,
 		      cairo_gl_shader_t *shader)
 {
@@ -321,7 +305,6 @@ static const cairo_gl_shader_impl_t shader_impl_core_2_0 = {
     bind_vec4_core_2_0,
     bind_matrix_core_2_0,
     bind_matrix4f_core_2_0,
-    bind_texture_core_2_0,
     use_program_core_2_0,
 };
 
@@ -788,6 +771,38 @@ _cairo_gl_shader_compile (cairo_gl_context_t *ctx,
     return status;
 }
 
+/* We always bind the source to texture unit 0 if present, and mask to
+ * texture unit 1 if present, so we can just initialize these once at
+ * compile time.
+ */
+static void
+_cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
+			       cairo_gl_shader_t *shader)
+{
+    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
+    GLint location;
+    GLint saved_program;
+
+    /* We have to save/restore the current program because we might be
+     * asked for a different program while a shader is bound.  This shouldn't
+     * be a performance issue, since this is only called once per compile.
+     */
+    glGetIntegerv (GL_CURRENT_PROGRAM, &saved_program);
+    dispatch->UseProgram (shader->program);
+
+    location = dispatch->GetUniformLocation (shader->program, "source_sampler");
+    if (location != -1) {
+	dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE);
+    }
+
+    location = dispatch->GetUniformLocation (shader->program, "mask_sampler");
+    if (location != -1) {
+	dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK);
+    }
+
+    dispatch->UseProgram (saved_program);
+}
+
 void
 _cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
 			     const char *name,
@@ -839,13 +854,6 @@ _cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
 }
 
 void
-_cairo_gl_shader_bind_texture (cairo_gl_context_t *ctx,
-			       const char *name, GLuint tex_unit)
-{
-    ctx->shader_impl->bind_texture (ctx, ctx->current_shader, name, tex_unit);
-}
-
-void
 _cairo_gl_set_shader (cairo_gl_context_t *ctx,
 		      cairo_gl_shader_t *shader)
 {
@@ -913,6 +921,8 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
 	return status;
     }
 
+    _cairo_gl_shader_set_samplers (ctx, &entry->shader);
+
     status = _cairo_cache_insert (&ctx->shaders, &entry->base);
     if (unlikely (status)) {
 	_cairo_gl_shader_fini (ctx, &entry->shader);
-- 
1.7.4.1



More information about the cairo mailing list