cogl: Make CoglSubTexture only work for quad rendering
authorNeil Roberts <neil@linux.intel.com>
Mon, 18 Jan 2010 09:22:04 +0000 (09:22 +0000)
committerNeil Roberts <neil@linux.intel.com>
Mon, 18 Jan 2010 09:22:04 +0000 (09:22 +0000)
The sub texture backend doesn't work well as a completely general
texture backend because for example when rendering with cogl_polygon
it needs to be able to tranform arbitrary texture coordinates without
reference to the other coordintes. This can't be done when the texture
coordinates are a multiple of one because sometimes the coordinate
should represent the left or top edge and sometimes it should
represent the bottom or top edge. For example if the s coordinates are
0 and 1 then 1 represents the right edge but if they are 1 and 2 then
1 represents the left edge.

Instead the sub-textures are now documented not to support coordinates
outside the range [0,1]. The coordinates for the sub-region are now
represented as integers as this helps avoid rounding issues. The
region can no longer be a super-region of the texture as this
simplifies the code quite a lot.

There are two new texture virtual functions:

transform_quad_coords_to_gl - This transforms two pairs of coordinates
     representing a quad. It will return FALSE if the coordinates can
     not be transformed. The sub texture backend uses this to detect
     coordinates that require repeating which causes cogl-primitives
     to use manual repeating.

ensure_non_quad_rendering - This is used in cogl_polygon and
     cogl_vertex_buffer to inform the texture backend that
     transform_quad_to_gl is going to be used. The atlas backend
     migrates the texture out of the atlas when it hits this.

12 files changed:
clutter/cogl/cogl/cogl-atlas-texture.c
clutter/cogl/cogl/cogl-primitives.c
clutter/cogl/cogl/cogl-sub-texture-private.h
clutter/cogl/cogl/cogl-sub-texture.c
clutter/cogl/cogl/cogl-texture-2d-sliced.c
clutter/cogl/cogl/cogl-texture-2d.c
clutter/cogl/cogl/cogl-texture-private.h
clutter/cogl/cogl/cogl-texture.c
clutter/cogl/cogl/cogl-texture.h
clutter/cogl/cogl/cogl-vertex-buffer.c
tests/conform/test-cogl-sub-texture.c
tests/conform/test-conform-main.c

index 4d7bf6f..4bbff22 100644 (file)
@@ -34,6 +34,7 @@
 #include "cogl-texture-private.h"
 #include "cogl-atlas-texture-private.h"
 #include "cogl-texture-2d-private.h"
+#include "cogl-sub-texture-private.h"
 #include "cogl-context.h"
 #include "cogl-handle.h"
 #include "cogl-texture-driver.h"
@@ -313,6 +314,17 @@ _cogl_atlas_texture_transform_coords_to_gl (CoglTexture *tex,
 }
 
 static gboolean
+_cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex,
+                                                 float *coords)
+{
+  CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
+
+  /* Forward on to the sub texture */
+  return _cogl_texture_transform_quad_coords_to_gl (atlas_tex->sub_texture,
+                                                    coords);
+}
+
+static gboolean
 _cogl_atlas_texture_get_gl_texture (CoglTexture *tex,
                                     GLuint *out_gl_handle,
                                     GLenum *out_gl_target)
@@ -337,12 +349,9 @@ _cogl_atlas_texture_set_filters (CoglTexture *tex,
 }
 
 static void
-_cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
+_cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
 {
-  CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
-
-  /* Mipmaps do not work well with the current atlas so instead we'll
-     just migrate the texture out and use a regular texture */
+  /* Make sure this texture is not in the atlas */
   if (atlas_tex->in_atlas)
     {
       CoglHandle atlas_texture;
@@ -382,11 +391,34 @@ _cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
 
       _cogl_atlas_texture_remove_from_atlas (atlas_tex);
     }
+}
+
+static void
+_cogl_atlas_texture_ensure_mipmaps (CoglTexture *tex)
+{
+  CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
+
+  /* Mipmaps do not work well with the current atlas so instead we'll
+     just migrate the texture out and use a regular texture */
+  _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex);
 
   /* Forward on to the sub texture */
   _cogl_texture_ensure_mipmaps (atlas_tex->sub_texture);
 }
 
+static void
+_cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex)
+{
+  CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
+
+  /* Sub textures can't support non-quad rendering so we'll just
+     migrate the texture out */
+  _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex);
+
+  /* Forward on to the sub texture */
+  _cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture);
+}
+
 static gboolean
 _cogl_atlas_texture_set_region (CoglTexture    *tex,
                                 int             src_x,
@@ -546,14 +578,11 @@ _cogl_atlas_texture_create_sub_texture (CoglHandle                full_texture,
 {
   /* Create a subtexture for the given rectangle not including the
      1-pixel border */
-  gfloat tex_width = cogl_texture_get_width (full_texture);
-  gfloat tex_height = cogl_texture_get_height (full_texture);
-  gfloat tx1 = (rectangle->x + 1) / tex_width;
-  gfloat ty1 = (rectangle->y + 1) / tex_height;
-  gfloat tx2 = (rectangle->x + rectangle->width - 1) / tex_width;
-  gfloat ty2 = (rectangle->y + rectangle->height - 1) / tex_height;
-
-  return cogl_texture_new_from_sub_texture (full_texture, tx1, ty1, tx2, ty2);
+  return _cogl_sub_texture_new (full_texture,
+                                rectangle->x + 1,
+                                rectangle->y + 1,
+                                rectangle->width - 2,
+                                rectangle->height - 2);
 }
 
 typedef struct _CoglAtlasTextureRepositionData
@@ -958,9 +987,11 @@ cogl_atlas_texture_vtable =
     _cogl_atlas_texture_is_sliced,
     _cogl_atlas_texture_can_hardware_repeat,
     _cogl_atlas_texture_transform_coords_to_gl,
+    _cogl_atlas_texture_transform_quad_coords_to_gl,
     _cogl_atlas_texture_get_gl_texture,
     _cogl_atlas_texture_set_filters,
     _cogl_atlas_texture_ensure_mipmaps,
+    _cogl_atlas_texture_ensure_non_quad_rendering,
     _cogl_atlas_texture_set_wrap_mode_parameter,
     _cogl_atlas_texture_get_format,
     _cogl_atlas_texture_get_gl_format,
index b23d015..1215725 100644 (file)
@@ -278,14 +278,14 @@ _cogl_multitexture_quad_single_primitive (float        x_1,
          the coordinates (such as in the sub texture backend). This
          should be safe to call because we know that the texture only
          has one slice. */
-      for (coord_num = 0; coord_num < 2; coord_num++)
-        {
-          float *s = out_tex_coords + coord_num * 2;
-          float *t = s + 1;
-          _cogl_texture_transform_coords_to_gl (tex_handle, s, t);
-          if (*s < 0.0f || *s > 1.0f || *t < 0.0f || *t > 1.0f)
-            need_repeat = TRUE;
-        }
+      if (!_cogl_texture_transform_quad_coords_to_gl (tex_handle,
+                                                      out_tex_coords))
+        /* If the backend can't support these coordinates then bail out */
+        return FALSE;
+      for (coord_num = 0; coord_num < 4; coord_num++)
+        if (out_tex_coords[coord_num] < 0.0f ||
+            out_tex_coords[coord_num] > 1.0f)
+          need_repeat = TRUE;
 
       /* If the texture has waste or we are using GL_TEXTURE_RECT we
        * can't handle texture repeating so we can't use the layer if
@@ -867,6 +867,11 @@ cogl_polygon (const CoglTextureVertex *vertices,
       if (tex_handle == COGL_INVALID_HANDLE)
         continue;
 
+      /* Give the texture a chance to know that we're rendering
+         non-quad shaped primitives. If the texture is in an atlas it
+         will be migrated */
+      _cogl_texture_ensure_non_quad_rendering (tex_handle);
+
       if (i == 0 && cogl_texture_is_sliced (tex_handle))
         {
 #if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
index 899f61e..c8fa4bb 100644 (file)
@@ -37,12 +37,11 @@ struct _CoglSubTexture
 
   CoglHandle  full_texture;
 
-  /* The texture coordinates of the subregion of full_texture */
-  gfloat      tx1, ty1;
-  gfloat      tx2, ty2;
-
-  /* Are all of the texture coordinates a multiple of one? */
-  gboolean    tex_coords_are_a_multiple;
+  /* The region represented by this sub-texture */
+  gint        sub_x;
+  gint        sub_y;
+  gint        sub_width;
+  gint        sub_height;
 };
 
 GQuark
@@ -50,7 +49,7 @@ _cogl_handle_sub_texture_get_type (void);
 
 CoglHandle
 _cogl_sub_texture_new (CoglHandle full_texture,
-                       gfloat tx1, gfloat ty1,
-                       gfloat tx2, gfloat ty2);
+                       gint sub_x, gint sub_y,
+                       gint sub_width, gint sub_height);
 
 #endif /* __COGL_SUB_TEXTURE_H */
index d0213fe..164a23f 100644 (file)
@@ -46,63 +46,105 @@ COGL_HANDLE_DEFINE (SubTexture, sub_texture);
 
 static const CoglTextureVtable cogl_sub_texture_vtable;
 
-/* Maps from the texture coordinates of this texture to the texture
-   coordinates of the full texture */
-
 static void
-_cogl_sub_texture_map_coordinate_pair (CoglSubTexture *sub_tex,
-                                       gfloat *tx, gfloat *ty)
+_cogl_sub_texture_map_range (gfloat *t1, gfloat *t2,
+                             gint sub_offset,
+                             gint sub_size,
+                             gint full_size)
 {
-  *tx = *tx * (sub_tex->tx2 - sub_tex->tx1) + sub_tex->tx1;
-  *ty = *ty * (sub_tex->ty2 - sub_tex->ty1) + sub_tex->ty1;
+  gfloat t1_frac, t1_int, t2_frac, t2_int;
+
+  t1_frac = modff (*t1, &t1_int);
+  t2_frac = modff (*t2, &t2_int);
+
+  if (t1_frac < 0.0f)
+    {
+      t1_frac += 1.0f;
+      t1_int -= 1.0f;
+    }
+  if (t2_frac < 0.0f)
+    {
+      t2_frac += 1.0f;
+      t2_int -= 1.0f;
+    }
+
+  /* If one of the coordinates is zero we need to make sure it is
+     still greater than the other coordinate if it was originally so
+     we'll flip it to the other side  */
+  if (*t1 < *t2)
+    {
+      if (t2_frac == 0.0f)
+        {
+          t2_frac = 1.0f;
+          t2_int -= 1.0f;
+        }
+    }
+  else
+    {
+      if (t1_frac == 0.0f)
+        {
+          t1_frac = 1.0f;
+          t1_int -= 1.0f;
+        }
+    }
+
+  /* Convert the fractional part leaving the integer part intact */
+  t1_frac = (sub_offset + t1_frac * sub_size) / full_size;
+  *t1 = t1_frac + t1_int;
+
+  t2_frac = (sub_offset + t2_frac * sub_size) / full_size;
+  *t2 = t2_frac + t2_int;
 }
 
 static void
-_cogl_sub_texture_map_coordinate_set (CoglSubTexture *sub_tex,
-                                      gfloat *tx1, gfloat *ty1,
-                                      gfloat *tx2, gfloat *ty2)
+_cogl_sub_texture_map_quad (CoglSubTexture *sub_tex,
+                            gfloat *coords)
 {
-  _cogl_sub_texture_map_coordinate_pair (sub_tex, tx1, ty1);
-  _cogl_sub_texture_map_coordinate_pair (sub_tex, tx2, ty2);
+  guint full_width = cogl_texture_get_width (sub_tex->full_texture);
+  guint full_height = cogl_texture_get_height (sub_tex->full_texture);
+
+  _cogl_sub_texture_map_range (coords + 0, coords + 2,
+                               sub_tex->sub_x, sub_tex->sub_width,
+                               full_width);
+  _cogl_sub_texture_map_range (coords + 1, coords + 3,
+                               sub_tex->sub_y, sub_tex->sub_height,
+                               full_height);
 }
 
 /* Maps from the texture coordinates of the full texture to the
    texture coordinates of the sub texture */
-static void
-_cogl_sub_texture_unmap_coordinate_pair (CoglSubTexture *sub_tex,
-                                         gfloat *coords)
+static gfloat
+_cogl_sub_texture_unmap_coord (gfloat t,
+                               gint sub_offset,
+                               gint sub_size,
+                               gint full_size)
 {
-  if (sub_tex->tx1 == sub_tex->tx2)
-    coords[0] = sub_tex->tx1;
-  else
-    coords[0] = (coords[0] - sub_tex->tx1) / (sub_tex->tx2 - sub_tex->tx1);
+  gfloat frac_part, int_part;
+
+  /* Convert the fractional part leaving the integer part in tact */
+  frac_part = modff (t, &int_part);
 
-  if (sub_tex->ty1 == sub_tex->ty2)
-    coords[0] = sub_tex->ty1;
+  if (signbit (frac_part))
+    frac_part = ((1.0f + frac_part) * full_size -
+                 sub_offset - sub_size) / sub_size;
   else
-    coords[1] = (coords[1] - sub_tex->ty1) / (sub_tex->ty2 - sub_tex->ty1);
-}
+    frac_part = (frac_part * full_size - sub_offset) / sub_size;
 
-static void
-_cogl_sub_texture_unmap_coordinate_set (CoglSubTexture *sub_tex,
-                                        gfloat *coords)
-{
-  _cogl_sub_texture_unmap_coordinate_pair (sub_tex, coords);
-  _cogl_sub_texture_unmap_coordinate_pair (sub_tex, coords + 2);
+  return frac_part + int_part;
 }
 
-static gboolean
-_cogl_sub_texture_same_int_part (float t1, float t2)
+static void
+_cogl_sub_texture_unmap_coords (CoglSubTexture *sub_tex,
+                                gfloat *s,
+                                gfloat *t)
 {
-  float int_part1, int_part2;
-  float frac_part1, frac_part2;
-
-  frac_part1 = modff (t1, &int_part1);
-  frac_part2 = modff (t2, &int_part2);
+  guint full_width = cogl_texture_get_width (sub_tex->full_texture);
+  guint full_height = cogl_texture_get_height (sub_tex->full_texture);
 
-  return (int_part1 == int_part2 ||
-          ((frac_part1 == 0.0f || frac_part2 == 0.0f) &&
-           ABS (int_part1 - int_part2) == 1.0f));
+  *s = _cogl_sub_texture_unmap_coord (*s, sub_tex->sub_x, sub_tex->sub_width,
+                                      full_width);
+  *t = _cogl_sub_texture_unmap_coord (*t, sub_tex->sub_y, sub_tex->sub_height,
+                                      full_height);
 }
 
 typedef struct _CoglSubTextureForeachData
@@ -126,7 +168,12 @@ _cogl_sub_texture_foreach_cb (CoglHandle handle,
   memcpy (virtual_coords, full_virtual_coords, sizeof (virtual_coords));
   /* Convert the virtual coords from the full-texture space to the sub
      texture space */
-  _cogl_sub_texture_unmap_coordinate_set (data->sub_tex, virtual_coords);
+  _cogl_sub_texture_unmap_coords (data->sub_tex,
+                                  &virtual_coords[0],
+                                  &virtual_coords[1]);
+  _cogl_sub_texture_unmap_coords (data->sub_tex,
+                                  &virtual_coords[2],
+                                  &virtual_coords[3]);
 
   data->callback (handle, gl_handle, gl_target,
                   slice_coords, virtual_coords,
@@ -142,11 +189,7 @@ _cogl_sub_texture_manual_repeat_cb (const float *coords,
 
   memcpy (mapped_coords, coords, sizeof (mapped_coords));
 
-  _cogl_sub_texture_map_coordinate_set (data->sub_tex,
-                                        &mapped_coords[0],
-                                        &mapped_coords[1],
-                                        &mapped_coords[2],
-                                        &mapped_coords[3]);
+  _cogl_sub_texture_map_quad (data->sub_tex, mapped_coords);
 
   _cogl_texture_foreach_sub_texture_in_region (data->sub_tex->full_texture,
                                                mapped_coords[0],
@@ -174,30 +217,10 @@ _cogl_sub_texture_foreach_sub_texture_in_region (
   data.callback = callback;
   data.user_data = user_data;
 
-  /* If there is no repeating or the sub texture coordinates are a
-     multiple of the whole texture then we can just directly map the
-     texture coordinates */
-  if (sub_tex->tex_coords_are_a_multiple ||
-      (_cogl_sub_texture_same_int_part (virtual_tx_1, virtual_tx_2) &&
-       _cogl_sub_texture_same_int_part (virtual_ty_1, virtual_ty_2)))
-    {
-      _cogl_sub_texture_map_coordinate_set (sub_tex,
-                                            &virtual_tx_1,
-                                            &virtual_ty_1,
-                                            &virtual_tx_2,
-                                            &virtual_ty_2);
-
-      _cogl_texture_foreach_sub_texture_in_region
-        (sub_tex->full_texture,
-         virtual_tx_1, virtual_ty_1,
-         virtual_tx_2, virtual_ty_2,
-         _cogl_sub_texture_foreach_cb, &data);
-    }
-  else
-    _cogl_texture_iterate_manual_repeats (_cogl_sub_texture_manual_repeat_cb,
-                                          virtual_tx_1, virtual_ty_1,
-                                          virtual_tx_2, virtual_ty_2,
-                                          &data);
+  _cogl_texture_iterate_manual_repeats (_cogl_sub_texture_manual_repeat_cb,
+                                        virtual_tx_1, virtual_ty_1,
+                                        virtual_tx_2, virtual_ty_2,
+                                        &data);
 }
 
 static void
@@ -219,12 +242,21 @@ _cogl_sub_texture_free (CoglSubTexture *sub_tex)
 
 CoglHandle
 _cogl_sub_texture_new (CoglHandle full_texture,
-                       gfloat tx1, gfloat ty1,
-                       gfloat tx2, gfloat ty2)
+                       gint sub_x, gint sub_y,
+                       gint sub_width, gint sub_height)
 {
   CoglSubTexture *sub_tex;
   CoglTexture    *tex;
-  gfloat          integer_part;
+  guint           full_width, full_height;
+
+  full_width = cogl_texture_get_width (full_texture);
+  full_height = cogl_texture_get_width (full_texture);
+
+  /* The region must specify a non-zero subset of the full texture */
+  g_return_val_if_fail (sub_x >= 0 && sub_y >= 0, COGL_INVALID_HANDLE);
+  g_return_val_if_fail (sub_width > 0 && sub_height > 0, COGL_INVALID_HANDLE);
+  g_return_val_if_fail (sub_x + sub_width <= full_width, COGL_INVALID_HANDLE);
+  g_return_val_if_fail (sub_y + sub_height <= full_height, COGL_INVALID_HANDLE);
 
   sub_tex = g_new (CoglSubTexture, 1);
 
@@ -233,18 +265,10 @@ _cogl_sub_texture_new (CoglHandle full_texture,
 
   sub_tex->full_texture = cogl_handle_ref (full_texture);
 
-  sub_tex->tx1 = tx1;
-  sub_tex->ty1 = ty1;
-  sub_tex->tx2 = tx2;
-  sub_tex->ty2 = ty2;
-
-  /* Track whether the texture coords are a multiple of one because in
-     that case we can use hardware repeating */
-  sub_tex->tex_coords_are_a_multiple
-    = (modff (tx1, &integer_part) == 0.0f &&
-       modff (ty1, &integer_part) == 0.0f &&
-       modff (tx2, &integer_part) == 0.0f &&
-       modff (ty2, &integer_part) == 0.0f);
+  sub_tex->sub_x = sub_x;
+  sub_tex->sub_y = sub_y;
+  sub_tex->sub_width = sub_width;
+  sub_tex->sub_height = sub_height;
 
   return _cogl_sub_texture_handle_new (sub_tex);
 }
@@ -270,11 +294,12 @@ _cogl_sub_texture_can_hardware_repeat (CoglTexture *tex)
 {
   CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
 
-  /* We can hardware repeat if the full texture can hardware repeat
-     and the coordinates for the subregion are all a multiple of the
-     full size of the texture (ie, they have no fractional part) */
-
-  return (sub_tex->tex_coords_are_a_multiple &&
+  /* We can hardware repeat if the subtexture actually represents all of the
+     of the full texture */
+  return (sub_tex->sub_width ==
+          cogl_texture_get_width (sub_tex->full_texture) &&
+          sub_tex->sub_height ==
+          cogl_texture_get_height (sub_tex->full_texture) &&
           _cogl_texture_can_hardware_repeat (sub_tex->full_texture));
 }
 
@@ -285,8 +310,34 @@ _cogl_sub_texture_transform_coords_to_gl (CoglTexture *tex,
 {
   CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
 
-  _cogl_sub_texture_map_coordinate_pair (sub_tex, s, t);
-  _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t);
+  /* This won't work if the sub texture is not the size of the full
+     texture and the coordinates are outside the range [0,1] */
+  *s = ((*s * sub_tex->sub_width + sub_tex->sub_x) /
+        cogl_texture_get_width (sub_tex->full_texture));
+  *t = ((*t * sub_tex->sub_height + sub_tex->sub_y) /
+        cogl_texture_get_height (sub_tex->full_texture));
+
+  return _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t);
+}
+
+static gboolean
+_cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex,
+                                               float *coords)
+{
+  CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
+  int i;
+
+  /* We can't support repeating with this method. In this case
+     cogl-primitives will resort to manual repeating */
+  for (i = 0; i < 4; i++)
+    if (coords[i] < 0.0f || coords[i] > 1.0f)
+      return FALSE;
+
+  _cogl_sub_texture_map_quad (sub_tex, coords);
+
+  _cogl_texture_transform_quad_coords_to_gl (sub_tex->full_texture, coords);
+
+  return TRUE;
 }
 
 static gboolean
@@ -320,67 +371,8 @@ _cogl_sub_texture_ensure_mipmaps (CoglTexture *tex)
 }
 
 static void
-_cogl_sub_texture_get_next_chunk (int pos, int end,
-                                  int tex_size,
-                                  int *chunk_start, int *chunk_end)
+_cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex)
 {
-  /* pos and end may be negative or greater than the size of the
-     texture. We want to calculate the next largest range we can copy
-     in one chunk */
-
-  if (pos < 0)
-    /* The behaviour of % for negative numbers is implementation
-       dependant in C89 so we have to do this */
-    *chunk_start = (tex_size - pos) % tex_size;
-  else
-    *chunk_start = pos % tex_size;
-
-  /* If the region is larger than the remaining size of the texture
-     then we need to crop it */
-  if (end - pos > tex_size - *chunk_start)
-    end = pos + tex_size - *chunk_start;
-
-  if (end < 0)
-    *chunk_end = (tex_size - end) % tex_size;
-  else
-    *chunk_end = end % tex_size;
-
-  if (*chunk_end == 0)
-    *chunk_end = tex_size;
-}
-
-static void
-_cogl_sub_texture_get_x_pixel_pos (CoglSubTexture *sub_tex,
-                                   gint *px1, gint *px2)
-{
-  gint full_width = cogl_texture_get_width (sub_tex->full_texture);
-
-  *px1 = full_width * sub_tex->tx1;
-  *px2 = full_width * sub_tex->tx2;
-
-  if (*px1 > *px2)
-    {
-      gint temp = *px1;
-      *px1 = *px2;
-      *px2 = temp;
-    }
-}
-
-static void
-_cogl_sub_texture_get_y_pixel_pos (CoglSubTexture *sub_tex,
-                                   gint *py1, gint *py2)
-{
-  gint full_height = cogl_texture_get_height (sub_tex->full_texture);
-
-  *py1 = full_height * sub_tex->ty1;
-  *py2 = full_height * sub_tex->ty2;
-
-  if (*py1 > *py2)
-    {
-      gint temp = *py1;
-      *py1 = *py2;
-      *py2 = temp;
-    }
 }
 
 static gboolean
@@ -397,144 +389,17 @@ _cogl_sub_texture_set_region (CoglTexture    *tex,
                               unsigned int    rowstride,
                               const guint8   *data)
 {
-  CoglSubTexture  *sub_tex          = COGL_SUB_TEXTURE (tex);
-  gint             full_tex_width, full_tex_height;
-  gint             bpp;
-  gint             px1, py1, px2, py2;
-  gint             it_x, it_y;
-  gint             src_x1, src_y1, src_x2, src_y2;
-  CoglBitmap       source_bmp;
-  CoglBitmap       temp_bmp;
-  gboolean         source_bmp_owner = FALSE;
-  CoglPixelFormat  closest_format;
-  GLenum           closest_gl_format;
-  GLenum           closest_gl_type;
-  gboolean         success;
-  CoglPixelFormat  tex_format;
-
-  /* Check for valid format */
-  if (format == COGL_PIXEL_FORMAT_ANY)
-    return FALSE;
-
-  /* Shortcut out early if the image is empty */
-  if (width == 0 || height == 0)
-    return TRUE;
-
-  /* FIXME: If the sub texture coordinates are swapped around then we
-     should flip the bitmap */
-
-  _cogl_sub_texture_get_x_pixel_pos (sub_tex, &px1, &px2);
-  _cogl_sub_texture_get_y_pixel_pos (sub_tex, &py1, &py2);
-
-  full_tex_width = cogl_texture_get_width (sub_tex->full_texture);
-  full_tex_height = cogl_texture_get_height (sub_tex->full_texture);
-
-  /* Init source bitmap */
-  source_bmp.width = width;
-  source_bmp.height = height;
-  source_bmp.format = format;
-  source_bmp.data = (guchar*) data;
-
-  /* Rowstride from texture width if none specified */
-  bpp = _cogl_get_format_bpp (format);
-  source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride;
-
-  /* Find closest format to internal that's supported by GL */
-  tex_format = cogl_texture_get_format (sub_tex->full_texture);
-  closest_format = _cogl_pixel_format_to_gl (tex_format,
-                                             NULL, /* don't need */
-                                             &closest_gl_format,
-                                             &closest_gl_type);
-
-  /* If no direct match, convert */
-  if (closest_format != format)
-    {
-      /* Convert to required format */
-      success = _cogl_bitmap_convert_and_premult (&source_bmp,
-                                                  &temp_bmp,
-                                                  closest_format);
-
-      /* Swap bitmaps if succeeded */
-      if (!success) return FALSE;
-      source_bmp = temp_bmp;
-      source_bmp_owner = TRUE;
-    }
-
-  for (it_y = py1; it_y < py2; it_y += src_y2 - src_y1)
-    {
-      _cogl_sub_texture_get_next_chunk (it_y, py2, full_tex_width,
-                                        &src_y1, &src_y2);
-
-      for (it_x = px1; it_x < px2; it_x += src_x2 - src_x1)
-        {
-          gint virt_x_1, virt_y_1, virt_width, virt_height;
-          gint copy_dst_x, copy_dst_y, copy_dst_width, copy_dst_height;
-
-          _cogl_sub_texture_get_next_chunk (it_x, px2, full_tex_height,
-                                            &src_x1, &src_x2);
-
-          /* Offset of the chunk from the left edge in the virtual sub
-             texture coordinates */
-          virt_x_1 = it_x - px1;
-          /* Pixel width covered by this chunk */
-          virt_width = src_x2 - src_x1;
-          /* Offset of the chunk from the top edge in the virtual sub
-             texture coordinates */
-          virt_y_1 = it_y - py1;
-          /* Pixel height covered by this chunk */
-          virt_height = src_y2 - src_y1;
-
-          /* Check if this chunk intersects with the update region */
-          if (dst_x + dst_width <= virt_x_1 ||
-              dst_x >= virt_x_1 + virt_width ||
-              dst_y + dst_height <= it_y - py1 ||
-              dst_y >= virt_y_1 + virt_height)
-            continue;
-
-          /* Calculate the intersection in virtual coordinates */
-          copy_dst_width = dst_width;
-          if (dst_x < virt_x_1)
-            {
-              copy_dst_width -= virt_x_1 - dst_x;
-              copy_dst_x = virt_x_1;
-            }
-          else
-            copy_dst_x = dst_x;
-          if (copy_dst_width + copy_dst_x > virt_x_1 + virt_width)
-            copy_dst_width = virt_x_1 + virt_width - copy_dst_x;
-
-          copy_dst_height = dst_height;
-          if (dst_y < virt_y_1)
-            {
-              copy_dst_height -= virt_y_1 - dst_y;
-              copy_dst_y = virt_y_1;
-            }
-          else
-            copy_dst_y = dst_y;
-          if (copy_dst_height + copy_dst_y > virt_y_1 + virt_height)
-            copy_dst_height = virt_y_1 + virt_height - copy_dst_y;
-
-          /* Update the region in the full texture */
-          cogl_texture_set_region (sub_tex->full_texture,
-                                   src_x + copy_dst_x - dst_x,
-                                   src_y + copy_dst_y - dst_y,
-                                   src_x1 + copy_dst_x - virt_x_1,
-                                   src_y1 + copy_dst_y - virt_y_1,
-                                   copy_dst_width,
-                                   copy_dst_height,
-                                   width,
-                                   height,
-                                   format,
-                                   rowstride,
-                                   data);
-        }
-    }
-
-  /* Free data if owner */
-  if (source_bmp_owner)
-    g_free (source_bmp.data);
-
-  return TRUE;
+  CoglSubTexture  *sub_tex = COGL_SUB_TEXTURE (tex);
+
+  return cogl_texture_set_region (sub_tex->full_texture,
+                                  src_x, src_y,
+                                  dst_x + sub_tex->sub_x,
+                                  dst_y + sub_tex->sub_y,
+                                  dst_width, dst_height,
+                                  width, height,
+                                  format,
+                                  rowstride,
+                                  data);
 }
 
 static void
@@ -571,7 +436,6 @@ _cogl_sub_texture_get_data (CoglTexture     *tex,
   guint8 *full_data;
   int byte_size, full_size;
   gint bpp;
-  gint px1, py1, px2, py2;
   gint full_tex_width, full_tex_height;
 
   /* FIXME: This gets the full data from the full texture and then
@@ -583,19 +447,16 @@ _cogl_sub_texture_get_data (CoglTexture     *tex,
   if (format == COGL_PIXEL_FORMAT_ANY)
     format = cogl_texture_get_format (sub_tex->full_texture);
 
-  _cogl_sub_texture_get_x_pixel_pos (sub_tex, &px1, &px2);
-  _cogl_sub_texture_get_y_pixel_pos (sub_tex, &py1, &py2);
-
   full_tex_width = cogl_texture_get_width (sub_tex->full_texture);
   full_tex_height = cogl_texture_get_height (sub_tex->full_texture);
 
   /* Rowstride from texture width if none specified */
   bpp = _cogl_get_format_bpp (format);
   if (rowstride == 0)
-    rowstride = px2 - px1;
+    rowstride = sub_tex->sub_width * bpp;
 
   /* Return byte size if only that requested */
-  byte_size = (py2 - py1) * rowstride;
+  byte_size = sub_tex->sub_height * rowstride;
   if (data == NULL)
     return byte_size;
 
@@ -606,32 +467,15 @@ _cogl_sub_texture_get_data (CoglTexture     *tex,
                                      full_rowstride, full_data);
 
   if (full_size)
-    {
-      int dst_x, dst_y;
-      int src_x1, src_y1;
-      int src_x2, src_y2;
-
-      for (dst_y = py1; dst_y < py2; dst_y += src_y2 - src_y1)
-        {
-          _cogl_sub_texture_get_next_chunk (dst_y, py2, full_tex_width,
-                                            &src_y1, &src_y2);
-
-          for (dst_x = px1; dst_x < px2; dst_x += src_x2 - src_x1)
-            {
-              _cogl_sub_texture_get_next_chunk (dst_x, px2, full_tex_height,
-                                                &src_x1, &src_x2);
-
-              _cogl_sub_texture_copy_region (data, full_data,
-                                             dst_x - px1, dst_y - py1,
-                                             src_x1, src_y1,
-                                             src_x2 - src_x1,
-                                             src_y2 - src_y1,
-                                             rowstride,
-                                             full_rowstride,
-                                             bpp);
-            }
-        }
-    }
+    _cogl_sub_texture_copy_region (data, full_data,
+                                   0, 0,
+                                   sub_tex->sub_x,
+                                   sub_tex->sub_y,
+                                   sub_tex->sub_width,
+                                   sub_tex->sub_height,
+                                   rowstride,
+                                   full_rowstride,
+                                   bpp);
   else
     byte_size = 0;
 
@@ -660,22 +504,16 @@ static gint
 _cogl_sub_texture_get_width (CoglTexture *tex)
 {
   CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
-  gint px1, px2;
-
-  _cogl_sub_texture_get_x_pixel_pos (sub_tex, &px1, &px2);
 
-  return px2 - px1;
+  return sub_tex->sub_width;
 }
 
 static gint
 _cogl_sub_texture_get_height (CoglTexture *tex)
 {
   CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
-  gint py1, py2;
-
-  _cogl_sub_texture_get_y_pixel_pos (sub_tex, &py1, &py2);
 
-  return py2 - py1;
+  return sub_tex->sub_height;
 }
 
 static const CoglTextureVtable
@@ -688,9 +526,11 @@ cogl_sub_texture_vtable =
     _cogl_sub_texture_is_sliced,
     _cogl_sub_texture_can_hardware_repeat,
     _cogl_sub_texture_transform_coords_to_gl,
+    _cogl_sub_texture_transform_quad_coords_to_gl,
     _cogl_sub_texture_get_gl_texture,
     _cogl_sub_texture_set_filters,
     _cogl_sub_texture_ensure_mipmaps,
+    _cogl_sub_texture_ensure_non_quad_rendering,
     _cogl_sub_texture_set_wrap_mode_parameter,
     _cogl_sub_texture_get_format,
     _cogl_sub_texture_get_gl_format,
index 0f53bc1..7743f9f 100644 (file)
@@ -1267,6 +1267,19 @@ _cogl_texture_2d_sliced_transform_coords_to_gl (CoglTexture *tex,
 }
 
 static gboolean
+_cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex,
+                                                     float *coords)
+{
+  if (_cogl_texture_2d_sliced_is_sliced (tex))
+    return FALSE;
+
+  _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 0, coords + 1);
+  _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 2, coords + 3);
+
+  return TRUE;
+}
+
+static gboolean
 _cogl_texture_2d_sliced_get_gl_texture (CoglTexture *tex,
                                         GLuint *out_gl_handle,
                                         GLenum *out_gl_target)
@@ -1362,6 +1375,12 @@ _cogl_texture_2d_sliced_ensure_mipmaps (CoglTexture *tex)
   tex_2ds->mipmaps_dirty = FALSE;
 }
 
+static void
+_cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex)
+{
+  /* Nothing needs to be done */
+}
+
 static gboolean
 _cogl_texture_2d_sliced_set_region (CoglTexture    *tex,
                                     int             src_x,
@@ -1673,9 +1692,11 @@ cogl_texture_2d_sliced_vtable =
     _cogl_texture_2d_sliced_is_sliced,
     _cogl_texture_2d_sliced_can_hardware_repeat,
     _cogl_texture_2d_sliced_transform_coords_to_gl,
+    _cogl_texture_2d_sliced_transform_quad_coords_to_gl,
     _cogl_texture_2d_sliced_get_gl_texture,
     _cogl_texture_2d_sliced_set_filters,
     _cogl_texture_2d_sliced_ensure_mipmaps,
+    _cogl_texture_2d_sliced_ensure_non_quad_rendering,
     _cogl_texture_2d_sliced_set_wrap_mode_parameter,
     _cogl_texture_2d_sliced_get_format,
     _cogl_texture_2d_sliced_get_gl_format,
index f6bf603..cd3f3a1 100644 (file)
@@ -343,6 +343,15 @@ _cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex,
 }
 
 static gboolean
+_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex,
+                                              float *coords)
+{
+  /* The texture coordinates map directly so we don't need to do
+     anything */
+  return TRUE;
+}
+
+static gboolean
 _cogl_texture_2d_get_gl_texture (CoglTexture *tex,
                                  GLuint *out_gl_handle,
                                  GLenum *out_gl_target)
@@ -399,6 +408,12 @@ _cogl_texture_2d_ensure_mipmaps (CoglTexture *tex)
   tex_2d->mipmaps_dirty = FALSE;
 }
 
+static void
+_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex)
+{
+  /* Nothing needs to be done */
+}
+
 static gboolean
 _cogl_texture_2d_set_region (CoglTexture    *tex,
                              int             src_x,
@@ -612,9 +627,11 @@ cogl_texture_2d_vtable =
     _cogl_texture_2d_is_sliced,
     _cogl_texture_2d_can_hardware_repeat,
     _cogl_texture_2d_transform_coords_to_gl,
+    _cogl_texture_2d_transform_quad_coords_to_gl,
     _cogl_texture_2d_get_gl_texture,
     _cogl_texture_2d_set_filters,
     _cogl_texture_2d_ensure_mipmaps,
+    _cogl_texture_2d_ensure_non_quad_rendering,
     _cogl_texture_2d_set_wrap_mode_parameter,
     _cogl_texture_2d_get_format,
     _cogl_texture_2d_get_gl_format,
index ad6449d..e593743 100644 (file)
@@ -84,6 +84,8 @@ struct _CoglTextureVtable
   void (* transform_coords_to_gl) (CoglTexture *tex,
                                    float *s,
                                    float *t);
+  gboolean (* transform_quad_coords_to_gl) (CoglTexture *tex,
+                                            float *coords);
 
   gboolean (* get_gl_texture) (CoglTexture *tex,
                                GLuint *out_gl_handle,
@@ -94,6 +96,7 @@ struct _CoglTextureVtable
                         GLenum mag_filter);
 
   void (* ensure_mipmaps) (CoglTexture *tex);
+  void (* ensure_non_quad_rendering) (CoglTexture *tex);
 
   void (* set_wrap_mode_parameter) (CoglTexture *tex,
                                     GLenum wrap_mode);
@@ -137,6 +140,10 @@ void
 _cogl_texture_transform_coords_to_gl (CoglHandle handle,
                                       float *s,
                                       float *t);
+gboolean
+_cogl_texture_transform_quad_coords_to_gl (CoglHandle handle,
+                                           float *coords);
+
 GLenum
 _cogl_texture_get_gl_format (CoglHandle handle);
 
@@ -152,6 +159,9 @@ _cogl_texture_set_filters (CoglHandle handle,
 void
 _cogl_texture_ensure_mipmaps (CoglHandle handle);
 
+void
+_cogl_texture_ensure_non_quad_rendering (CoglHandle handle);
+
 /* Utility functions to help uploading a bitmap. These are intended to
  * be used by CoglTexture implementations or drivers... */
 
index 85a6de7..09acb01 100644 (file)
@@ -428,12 +428,13 @@ cogl_texture_new_from_foreign (GLuint           gl_handle,
 
 CoglHandle
 cogl_texture_new_from_sub_texture (CoglHandle full_texture,
-                                   gfloat     tx1,
-                                   gfloat     ty1,
-                                   gfloat     tx2,
-                                   gfloat     ty2)
+                                   gint       sub_x,
+                                   gint       sub_y,
+                                   gint       sub_width,
+                                   gint       sub_height)
 {
-  return _cogl_sub_texture_new (full_texture, tx1, ty1, tx2, ty2);
+  return _cogl_sub_texture_new (full_texture, sub_x, sub_y,
+                                sub_width, sub_height);
 }
 
 guint
@@ -574,6 +575,15 @@ _cogl_texture_transform_coords_to_gl (CoglHandle handle,
   tex->vtable->transform_coords_to_gl (tex, s, t);
 }
 
+gboolean
+_cogl_texture_transform_quad_coords_to_gl (CoglHandle handle,
+                                           float *coords)
+{
+  CoglTexture *tex = COGL_TEXTURE (handle);
+
+  return tex->vtable->transform_quad_coords_to_gl (tex, coords);
+}
+
 GLenum
 _cogl_texture_get_gl_format (CoglHandle handle)
 {
@@ -625,6 +635,19 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle)
   tex->vtable->ensure_mipmaps (tex);
 }
 
+void
+_cogl_texture_ensure_non_quad_rendering (CoglHandle handle)
+{
+  CoglTexture *tex;
+
+  if (!cogl_is_texture (handle))
+    return;
+
+  tex = COGL_TEXTURE (handle);
+
+  return tex->vtable->ensure_non_quad_rendering (tex);
+}
+
 gboolean
 cogl_texture_set_region (CoglHandle       handle,
                         gint             src_x,
index 2ab90c8..c0becf9 100644 (file)
@@ -320,18 +320,18 @@ gboolean        cogl_texture_set_region       (CoglHandle          handle,
 /**
  * cogl_texture_new_from_sub_texture:
  * @full_texture: a #CoglHandle to an existing texture
- * @tx1: X coordinate of the top-left of the subregion
- * @ty1: Y coordinate of the top-left of the subregion
- * @tx2: X coordinate of the bottom-right of the subregion
- * @ty2: Y coordinate of the bottom-right of the subregion
+ * @sub_x: X coordinate of the top-left of the subregion
+ * @sub_y: Y coordinate of the top-left of the subregion
+ * @sub_width: Width in pixels of the subregion
+ * @sub_height: Height in pixels of the subregion
  *
  * Creates a new texture which represents a subregion of another
  * texture. The GL resources will be shared so that no new texture
  * data is actually allocated.
  *
- * You can also specify texture coordinates outside the range of [0,1]
- * to make a texture that represents a repeated version of another
- * texture.
+ * Sub textures have undefined behaviour texture coordinates outside
+ * of the range [0,1] are used. They also do not work with
+ * CoglVertexBuffers.
  *
  * Return value: a #CoglHandle to the new texture.
  *
@@ -339,10 +339,10 @@ gboolean        cogl_texture_set_region       (CoglHandle          handle,
  */
 CoglHandle      cogl_texture_new_from_sub_texture
                                               (CoglHandle full_texture,
-                                               gfloat     tx1,
-                                               gfloat     ty1,
-                                               gfloat     tx2,
-                                               gfloat     ty2);
+                                               gint       sub_x,
+                                               gint       sub_y,
+                                               gint       sub_width,
+                                               gint       sub_height);
 
 #ifndef COGL_DISABLE_DEPRECATED
 
index 26d09ce..943b777 100644 (file)
@@ -1637,6 +1637,11 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
       if (tex_handle == COGL_INVALID_HANDLE)
         continue;
 
+      /* Give the texture a chance to know that we're rendering
+         non-quad shaped primitives. If the texture is in an atlas it
+         will be migrated */
+      _cogl_texture_ensure_non_quad_rendering (tex_handle);
+
       if (!_cogl_texture_can_hardware_repeat (tex_handle))
         {
           g_warning ("Disabling layer %d of the current source material, "
index 45449b9..ea0f612 100644 (file)
@@ -74,9 +74,10 @@ draw_frame (TestState *state)
 
   /* Create a sub texture of the bottom right quarter of the texture */
   sub_texture = cogl_texture_new_from_sub_texture (state->tex,
-                                                   1.0f / SOURCE_DIVISIONS_X,
-                                                   1.0f / SOURCE_DIVISIONS_Y,
-                                                   1.0f, 1.0f);
+                                                   DIVISION_WIDTH,
+                                                   DIVISION_HEIGHT,
+                                                   DIVISION_WIDTH,
+                                                   DIVISION_HEIGHT);
 
   /* Paint it */
   cogl_set_source_texture (sub_texture);
@@ -84,22 +85,19 @@ draw_frame (TestState *state)
 
   cogl_handle_unref (sub_texture);
 
-  /* Repeat a sub texture of the top half of the full texture */
+  /* Repeat a sub texture of the top half of the full texture. This is
+     documented to be undefined so it doesn't technically have to work
+     but it will with the current implementation */
   sub_texture = cogl_texture_new_from_sub_texture (state->tex,
-                                                   0.0f, 0.0f, 1.0f, 0.5f);
+                                                   0, 0,
+                                                   SOURCE_SIZE,
+                                                   DIVISION_HEIGHT);
   cogl_set_source_texture (sub_texture);
   cogl_rectangle_with_texture_coords (0.0f, SOURCE_SIZE,
                                       SOURCE_SIZE * 2.0f, SOURCE_SIZE * 1.5f,
                                       0.0f, 0.0f,
                                       2.0f, 1.0f);
   cogl_handle_unref (sub_texture);
-
-  /* Create a texture that repeats the source texture twice */
-  sub_texture = cogl_texture_new_from_sub_texture (state->tex,
-                                                   0.0f, 0.0f, 2.0f, 2.0f);
-  cogl_set_source_texture (sub_texture);
-  cogl_rectangle (0.0f, SOURCE_SIZE * 2, SOURCE_SIZE * 2, SOURCE_SIZE * 4);
-  cogl_handle_unref (sub_texture);
 }
 
 static gboolean
@@ -209,22 +207,12 @@ validate_result (TestState *state)
                                DIVISION_WIDTH, DIVISION_HEIGHT,
                                corner_colors + division_num));
 
-  /* Sub texture that repeats the texture (the opposite of a sub-texture?) */
-  for (y = 0; y < SOURCE_DIVISIONS_Y * 2; y++)
-    for (x = 0; x < SOURCE_DIVISIONS_X * 2; x++)
-      {
-        guint color_num = (y % SOURCE_DIVISIONS_Y * SOURCE_DIVISIONS_X +
-                           x % SOURCE_DIVISIONS_X);
-        g_assert (validate_part (state,
-                                 x * DIVISION_WIDTH,
-                                 y * DIVISION_WIDTH + SOURCE_SIZE * 2,
-                                 DIVISION_WIDTH, DIVISION_HEIGHT,
-                                 corner_colors + color_num));
-      }
-
   /* Try reading back the texture data */
   sub_texture = cogl_texture_new_from_sub_texture (state->tex,
-                                                   0.25f, 0.25f, 0.75f, 0.75f);
+                                                   SOURCE_SIZE / 4,
+                                                   SOURCE_SIZE / 4,
+                                                   SOURCE_SIZE / 2,
+                                                   SOURCE_SIZE / 2);
   tex_width = cogl_texture_get_width (sub_texture);
   tex_height = cogl_texture_get_height (sub_texture);
   p = texture_data = g_malloc (tex_width * tex_height * 4);
@@ -248,39 +236,14 @@ validate_result (TestState *state)
   g_free (texture_data);
   cogl_handle_unref (sub_texture);
 
-  /* Try reading back the repeated texture data */
-  sub_texture = cogl_texture_new_from_sub_texture (state->tex,
-                                                   0.0f, 0.0f, 2.0f, 2.0f);
-  tex_width = cogl_texture_get_width (sub_texture);
-  tex_height = cogl_texture_get_height (sub_texture);
-  p = texture_data = g_malloc (tex_width * tex_height * 4);
-  cogl_texture_get_data (sub_texture, COGL_PIXEL_FORMAT_RGBA_8888,
-                         tex_width * 4,
-                         texture_data);
-  for (y = 0; y < tex_height; y++)
-    for (x = 0; x < tex_width; x++)
-      {
-        int div_x = x / DIVISION_WIDTH % SOURCE_DIVISIONS_X;
-        int div_y = y / DIVISION_HEIGHT % SOURCE_DIVISIONS_Y;
-        const ClutterColor *color = (corner_colors + div_x +
-                                     div_y * SOURCE_DIVISIONS_X);
-        g_assert (p[0] == color->red);
-        g_assert (p[1] == color->green);
-        g_assert (p[2] == color->blue);
-        p += 4;
-      }
-  g_free (texture_data);
-  cogl_handle_unref (sub_texture);
-
   /* Create a 256x256 test texture */
   test_tex = create_test_texture ();
-  /* Create a sub texture the views the bottom right and top left of
-     the texture by wrapping around */
+  /* Create a sub texture the views the center half of the texture */
   sub_texture = cogl_texture_new_from_sub_texture (test_tex,
-                                                   0.5f, 0.5f, 1.5f, 1.5f);
-  /* Update the center of the sub texture */
+                                                   64, 64, 128, 128);
+  /* Update the center half of the sub texture */
   texture_data = create_update_data ();
-  cogl_texture_set_region (sub_texture, 0, 0, 64, 64, 128, 128, 256, 256,
+  cogl_texture_set_region (sub_texture, 0, 0, 32, 32, 64, 64, 256, 256,
                            COGL_PIXEL_FORMAT_RGBA_8888_PRE, 256 * 4,
                            texture_data);
   g_free (texture_data);
@@ -294,13 +257,13 @@ validate_result (TestState *state)
   for (y = 0; y < 256; y++)
     for (x = 0; x < 256; x++)
       {
-        /* If we're in the center of the subregion.. */
-        if ((x < 64 || x >= 192) && (y < 64 || y >= 192))
+        /* If we're in the center quarter */
+        if (x >= 96 && x < 160 && y >= 96 && y < 160)
           {
             g_assert ((*p++) == 0);
             g_assert ((*p++) == 0);
-            g_assert ((*p++) == ((x + 64) & 0xff));
-            g_assert ((*p++) == ((y + 64) & 0xff));
+            g_assert ((*p++) == x - 96);
+            g_assert ((*p++) == y - 96);
           }
         else
           {
index 3b55ebb..3681fe2 100644 (file)
@@ -145,7 +145,6 @@ main (int argc, char **argv)
   TEST_CONFORM_SIMPLE ("/opacity", test_paint_opacity);
 
   TEST_CONFORM_SIMPLE ("/texture", test_texture_fbo);
-  TEST_CONFORM_SIMPLE ("/texture", test_cogl_sub_texture);
 
   TEST_CONFORM_SIMPLE ("/path", test_path);
 
@@ -189,6 +188,7 @@ main (int argc, char **argv)
   TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_npot_texture);
   TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_multitexture);
   TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_mipmaps);
+  TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_sub_texture);
 
   TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_contiguous);
   TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_interleved);