[cogl] cogl-pipeline-fragend-glsl: Cache the results of texture lookups



commit e7f374d7995eed42df5f84a8831f820dcf8ab72b
Author: Neil Roberts <neil linux intel com>
Date:   Fri Aug 12 16:29:30 2011 +0100

    cogl-pipeline-fragend-glsl: Cache the results of texture lookups
    
    Whenever a texture lookup is performed for a layer the result is now
    stored in a variable and used repeatedly instead of generating the
    code for the lookup every time it is accessed. This means for example
    when using the INTERPOLATE function with a texture lookup for the
    third parameter it will only generate one texture lookup instead of
    two.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=656426
    
    Reviewed-by: Robert Bragg <robert linux intel com>

 cogl/cogl-pipeline-fragend-glsl.c |  138 +++++++++++++++++++++----------------
 1 files changed, 78 insertions(+), 60 deletions(-)
---
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index e317852..48e523b 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -337,10 +337,9 @@ add_constant_lookup (CoglPipelineShaderState *shader_state,
 }
 
 static void
-add_texture_lookup (CoglPipelineShaderState *shader_state,
-                    CoglPipeline *pipeline,
-                    CoglPipelineLayer *layer,
-                    const char *swizzle)
+ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
+                                 CoglPipeline *pipeline,
+                                 CoglPipelineLayer *layer)
 {
   CoglHandle texture;
   int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
@@ -348,11 +347,19 @@ add_texture_lookup (CoglPipelineShaderState *shader_state,
 
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
+  if (shader_state->unit_state[unit_index].sampled)
+    return;
+
+  shader_state->unit_state[unit_index].sampled = TRUE;
+
+  g_string_append_printf (shader_state->source,
+                          "  vec4 texel%i = ",
+                          unit_index);
+
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
     {
       g_string_append (shader_state->source,
-                       "vec4 (1.0, 1.0, 1.0, 1.0).");
-      g_string_append (shader_state->source, swizzle);
+                       "vec4 (1.0, 1.0, 1.0, 1.0);\n");
 
       return;
     }
@@ -400,15 +407,11 @@ add_texture_lookup (CoglPipelineShaderState *shader_state,
         }
     }
 
-  /* Create a sampler uniform for this layer if we haven't already */
-  if (!shader_state->unit_state[unit_index].sampled)
-    {
-      g_string_append_printf (shader_state->header,
-                              "uniform sampler%s _cogl_sampler_%i;\n",
-                              target_string,
-                              unit_index);
-      shader_state->unit_state[unit_index].sampled = TRUE;
-    }
+  /* Create a sampler uniform */
+  g_string_append_printf (shader_state->header,
+                          "uniform sampler%s _cogl_sampler_%i;\n",
+                          target_string,
+                          unit_index);
 
   g_string_append_printf (shader_state->source,
                           "texture%s (_cogl_sampler_%i, ",
@@ -433,31 +436,7 @@ add_texture_lookup (CoglPipelineShaderState *shader_state,
                             "cogl_tex_coord_in[%d].%s",
                             unit_index, tex_coord_swizzle);
 
-  g_string_append_printf (shader_state->source, ").%s", swizzle);
-}
-
-typedef struct
-{
-  int unit_index;
-  CoglPipelineLayer *layer;
-} FindPipelineLayerData;
-
-static gboolean
-find_pipeline_layer_cb (CoglPipelineLayer *layer,
-                        void *user_data)
-{
-  FindPipelineLayerData *data = user_data;
-  int unit_index;
-
-  unit_index = _cogl_pipeline_layer_get_unit_index (layer);
-
-  if (unit_index == data->unit_index)
-    {
-      data->layer = layer;
-      return FALSE;
-    }
-
-  return TRUE;
+  g_string_append (shader_state->source, ");\n");
 }
 
 static void
@@ -492,10 +471,10 @@ add_arg (CoglPipelineShaderState *shader_state,
   switch (src)
     {
     case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE:
-      add_texture_lookup (shader_state,
-                          pipeline,
-                          layer,
-                          swizzle);
+      g_string_append_printf (shader_source,
+                              "texel%i.%s",
+                              _cogl_pipeline_layer_get_unit_index (layer),
+                              swizzle);
       break;
 
     case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT:
@@ -522,25 +501,39 @@ add_arg (CoglPipelineShaderState *shader_state,
     default:
       if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 &&
           src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32)
-        {
-          FindPipelineLayerData data;
+        g_string_append_printf (shader_source,
+                                "texel%i.%s",
+                                src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0,
+                                swizzle);
+      break;
+    }
 
-          data.unit_index = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0;
-          data.layer = layer;
+  g_string_append_c (shader_source, ')');
+}
 
-          _cogl_pipeline_foreach_layer_internal (pipeline,
-                                                 find_pipeline_layer_cb,
-                                                 &data);
 
-          add_texture_lookup (shader_state,
-                              pipeline,
-                              data.layer,
-                              swizzle);
-        }
-      break;
+typedef struct
+{
+  int unit_index;
+  CoglPipelineLayer *layer;
+} FindPipelineLayerData;
+
+static gboolean
+find_pipeline_layer_cb (CoglPipelineLayer *layer,
+                        void *user_data)
+{
+  FindPipelineLayerData *data = user_data;
+  int unit_index;
+
+  unit_index = _cogl_pipeline_layer_get_unit_index (layer);
+
+  if (unit_index == data->unit_index)
+    {
+      data->layer = layer;
+      return FALSE;
     }
 
-  g_string_append_c (shader_source, ')');
+  return TRUE;
 }
 
 static void
@@ -549,12 +542,12 @@ ensure_arg_generated (CoglPipeline *pipeline,
                       int previous_layer_index,
                       CoglPipelineCombineSource src)
 {
+  CoglPipelineShaderState *shader_state = get_shader_state (pipeline);
+
   switch (src)
     {
-    case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE:
     case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT:
     case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR:
-    default:
       /* These don't involve any other layers */
       break;
 
@@ -562,6 +555,31 @@ ensure_arg_generated (CoglPipeline *pipeline,
       if (previous_layer_index >= 0)
         ensure_layer_generated (pipeline, previous_layer_index);
       break;
+
+    case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE:
+      ensure_texture_lookup_generated (shader_state,
+                                       pipeline,
+                                       layer);
+      break;
+
+    default:
+      if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 &&
+          src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32)
+        {
+          FindPipelineLayerData data;
+
+          data.unit_index = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0;
+          data.layer = layer;
+
+          _cogl_pipeline_foreach_layer_internal (pipeline,
+                                                 find_pipeline_layer_cb,
+                                                 &data);
+
+          ensure_texture_lookup_generated (shader_state,
+                                           pipeline,
+                                           data.layer);
+        }
+      break;
     }
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]