<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Malgun Gothic";
        panose-1:2 11 5 3 2 0 0 2 0 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@Malgun Gothic";
        panose-1:2 11 5 3 2 0 0 2 0 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">On mobile drivers, where a typical glGetUniform takes 2 – 3 microseconds.  This is called possibly multiple times for each drawing operation.  Saving uniform locations reduces time.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">From d8209e455e1c1b66d4d8ff67c842cfa6bf7e44de Mon Sep 17 00:00:00 2001<o:p></o:p></p>
<p class="MsoNormal">From: Henry Song <henry.song@samsung.com><o:p></o:p></p>
<p class="MsoNormal">Date: Fri, 11 Jan 2013 14:12:12 +0100<o:p></o:p></p>
<p class="MsoNormal">Subject: [PATCH] gl: Cache shader uniform locations<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Instead of continuously calling glUniformLocation each time we have<o:p></o:p></p>
<p class="MsoNormal">flushed, cache the uniform locations in the shader object.<o:p></o:p></p>
<p class="MsoNormal">---<o:p></o:p></p>
<p class="MsoNormal">src/cairo-gl-composite.c |   2 +-<o:p></o:p></p>
<p class="MsoNormal">src/cairo-gl-operand.c   |  50 +++++++++++-------------<o:p></o:p></p>
<p class="MsoNormal">src/cairo-gl-private.h   |  41 ++++++++++++++++---<o:p></o:p></p>
<p class="MsoNormal">src/cairo-gl-shaders.c   | 100 +++++++++++++++++++++++++++++++++++++----------<o:p></o:p></p>
<p class="MsoNormal">4 files changed, 139 insertions(+), 54 deletions(-)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c<o:p></o:p></p>
<p class="MsoNormal">index 1dcc6a1..23db7aa 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/src/cairo-gl-composite.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/cairo-gl-composite.c<o:p></o:p></p>
<p class="MsoNormal">@@ -134,7 +134,7 @@ static void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_composite_bind_to_shader (cairo_gl_context_t   *ctx,<o:p></o:p></p>
<p class="MsoNormal">                                                                   cairo_gl_composite_t *setup)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">-    _cairo_gl_shader_bind_matrix4f(ctx, "ModelViewProjectionMatrix",<o:p></o:p></p>
<p class="MsoNormal">+    _cairo_gl_shader_bind_matrix4f(ctx, CAIRO_GL_UNIFORM_PROJECTION_MATRIX,<o:p></o:p></p>
<p class="MsoNormal">                                                                  ctx->modelviewprojection_matrix);<o:p></o:p></p>
<p class="MsoNormal">     _cairo_gl_operand_bind_to_shader (ctx, &setup->src,  CAIRO_GL_TEX_SOURCE);<o:p></o:p></p>
<p class="MsoNormal">     _cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK);<o:p></o:p></p>
<p class="MsoNormal">diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c<o:p></o:p></p>
<p class="MsoNormal">index 7b5b404..5f0f9db 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/src/cairo-gl-operand.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/cairo-gl-operand.c<o:p></o:p></p>
<p class="MsoNormal">@@ -613,14 +613,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">                                   cairo_gl_operand_t *operand,<o:p></o:p></p>
<p class="MsoNormal">                                   cairo_gl_tex_t      tex_unit)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">-    char uniform_name[50];<o:p></o:p></p>
<p class="MsoNormal">-    char *custom_part;<o:p></o:p></p>
<p class="MsoNormal">-    static const char *names[] = { "source", "mask" };<o:p></o:p></p>
<p class="MsoNormal">     const cairo_matrix_t *texgen = NULL;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">-    strcpy (uniform_name, names[tex_unit]);<o:p></o:p></p>
<p class="MsoNormal">-    custom_part = uniform_name + strlen (names[tex_unit]);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">     switch (operand->type) {<o:p></o:p></p>
<p class="MsoNormal">     default:<o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_COUNT:<o:p></o:p></p>
<p class="MsoNormal">@@ -629,32 +623,31 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">               return;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_CONSTANT:<o:p></o:p></p>
<p class="MsoNormal">-        strcpy (custom_part, "_constant");<o:p></o:p></p>
<p class="MsoNormal">               _cairo_gl_shader_bind_vec4 (ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                    uniform_name,<o:p></o:p></p>
<p class="MsoNormal">-                                    operand->constant.color[0],<o:p></o:p></p>
<p class="MsoNormal">-                                    operand->constant.color[1],<o:p></o:p></p>
<p class="MsoNormal">-                                    operand->constant.color[2],<o:p></o:p></p>
<p class="MsoNormal">-                                    operand->constant.color[3]);<o:p></o:p></p>
<p class="MsoNormal">-              return;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">+                                                                 _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                             CAIRO_GL_UNIFORM_CONSTANT, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">+                                                                 operand->constant.color[0],<o:p></o:p></p>
<p class="MsoNormal">+                                                                 operand->constant.color[1],<o:p></o:p></p>
<p class="MsoNormal">+                                                                 operand->constant.color[2],<o:p></o:p></p>
<p class="MsoNormal">+                                                                 operand->constant.color[3]);<o:p></o:p></p>
<p class="MsoNormal">+        return;<o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:<o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:<o:p></o:p></p>
<p class="MsoNormal">-              strcpy (custom_part, "_a");<o:p></o:p></p>
<p class="MsoNormal">               _cairo_gl_shader_bind_float  (ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                                    uniform_name,<o:p></o:p></p>
<p class="MsoNormal">+                                                                   _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                               CAIRO_GL_UNIFORM_A, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">                                                                     operand->gradient.a);<o:p></o:p></p>
<p class="MsoNormal">               /* fall through */<o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:<o:p></o:p></p>
<p class="MsoNormal">-              strcpy (custom_part, "_circle_d");<o:p></o:p></p>
<p class="MsoNormal">-              _cairo_gl_shader_bind_vec3   (ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                                    uniform_name,<o:p></o:p></p>
<p class="MsoNormal">+             _cairo_gl_shader_bind_vec3 (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                 _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                             CAIRO_GL_UNIFORM_CIRCLE_D, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">                                                                     operand->gradient.circle_d.center.x,<o:p></o:p></p>
<p class="MsoNormal">                                                                     operand->gradient.circle_d.center.y,<o:p></o:p></p>
<p class="MsoNormal">                                                                     operand->gradient.circle_d.radius);<o:p></o:p></p>
<p class="MsoNormal">-              strcpy (custom_part, "_radius_0");<o:p></o:p></p>
<p class="MsoNormal">               _cairo_gl_shader_bind_float  (ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                                    uniform_name,<o:p></o:p></p>
<p class="MsoNormal">+                                                                   _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                               CAIRO_GL_UNIFORM_RADIUS_0, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">                                                                     operand->gradient.radius_0);<o:p></o:p></p>
<p class="MsoNormal">         /* fall through */<o:p></o:p></p>
<p class="MsoNormal">     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:<o:p></o:p></p>
<p class="MsoNormal">@@ -677,8 +670,10 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">                               width = operand->gradient.gradient->cache_entry.size,<o:p></o:p></p>
<p class="MsoNormal">                               height = 1;<o:p></o:p></p>
<p class="MsoNormal">                   }<o:p></o:p></p>
<p class="MsoNormal">-                  strcpy (custom_part, "_texdims");<o:p></o:p></p>
<p class="MsoNormal">-                  _cairo_gl_shader_bind_vec2 (ctx, uniform_name, width, height);<o:p></o:p></p>
<p class="MsoNormal">+                 _cairo_gl_shader_bind_vec2 (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                             _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                                 CAIRO_GL_UNIFORM_TEXDIMS, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">+                                                                             width, height);<o:p></o:p></p>
<p class="MsoNormal">               }<o:p></o:p></p>
<p class="MsoNormal">               break;<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal">@@ -690,11 +685,12 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">                   if (operand->gradient.texgen)<o:p></o:p></p>
<p class="MsoNormal">                                   texgen = &operand->gradient.m;<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal">-    if (texgen) {<o:p></o:p></p>
<p class="MsoNormal">-                  char name[20];<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">-                  sprintf (name, "%s_texgen", names[tex_unit]);<o:p></o:p></p>
<p class="MsoNormal">-                  _cairo_gl_shader_bind_matrix(ctx, name, texgen);<o:p></o:p></p>
<p class="MsoNormal">+    if (texgen) {<o:p></o:p></p>
<p class="MsoNormal">+             _cairo_gl_shader_bind_matrix (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                   _cairo_gl_shader_uniform_for_texunit (<o:p></o:p></p>
<p class="MsoNormal">+                                                                               CAIRO_GL_UNIFORM_TEXGEN, tex_unit),<o:p></o:p></p>
<p class="MsoNormal">+                                                                   texgen);<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h<o:p></o:p></p>
<p class="MsoNormal">index d49e3d9..8985fe1 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/src/cairo-gl-private.h<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/cairo-gl-private.h<o:p></o:p></p>
<p class="MsoNormal">@@ -105,6 +105,30 @@ typedef enum cairo_gl_flavor {<o:p></o:p></p>
<p class="MsoNormal">     CAIRO_GL_FLAVOR_ES = 2<o:p></o:p></p>
<p class="MsoNormal">} cairo_gl_flavor_t;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+/* The order here is sensitive because of the logic of <o:p>
</o:p></p>
<p class="MsoNormal">+ *_cairo_gl_shader_uniform_for_texunit. */<o:p></o:p></p>
<p class="MsoNormal">+typedef enum cairo_gl_uniform_t {<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_TEXDIMS,    /* "source_texdims" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_TEXGEN,     /* "source_texgen" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_CONSTANT,   /* "source_constant" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_SAMPLER,    /* "source_sampler" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_A,          /* "source_a" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_CIRCLE_D,   /* "source_circle_d" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_RADIUS_0,   /* "source_radius_0" */<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_TEXDIMS,      /* "mask_texdims" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_TEXGEN,       /* "mask_texgen" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_CONSTANT,     /* "mask_constant" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_SAMPLER,      /* "mask_sampler" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_A,            /* "mask_a" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_CIRCLE_D,     /* "mask_circle_d" */<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MASK_RADIUS_0,     /* "mask_radius_0" */<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_PROJECTION_MATRIX, /* "ModelViewProjectionMatrix" */<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    CAIRO_GL_UNIFORM_MAX<o:p></o:p></p>
<p class="MsoNormal">+} cairo_gl_uniform_t;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">/* Indices for vertex attributes used by BindAttribLocation etc */<o:p></o:p></p>
<p class="MsoNormal">enum {<o:p></o:p></p>
<p class="MsoNormal">     CAIRO_GL_VERTEX_ATTRIB_INDEX = 0,<o:p></o:p></p>
<p class="MsoNormal">@@ -201,6 +225,7 @@ typedef enum cairo_gl_tex {<o:p></o:p></p>
<p class="MsoNormal">typedef struct cairo_gl_shader {<o:p></o:p></p>
<p class="MsoNormal">     GLuint fragment_shader;<o:p></o:p></p>
<p class="MsoNormal">     GLuint program;<o:p></o:p></p>
<p class="MsoNormal">+    GLint uniforms[CAIRO_GL_UNIFORM_MAX];<o:p></o:p></p>
<p class="MsoNormal">} cairo_gl_shader_t;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> typedef enum cairo_gl_shader_in {<o:p></o:p></p>
<p class="MsoNormal">@@ -649,37 +674,41 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">                               cairo_gl_shader_in_t in,<o:p></o:p></p>
<p class="MsoNormal">                               cairo_gl_shader_t **shader);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+cairo_private cairo_gl_uniform_t<o:p></o:p></p>
<p class="MsoNormal">+_cairo_gl_shader_uniform_for_texunit (cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">+                                                                   cairo_gl_tex_t tex_unit);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                   const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                  cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                    float value);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0, float value1);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value1,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value2);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0, float value1,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value2, float value3);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                    const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                   cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                     const cairo_matrix_t* m);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                              const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                             cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                               GLfloat* gl_m);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_private void<o:p></o:p></p>
<p class="MsoNormal">diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c<o:p></o:p></p>
<p class="MsoNormal">index d8de712..b9eb5c7 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/src/cairo-gl-shaders.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/cairo-gl-shaders.c<o:p></o:p></p>
<p class="MsoNormal">@@ -44,6 +44,52 @@<o:p></o:p></p>
<p class="MsoNormal">#include "cairo-error-private.h"<o:p></o:p></p>
<p class="MsoNormal">#include "cairo-output-stream-private.h"<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">+static GLint<o:p></o:p></p>
<p class="MsoNormal">+_cairo_gl_shader_get_uniform_location (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                    cairo_gl_shader_t *shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                    cairo_gl_uniform_t uniform)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+    /* This should be kept in sync with the enum<o:p></o:p></p>
<p class="MsoNormal">+     * definition in cairo-gl-private.h. */<o:p></o:p></p>
<p class="MsoNormal">+    const char *names[CAIRO_GL_UNIFORM_MAX] = {<o:p></o:p></p>
<p class="MsoNormal">+             "source_texdims",<o:p></o:p></p>
<p class="MsoNormal">+             "source_texgen",<o:p></o:p></p>
<p class="MsoNormal">+             "source_constant",<o:p></o:p></p>
<p class="MsoNormal">+             "source_sampler",<o:p></o:p></p>
<p class="MsoNormal">+             "source_a",<o:p></o:p></p>
<p class="MsoNormal">+             "source_circle_d",<o:p></o:p></p>
<p class="MsoNormal">+             "source_radius_0",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_texdims",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_texgen",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_constant",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_sampler",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_a",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_circle_d",<o:p></o:p></p>
<p class="MsoNormal">+             "mask_radius_0",<o:p></o:p></p>
<p class="MsoNormal">+             "ModelViewProjectionMatrix"<o:p></o:p></p>
<p class="MsoNormal">+    };<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    if (shader->uniforms[uniform] != -1)<o:p></o:p></p>
<p class="MsoNormal">+             return shader->uniforms[uniform];<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    shader->uniforms[uniform] =<o:p></o:p></p>
<p class="MsoNormal">+             ctx->dispatch.GetUniformLocation (shader->program,<o:p></o:p></p>
<p class="MsoNormal">+                                                                               names[uniform]);<o:p></o:p></p>
<p class="MsoNormal">+    return shader->uniforms[uniform];<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+cairo_gl_uniform_t<o:p></o:p></p>
<p class="MsoNormal">+_cairo_gl_shader_uniform_for_texunit (cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">+                                                                   cairo_gl_tex_t tex_unit)<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+    assert (uniform < CAIRO_GL_UNIFORM_MASK_TEXDIMS);<o:p></o:p></p>
<p class="MsoNormal">+    assert (tex_unit == CAIRO_GL_TEX_SOURCE || tex_unit == CAIRO_GL_TEX_MASK);<o:p></o:p></p>
<p class="MsoNormal">+    if (tex_unit == CAIRO_GL_TEX_SOURCE)<o:p></o:p></p>
<p class="MsoNormal">+             return uniform;<o:p></o:p></p>
<p class="MsoNormal">+    else<o:p></o:p></p>
<p class="MsoNormal">+             return uniform + CAIRO_GL_UNIFORM_MASK_TEXDIMS;<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">static cairo_status_t<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">                                                                  cairo_gl_shader_t *shader,<o:p></o:p></p>
<p class="MsoNormal">@@ -139,8 +185,12 @@ _cairo_gl_shader_cache_destroy (void *data)<o:p></o:p></p>
<p class="MsoNormal">static void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_init (cairo_gl_shader_t *shader)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">+    int i;<o:p></o:p></p>
<p class="MsoNormal">     shader->fragment_shader = 0;<o:p></o:p></p>
<p class="MsoNormal">     shader->program = 0;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    for (i = 0; i < CAIRO_GL_UNIFORM_MAX; i++)<o:p></o:p></p>
<p class="MsoNormal">+             shader->uniforms[i] = -1;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> cairo_status_t<o:p></o:p></p>
<p class="MsoNormal">@@ -872,12 +922,14 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">     glGetIntegerv (GL_CURRENT_PROGRAM, &saved_program);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->UseProgram (shader->program);<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">-    location = dispatch->GetUniformLocation (shader->program, "source_sampler");<o:p></o:p></p>
<p class="MsoNormal">+    location = _cairo_gl_shader_get_uniform_location (ctx, shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                   CAIRO_GL_UNIFORM_SAMPLER);<o:p></o:p></p>
<p class="MsoNormal">     if (location != -1) {<o:p></o:p></p>
<p class="MsoNormal">               dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE);<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">-    location = dispatch->GetUniformLocation (shader->program, "mask_sampler");<o:p></o:p></p>
<p class="MsoNormal">+    location = _cairo_gl_shader_get_uniform_location (ctx, shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                   CAIRO_GL_UNIFORM_MASK_SAMPLER);<o:p></o:p></p>
<p class="MsoNormal">     if (location != -1) {<o:p></o:p></p>
<p class="MsoNormal">               dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK);<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal">@@ -887,64 +939,70 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                   const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                  cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                    float value)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">     assert (location != -1);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->Uniform1f (location, value);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value1)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">     assert (location != -1);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->Uniform2f (location, value0, value1);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value1,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value2)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">     assert (location != -1);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->Uniform3f (location, value0, value1, value2);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                  const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                 cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value0, float value1,<o:p></o:p></p>
<p class="MsoNormal">                                                   float value2, float value3)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">     assert (location != -1);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->Uniform4f (location, value0, value1, value2, value3);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                    const char *name,<o:p></o:p></p>
<p class="MsoNormal">+                                                   cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">                                                     const cairo_matrix_t* m)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">     float gl_m[9] = {<o:p></o:p></p>
<p class="MsoNormal">               m->xx, m->xy, m->x0,<o:p></o:p></p>
<p class="MsoNormal">               m->yx, m->yy, m->y0,<o:p></o:p></p>
<p class="MsoNormal">@@ -956,11 +1014,13 @@ _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> void<o:p></o:p></p>
<p class="MsoNormal">_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,<o:p></o:p></p>
<p class="MsoNormal">-                                                              const char *name, GLfloat* gl_m)<o:p></o:p></p>
<p class="MsoNormal">+                                                             cairo_gl_uniform_t uniform,<o:p></o:p></p>
<p class="MsoNormal">+                                                             GLfloat* gl_m)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;<o:p></o:p></p>
<p class="MsoNormal">-    GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,<o:p></o:p></p>
<p class="MsoNormal">-                                                                                                 name);<o:p></o:p></p>
<p class="MsoNormal">+    GLint location = _cairo_gl_shader_get_uniform_location (ctx,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 ctx->current_shader,<o:p></o:p></p>
<p class="MsoNormal">+                                                                                                                 uniform);<o:p></o:p></p>
<p class="MsoNormal">     assert (location != -1);<o:p></o:p></p>
<p class="MsoNormal">     dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">-- <o:p></o:p></p>
<p class="MsoNormal">1.8.1.2<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>