From 22c61c53157840011936b1f5cee3756b19504f45 Mon Sep 17 00:00:00 2001
From: Neil Roberts <neil@linux.intel.com>
Date: Thu, 11 Nov 2010 16:18:25 +0000
Subject: [PATCH] cogl-pipeline: Use layer overrides as CoglHandles instead of
 GLuint

Since d5634e37 the sliced texture backend now works in terms of
CoglTexture2Ds so there's no need to have special casing for
overriding the texture of a pipeline layer with a GL handle. Instead
we can just use cogl_pipeline_set_layer_texture with the
CoglHandle. The special _cogl_pipeline_set_layer_gl_texture_slice
function has now been removed and parts of the code for comparing
materials have been simplified.
---
 cogl/cogl-journal-private.h  |   2 +-
 cogl/cogl-journal.c          |   2 +-
 cogl/cogl-pipeline-opengl.c  |  35 ++++--------
 cogl/cogl-pipeline-private.h |   7 +--
 cogl/cogl-pipeline.c         | 105 ++++-------------------------------
 cogl/cogl-primitives.c       |  15 ++++-
 6 files changed, 38 insertions(+), 128 deletions(-)

diff --git a/cogl/cogl-journal-private.h b/cogl/cogl-journal-private.h
index 977866eb0..79d001461 100644
--- a/cogl/cogl-journal-private.h
+++ b/cogl/cogl-journal-private.h
@@ -46,7 +46,7 @@ _cogl_journal_log_quad (const float  *position,
                         CoglPipeline *pipeline,
                         int           n_layers,
                         guint32       fallback_layers,
-                        GLuint        layer0_override_texture,
+                        CoglHandle    layer0_override_texture,
                         const CoglPipelineWrapModeOverrides *
                                       wrap_mode_overrides,
                         const float  *tex_coords,
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index cb1e2e249..584726623 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -765,7 +765,7 @@ _cogl_journal_log_quad (const float  *position,
                         CoglPipeline *pipeline,
                         int           n_layers,
                         guint32       fallback_layers,
-                        GLuint        layer0_override_texture,
+                        CoglHandle    layer0_override_texture,
                         const CoglPipelineWrapModeOverrides *
                                       wrap_mode_overrides,
                         const float  *tex_coords,
diff --git a/cogl/cogl-pipeline-opengl.c b/cogl/cogl-pipeline-opengl.c
index 9a69b38e7..80a7ebeaa 100644
--- a/cogl/cogl-pipeline-opengl.c
+++ b/cogl/cogl-pipeline-opengl.c
@@ -375,26 +375,6 @@ _cogl_get_max_texture_image_units (void)
 }
 #endif
 
-static void
-_cogl_pipeline_layer_get_texture_info (CoglPipelineLayer *layer,
-                                       CoglHandle *texture,
-                                       GLuint *gl_texture,
-                                       GLuint *gl_target)
-{
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  *texture = layer->texture;
-  if (G_UNLIKELY (*texture == COGL_INVALID_HANDLE))
-    *texture = ctx->default_gl_texture_2d_tex;
-  if (layer->texture_overridden)
-    {
-      *gl_texture = layer->slice_gl_texture;
-      *gl_target = layer->slice_gl_target;
-    }
-  else
-    cogl_texture_get_gl_texture (*texture, gl_texture, gl_target);
-}
-
 #ifndef HAVE_COGL_GLES
 
 static gboolean
@@ -638,6 +618,8 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
   unsigned long                layers_difference =
     flush_state->layer_differences[unit_index];
 
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
   /* There may not be enough texture units so we can bail out if
    * that's the case...
    */
@@ -659,14 +641,17 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
       CoglPipelineLayer *authority =
         _cogl_pipeline_layer_get_authority (layer,
                                             COGL_PIPELINE_LAYER_STATE_TEXTURE);
-      CoglHandle texture = NULL;
+      CoglHandle texture;
       GLuint     gl_texture;
       GLenum     gl_target;
 
-      _cogl_pipeline_layer_get_texture_info (authority,
-                                             &texture,
-                                             &gl_texture,
-                                             &gl_target);
+      texture = (authority->texture == COGL_INVALID_HANDLE ?
+                 ctx->default_gl_texture_2d_tex :
+                 authority->texture);
+
+      cogl_texture_get_gl_texture (texture,
+                                   &gl_texture,
+                                   &gl_target);
 
       _cogl_set_active_texture_unit (unit_index);
 
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index b14669706..9767694c1 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -230,11 +230,6 @@ struct _CoglPipelineLayer
   /* The texture for this layer, or COGL_INVALID_HANDLE for an empty
    * layer */
   CoglHandle                 texture;
-  gboolean                   texture_overridden;
-  /* If ->texture_overridden == TRUE then the texture is instead
-   * defined by these... */
-  GLuint                     slice_gl_texture;
-  GLenum                     slice_gl_target;
 
   CoglPipelineFilter         mag_filter;
   CoglPipelineFilter         min_filter;
@@ -707,7 +702,7 @@ typedef struct _CoglPipelineFlushOptions
 
   guint32                       fallback_layers;
   guint32                       disable_layers;
-  GLuint                        layer0_override_texture;
+  CoglHandle                    layer0_override_texture;
   CoglPipelineWrapModeOverrides wrap_mode_overrides;
 } CoglPipelineFlushOptions;
 
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index ce2c143f1..6e3428ef0 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -2059,13 +2059,10 @@ _cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority,
     }
 }
 
-static void
-_cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
-                                  int layer_index,
-                                  CoglHandle texture,
-                                  gboolean overriden,
-                                  GLuint slice_gl_texture,
-                                  GLenum slice_gl_target)
+void
+cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
+                                 int layer_index,
+                                 CoglHandle texture)
 {
   CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE;
   CoglPipelineLayer *layer;
@@ -2084,11 +2081,7 @@ _cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
    * state we want to change */
   authority = _cogl_pipeline_layer_get_authority (layer, change);
 
-  if (authority->texture_overridden == overriden &&
-      authority->texture == texture &&
-      (authority->texture_overridden == FALSE ||
-       (authority->slice_gl_texture == slice_gl_texture &&
-        authority->slice_gl_target == slice_gl_target)))
+  if (authority->texture == texture)
     return;
 
   new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change);
@@ -2107,11 +2100,7 @@ _cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
           CoglPipelineLayer *old_authority =
             _cogl_pipeline_layer_get_authority (parent, change);
 
-          if (old_authority->texture_overridden == overriden &&
-              old_authority->texture == texture &&
-              (old_authority->texture_overridden == FALSE ||
-               (old_authority->slice_gl_texture == slice_gl_texture &&
-                old_authority->slice_gl_target == slice_gl_target)))
+          if (old_authority->texture == texture)
             {
               layer->differences &= ~change;
 
@@ -2133,9 +2122,6 @@ _cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
       layer->texture != COGL_INVALID_HANDLE)
     cogl_handle_unref (layer->texture);
   layer->texture = texture;
-  layer->texture_overridden = overriden;
-  layer->slice_gl_texture = slice_gl_texture;
-  layer->slice_gl_target = slice_gl_target;
 
   /* If we weren't previously the authority on this state then we need
    * to extended our differences mask and so it's possible that some
@@ -2152,43 +2138,6 @@ changed:
   handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
 }
 
-static void
-_cogl_pipeline_set_layer_gl_texture_slice (CoglPipeline *pipeline,
-                                           int layer_index,
-                                           CoglHandle texture,
-                                           GLuint slice_gl_texture,
-                                           GLenum slice_gl_target)
-{
-  g_return_if_fail (cogl_is_pipeline (pipeline));
-  /* GL texture overrides can only be set in association with a parent
-   * CoglTexture */
-  g_return_if_fail (cogl_is_texture (texture));
-
-  _cogl_pipeline_set_layer_texture (pipeline,
-                                    layer_index,
-                                    texture,
-                                    TRUE, /* slice override */
-                                    slice_gl_texture,
-                                    slice_gl_target);
-}
-
-void
-cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
-                                 int layer_index,
-                                 CoglHandle texture)
-{
-  g_return_if_fail (cogl_is_pipeline (pipeline));
-  g_return_if_fail (texture == COGL_INVALID_HANDLE ||
-                    cogl_is_texture (texture));
-
-  _cogl_pipeline_set_layer_texture (pipeline,
-                                    layer_index,
-                                    texture,
-                                    FALSE, /* slice override */
-                                    0, /* slice_gl_texture */
-                                    0); /* slice_gl_target */
-}
-
 typedef struct
 {
   int i;
@@ -2737,28 +2686,18 @@ apply_wrap_mode_overrides_cb (CoglPipelineLayer *layer,
 typedef struct
 {
   CoglPipeline *pipeline;
-  GLuint gl_texture;
+  CoglHandle texture;
 } CoglPipelineOverrideLayerState;
 
 static gboolean
 override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data)
 {
   CoglPipelineOverrideLayerState *state = user_data;
-  CoglHandle texture;
-  GLenum gl_target;
 
-  texture = _cogl_pipeline_layer_get_texture (layer);
+  cogl_pipeline_set_layer_texture (state->pipeline,
+                                   layer->index,
+                                   state->texture);
 
-  if (texture != COGL_INVALID_HANDLE)
-    cogl_texture_get_gl_texture (texture, NULL, &gl_target);
-  else
-    gl_target = GL_TEXTURE_2D;
-
-  _cogl_pipeline_set_layer_gl_texture_slice (state->pipeline,
-                                             layer->index,
-                                             texture,
-                                             state->gl_texture,
-                                             gl_target);
   return TRUE;
 }
 
@@ -2810,7 +2749,7 @@ _cogl_pipeline_apply_overrides (CoglPipeline *pipeline,
        * _cogl_pipeline_foreach_layer_internal() here even though we know
        * there's only one layer. */
       state.pipeline = pipeline;
-      state.gl_texture = options->layer0_override_texture;
+      state.texture = options->layer0_override_texture;
       _cogl_pipeline_foreach_layer_internal (pipeline,
                                              override_layer_texture_cb,
                                              &state);
@@ -2833,26 +2772,7 @@ static gboolean
 _cogl_pipeline_layer_texture_equal (CoglPipelineLayer *authority0,
                                     CoglPipelineLayer *authority1)
 {
-  GLuint gl_handle0, gl_handle1;
-  GLenum gl_target0, gl_target1;
-
-  if (authority0->texture_overridden)
-    {
-      gl_handle0 = authority0->slice_gl_texture;
-      gl_target0 = authority0->slice_gl_target;
-    }
-  else
-    cogl_texture_get_gl_texture (authority0->texture, &gl_handle0, &gl_target0);
-
-  if (authority1->texture_overridden)
-    {
-      gl_handle1 = authority1->slice_gl_texture;
-      gl_target1 = authority1->slice_gl_target;
-    }
-  else
-    cogl_texture_get_gl_texture (authority1->texture, &gl_handle1, &gl_target1);
-
-  return gl_handle0 == gl_handle1 && gl_target0 == gl_target1;
+  return authority0->texture == authority1->texture;
 }
 
 /* Determine the mask of differences between two layers.
@@ -4633,7 +4553,6 @@ _cogl_pipeline_init_default_layers (void)
   layer->unit_index = 0;
 
   layer->texture = COGL_INVALID_HANDLE;
-  layer->texture_overridden = FALSE;
 
   layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR;
   layer->min_filter = COGL_PIPELINE_FILTER_LINEAR;
diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c
index 5329ea29c..23244ebb1 100644
--- a/cogl/cogl-primitives.c
+++ b/cogl/cogl-primitives.c
@@ -50,6 +50,7 @@
 typedef struct _TextureSlicedQuadState
 {
   CoglPipeline *pipeline;
+  CoglHandle main_texture;
   float tex_virtual_origin_x;
   float tex_virtual_origin_y;
   float quad_origin_x;
@@ -79,6 +80,7 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
                           void *user_data)
 {
   TextureSlicedQuadState *state = user_data;
+  CoglHandle texture_override;
   float quad_coords[4];
 
 #define TEX_VIRTUAL_TO_QUAD(V, Q, AXIS) \
@@ -113,11 +115,18 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
              subtexture_coords[0], subtexture_coords[1],
              subtexture_coords[2], subtexture_coords[3]);
 
+  /* We only need to override the texture if it's different from the
+     main texture */
+  if (texture_handle == state->main_texture)
+    texture_override = COGL_INVALID_HANDLE;
+  else
+    texture_override = texture_handle;
+
   _cogl_journal_log_quad (quad_coords,
                           state->pipeline,
                           1, /* one layer */
                           0, /* don't need to use fallbacks */
-                          gl_handle, /* replace the layer0 texture */
+                          texture_override, /* replace the layer0 texture */
                           NULL, /* we never use wrap mode overrides */
                           subtexture_coords,
                           4);
@@ -299,6 +308,8 @@ _cogl_texture_quad_multiple_primitives (CoglHandle    tex_handle,
                                validate_first_layer_cb,
                                &validate_first_layer_state);
 
+  state.main_texture = tex_handle;
+
   if (validate_first_layer_state.override_pipeline)
     state.pipeline = validate_first_layer_state.override_pipeline;
   else
@@ -537,7 +548,7 @@ _cogl_multitexture_quad_single_primitive (const float  *position,
                           pipeline,
                           n_layers,
                           0, /* we don't need fallback layers */
-                          0, /* don't replace the layer0 texture */
+                          COGL_INVALID_HANDLE, /* no texture override */
                           NULL, /* we never use wrap mode overrides */
                           final_tex_coords,
                           n_layers * 4);