[cogl] Allow npot Texture2D creation with only basic npot support



commit 6f6c5734d076372d98d0ec331b177ef7d65aa67d
Author: Robert Bragg <robert linux intel com>
Date:   Tue Apr 24 17:44:38 2012 +0100

    Allow npot Texture2D creation with only basic npot support
    
    Cogl has feature flags for basic npot texture support and then separate
    flags for npot + repeat and npot + mipmap. If those three features are
    available then there is a feature for full-npot support too for
    convenience. The cogl_texture_2d_new_ constructors were checking for
    full npot support and failing if not available but since we expose the
    fine grained features to the user the user should be able to check the
    limitations of npot textures and still choose to allocate them.
    
    _cogl_texture_2d_can_create() now only checks for basic npot support
    when creating a npot texture.  Since this change also affects the
    automagic cogl_texture_ constructors they now check for basic npot +
    mipmap support before considering using a Texture2D.
    
    Notably the cogl_texture_ constructors will try constructing a Texture2D
    even if we don't have npot + repeat support since the alternative is a
    sliced texture which will need manual repeating anyway. Accordingly the
    Texture2D::can_hardware_repeat and ::transform_quad_coords_to_gl vfuncs
    have been made aware of the npot + repeat feature flag.
    
    Reviewed-by: Neil Roberts <neil linux intel com>

 cogl/cogl-bitmap-private.h |   27 ++++++++++++++++++++
 cogl/cogl-bitmap.c         |   26 --------------------
 cogl/cogl-texture-2d.c     |   25 ++++++++++++++----
 cogl/cogl-texture.c        |   57 ++++++++++++++++++++++++++++++--------------
 4 files changed, 85 insertions(+), 50 deletions(-)
---
diff --git a/cogl/cogl-bitmap-private.h b/cogl/cogl-bitmap-private.h
index c6b3cfc..a95754a 100644
--- a/cogl/cogl-bitmap-private.h
+++ b/cogl/cogl-bitmap-private.h
@@ -32,6 +32,33 @@
 #include "cogl-buffer.h"
 #include "cogl-bitmap.h"
 
+struct _CoglBitmap
+{
+  CoglObject _parent;
+
+  /* Pointer back to the context that this bitmap was created with */
+  CoglContext *context;
+
+  CoglPixelFormat format;
+  int width;
+  int height;
+  int rowstride;
+
+  uint8_t *data;
+
+  CoglBool mapped;
+  CoglBool bound;
+
+  /* If this is non-null then 'data' is ignored and instead it is
+     fetched from this shared bitmap. */
+  CoglBitmap *shared_bmp;
+
+  /* If this is non-null then 'data' is treated as an offset into the
+     buffer and map will divert to mapping the buffer */
+  CoglBuffer *buffer;
+};
+
+
 /*
  * _cogl_bitmap_new_with_malloc_buffer:
  * @context: A #CoglContext
diff --git a/cogl/cogl-bitmap.c b/cogl/cogl-bitmap.c
index 1f0a673..fb233df 100644
--- a/cogl/cogl-bitmap.c
+++ b/cogl/cogl-bitmap.c
@@ -35,32 +35,6 @@
 
 #include <string.h>
 
-struct _CoglBitmap
-{
-  CoglObject _parent;
-
-  /* Pointer back to the context that this bitmap was created with */
-  CoglContext *context;
-
-  CoglPixelFormat format;
-  int width;
-  int height;
-  int rowstride;
-
-  uint8_t *data;
-
-  CoglBool mapped;
-  CoglBool bound;
-
-  /* If this is non-null then 'data' is ignored and instead it is
-     fetched from this shared bitmap. */
-  CoglBitmap *shared_bmp;
-
-  /* If this is non-null then 'data' is treated as an offset into the
-     buffer and map will divert to mapping the buffer */
-  CoglBuffer *buffer;
-};
-
 static void _cogl_bitmap_free (CoglBitmap *bmp);
 
 COGL_OBJECT_DEFINE (Bitmap, bitmap);
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 4905dbf..efb1933 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -115,7 +115,7 @@ _cogl_texture_2d_can_create (unsigned int width,
 
   /* If NPOT textures aren't supported then the size must be a power
      of two */
-  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) &&
+  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
       (!_cogl_util_is_pot (width) ||
        !_cogl_util_is_pot (height)))
     return FALSE;
@@ -631,7 +631,16 @@ _cogl_texture_2d_is_sliced (CoglTexture *tex)
 static CoglBool
 _cogl_texture_2d_can_hardware_repeat (CoglTexture *tex)
 {
-  return TRUE;
+  CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
+
+  _COGL_GET_CONTEXT (ctx, FALSE);
+
+  if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT) ||
+      (_cogl_util_is_pot (tex_2d->width) &&
+       _cogl_util_is_pot (tex_2d->height)))
+    return TRUE;
+  else
+    return FALSE;
 }
 
 static void
@@ -650,15 +659,19 @@ _cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex,
   /* The texture coordinates map directly so we don't need to do
      anything other than check for repeats */
 
-  CoglBool need_repeat = FALSE;
   int i;
 
   for (i = 0; i < 4; i++)
     if (coords[i] < 0.0f || coords[i] > 1.0f)
-      need_repeat = TRUE;
+      {
+        /* Repeat is needed */
+        return (_cogl_texture_2d_can_hardware_repeat (tex) ?
+                COGL_TRANSFORM_HARDWARE_REPEAT :
+                COGL_TRANSFORM_SOFTWARE_REPEAT);
+      }
 
-  return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT
-          : COGL_TRANSFORM_NO_REPEAT);
+  /* No repeat is needed */
+  return COGL_TRANSFORM_NO_REPEAT;
 }
 
 static CoglBool
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 5d591d5..e78ba92 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -322,11 +322,18 @@ cogl_texture_new_with_size (unsigned int     width,
 
   _COGL_GET_CONTEXT (ctx, NULL);
 
-  /* First try creating a fast-path non-sliced texture */
-  tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
-                                                     width, height,
-                                                     internal_format,
-                                                     NULL));
+  if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) ||
+      (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
+       cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
+    {
+      /* First try creating a fast-path non-sliced texture */
+      tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
+                                                         width, height,
+                                                         internal_format,
+                                                         NULL));
+    }
+  else
+    tex = NULL;
 
   if (tex)
     {
@@ -393,7 +400,9 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
                               CoglPixelFormat  internal_format)
 {
   CoglAtlasTexture *atlas_tex;
-  CoglTexture2D *tex_2d;
+  CoglTexture *tex;
+
+  _COGL_GET_CONTEXT (ctx, FALSE);
 
   /* First try putting the texture in the atlas */
   if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap,
@@ -402,21 +411,33 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
     return COGL_TEXTURE (atlas_tex);
 
   /* If that doesn't work try a fast path 2D texture */
-  if ((tex_2d = cogl_texture_2d_new_from_bitmap (bitmap,
-                                                 internal_format,
-                                                 NULL)))
+  if ((_cogl_util_is_pot (bitmap->width) &&
+       _cogl_util_is_pot (bitmap->height)) ||
+      (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
+       cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
+    {
+      tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap,
+                                                           internal_format,
+                                                           NULL));
+    }
+  else
+    tex = NULL;
+
+  if (tex)
     {
-      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex_2d),
-                                              !(flags &
-                                                COGL_TEXTURE_NO_AUTO_MIPMAP));
-      return COGL_TEXTURE (tex_2d);
+      CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
+      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
+                                              auto_mipmap);
+    }
+  else
+    {
+      /* Otherwise create a sliced texture */
+      tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
+                                                             flags,
+                                                             internal_format));
     }
 
-  /* Otherwise create a sliced texture */
-  return
-    COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
-                                                           flags,
-                                                           internal_format));
+  return tex;
 }
 
 CoglTexture *



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