[Cogl] [PATCH 04/11] 2d-sliced: add _new_from_file/data/bitmap apis

Robert Bragg robert at sixbynine.org
Thu Jun 27 09:22:11 PDT 2013


From: Robert Bragg <robert at linux.intel.com>

This adds cogl_texture_2d_sliced_new_from_bitmap/data/file apis in
preparation for removing the cogl_texture_new_from_bitmap/file apis that
are considered a bit too magic, but we don't want to loose the
convenience they have.
---
 cogl/cogl-auto-texture.c               |  57 ++++++++----
 cogl/cogl-texture-2d-sliced-private.h  |   2 +-
 cogl/cogl-texture-2d-sliced.c          |  99 ++++++++++++++++----
 cogl/cogl-texture-2d-sliced.h          | 165 +++++++++++++++++++++++++++++++++
 doc/reference/cogl2/cogl2-sections.txt |   3 +
 5 files changed, 289 insertions(+), 37 deletions(-)

diff --git a/cogl/cogl-auto-texture.c b/cogl/cogl-auto-texture.c
index 6ee5e5f..0f546de 100644
--- a/cogl/cogl-auto-texture.c
+++ b/cogl/cogl-auto-texture.c
@@ -46,6 +46,16 @@
 #include "cogl-sub-texture.h"
 #include "cogl-texture-2d-gl.h"
 
+static void
+set_auto_mipmap_cb (CoglTexture *sub_texture,
+                    const float *sub_texture_coords,
+                    const float *meta_coords,
+                    void *user_data)
+{
+  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (sub_texture),
+                                          FALSE);
+}
+
 CoglTexture *
 cogl_texture_new_with_size (CoglContext *ctx,
                             int width,
@@ -79,17 +89,10 @@ cogl_texture_new_with_size (CoglContext *ctx,
   else
     tex = NULL;
 
-  if (tex)
-    {
-      CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
-      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
-                                              auto_mipmap);
-    }
-  else
+  if (!tex)
     {
       /* If it fails resort to sliced textures */
       int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE;
-      cogl_error_free (skip_error);
       tex = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx,
                                                                 width,
                                                                 height,
@@ -97,6 +100,22 @@ cogl_texture_new_with_size (CoglContext *ctx,
                                                                 internal_format));
     }
 
+  if (tex &&
+      flags & COGL_TEXTURE_NO_AUTO_MIPMAP)
+    {
+      /* To be able to iterate the slices of a #CoglTexture2DSliced we
+       * need to ensure the texture is allocated... */
+      if (!cogl_texture_allocate (tex, error))
+        return NULL;
+
+      cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex),
+                                           0, 0, 1, 1,
+                                           COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE,
+                                           COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE,
+                                           set_auto_mipmap_cb,
+                                           NULL);
+    }
+
   return tex;
 }
 
@@ -181,22 +200,28 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
   else
     tex = NULL;
 
-  if (tex)
-    {
-      CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP);
-      cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex),
-                                              auto_mipmap);
-    }
-  else
+  if (!tex)
     {
       /* Otherwise create a sliced texture */
+      int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE;
       tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
-                                                             flags,
+                                                             max_waste,
                                                              internal_format,
                                                              can_convert_in_place,
                                                              error));
     }
 
+  if (tex &&
+      flags & COGL_TEXTURE_NO_AUTO_MIPMAP)
+    {
+      cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex),
+                                           0, 0, 1, 1,
+                                           COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE,
+                                           COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE,
+                                           set_auto_mipmap_cb,
+                                           NULL);
+    }
+
   return tex;
 }
 
diff --git a/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl-texture-2d-sliced-private.h
index 2d5106f..4ba30c5 100644
--- a/cogl/cogl-texture-2d-sliced-private.h
+++ b/cogl/cogl-texture-2d-sliced-private.h
@@ -54,7 +54,7 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *context,
 
 CoglTexture2DSliced *
 _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
-                                         CoglTextureFlags flags,
+                                         int max_waste,
                                          CoglPixelFormat internal_format,
                                          CoglBool can_convert_in_place,
                                          CoglError **error);
diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c
index 88e0553..c2fdc85 100644
--- a/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl-texture-2d-sliced.c
@@ -956,7 +956,7 @@ _cogl_texture_2d_sliced_allocate (CoglTexture *tex,
 
 CoglTexture2DSliced *
 _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
-                                         CoglTextureFlags flags,
+                                         int max_waste,
                                          CoglPixelFormat internal_format,
                                          CoglBool can_convert_in_place,
                                          CoglError **error)
@@ -964,8 +964,7 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
   CoglContext *ctx;
   CoglTexture2DSliced *tex_2ds;
   CoglBitmap *upload_bmp;
-  int width, height, max_waste;
-  int i;
+  int width, height;
 
   _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
 
@@ -977,11 +976,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
   /* Create new texture and fill with loaded data */
   tex_2ds = g_new0 (CoglTexture2DSliced, 1);
 
-  if (flags & COGL_TEXTURE_NO_SLICING)
-    max_waste = -1;
-  else
-    max_waste = COGL_TEXTURE_MAX_WASTE;
-
   internal_format =
     _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp),
                                              internal_format);
@@ -1016,18 +1010,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
 
   cogl_object_unref (upload_bmp);
 
-  if ((flags & COGL_TEXTURE_NO_AUTO_MIPMAP))
-    for (i = 0; i < tex_2ds->slice_textures->len; i++)
-      {
-        CoglPrimitiveTexture *slice_tex;
-
-        slice_tex = g_array_index (tex_2ds->slice_textures,
-                                   CoglPrimitiveTexture *,
-                                   i);
-
-        cogl_primitive_texture_set_auto_mipmap (slice_tex, FALSE);
-      }
-
   return _cogl_texture_2d_sliced_object_new (tex_2ds);
 
  error:
@@ -1037,6 +1019,19 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
 }
 
 CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
+                                        int max_waste,
+                                        CoglPixelFormat internal_format,
+                                        CoglError **error)
+{
+  return _cogl_texture_2d_sliced_new_from_bitmap (bmp,
+                                                  max_waste,
+                                                  internal_format,
+                                                  FALSE,
+                                                  error);
+}
+
+CoglTexture2DSliced *
 _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
                                           unsigned int gl_handle,
                                           unsigned int gl_target,
@@ -1128,6 +1123,70 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
   return _cogl_texture_2d_sliced_object_new (tex_2ds);
 }
 
+CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_data (CoglContext *ctx,
+                                      int width,
+                                      int height,
+                                      int max_waste,
+                                      CoglPixelFormat format,
+                                      CoglPixelFormat internal_format,
+                                      int rowstride,
+                                      const uint8_t *data,
+                                      CoglError **error)
+{
+  CoglBitmap *bmp;
+  CoglTexture2DSliced *tex_2ds;
+
+  _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL);
+  _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL);
+
+  /* Rowstride from width if not given */
+  if (rowstride == 0)
+    rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
+
+  /* Wrap the data into a bitmap */
+  bmp = cogl_bitmap_new_for_data (ctx,
+                                  width, height,
+                                  format,
+                                  rowstride,
+                                  (uint8_t *) data);
+
+  tex_2ds = cogl_texture_2d_sliced_new_from_bitmap (bmp, max_waste,
+                                                    internal_format,
+                                                    error);
+
+  cogl_object_unref (bmp);
+
+  return tex_2ds;
+}
+
+CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_file (CoglContext *ctx,
+                                      const char *filename,
+                                      int max_waste,
+                                      CoglPixelFormat internal_format,
+                                      CoglError **error)
+{
+  CoglBitmap *bmp;
+  CoglTexture2DSliced *tex_2ds = NULL;
+
+  _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL);
+
+  bmp = cogl_bitmap_new_from_file (ctx, filename, error);
+  if (bmp == NULL)
+    return NULL;
+
+  tex_2ds = _cogl_texture_2d_sliced_new_from_bitmap (bmp,
+                                           max_waste,
+                                           internal_format,
+                                           TRUE, /* can convert in-place */
+                                           error);
+
+  cogl_object_unref (bmp);
+
+  return tex_2ds;
+}
+
 static CoglBool
 _cogl_texture_2d_sliced_is_foreign (CoglTexture *tex)
 {
diff --git a/cogl/cogl-texture-2d-sliced.h b/cogl/cogl-texture-2d-sliced.h
index e26157e..882bdd6 100644
--- a/cogl/cogl-texture-2d-sliced.h
+++ b/cogl/cogl-texture-2d-sliced.h
@@ -114,6 +114,171 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
                                       CoglPixelFormat internal_format);
 
 /**
+ * cogl_texture_2d_sliced_new_from_file:
+ * @ctx: A #CoglContext
+ * @filename: the file to load
+ * @max_waste: The threshold of how wide a strip of wasted texels
+ *             are allowed along the right and bottom textures before
+ *             they must be sliced to reduce the amount of waste. A
+ *             negative can be passed to disable slicing.
+ * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
+ *    texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied
+ *    format similar to the format of the source data will be used. The
+ *    default blending equations of Cogl expect premultiplied color data;
+ *    the main use of passing a non-premultiplied format here is if you
+ *    have non-premultiplied source data and are going to adjust the blend
+ *    mode (see cogl_material_set_blend()) or use the data for something
+ *    other than straight blending.
+ * @error: A #CoglError to catch exceptional errors or %NULL
+ *
+ * Creates a #CoglTexture2DSliced from an image file.
+ *
+ * A #CoglTexture2DSliced may internally be comprised of 1 or more
+ * #CoglTexture2D textures depending on GPU limitations.  For example
+ * if the GPU only supports power-of-two sized textures then a sliced
+ * texture will turn a non-power-of-two size into a combination of
+ * smaller power-of-two sized textures. If the requested texture size
+ * is larger than is supported by the hardware then the texture will
+ * be sliced into smaller textures that can be accessed by the
+ * hardware.
+ *
+ * @max_waste is used as a threshold for recursively slicing the
+ * right-most or bottom-most slices into smaller sizes until the
+ * wasted padding at the bottom and right of the textures is less than
+ * specified. A negative @max_waste will disable slicing.
+ *
+ * <note>It's possible for the allocation of a sliced texture to fail
+ * later due to impossible slicing constraints if a negative
+ * @max_waste value is given. If the given virtual texture size is
+ * larger than is supported by the hardware but slicing is disabled
+ * the texture size would be too large to handle.</note>
+ *
+ * Return value: A newly created #CoglTexture2DSliced or %NULL on
+ *               failure and @error will be updated.
+ *
+ * Since: 1.16
+ */
+CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_file (CoglContext *ctx,
+                                      const char *filename,
+                                      int max_waste,
+                                      CoglPixelFormat internal_format,
+                                      CoglError **error);
+
+/**
+ * cogl_texture_2d_sliced_new_from_data:
+ * @width: width of texture in pixels
+ * @height: height of texture in pixels
+ * @format: the #CoglPixelFormat the buffer is stored in in RAM
+ * @max_waste: The threshold of how wide a strip of wasted texels
+ *             are allowed along the right and bottom textures before
+ *             they must be sliced to reduce the amount of waste. A
+ *             negative can be passed to disable slicing.
+ * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
+ *    texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied
+ *    format similar to the format of the source data will be used. The
+ *    default blending equations of Cogl expect premultiplied color data;
+ *    the main use of passing a non-premultiplied format here is if you
+ *    have non-premultiplied source data and are going to adjust the blend
+ *    mode (see cogl_material_set_blend()) or use the data for something
+ *    other than straight blending.
+ * @rowstride: the memory offset in bytes between the start of each
+ *    row in @data. A value of 0 will make Cogl automatically
+ *    calculate @rowstride from @width and @format.
+ * @data: pointer the memory region where the source buffer resides
+ * @error: A #CoglError to catch exceptional errors or %NULL
+ *
+ * Creates a new #CoglTexture2DSliced texture based on data residing
+ * in memory.
+ *
+ * A #CoglTexture2DSliced may internally be comprised of 1 or more
+ * #CoglTexture2D textures depending on GPU limitations.  For example
+ * if the GPU only supports power-of-two sized textures then a sliced
+ * texture will turn a non-power-of-two size into a combination of
+ * smaller power-of-two sized textures. If the requested texture size
+ * is larger than is supported by the hardware then the texture will
+ * be sliced into smaller textures that can be accessed by the
+ * hardware.
+ *
+ * @max_waste is used as a threshold for recursively slicing the
+ * right-most or bottom-most slices into smaller sizes until the
+ * wasted padding at the bottom and right of the textures is less than
+ * specified. A negative @max_waste will disable slicing.
+ *
+ * <note>It's possible for the allocation of a sliced texture to fail
+ * later due to impossible slicing constraints if a negative
+ * @max_waste value is given. If the given virtual texture size is
+ * larger than is supported by the hardware but slicing is disabled
+ * the texture size would be too large to handle.</note>
+ *
+ * Return value: A newly created #CoglTexture2DSliced or %NULL on
+ *               failure and @error will be updated.
+ *
+ * Since: 1.16
+ */
+CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_data (CoglContext *ctx,
+                                      int width,
+                                      int height,
+                                      int max_waste,
+                                      CoglPixelFormat format,
+                                      CoglPixelFormat internal_format,
+                                      int rowstride,
+                                      const uint8_t *data,
+                                      CoglError **error);
+
+/**
+ * cogl_texture_2d_sliced_new_from_bitmap:
+ * @bitmap: A #CoglBitmap
+ * @max_waste: The threshold of how wide a strip of wasted texels
+ *             are allowed along the right and bottom textures before
+ *             they must be sliced to reduce the amount of waste. A
+ *             negative can be passed to disable slicing.
+ * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
+ *    texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied
+ *    format similar to the format of the source data will be used. The
+ *    default blending equations of Cogl expect premultiplied color data;
+ *    the main use of passing a non-premultiplied format here is if you
+ *    have non-premultiplied source data and are going to adjust the blend
+ *    mode (see cogl_material_set_blend()) or use the data for something
+ *    other than straight blending.
+ * @error: A #CoglError to catch exceptional errors or %NULL
+ *
+ * Creates a new #CoglTexture2DSliced texture based on data residing
+ * in a bitmap.
+ *
+ * A #CoglTexture2DSliced may internally be comprised of 1 or more
+ * #CoglTexture2D textures depending on GPU limitations.  For example
+ * if the GPU only supports power-of-two sized textures then a sliced
+ * texture will turn a non-power-of-two size into a combination of
+ * smaller power-of-two sized textures. If the requested texture size
+ * is larger than is supported by the hardware then the texture will
+ * be sliced into smaller textures that can be accessed by the
+ * hardware.
+ *
+ * @max_waste is used as a threshold for recursively slicing the
+ * right-most or bottom-most slices into smaller sizes until the
+ * wasted padding at the bottom and right of the textures is less than
+ * specified. A negative @max_waste will disable slicing.
+ *
+ * <note>It's possible for the allocation of a sliced texture to fail
+ * later due to impossible slicing constraints if a negative
+ * @max_waste value is given. If the given virtual texture size is
+ * larger than is supported by the hardware but slicing is disabled
+ * the texture size would be too large to handle.</note>
+ *
+ * Return value: A newly created #CoglTexture2DSliced or %NULL on
+ *               failure and @error will be updated.
+ *
+ * Since: 1.16
+ */
+CoglTexture2DSliced *
+cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
+                                        int max_waste,
+                                        CoglPixelFormat internal_format,
+                                        CoglError **error);
+
+/**
  * cogl_is_texture_2d_sliced:
  * @object: A #CoglObject pointer
  *
diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
index 9e7df49..29f0405 100644
--- a/doc/reference/cogl2/cogl2-sections.txt
+++ b/doc/reference/cogl2/cogl2-sections.txt
@@ -426,6 +426,9 @@ cogl_is_atlas_texture
 <TITLE>Sliced Textures</TITLE>
 CoglTexture2DSliced
 cogl_texture_2d_sliced_new_with_size
+cogl_texture_2d_sliced_new_from_file
+cogl_texture_2d_sliced_new_from_data
+cogl_texture_2d_sliced_new_from_bitmap
 cogl_is_texture_2d_sliced
 </SECTION>
 
-- 
1.8.2.1



More information about the Cogl mailing list