[cogl/wip/neil/snippets: 17/21] fragend-glsl: Don't generate the default texture lookup if replaced



commit 68864111e208e9f031e1c81e7580cd323a951b11
Author: Neil Roberts <neil linux intel com>
Date:   Fri Nov 25 22:02:53 2011 +0000

    fragend-glsl: Don't generate the default texture lookup if replaced
    
    Previously the function containing the default texture lookup is
    always generated regardless of whether there is a snippet with a
    replace string which would cause it not be used. Now this snippets are
    all scanned to check for replace strings before generating the texture
    lookup.

 cogl/cogl-pipeline-fragend-glsl.c |  122 +++++++++++++++++++++----------------
 tests/conform/test-snippets.c     |   15 +++++
 2 files changed, 85 insertions(+), 52 deletions(-)
---
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index 15bea59..b7500eb 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -37,6 +37,7 @@
 #include "cogl-pipeline-layer-private.h"
 #include "cogl-shader-private.h"
 #include "cogl-blend-string.h"
+#include "cogl-snippet-private.h"
 
 #ifdef COGL_PIPELINE_FRAGEND_GLSL
 
@@ -201,6 +202,19 @@ get_layer_fragment_snippets (CoglPipelineLayer *layer)
 }
 
 static gboolean
+has_replace_hook (CoglPipelineLayer *layer,
+                  CoglSnippetHook hook)
+{
+  CoglPipelineSnippet *snippet;
+
+  COGL_LIST_FOREACH (snippet, get_layer_fragment_snippets (layer), list_node)
+    if (snippet->snippet->hook == hook && snippet->snippet->replace)
+      return TRUE;
+
+  return FALSE;
+}
+
+static gboolean
 _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
                                    int n_layers,
                                    unsigned long pipelines_difference,
@@ -374,9 +388,7 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
                                  CoglPipeline *pipeline,
                                  CoglPipelineLayer *layer)
 {
-  CoglHandle texture;
   int unit_index = _cogl_pipeline_layer_get_unit_index (layer);
-  const char *target_string, *tex_coord_swizzle;
   CoglPipelineSnippetData snippet_data;
 
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -415,72 +427,78 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
 
   g_string_append (shader_state->source, ");\n");
 
-  texture = _cogl_pipeline_layer_get_texture (layer);
-
-  if (texture == NULL)
+  /* There's no need to generate the real texture lookup if it's going
+     to be replaced */
+  if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP))
     {
-      target_string = "2D";
-      tex_coord_swizzle = "st";
-    }
-  else
-    {
-      GLenum gl_target;
+      CoglHandle texture = _cogl_pipeline_layer_get_texture (layer);
+      const char *target_string, *tex_coord_swizzle;
 
-      cogl_texture_get_gl_texture (texture, NULL, &gl_target);
-      switch (gl_target)
+      if (texture == NULL)
+        {
+          target_string = "2D";
+          tex_coord_swizzle = "st";
+        }
+      else
         {
+          GLenum gl_target;
+
+          cogl_texture_get_gl_texture (texture, NULL, &gl_target);
+          switch (gl_target)
+            {
 #ifdef HAVE_COGL_GL
-        case GL_TEXTURE_1D:
-          target_string = "1D";
-          tex_coord_swizzle = "s";
-          break;
+            case GL_TEXTURE_1D:
+              target_string = "1D";
+              tex_coord_swizzle = "s";
+              break;
 #endif
 
-        case GL_TEXTURE_2D:
-          target_string = "2D";
-          tex_coord_swizzle = "st";
-          break;
+            case GL_TEXTURE_2D:
+              target_string = "2D";
+              tex_coord_swizzle = "st";
+              break;
 
 #ifdef GL_ARB_texture_rectangle
-        case GL_TEXTURE_RECTANGLE_ARB:
-          target_string = "2DRect";
-          tex_coord_swizzle = "st";
-          break;
+            case GL_TEXTURE_RECTANGLE_ARB:
+              target_string = "2DRect";
+              tex_coord_swizzle = "st";
+              break;
 #endif
 
-        case GL_TEXTURE_3D:
-          target_string = "3D";
-          tex_coord_swizzle = "stp";
-          break;
+            case GL_TEXTURE_3D:
+              target_string = "3D";
+              tex_coord_swizzle = "stp";
+              break;
 
-        default:
-          g_assert_not_reached ();
+            default:
+              g_assert_not_reached ();
+            }
         }
-    }
 
-  /* Create a sampler uniform */
-  if (G_LIKELY (!COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
-    g_string_append_printf (shader_state->header,
-                            "uniform sampler%s _cogl_sampler_%i;\n",
-                            target_string,
-                            unit_index);
+      /* Create a sampler uniform */
+      if (G_LIKELY (!COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
+        g_string_append_printf (shader_state->header,
+                                "uniform sampler%s _cogl_sampler_%i;\n",
+                                target_string,
+                                unit_index);
 
-  g_string_append_printf (shader_state->header,
-                          "vec4\n"
-                          "cogl_real_texture_lookup%i (vec4 coords)\n"
-                          "{\n"
-                          "  return ",
-                          unit_index);
+      g_string_append_printf (shader_state->header,
+                              "vec4\n"
+                              "cogl_real_texture_lookup%i (vec4 coords)\n"
+                              "{\n"
+                              "  return ",
+                              unit_index);
 
-  if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
-    g_string_append (shader_state->header,
-                     "vec4 (1.0, 1.0, 1.0, 1.0);\n");
-  else
-    g_string_append_printf (shader_state->header,
-                            "texture%s (_cogl_sampler_%i, coords.%s);\n",
-                            target_string, unit_index, tex_coord_swizzle);
+      if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
+        g_string_append (shader_state->header,
+                         "vec4 (1.0, 1.0, 1.0, 1.0);\n");
+      else
+        g_string_append_printf (shader_state->header,
+                                "texture%s (_cogl_sampler_%i, coords.%s);\n",
+                                target_string, unit_index, tex_coord_swizzle);
 
-  g_string_append (shader_state->header, "}\n");
+      g_string_append (shader_state->header, "}\n");
+    }
 
   /* Wrap the texture lookup in any snippets that have been hooked */
   memset (&snippet_data, 0, sizeof (snippet_data));
diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c
index 1722cb4..bb0cf34 100644
--- a/tests/conform/test-snippets.c
+++ b/tests/conform/test-snippets.c
@@ -232,6 +232,20 @@ paint (TestState *state)
 
   cogl_object_unref (snippet);
 
+  /* Check replacing the texture lookup hook */
+  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, NULL, NULL);
+  cogl_snippet_set_replace (snippet, "cogl_texel = vec4 (0.0, 0.0, 1.0, 0.0);");
+
+  pipeline = create_texture_pipeline ();
+  cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
+  cogl_push_source (pipeline);
+  cogl_rectangle_with_texture_coords (90, 0, 100, 10,
+                                      0, 0, 0, 0);
+  cogl_pop_source ();
+  cogl_object_unref (pipeline);
+
+  cogl_object_unref (snippet);
+
   /* Test replacing a previous snippet */
   pipeline = create_texture_pipeline ();
 
@@ -302,6 +316,7 @@ validate_result (void)
   test_utils_check_pixel (65, 5, 0x00ff00ff);
   test_utils_check_pixel (75, 5, 0x808000ff);
   test_utils_check_pixel (85, 5, 0x00ffffff);
+  test_utils_check_pixel (95, 5, 0x0000ffff);
   test_utils_check_pixel (105, 5, 0xff0000ff);
 }
 



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