[cogl/wip/neil/master-next: 2/4] cogl-pipeline-layer: Use CoglTextureType instead of GL target enum



commit 86ce99168be6d269650500c1a9b95139d28e9ee0
Author: Neil Roberts <neil linux intel com>
Date:   Thu Feb 9 12:52:45 2012 +0000

    cogl-pipeline-layer: Use CoglTextureType instead of GL target enum
    
    Instead of storing the GLenum for the target of the last used texture
    for a layer it now stores the CoglTextureType instead. The state name
    has been renamed to 'texture type' instead of 'texture target'.
    Previously the default pipeline layer would store 0 here to represent
    that there is no texture. This has been changed to store
    COGL_TEXTURE_TYPE_2D instead which means that all pipeline layers
    always have a valid value for the texture type. Any places that were
    previously fetching the texture from a layer to determine the target
    (for example when generating shaders or when enabling a particular
    texture target) now use the texture type instead. This means they will
    work even for layers that don't have a texture.
    
    This also changes it so that when binding a fallback texture instead
    of always using a 2D texture it will now use the default texture
    corresponding to the texture type of the layer. That way when the
    generated shader tries to do a texture lookup for that type of texture
    it will get a valid texture object. To make this work the patch adds a
    default texture for 3D textures to the context and also makes the
    default rectangle texture actually be a rectangle texture instead of
    using a 2D texture.

 cogl/cogl-context-private.h              |    1 +
 cogl/cogl-context.c                      |   50 +++++++++++++------
 cogl/cogl-pipeline-fragend-arbfp.c       |   58 +++++++++++-----------
 cogl/cogl-pipeline-fragend-fixed.c       |   37 +++++++++-----
 cogl/cogl-pipeline-fragend-glsl.c        |   55 ++++++++-------------
 cogl/cogl-pipeline-layer-private.h       |   15 ++++--
 cogl/cogl-pipeline-layer-state-private.h |   12 ++--
 cogl/cogl-pipeline-layer-state.c         |   77 +++++++++++++++---------------
 cogl/cogl-pipeline-layer.c               |   14 +++---
 cogl/cogl-pipeline-opengl.c              |   21 +++++---
 cogl/cogl-pipeline.c                     |   36 ++++++++------
 11 files changed, 204 insertions(+), 172 deletions(-)
---
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
index 946d24a..c9dd71f 100644
--- a/cogl/cogl-context-private.h
+++ b/cogl/cogl-context-private.h
@@ -126,6 +126,7 @@ struct _CoglContext
 
   /* Textures */
   CoglHandle        default_gl_texture_2d_tex;
+  CoglHandle        default_gl_texture_3d_tex;
   CoglHandle        default_gl_texture_rect_tex;
 
   /* Central list of all framebuffers so all journals can be flushed
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index 21c10b7..e773006 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -38,6 +38,9 @@
 #include "cogl-renderer-private.h"
 #include "cogl-journal-private.h"
 #include "cogl-texture-private.h"
+#include "cogl-texture-2d-private.h"
+#include "cogl-texture-3d-private.h"
+#include "cogl-texture-rectangle-private.h"
 #include "cogl-pipeline-private.h"
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-framebuffer-private.h"
@@ -130,6 +133,7 @@ cogl_context_new (CoglDisplay *display,
 {
   CoglContext *context;
   GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
+  CoglBitmap *default_texture_bitmap;
   const CoglWinsysVtable *winsys;
   int i;
 
@@ -275,6 +279,7 @@ cogl_context_new (CoglDisplay *display,
   context->legacy_state_set = 0;
 
   context->default_gl_texture_2d_tex = NULL;
+  context->default_gl_texture_3d_tex = NULL;
   context->default_gl_texture_rect_tex = NULL;
 
   context->framebuffers = NULL;
@@ -376,25 +381,36 @@ cogl_context_new (CoglDisplay *display,
   _cogl_matrix_stack_init_cache (&_context->builtin_flushed_projection);
   _cogl_matrix_stack_init_cache (&_context->builtin_flushed_modelview);
 
+  default_texture_bitmap =
+    _cogl_bitmap_new_from_data (default_texture_data,
+                                COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                                1, 1, /* width/height */
+                                4, /* rowstride */
+                                NULL, /* destroy function */
+                                NULL /* destroy function data */);
+
   /* Create default textures used for fall backs */
   context->default_gl_texture_2d_tex =
-    cogl_texture_new_from_data (1, /* width */
-                                1, /* height */
-                                COGL_TEXTURE_NO_SLICING,
-                                COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */
-                                /* internal format */
-                                COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                                0, /* auto calc row stride */
-                                default_texture_data);
+    _cogl_texture_2d_new_from_bitmap (default_texture_bitmap,
+                                      COGL_TEXTURE_NONE,
+                                      /* internal format */
+                                      COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                                      NULL);
+  /* If 3D or rectangle textures aren't supported then these should
+     just silently return NULL */
+  context->default_gl_texture_3d_tex =
+    _cogl_texture_3d_new_from_bitmap (default_texture_bitmap,
+                                      1, /* height */
+                                      1, /* depth */
+                                      COGL_TEXTURE_NONE,
+                                      COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                                      NULL);
   context->default_gl_texture_rect_tex =
-    cogl_texture_new_from_data (1, /* width */
-                                1, /* height */
-                                COGL_TEXTURE_NO_SLICING,
-                                COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */
-                                /* internal format */
-                                COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                                0, /* auto calc row stride */
-                                default_texture_data);
+    _cogl_texture_rectangle_new_from_bitmap (default_texture_bitmap,
+                                             COGL_TEXTURE_NONE,
+                                             COGL_PIXEL_FORMAT_RGBA_8888_PRE);
+
+  cogl_object_unref (default_texture_bitmap);
 
   cogl_push_source (context->opaque_color_pipeline);
   _cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
@@ -433,6 +449,8 @@ _cogl_context_free (CoglContext *context)
 
   if (context->default_gl_texture_2d_tex)
     cogl_object_unref (context->default_gl_texture_2d_tex);
+  if (context->default_gl_texture_3d_tex)
+    cogl_object_unref (context->default_gl_texture_3d_tex);
   if (context->default_gl_texture_rect_tex)
     cogl_object_unref (context->default_gl_texture_rect_tex);
 
diff --git a/cogl/cogl-pipeline-fragend-arbfp.c b/cogl/cogl-pipeline-fragend-arbfp.c
index b08899b..a3d99b1 100644
--- a/cogl/cogl-pipeline-fragend-arbfp.c
+++ b/cogl/cogl-pipeline-fragend-arbfp.c
@@ -291,26 +291,31 @@ _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
 }
 
 static const char *
-gl_target_to_arbfp_string (GLenum gl_target)
+texture_type_to_arbfp_string (CoglTextureType texture_type)
 {
-  if (gl_target == GL_TEXTURE_1D)
-    return "1D";
-  else if (gl_target == GL_TEXTURE_2D)
-    return "2D";
-#ifdef GL_ARB_texture_rectangle
-  else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
-    return "RECT";
+  switch (texture_type)
+    {
+#if 0 /* TODO */
+    case COGL_TEXTURE_TYPE_1D:
+      return "1D";
 #endif
-  else if (gl_target == GL_TEXTURE_3D)
-    return "3D";
-  else
-    return "2D";
+    case COGL_TEXTURE_TYPE_2D:
+      return "2D";
+    case COGL_TEXTURE_TYPE_3D:
+      return "3D";
+    case COGL_TEXTURE_TYPE_RECTANGLE:
+      return "RECT";
+    }
+
+  g_warn_if_reached ();
+
+  return "2D";
 }
 
 static void
 setup_texture_source (CoglPipelineShaderState *shader_state,
                       int unit_index,
-                      GLenum gl_target)
+                      CoglTextureType texture_type)
 {
   if (!shader_state->unit_state[unit_index].sampled)
     {
@@ -329,7 +334,7 @@ setup_texture_source (CoglPipelineShaderState *shader_state,
                                 unit_index,
                                 unit_index,
                                 unit_index,
-                                gl_target_to_arbfp_string (gl_target));
+                                texture_type_to_arbfp_string (texture_type));
       shader_state->unit_state[unit_index].sampled = TRUE;
     }
 }
@@ -349,7 +354,7 @@ typedef struct _CoglPipelineFragendARBfpArg
 
   /* for type = TEXTURE */
   int texture_unit;
-  GLenum texture_target;
+  CoglTextureType texture_type;
 
   /* for type = CONSTANT */
   int constant_id;
@@ -392,8 +397,6 @@ setup_arg (CoglPipeline *pipeline,
 {
   CoglPipelineShaderState *shader_state = get_shader_state (pipeline);
   static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" };
-  GLenum gl_target;
-  CoglHandle texture;
 
   switch (src)
     {
@@ -401,12 +404,9 @@ setup_arg (CoglPipeline *pipeline,
       arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE;
       arg->name = "texel%d";
       arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer);
-      texture = _cogl_pipeline_layer_get_texture (layer);
-      if (texture)
-        cogl_texture_get_gl_texture (texture, NULL, &gl_target);
-      else
-        gl_target = GL_TEXTURE_2D;
-      setup_texture_source (shader_state, arg->texture_unit, gl_target);
+      setup_texture_source (shader_state,
+                            arg->texture_unit,
+                            _cogl_pipeline_layer_get_texture_type (layer));
       break;
     case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT:
       {
@@ -437,12 +437,12 @@ setup_arg (CoglPipeline *pipeline,
       arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE;
       arg->name = "texture[%d]";
       arg->texture_unit = src - GL_TEXTURE0;
-      texture = _cogl_pipeline_layer_get_texture (layer);
-      if (texture)
-        cogl_texture_get_gl_texture (texture, NULL, &gl_target);
-      else
-        gl_target = GL_TEXTURE_2D;
-      setup_texture_source (shader_state, arg->texture_unit, gl_target);
+      /* FIXME: Is this right? Shouldn't it be using the texture type
+         of the layer for the given unit, not the type of the layer
+         we're generating for? */
+      setup_texture_source (shader_state,
+                            arg->texture_unit,
+                            _cogl_pipeline_layer_get_texture_type (layer));
     }
 
   arg->swizzle = "";
diff --git a/cogl/cogl-pipeline-fragend-fixed.c b/cogl/cogl-pipeline-fragend-fixed.c
index 64b84b8..44edfa1 100644
--- a/cogl/cogl-pipeline-fragend-fixed.c
+++ b/cogl/cogl-pipeline-fragend-fixed.c
@@ -50,6 +50,10 @@
 #include <glib/gprintf.h>
 #include <string.h>
 
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#endif
+
 const CoglPipelineFragend _cogl_pipeline_fixed_fragend;
 
 static void
@@ -149,20 +153,27 @@ _cogl_pipeline_fragend_fixed_add_layer (CoglPipeline *pipeline,
       return TRUE;
     }
 
-  /* Handle enabling or disabling the right texture target */
-  if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET)
+  /* Handle enabling or disabling the right texture type */
+  if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE)
     {
-      CoglPipelineLayer *tex_authority =
-        _cogl_pipeline_layer_get_authority (layer,
-                                            COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA);
-      CoglPipelineLayer *target_authority =
-        _cogl_pipeline_layer_get_authority (layer,
-                                            COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET);
-      /* XXX: currently layers with no associated texture fallback to
-       * using ctx->default_gl_texture_2d_tex so they have a texture
-       * target of GL_TEXTURE_2D */
-      GLenum gl_target =
-        tex_authority->texture ? target_authority->target : GL_TEXTURE_2D;
+      CoglTextureType texture_type =
+        _cogl_pipeline_layer_get_texture_type (layer);
+      GLenum gl_target;
+
+      switch (texture_type)
+        {
+        case COGL_TEXTURE_TYPE_2D:
+          gl_target = GL_TEXTURE_2D;
+          break;
+
+        case COGL_TEXTURE_TYPE_3D:
+          gl_target = GL_TEXTURE_3D;
+          break;
+
+        case COGL_TEXTURE_TYPE_RECTANGLE:
+          gl_target = GL_TEXTURE_RECTANGLE_ARB;
+          break;
+        }
 
       _cogl_set_active_texture_unit (unit_index);
 
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c
index 890e3b1..91a3e6b 100644
--- a/cogl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/cogl-pipeline-fragend-glsl.c
@@ -422,48 +422,33 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
      to be replaced */
   if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP))
     {
-      CoglHandle texture = _cogl_pipeline_layer_get_texture (layer);
+      CoglTextureType texture_type =
+        _cogl_pipeline_layer_get_texture_type (layer);
       const char *target_string, *tex_coord_swizzle;
 
-      if (texture == NULL)
+      switch (texture_type)
         {
-          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;
+#if 0 /* TODO */
+        case COGL_TEXTURE_TYPE_1D:
+          target_string = "1D";
+          tex_coord_swizzle = "s";
+          break;
 #endif
 
-            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;
-#endif
+        case COGL_TEXTURE_TYPE_2D:
+          target_string = "2D";
+          tex_coord_swizzle = "st";
+          break;
 
-            case GL_TEXTURE_3D:
-              target_string = "3D";
-              tex_coord_swizzle = "stp";
-              break;
+        case COGL_TEXTURE_TYPE_3D:
+          target_string = "3D";
+          tex_coord_swizzle = "stp";
+          break;
 
-            default:
-              g_assert_not_reached ();
-            }
+        case COGL_TEXTURE_TYPE_RECTANGLE:
+          target_string = "2DRect";
+          tex_coord_swizzle = "st";
+          break;
         }
 
       /* Create a sampler uniform */
diff --git a/cogl/cogl-pipeline-layer-private.h b/cogl/cogl-pipeline-layer-private.h
index 0bd7034..6911b2b 100644
--- a/cogl/cogl-pipeline-layer-private.h
+++ b/cogl/cogl-pipeline-layer-private.h
@@ -71,7 +71,7 @@ typedef enum
 {
   /* sparse state */
   COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
-  COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX,
+  COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
   COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
   COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
   COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
@@ -99,8 +99,8 @@ typedef enum
 {
   COGL_PIPELINE_LAYER_STATE_UNIT =
     1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
-  COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET =
-    1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX,
+  COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE =
+    1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
   COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
     1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
   COGL_PIPELINE_LAYER_STATE_FILTERS =
@@ -259,7 +259,11 @@ struct _CoglPipelineLayer
   /* The texture for this layer, or NULL for an empty
    * layer */
   CoglTexture               *texture;
-  GLenum                     target;
+  /* The type of the texture. This is always set even if the texture
+     is NULL and it will be used to determine what type of texture
+     lookups to use in any shaders generated by the pipeline
+     backends. */
+  CoglTextureType            texture_type;
 
   CoglPipelineFilter         mag_filter;
   CoglPipelineFilter         min_filter;
@@ -363,6 +367,9 @@ _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
 CoglTexture *
 _cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
 
+CoglTextureType
+_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer);
+
 CoglPipelineFilter
 _cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);
 
diff --git a/cogl/cogl-pipeline-layer-state-private.h b/cogl/cogl-pipeline-layer-state-private.h
index 52bbe0e..992e889 100644
--- a/cogl/cogl-pipeline-layer-state-private.h
+++ b/cogl/cogl-pipeline-layer-state-private.h
@@ -45,9 +45,9 @@ _cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline,
                                      int layer_index);
 
 gboolean
-_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0,
-                                           CoglPipelineLayer *authority1,
-                                           CoglPipelineEvalFlags flags);
+_cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
+                                         CoglPipelineLayer *authority1,
+                                         CoglPipelineEvalFlags flags);
 
 gboolean
 _cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0,
@@ -92,9 +92,9 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
                                       CoglPipelineHashState *state);
 
 void
-_cogl_pipeline_layer_hash_texture_target_state (CoglPipelineLayer *authority,
-                                                CoglPipelineLayer **authorities,
-                                                CoglPipelineHashState *state);
+_cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
+                                              CoglPipelineLayer **authorities,
+                                              CoglPipelineHashState *state);
 
 void
 _cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority,
diff --git a/cogl/cogl-pipeline-layer-state.c b/cogl/cogl-pipeline-layer-state.c
index 49e01c8..f70d2c7 100644
--- a/cogl/cogl-pipeline-layer-state.c
+++ b/cogl/cogl-pipeline-layer-state.c
@@ -129,12 +129,22 @@ cogl_pipeline_get_layer_texture (CoglPipeline *pipeline,
   return _cogl_pipeline_layer_get_texture (layer);
 }
 
+CoglTextureType
+_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer)
+{
+  CoglPipelineLayer *authority =
+    _cogl_pipeline_layer_get_authority (layer,
+                                        COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE);
+
+  return authority->texture_type;
+}
+
 static void
-_cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
-                                         int layer_index,
-                                         GLenum target)
+_cogl_pipeline_set_layer_texture_type (CoglPipeline *pipeline,
+                                       int layer_index,
+                                       CoglTextureType texture_type)
 {
-  CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET;
+  CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE;
   CoglPipelineLayer *layer;
   CoglPipelineLayer *authority;
   CoglPipelineLayer *new;
@@ -151,7 +161,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
    * state we want to change */
   authority = _cogl_pipeline_layer_get_authority (layer, change);
 
-  if (target == authority->target)
+  if (texture_type == authority->texture_type)
     return;
 
   new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change);
@@ -170,7 +180,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
           CoglPipelineLayer *old_authority =
             _cogl_pipeline_layer_get_authority (parent, change);
 
-          if (old_authority->target == target)
+          if (old_authority->texture_type == texture_type)
             {
               layer->differences &= ~change;
 
@@ -183,7 +193,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
         }
     }
 
-  layer->target = target;
+  layer->texture_type = texture_type;
 
   /* 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
@@ -279,30 +289,13 @@ changed:
   _cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
 }
 
-/* A convenience for querying the target of a given texture that
- * notably returns 0 for NULL textures - so we can say that a layer
- * with no associated CoglTexture will have a texture target of 0.
- */
-static GLenum
-get_texture_target (CoglTexture *texture)
-{
-  GLuint ignore_handle;
-  GLenum gl_target;
-
-  _COGL_RETURN_VAL_IF_FAIL (texture, 0);
-
-  cogl_texture_get_gl_texture (texture, &ignore_handle, &gl_target);
-
-  return gl_target;
-}
-
 void
 cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
                                  int layer_index,
                                  CoglTexture *texture)
 {
   /* For the convenience of fragend code we separate texture state
-   * into the "target" and the "data", and setting a layer texture
+   * into the "type" and the "data", and setting a layer texture
    * updates both of these properties.
    *
    * One example for why this is helpful is that the fragends may
@@ -311,17 +304,22 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
    * For the sake of determining if pipelines have equivalent fragment
    * processing state we don't need to compare that the same
    * underlying texture objects are referenced by the pipelines but we
-   * do need to see if they use the same texture targets. Making this
+   * do need to see if they use the same texture types. Making this
    * distinction is much simpler if they are in different state
    * groups.
    *
-   * Note: if a NULL texture is set then we leave the target unchanged
+   * Note: if a NULL texture is set then we leave the type unchanged
    * so we can avoid needlessly invalidating any associated fragment
    * program.
    */
   if (texture)
-    _cogl_pipeline_set_layer_texture_target (pipeline, layer_index,
-                                             get_texture_target (texture));
+    {
+      CoglTextureType texture_type =
+        cogl_texture_get_type (texture);
+      _cogl_pipeline_set_layer_texture_type (pipeline,
+                                             layer_index,
+                                             texture_type);
+    }
   _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture);
 }
 
@@ -867,11 +865,11 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
 }
 
 gboolean
-_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0,
-                                           CoglPipelineLayer *authority1,
-                                           CoglPipelineEvalFlags flags)
+_cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
+                                         CoglPipelineLayer *authority1,
+                                         CoglPipelineEvalFlags flags)
 {
-  return authority0->target == authority1->target;
+  return authority0->texture_type == authority1->texture_type;
 }
 
 gboolean
@@ -1613,14 +1611,15 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
 }
 
 void
-_cogl_pipeline_layer_hash_texture_target_state (CoglPipelineLayer *authority,
-                                                CoglPipelineLayer **authorities,
-                                                CoglPipelineHashState *state)
+_cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
+                                              CoglPipelineLayer **authorities,
+                                              CoglPipelineHashState *state)
 {
-  GLenum gl_target = authority->target;
+  CoglTextureType texture_type = authority->texture_type;
 
-  state->hash =
-    _cogl_util_one_at_a_time_hash (state->hash, &gl_target, sizeof (gl_target));
+  state->hash = _cogl_util_one_at_a_time_hash (state->hash,
+                                               &texture_type,
+                                               sizeof (texture_type));
 }
 
 void
diff --git a/cogl/cogl-pipeline-layer.c b/cogl/cogl-pipeline-layer.c
index d2d799d..558a8b6 100644
--- a/cogl/cogl-pipeline-layer.c
+++ b/cogl/cogl-pipeline-layer.c
@@ -165,7 +165,7 @@ _cogl_pipeline_layer_init_multi_property_sparse_state (
     /* XXX: avoid using a default: label so we get a warning if we
      * don't explicitly handle a newly defined state-group here. */
     case COGL_PIPELINE_LAYER_STATE_UNIT:
-    case COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET:
+    case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE:
     case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA:
     case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS:
     case COGL_PIPELINE_LAYER_STATE_USER_MATRIX:
@@ -544,13 +544,13 @@ _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
                                             layers_difference,
                                             authorities1);
 
-  if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET)
+  if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE)
     {
       CoglPipelineLayerStateIndex state_index =
-        COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX;
-      if (!_cogl_pipeline_layer_texture_target_equal (authorities0[state_index],
-                                                      authorities1[state_index],
-                                                      flags))
+        COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX;
+      if (!_cogl_pipeline_layer_texture_type_equal (authorities0[state_index],
+                                                    authorities1[state_index],
+                                                    flags))
         return FALSE;
     }
 
@@ -655,7 +655,7 @@ _cogl_pipeline_init_default_layers (void)
   layer->unit_index = 0;
 
   layer->texture = NULL;
-  layer->target = 0;
+  layer->texture_type = COGL_TEXTURE_TYPE_2D;
 
   layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR;
   layer->min_filter = COGL_PIPELINE_FILTER_LINEAR;
diff --git a/cogl/cogl-pipeline-opengl.c b/cogl/cogl-pipeline-opengl.c
index aaf5ea8..46c4241 100644
--- a/cogl/cogl-pipeline-opengl.c
+++ b/cogl/cogl-pipeline-opengl.c
@@ -779,16 +779,23 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
 
   if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
     {
-      unsigned long state = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA;
-      CoglPipelineLayer *authority =
-        _cogl_pipeline_layer_get_authority (layer, state);
-      CoglTexture *texture;
+      CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer);
       GLuint gl_texture;
       GLenum gl_target;
 
-      texture = (authority->texture == NULL ?
-                 ctx->default_gl_texture_2d_tex :
-                 authority->texture);
+      if (texture == NULL)
+        switch (_cogl_pipeline_layer_get_texture_type (layer))
+          {
+          case COGL_TEXTURE_TYPE_2D:
+            texture = ctx->default_gl_texture_2d_tex;
+            break;
+          case COGL_TEXTURE_TYPE_3D:
+            texture = ctx->default_gl_texture_3d_tex;
+            break;
+          case COGL_TEXTURE_TYPE_RECTANGLE:
+            texture = ctx->default_gl_texture_rect_tex;
+            break;
+          }
 
       cogl_texture_get_gl_texture (texture,
                                    &gl_texture,
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 74ba160..fa3b1e2 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -1870,8 +1870,8 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
 {
   CoglPipelineFallbackState *state = user_data;
   CoglPipeline *pipeline = state->pipeline;
-  CoglHandle texture = _cogl_pipeline_layer_get_texture (layer);
-  GLenum gl_target;
+  CoglTextureType texture_type = _cogl_pipeline_layer_get_texture_type (layer);
+  CoglTexture *texture = NULL;
   COGL_STATIC_COUNTER (layer_fallback_counter,
                        "layer fallback counter",
                        "Increments each time a layer's texture is "
@@ -1885,18 +1885,22 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
 
   COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter);
 
-  if (G_LIKELY (texture != NULL))
-    cogl_texture_get_gl_texture (texture, NULL, &gl_target);
-  else
-    gl_target = GL_TEXTURE_2D;
+  switch (texture_type)
+    {
+    case COGL_TEXTURE_TYPE_2D:
+      texture = ctx->default_gl_texture_2d_tex;
+      break;
 
-  if (gl_target == GL_TEXTURE_2D)
-    texture = ctx->default_gl_texture_2d_tex;
-#ifdef HAVE_COGL_GL
-  else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
-    texture = ctx->default_gl_texture_rect_tex;
-#endif
-  else
+    case COGL_TEXTURE_TYPE_3D:
+      texture = ctx->default_gl_texture_3d_tex;
+      break;
+
+    case COGL_TEXTURE_TYPE_RECTANGLE:
+      texture = ctx->default_gl_texture_rect_tex;
+      break;
+    }
+
+  if (texture == NULL)
     {
       g_warning ("We don't have a fallback texture we can use to fill "
                  "in for an invalid pipeline layer, since it was "
@@ -2605,8 +2609,8 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
   CoglPipelineLayerStateIndex _index;
   layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] =
     _cogl_pipeline_layer_hash_unit_state;
-  layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX] =
-    _cogl_pipeline_layer_hash_texture_target_state;
+  layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX] =
+    _cogl_pipeline_layer_hash_texture_type_state;
   layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] =
     _cogl_pipeline_layer_hash_texture_data_state;
   layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX] =
@@ -2912,7 +2916,7 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
 {
   CoglPipelineLayerState state =
     (COGL_PIPELINE_LAYER_STATE_COMBINE |
-     COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET |
+     COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE |
      COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS |
      COGL_PIPELINE_LAYER_STATE_UNIT |
      COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);



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