[cogl/wip/rib/master-next: 24/36] meta-texture: This publicly exposes CoglMetaTexture
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/rib/master-next: 24/36] meta-texture: This publicly exposes CoglMetaTexture
- Date: Mon, 17 Oct 2011 12:47:16 +0000 (UTC)
commit 08530c9d598f416ba5df000f9249dafe413b9b05
Author: Robert Bragg <robert linux intel com>
Date: Sat Oct 8 14:13:03 2011 +0100
meta-texture: This publicly exposes CoglMetaTexture
CoglMetaTexture is an interface for dealing with high level textures
that may be comprised of one or more low-level textures internally. The
interface allows the development of primitive drawing APIs that can draw
with high-level textures (such as atlas textures) even though the
GPU doesn't natively understand these texture types.
There is currently just one function that's part of this interface:
cogl_meta_texture_foreach_in_region() which allows an application to
resolve the internal, low-level textures of a high-level texture.
cogl_rectangle() uses this API for example so that it can easily emulate
the _REPEAT wrap mode for textures that the hardware can't natively
handle repeating of.
cogl-pango/cogl-pango-render.c | 16 ++--
cogl/Makefile.am | 2 +
cogl/cogl-atlas-texture.c | 20 +++--
cogl/cogl-meta-texture.c | 169 +++++++++++++++++++++++++++++++++
cogl/cogl-primitives.c | 74 +++++++++-----
cogl/cogl-spans.c | 24 +++--
cogl/cogl-spans.h | 37 ++++---
cogl/cogl-sub-texture.c | 83 +++++++---------
cogl/cogl-texture-2d-sliced.c | 28 ++++--
cogl/cogl-texture-2d.c | 71 +-------------
cogl/cogl-texture-3d.c | 76 +---------------
cogl/cogl-texture-private.h | 32 +------
cogl/cogl-texture-rectangle-private.h | 3 +
cogl/cogl-texture-rectangle.c | 81 +----------------
cogl/cogl-texture.c | 132 +------------------------
cogl/cogl.h | 1 +
cogl/winsys/cogl-texture-pixmap-x11.c | 81 ++++++++++++++--
17 files changed, 417 insertions(+), 513 deletions(-)
---
diff --git a/cogl-pango/cogl-pango-render.c b/cogl-pango/cogl-pango-render.c
index ff974d6..3f87b52 100644
--- a/cogl-pango/cogl-pango-render.c
+++ b/cogl-pango/cogl-pango-render.c
@@ -140,13 +140,15 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv,
the neighbouring glyphs are coming from the same atlas and bundle
them together into a single VBO */
- _cogl_texture_foreach_sub_texture_in_region (cache_value->texture,
- cache_value->tx1,
- cache_value->ty1,
- cache_value->tx2,
- cache_value->ty2,
- cogl_pango_renderer_slice_cb,
- &data);
+ cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (cache_value->texture),
+ cache_value->tx1,
+ cache_value->ty1,
+ cache_value->tx2,
+ cache_value->ty2,
+ COGL_PIPELINE_WRAP_MODE_REPEAT,
+ COGL_PIPELINE_WRAP_MODE_REPEAT,
+ cogl_pango_renderer_slice_cb,
+ &data);
}
static void cogl_pango_renderer_finalize (GObject *object);
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 3135afd..7e3e943 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -78,6 +78,7 @@ cogl_public_h = \
$(srcdir)/cogl-texture-3d.h \
$(srcdir)/cogl-texture-2d.h \
$(srcdir)/cogl-texture-2d-sliced.h \
+ $(srcdir)/cogl-meta-texture.h \
$(srcdir)/cogl-types.h \
$(srcdir)/cogl-vertex-buffer.h \
$(srcdir)/cogl-index-buffer.h \
@@ -295,6 +296,7 @@ cogl_sources_c = \
$(srcdir)/cogl-atlas.c \
$(srcdir)/cogl-atlas-texture-private.h \
$(srcdir)/cogl-atlas-texture.c \
+ $(srcdir)/cogl-meta-texture.c \
$(srcdir)/cogl-blit.h \
$(srcdir)/cogl-blit.c \
$(srcdir)/cogl-spans.h \
diff --git a/cogl/cogl-atlas-texture.c b/cogl/cogl-atlas-texture.c
index 3fc459b..a2a1701 100644
--- a/cogl/cogl-atlas-texture.c
+++ b/cogl/cogl-atlas-texture.c
@@ -225,19 +225,23 @@ _cogl_atlas_texture_foreach_sub_texture_in_region (
float virtual_ty_1,
float virtual_tx_2,
float virtual_ty_2,
- CoglTextureSliceCallback callback,
+ CoglPipelineWrapMode wrap_x,
+ CoglPipelineWrapMode wrap_y,
+ CoglMetaTextureCallback callback,
void *user_data)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Forward on to the sub texture */
- _cogl_texture_foreach_sub_texture_in_region (atlas_tex->sub_texture,
- virtual_tx_1,
- virtual_ty_1,
- virtual_tx_2,
- virtual_ty_2,
- callback,
- user_data);
+ cogl_meta_texture_foreach_in_region (atlas_tex->sub_texture,
+ virtual_tx_1,
+ virtual_ty_1,
+ virtual_tx_2,
+ virtual_ty_2,
+ wrap_x,
+ wrap_y,
+ callback,
+ user_data);
}
static void
diff --git a/cogl/cogl-meta-texture.c b/cogl/cogl-meta-texture.c
new file mode 100644
index 0000000..1fbe877
--- /dev/null
+++ b/cogl/cogl-meta-texture.c
@@ -0,0 +1,169 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Authors:
+ * Robert Bragg <robert linux intel com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cogl-texture.h"
+#include "cogl-matrix.h"
+#include "cogl-spans.h"
+#include "cogl-meta-texture.h"
+#include "cogl-texture-rectangle-private.h"
+
+void
+cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture,
+ float tx_1,
+ float ty_1,
+ float tx_2,
+ float ty_2,
+ CoglPipelineWrapMode wrap_s,
+ CoglPipelineWrapMode wrap_t,
+ CoglMetaTextureCallback callback,
+ void *user_data)
+{
+ CoglTexture *texture = COGL_TEXTURE (meta_texture);
+
+ /* XXX: at some point this wont be routed through the CoglTexture
+ * vtable, instead their will be a separate CoglMetaTexture
+ * interface vtable. */
+
+ if (texture->vtable->foreach_sub_texture_in_region)
+ texture->vtable->foreach_sub_texture_in_region (texture,
+ tx_1,
+ ty_1,
+ tx_2,
+ ty_2,
+ wrap_s,
+ wrap_t,
+ callback,
+ user_data);
+ else
+ {
+ int width = cogl_texture_get_height (COGL_TEXTURE (meta_texture));
+ int height = cogl_texture_get_height (COGL_TEXTURE (meta_texture));
+ CoglSpan x_span = { 0, width, 0 };
+ CoglSpan y_span = { 0, height, 0 };
+ float x_normalize_factor, y_normalize_factor;
+ CoglSpanIter iter_x;
+ CoglSpanIter iter_y;
+ float slice_coords[4];
+
+ if (_cogl_is_texture_rectangle (meta_texture))
+ x_normalize_factor = y_normalize_factor = 1;
+ else
+ {
+ x_normalize_factor = width;
+ y_normalize_factor = height;
+ }
+
+ /* Slice spans are stored in denormalized coordinates, and this
+ * is what the _cogl_span_iter_* funcs expect to be given, so we
+ * scale the given virtual coordinates by the texture size to
+ * denormalize.
+ */
+ /* XXX: I wonder if it's worth changing how we store spans so we
+ * can avoid the need to denormalize here */
+ tx_1 *= x_normalize_factor;
+ ty_1 *= y_normalize_factor;
+ tx_2 *= x_normalize_factor;
+ ty_2 *= y_normalize_factor;
+
+ /* Iterate the y axis of the virtual rectangle */
+ for (_cogl_span_iter_begin (&iter_y,
+ &y_span,
+ 1,
+ y_normalize_factor,
+ ty_1,
+ ty_2,
+ wrap_t);
+ !_cogl_span_iter_end (&iter_y);
+ _cogl_span_iter_next (&iter_y))
+ {
+ if (iter_y.flipped)
+ {
+ slice_coords[1] = iter_y.intersect_end;
+ slice_coords[3] = iter_y.intersect_start;
+ }
+ else
+ {
+ slice_coords[1] = iter_y.intersect_start;
+ slice_coords[3] = iter_y.intersect_end;
+ }
+
+ /* Localize slice texture coordinates */
+ slice_coords[1] -= iter_y.pos;
+ slice_coords[3] -= iter_y.pos;
+
+ /* Normalize slice texture coordinates */
+ slice_coords[1] /= iter_y.span->size;
+ slice_coords[3] /= iter_y.span->size;
+
+ /* Iterate the x axis of the virtual rectangle */
+ for (_cogl_span_iter_begin (&iter_x,
+ &x_span,
+ 1,
+ x_normalize_factor,
+ tx_1,
+ tx_2,
+ wrap_s);
+ !_cogl_span_iter_end (&iter_x);
+ _cogl_span_iter_next (&iter_x))
+ {
+ float normalized_vcoords[4];
+
+ if (iter_x.flipped)
+ {
+ slice_coords[0] = iter_x.intersect_end;
+ slice_coords[2] = iter_x.intersect_start;
+ }
+ else
+ {
+ slice_coords[0] = iter_x.intersect_start;
+ slice_coords[2] = iter_x.intersect_end;
+ }
+
+ /* Localize slice texture coordinates */
+ slice_coords[0] -= iter_x.pos;
+ slice_coords[2] -= iter_x.pos;
+
+ /* Normalize slice texture coordinates */
+ slice_coords[0] /= iter_x.span->size;
+ slice_coords[2] /= iter_x.span->size;
+
+ normalized_vcoords[0] = iter_x.intersect_start / width;
+ normalized_vcoords[1] = iter_y.intersect_start / height;
+ normalized_vcoords[2] = iter_x.intersect_end / width;
+ normalized_vcoords[3] = iter_y.intersect_end / height;
+
+ callback (COGL_TEXTURE (meta_texture),
+ slice_coords,
+ normalized_vcoords,
+ user_data);
+ }
+ }
+ }
+}
diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c
index 9281306..27707bb 100644
--- a/cogl/cogl-primitives.c
+++ b/cogl/cogl-primitives.c
@@ -37,6 +37,7 @@
#include "cogl-framebuffer-private.h"
#include "cogl-attribute-private.h"
#include "cogl-private.h"
+#include "cogl-meta-texture.h"
#include <string.h>
#include <math.h>
@@ -139,6 +140,8 @@ validate_first_layer_cb (CoglPipeline *pipeline,
ValidateFirstLayerState *state = user_data;
CoglPipelineWrapMode clamp_to_edge =
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE;
+ CoglPipelineWrapMode wrap_s;
+ CoglPipelineWrapMode wrap_t;
/* We can't use hardware repeat so we need to set clamp to edge
* otherwise it might pull in edge pixels from the other side. By
@@ -184,15 +187,16 @@ validate_first_layer_cb (CoglPipeline *pipeline,
*/
/* TODO: support multitexturing */
static void
-_cogl_texture_quad_multiple_primitives (CoglTexture *texture,
+_cogl_texture_quad_multiple_primitives (CoglTexture *texture,
CoglPipeline *pipeline,
- gboolean clamp_s,
- gboolean clamp_t,
- const float *position,
- float tx_1,
- float ty_1,
- float tx_2,
- float ty_2)
+ int layer_index,
+ gboolean check_clamp_s,
+ gboolean check_clamp_t,
+ const float *position,
+ float tx_1,
+ float ty_1,
+ float tx_2,
+ float ty_2)
{
TextureSlicedQuadState state;
gboolean tex_virtual_flipped_x;
@@ -200,12 +204,17 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
gboolean quad_flipped_x;
gboolean quad_flipped_y;
ValidateFirstLayerState validate_first_layer_state;
+ CoglPipelineWrapMode wrap_s, wrap_t;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ wrap_s = cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index);
+ wrap_t = cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index);
+
/* If the wrap mode is clamp to edge then we'll recursively draw the
stretched part and replace the coordinates */
- if (clamp_s && tx_1 != tx_2)
+ if (check_clamp_s &&
+ wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && tx_1 != tx_2)
{
float *replacement_position = g_newa (float, 4);
float old_tx_1 = tx_1, old_tx_2 = tx_2;
@@ -225,7 +234,8 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
(tx_1 - old_tx_1) / (old_tx_2 - old_tx_1)),
position[3] };
_cogl_texture_quad_multiple_primitives (texture, pipeline,
- FALSE, clamp_t,
+ layer_index,
+ FALSE, TRUE,
tmp_position,
tx_1, ty_1, tx_1, ty_2);
replacement_position[0] = tmp_position[2];
@@ -240,7 +250,8 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
(tx_2 - old_tx_1) / (old_tx_2 - old_tx_1)),
position[1], position[2], position[3] };
_cogl_texture_quad_multiple_primitives (texture, pipeline,
- FALSE, clamp_t,
+ layer_index,
+ FALSE, TRUE,
tmp_position,
tx_2, ty_1, tx_2, ty_2);
replacement_position[2] = tmp_position[0];
@@ -253,7 +264,8 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
position = replacement_position;
}
- if (clamp_t && ty_1 != ty_2)
+ if (check_clamp_t &&
+ wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && ty_1 != ty_2)
{
float *replacement_position = g_newa (float, 4);
float old_ty_1 = ty_1, old_ty_2 = ty_2;
@@ -272,7 +284,8 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
(position[3] - position[1]) *
(ty_1 - old_ty_1) / (old_ty_2 - old_ty_1)) };
_cogl_texture_quad_multiple_primitives (texture, pipeline,
- clamp_s, FALSE,
+ layer_index,
+ TRUE, FALSE,
tmp_position,
tx_1, ty_1, tx_2, ty_1);
replacement_position[1] = tmp_position[3];
@@ -288,7 +301,8 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
(ty_2 - old_ty_1) / (old_ty_2 - old_ty_1)),
position[2], position[3] };
_cogl_texture_quad_multiple_primitives (texture, pipeline,
- clamp_s, FALSE,
+ layer_index,
+ TRUE, FALSE,
tmp_position,
tx_1, ty_2, tx_2, ty_2);
replacement_position[3] = tmp_position[1];
@@ -354,10 +368,23 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1));
state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1));
- _cogl_texture_foreach_sub_texture_in_region (texture,
- tx_1, ty_1, tx_2, ty_2,
- log_quad_sub_textures_cb,
- &state);
+ /* cogl_meta_texture_foreach_in_region only allows WRAP_MODE_REPEAT.
+ * If CLAMP_TO_EDGE is in use then we have already dealt with
+ * emulation for that and we can just pass WRAP_MODE_REPEAT here...
+ */
+ if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC ||
+ wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
+ wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT;
+ if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC ||
+ wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
+ wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT;
+
+ cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
+ tx_1, ty_1, tx_2, ty_2,
+ wrap_s,
+ wrap_t,
+ log_quad_sub_textures_cb,
+ &state);
if (validate_first_layer_state.override_pipeline)
cogl_object_unref (validate_first_layer_state.override_pipeline);
@@ -760,7 +787,6 @@ _cogl_rectangles_with_multitexture_coords (
CoglTexture *texture;
const float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
const float *tex_coords;
- gboolean clamp_s, clamp_t;
if (!state.all_use_sliced_quad_fallback)
{
@@ -788,18 +814,12 @@ _cogl_rectangles_with_multitexture_coords (
else
tex_coords = default_tex_coords;
- clamp_s = (cogl_pipeline_get_layer_wrap_mode_s (pipeline,
- state.first_layer) ==
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- clamp_t = (cogl_pipeline_get_layer_wrap_mode_t (pipeline,
- state.first_layer) ==
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
-
COGL_NOTE (DRAW, "Drawing Tex Quad (Multi-Prim Mode)");
_cogl_texture_quad_multiple_primitives (texture,
pipeline,
- clamp_s, clamp_t,
+ state.first_layer,
+ TRUE, TRUE,
rects[i].position,
tex_coords[0],
tex_coords[1],
diff --git a/cogl/cogl-spans.c b/cogl/cogl-spans.c
index bf72274..1b2586c 100644
--- a/cogl/cogl-spans.c
+++ b/cogl/cogl-spans.c
@@ -35,7 +35,7 @@ void
_cogl_span_iter_update (CoglSpanIter *iter)
{
/* Pick current span */
- iter->span = &g_array_index (iter->array, CoglSpan, iter->index);
+ iter->span = &iter->spans[iter->index];
/* Offset next position by span size */
iter->next_pos = iter->pos +
@@ -67,17 +67,24 @@ _cogl_span_iter_update (CoglSpanIter *iter)
void
_cogl_span_iter_begin (CoglSpanIter *iter,
- GArray *spans,
- float normalize_factor,
- float cover_start,
- float cover_end)
+ const CoglSpan *spans,
+ int n_spans,
+ float normalize_factor,
+ float cover_start,
+ float cover_end,
+ CoglPipelineWrapMode wrap_mode)
{
float cover_start_normalized;
+ /* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be
+ * done at a higher level than here... */
+ g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT);
+
iter->index = 0;
iter->span = NULL;
- iter->array = spans;
+ iter->spans = spans;
+ iter->n_spans = n_spans;
/* We always iterate in a positive direction from the origin. If
* iter->flipped == TRUE that means whoever is using this API should
@@ -101,6 +108,8 @@ _cogl_span_iter_begin (CoglSpanIter *iter,
cover_start_normalized = cover_start / normalize_factor;
iter->origin = floorf (cover_start_normalized) * normalize_factor;
+ iter->wrap_mode = wrap_mode;
+
iter->cover_start = cover_start;
iter->cover_end = cover_end;
iter->pos = iter->origin;
@@ -118,8 +127,7 @@ _cogl_span_iter_next (CoglSpanIter *iter)
/* Move current position */
iter->pos = iter->next_pos;
- /* Pick next slice (wrap when last reached) */
- iter->index = (iter->index + 1) % iter->array->len;
+ iter->index = (iter->index + 1) % iter->n_spans;
/* Update intersection */
_cogl_span_iter_update (iter);
diff --git a/cogl/cogl-spans.h b/cogl/cogl-spans.h
index 1717522..e69833e 100644
--- a/cogl/cogl-spans.h
+++ b/cogl/cogl-spans.h
@@ -25,6 +25,7 @@
#define __COGL_SPANS_PRIVATE_H
#include "cogl-handle.h"
+#include "cogl-pipeline-layer-state.h"
typedef struct _CoglSpan
{
@@ -35,18 +36,20 @@ typedef struct _CoglSpan
typedef struct _CoglSpanIter
{
- int index;
- GArray *array;
- CoglSpan *span;
- float pos;
- float next_pos;
- float origin;
- float cover_start;
- float cover_end;
- float intersect_start;
- float intersect_end;
- gboolean intersects;
- gboolean flipped;
+ int index;
+ const CoglSpan *spans;
+ int n_spans;
+ const CoglSpan *span;
+ float pos;
+ float next_pos;
+ float origin;
+ float cover_start;
+ float cover_end;
+ float intersect_start;
+ float intersect_end;
+ gboolean intersects;
+ gboolean flipped;
+ CoglPipelineWrapMode wrap_mode;
} CoglSpanIter;
void
@@ -54,10 +57,12 @@ _cogl_span_iter_update (CoglSpanIter *iter);
void
_cogl_span_iter_begin (CoglSpanIter *iter,
- GArray *spans,
- float normalize_factor,
- float cover_start,
- float cover_end);
+ const CoglSpan *spans,
+ int n_spans,
+ float normalize_factor,
+ float cover_start,
+ float cover_end,
+ CoglPipelineWrapMode wrap_mode);
void
_cogl_span_iter_next (CoglSpanIter *iter);
diff --git a/cogl/cogl-sub-texture.c b/cogl/cogl-sub-texture.c
index 331eecc..9abc9b0 100644
--- a/cogl/cogl-sub-texture.c
+++ b/cogl/cogl-sub-texture.c
@@ -150,52 +150,31 @@ _cogl_sub_texture_unmap_coords (CoglSubTexture *sub_tex,
typedef struct _CoglSubTextureForeachData
{
CoglSubTexture *sub_tex;
- CoglTextureSliceCallback callback;
+ CoglMetaTextureCallback callback;
void *user_data;
} CoglSubTextureForeachData;
static void
-_cogl_sub_texture_foreach_cb (CoglTexture *texture,
- const float *slice_coords,
- const float *full_virtual_coords,
- void *user_data)
+full_texture_foreach_in_region_cb (CoglTexture *real_texture,
+ const float *real_texture_coords,
+ const float *full_texture_coords,
+ void *user_data)
{
CoglSubTextureForeachData *data = user_data;
- float virtual_coords[4];
+ CoglSubTexture *sub_tex = data->sub_tex;
+ float sub_texture_coords[4];
- memcpy (virtual_coords, full_virtual_coords, sizeof (virtual_coords));
+ memcpy (sub_texture_coords, full_texture_coords, sizeof (float) * 4);
/* Convert the virtual coords from the full-texture space to the sub
texture space */
- _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 (texture,
- slice_coords, virtual_coords,
- data->user_data);
-}
-
-static void
-_cogl_sub_texture_manual_repeat_cb (const float *coords,
- void *user_data)
-{
- CoglSubTextureForeachData *data = user_data;
- float mapped_coords[4];
-
- memcpy (mapped_coords, coords, sizeof (mapped_coords));
-
- _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],
- mapped_coords[1],
- mapped_coords[2],
- mapped_coords[3],
- _cogl_sub_texture_foreach_cb,
- user_data);
+ _cogl_sub_texture_unmap_coords (sub_tex,
+ &sub_texture_coords[0],
+ &sub_texture_coords[1]);
+ _cogl_sub_texture_unmap_coords (sub_tex,
+ &sub_texture_coords[2],
+ &sub_texture_coords[3]);
+ data->callback (real_texture,
+ real_texture_coords, sub_texture_coords, data->user_data);
}
static void
@@ -205,20 +184,28 @@ _cogl_sub_texture_foreach_sub_texture_in_region (
float virtual_ty_1,
float virtual_tx_2,
float virtual_ty_2,
- CoglTextureSliceCallback callback,
+ CoglPipelineWrapMode wrap_x,
+ CoglPipelineWrapMode wrap_y,
+ CoglMetaTextureCallback callback,
void *user_data)
{
CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
- CoglSubTextureForeachData data;
-
- data.sub_tex = sub_tex;
- data.callback = callback;
- data.user_data = user_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);
+ float mapped_coords[4] =
+ { virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2};
+ CoglSubTextureForeachData data = { sub_tex, callback, user_data };
+
+ /* map the virtual coordinates to ->full_texture coordinates */
+ _cogl_sub_texture_map_quad (sub_tex, mapped_coords);
+
+ cogl_meta_texture_foreach_in_region (sub_tex->full_texture,
+ mapped_coords[0],
+ mapped_coords[1],
+ mapped_coords[2],
+ mapped_coords[3],
+ wrap_x,
+ wrap_y,
+ full_texture_foreach_in_region_cb,
+ &data);
}
static void
diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c
index 0f3d355..d318c9c 100644
--- a/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl-texture-2d-sliced.c
@@ -71,7 +71,9 @@ _cogl_texture_2d_sliced_foreach_sub_texture_in_region (
float virtual_ty_1,
float virtual_tx_2,
float virtual_ty_2,
- CoglTextureSliceCallback callback,
+ CoglPipelineWrapMode wrap_x,
+ CoglPipelineWrapMode wrap_y,
+ CoglMetaTextureCallback callback,
void *user_data)
{
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
@@ -94,10 +96,12 @@ _cogl_texture_2d_sliced_foreach_sub_texture_in_region (
/* Iterate the y axis of the virtual rectangle */
for (_cogl_span_iter_begin (&iter_y,
- tex_2ds->slice_y_spans,
+ (CoglSpan *)tex_2ds->slice_y_spans->data,
+ tex_2ds->slice_y_spans->len,
height,
virtual_ty_1,
- virtual_ty_2);
+ virtual_ty_2,
+ wrap_y);
!_cogl_span_iter_end (&iter_y);
_cogl_span_iter_next (&iter_y))
{
@@ -122,10 +126,12 @@ _cogl_texture_2d_sliced_foreach_sub_texture_in_region (
/* Iterate the x axis of the virtual rectangle */
for (_cogl_span_iter_begin (&iter_x,
- tex_2ds->slice_x_spans,
+ (CoglSpan *)tex_2ds->slice_x_spans->data,
+ tex_2ds->slice_x_spans->len,
width,
virtual_tx_1,
- virtual_tx_2);
+ virtual_tx_2,
+ wrap_x);
!_cogl_span_iter_end (&iter_x);
_cogl_span_iter_next (&iter_x))
{
@@ -455,10 +461,12 @@ _cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds,
/* Iterate vertical spans */
for (source_y = src_y,
_cogl_span_iter_begin (&y_iter,
- tex_2ds->slice_y_spans,
+ (CoglSpan *)tex_2ds->slice_y_spans->data,
+ tex_2ds->slice_y_spans->len,
tex_2ds->height,
dst_y,
- dst_y + height);
+ dst_y + height,
+ COGL_PIPELINE_WRAP_MODE_REPEAT);
!_cogl_span_iter_end (&y_iter);
@@ -471,10 +479,12 @@ _cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds,
/* Iterate horizontal spans */
for (source_x = src_x,
_cogl_span_iter_begin (&x_iter,
- tex_2ds->slice_x_spans,
+ (CoglSpan *)tex_2ds->slice_x_spans->data,
+ tex_2ds->slice_x_spans->len,
tex_2ds->width,
dst_x,
- dst_x + width);
+ dst_x + width,
+ COGL_PIPELINE_WRAP_MODE_REPEAT);
!_cogl_span_iter_end (&x_iter);
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 4697917..c64b14e 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -57,78 +57,11 @@ static const CoglTextureVtable cogl_texture_2d_vtable;
typedef struct _CoglTexture2DManualRepeatData
{
CoglTexture2D *tex_2d;
- CoglTextureSliceCallback callback;
+ CoglMetaTextureCallback callback;
void *user_data;
} CoglTexture2DManualRepeatData;
static void
-_cogl_texture_2d_wrap_coords (float t_1, float t_2,
- float *out_t_1, float *out_t_2)
-{
- float int_part;
-
- /* Wrap t_1 and t_2 to the range [0,1] */
-
- modff (t_1 < t_2 ? t_1 : t_2, &int_part);
- t_1 -= int_part;
- t_2 -= int_part;
- if (cogl_util_float_signbit (int_part))
- {
- *out_t_1 = 1.0f + t_1;
- *out_t_2 = 1.0f + t_2;
- }
- else
- {
- *out_t_1 = t_1;
- *out_t_2 = t_2;
- }
-}
-
-static void
-_cogl_texture_2d_manual_repeat_cb (const float *coords,
- void *user_data)
-{
- CoglTexture2DManualRepeatData *data = user_data;
- float slice_coords[4];
-
- _cogl_texture_2d_wrap_coords (coords[0], coords[2],
- slice_coords + 0, slice_coords + 2);
- _cogl_texture_2d_wrap_coords (coords[1], coords[3],
- slice_coords + 1, slice_coords + 3);
-
- data->callback (COGL_TEXTURE (data->tex_2d),
- slice_coords,
- coords,
- data->user_data);
-}
-
-static void
-_cogl_texture_2d_foreach_sub_texture_in_region (
- CoglTexture *tex,
- float virtual_tx_1,
- float virtual_ty_1,
- float virtual_tx_2,
- float virtual_ty_2,
- CoglTextureSliceCallback callback,
- void *user_data)
-{
- CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex);
- CoglTexture2DManualRepeatData data;
-
- data.tex_2d = tex_2d;
- data.callback = callback;
- data.user_data = user_data;
-
- /* We need to implement manual repeating because if Cogl is calling
- this function then it will set the wrap mode to GL_CLAMP_TO_EDGE
- and hardware repeating can't be done */
- _cogl_texture_iterate_manual_repeats (_cogl_texture_2d_manual_repeat_cb,
- virtual_tx_1, virtual_ty_1,
- virtual_tx_2, virtual_ty_2,
- &data);
-}
-
-static void
_cogl_texture_2d_set_wrap_mode_parameters (CoglTexture *tex,
GLenum wrap_mode_s,
GLenum wrap_mode_t,
@@ -923,7 +856,7 @@ cogl_texture_2d_vtable =
{
_cogl_texture_2d_set_region,
_cogl_texture_2d_get_data,
- _cogl_texture_2d_foreach_sub_texture_in_region,
+ NULL, /* foreach_sub_texture_in_region */
_cogl_texture_2d_get_max_waste,
_cogl_texture_2d_is_sliced,
_cogl_texture_2d_can_hardware_repeat,
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c
index 58adee6..584bbbd 100644
--- a/cogl/cogl-texture-3d.c
+++ b/cogl/cogl-texture-3d.c
@@ -55,80 +55,6 @@ COGL_TEXTURE_DEFINE (Texture3D, texture_3d);
static const CoglTextureVtable cogl_texture_3d_vtable;
-typedef struct _CoglTexture3DManualRepeatData
-{
- CoglTexture3D *tex_3d;
- CoglTextureSliceCallback callback;
- void *user_data;
-} CoglTexture3DManualRepeatData;
-
-static void
-_cogl_texture_3d_wrap_coords (float t_1, float t_2,
- float *out_t_1, float *out_t_2)
-{
- float int_part;
-
- /* Wrap t_1 and t_2 to the range [0,1] */
-
- modff (t_1 < t_2 ? t_1 : t_2, &int_part);
- t_1 -= int_part;
- t_2 -= int_part;
- if (cogl_util_float_signbit (int_part))
- {
- *out_t_1 = 1.0f + t_1;
- *out_t_2 = 1.0f + t_2;
- }
- else
- {
- *out_t_1 = t_1;
- *out_t_2 = t_2;
- }
-}
-
-static void
-_cogl_texture_3d_manual_repeat_cb (const float *coords,
- void *user_data)
-{
- CoglTexture3DManualRepeatData *data = user_data;
- float slice_coords[4];
-
- _cogl_texture_3d_wrap_coords (coords[0], coords[2],
- slice_coords + 0, slice_coords + 2);
- _cogl_texture_3d_wrap_coords (coords[1], coords[3],
- slice_coords + 1, slice_coords + 3);
-
- data->callback (COGL_TEXTURE (data->tex_3d),
- slice_coords,
- coords,
- data->user_data);
-}
-
-static void
-_cogl_texture_3d_foreach_sub_texture_in_region (
- CoglTexture *tex,
- float virtual_tx_1,
- float virtual_ty_1,
- float virtual_tx_2,
- float virtual_ty_2,
- CoglTextureSliceCallback callback,
- void *user_data)
-{
- CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex);
- CoglTexture3DManualRepeatData data;
-
- data.tex_3d = tex_3d;
- data.callback = callback;
- data.user_data = user_data;
-
- /* We need to implement manual repeating because if Cogl is calling
- this function then it will set the wrap mode to GL_CLAMP_TO_EDGE
- and hardware repeating can't be done */
- _cogl_texture_iterate_manual_repeats (_cogl_texture_3d_manual_repeat_cb,
- virtual_tx_1, virtual_ty_1,
- virtual_tx_2, virtual_ty_2,
- &data);
-}
-
static void
_cogl_texture_3d_set_wrap_mode_parameters (CoglTexture *tex,
GLenum wrap_mode_s,
@@ -671,7 +597,7 @@ cogl_texture_3d_vtable =
{
_cogl_texture_3d_set_region,
_cogl_texture_3d_get_data,
- _cogl_texture_3d_foreach_sub_texture_in_region,
+ NULL, /* foreach_sub_texture_in_region */
_cogl_texture_3d_get_max_waste,
_cogl_texture_3d_is_sliced,
_cogl_texture_3d_can_hardware_repeat,
diff --git a/cogl/cogl-texture-private.h b/cogl/cogl-texture-private.h
index 0ca0a45..5f86210 100644
--- a/cogl/cogl-texture-private.h
+++ b/cogl/cogl-texture-private.h
@@ -30,14 +30,6 @@
typedef struct _CoglTextureVtable CoglTextureVtable;
-typedef void (*CoglTextureSliceCallback) (CoglTexture *texture,
- const float *slice_coords,
- const float *virtual_coords,
- void *user_data);
-
-typedef void (* CoglTextureManualRepeatCallback) (const float *coords,
- void *user_data);
-
/* Encodes three possibiloities result of transforming a quad */
typedef enum {
/* quad doesn't cross the boundaries of a texture */
@@ -92,7 +84,9 @@ struct _CoglTextureVtable
float virtual_ty_1,
float virtual_tx_2,
float virtual_ty_2,
- CoglTextureSliceCallback callback,
+ CoglPipelineWrapMode s_wrap,
+ CoglPipelineWrapMode t_wrap,
+ CoglMetaTextureCallback callback,
void *user_data);
int (* get_max_waste) (CoglTexture *tex);
@@ -189,15 +183,6 @@ _cogl_texture_register_texture_type (GQuark type);
_cogl_texture_register_texture_type (_cogl_handle_ \
## type_name ## _get_type ()))
-void
-_cogl_texture_foreach_sub_texture_in_region (CoglTexture *texture,
- float virtual_tx_1,
- float virtual_ty_1,
- float virtual_tx_2,
- float virtual_ty_2,
- CoglTextureSliceCallback callback,
- void *user_data);
-
gboolean
_cogl_texture_can_hardware_repeat (CoglTexture *texture);
@@ -256,17 +241,6 @@ _cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
void
_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride);
-/* Utility function for implementing manual repeating. Even texture
- backends that always support hardware repeating need this because
- when foreach_sub_texture_in_region is invoked Cogl will set the
- wrap mode to GL_CLAMP_TO_EDGE so hardware repeating can't be
- done */
-void
-_cogl_texture_iterate_manual_repeats (CoglTextureManualRepeatCallback callback,
- float tx_1, float ty_1,
- float tx_2, float ty_2,
- void *user_data);
-
/* Utility function to use as a fallback for getting the data of any
texture via the framebuffer */
diff --git a/cogl/cogl-texture-rectangle-private.h b/cogl/cogl-texture-rectangle-private.h
index 9a0dca2..07eca5e 100644
--- a/cogl/cogl-texture-rectangle-private.h
+++ b/cogl/cogl-texture-rectangle-private.h
@@ -52,6 +52,9 @@ struct _CoglTextureRectangle
gboolean is_foreign;
};
+gboolean
+_cogl_is_texture_rectangle (void *object);
+
GQuark
_cogl_handle_texture_rectangle_get_type (void);
diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c
index 558def6..a201153 100644
--- a/cogl/cogl-texture-rectangle.c
+++ b/cogl/cogl-texture-rectangle.c
@@ -59,85 +59,6 @@ COGL_TEXTURE_INTERNAL_DEFINE (TextureRectangle, texture_rectangle);
static const CoglTextureVtable cogl_texture_rectangle_vtable;
-typedef struct _CoglTextureRectangleManualRepeatData
-{
- CoglTextureRectangle *tex_rect;
- CoglTextureSliceCallback callback;
- void *user_data;
-} CoglTextureRectangleManualRepeatData;
-
-static void
-_cogl_texture_rectangle_wrap_coords (float t_1, float t_2,
- float *out_t_1, float *out_t_2)
-{
- float int_part;
-
- /* Wrap t_1 and t_2 to the range [0,1] */
-
- modff (t_1 < t_2 ? t_1 : t_2, &int_part);
- t_1 -= int_part;
- t_2 -= int_part;
- if (cogl_util_float_signbit (int_part))
- {
- *out_t_1 = 1.0f + t_1;
- *out_t_2 = 1.0f + t_2;
- }
- else
- {
- *out_t_1 = t_1;
- *out_t_2 = t_2;
- }
-}
-
-static void
-_cogl_texture_rectangle_manual_repeat_cb (const float *coords,
- void *user_data)
-{
- CoglTextureRectangleManualRepeatData *data = user_data;
- float slice_coords[4];
-
- _cogl_texture_rectangle_wrap_coords (coords[0], coords[2],
- slice_coords + 0, slice_coords + 2);
- _cogl_texture_rectangle_wrap_coords (coords[1], coords[3],
- slice_coords + 1, slice_coords + 3);
-
- slice_coords[0] *= data->tex_rect->width;
- slice_coords[1] *= data->tex_rect->height;
- slice_coords[2] *= data->tex_rect->width;
- slice_coords[3] *= data->tex_rect->height;
-
- data->callback (COGL_TEXTURE (data->tex_rect),
- slice_coords,
- coords,
- data->user_data);
-}
-
-static void
-_cogl_texture_rectangle_foreach_sub_texture_in_region (
- CoglTexture *tex,
- float virtual_tx_1,
- float virtual_ty_1,
- float virtual_tx_2,
- float virtual_ty_2,
- CoglTextureSliceCallback callback,
- void *user_data)
-{
- CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
- CoglTextureRectangleManualRepeatData data;
-
- data.tex_rect = tex_rect;
- data.callback = callback;
- data.user_data = user_data;
-
- /* We need to implement manual repeating because if Cogl is calling
- this function then it will set the wrap mode to GL_CLAMP_TO_EDGE
- and hardware repeating can't be done */
- _cogl_texture_iterate_manual_repeats
- (_cogl_texture_rectangle_manual_repeat_cb,
- virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2,
- &data);
-}
-
static gboolean
can_use_wrap_mode (GLenum wrap_mode)
{
@@ -653,7 +574,7 @@ cogl_texture_rectangle_vtable =
{
_cogl_texture_rectangle_set_region,
_cogl_texture_rectangle_get_data,
- _cogl_texture_rectangle_foreach_sub_texture_in_region,
+ NULL, /* foreach_sub_texture_in_region */
_cogl_texture_rectangle_get_max_waste,
_cogl_texture_rectangle_is_sliced,
_cogl_texture_rectangle_can_hardware_repeat,
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index b2e0a40..7440cae 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -292,101 +292,6 @@ _cogl_texture_set_wrap_mode_parameters (CoglTexture *texture,
wrap_mode_p);
}
-/* This is like CoglSpanIter except it deals with floats and it
- effectively assumes there is only one span from 0.0 to 1.0 */
-typedef struct _CoglTextureIter
-{
- float pos, end, next_pos;
- gboolean flipped;
- float t_1, t_2;
-} CoglTextureIter;
-
-static void
-_cogl_texture_iter_update (CoglTextureIter *iter)
-{
- float t_2;
- float frac_part;
-
- frac_part = modff (iter->pos, &iter->next_pos);
-
- /* modff rounds the int part towards zero so we need to add one if
- we're meant to be heading away from zero */
- if (iter->pos >= 0.0f || frac_part == 0.0f)
- iter->next_pos += 1.0f;
-
- if (iter->next_pos > iter->end)
- t_2 = iter->end;
- else
- t_2 = iter->next_pos;
-
- if (iter->flipped)
- {
- iter->t_1 = t_2;
- iter->t_2 = iter->pos;
- }
- else
- {
- iter->t_1 = iter->pos;
- iter->t_2 = t_2;
- }
-}
-
-static void
-_cogl_texture_iter_begin (CoglTextureIter *iter,
- float t_1, float t_2)
-{
- if (t_1 <= t_2)
- {
- iter->pos = t_1;
- iter->end = t_2;
- iter->flipped = FALSE;
- }
- else
- {
- iter->pos = t_2;
- iter->end = t_1;
- iter->flipped = TRUE;
- }
-
- _cogl_texture_iter_update (iter);
-}
-
-static void
-_cogl_texture_iter_next (CoglTextureIter *iter)
-{
- iter->pos = iter->next_pos;
- _cogl_texture_iter_update (iter);
-}
-
-static gboolean
-_cogl_texture_iter_end (CoglTextureIter *iter)
-{
- return iter->pos >= iter->end;
-}
-
-/* This invokes the callback with enough quads to cover the manually
- repeated range specified by the virtual texture coordinates without
- emitting coordinates outside the range [0,1] */
-void
-_cogl_texture_iterate_manual_repeats (CoglTextureManualRepeatCallback callback,
- float tx_1, float ty_1,
- float tx_2, float ty_2,
- void *user_data)
-{
- CoglTextureIter x_iter, y_iter;
-
- for (_cogl_texture_iter_begin (&y_iter, ty_1, ty_2);
- !_cogl_texture_iter_end (&y_iter);
- _cogl_texture_iter_next (&y_iter))
- for (_cogl_texture_iter_begin (&x_iter, tx_1, tx_2);
- !_cogl_texture_iter_end (&x_iter);
- _cogl_texture_iter_next (&x_iter))
- {
- float coords[4] = { x_iter.t_1, y_iter.t_1, x_iter.t_2, y_iter.t_2 };
- callback (coords, user_data);
- }
-}
-
CoglTexture *
cogl_texture_new_with_size (unsigned int width,
unsigned int height,
@@ -681,33 +586,6 @@ cogl_texture_is_sliced (CoglTexture *texture)
return texture->vtable->is_sliced (texture);
}
-/* Some CoglTextures, notably sliced textures or atlas textures when repeating
- * is used, will need to divide the coordinate space into multiple GL textures
- * (or rather; in the case of atlases duplicate a single texture in multiple
- * positions to handle repeating)
- *
- * This function helps you implement primitives using such textures by
- * invoking a callback once for each sub texture that intersects a given
- * region specified in texture coordinates.
- */
-void
-_cogl_texture_foreach_sub_texture_in_region (CoglTexture *texture,
- float virtual_tx_1,
- float virtual_ty_1,
- float virtual_tx_2,
- float virtual_ty_2,
- CoglTextureSliceCallback callback,
- void *user_data)
-{
- texture->vtable->foreach_sub_texture_in_region (texture,
- virtual_tx_1,
- virtual_ty_1,
- virtual_tx_2,
- virtual_ty_2,
- callback,
- user_data);
-}
-
/* If this returns FALSE, that implies _foreach_sub_texture_in_region
* will be needed to iterate over multiple sub textures for regions whos
* texture coordinates extend out of the range [0,1]
@@ -1353,10 +1231,12 @@ cogl_texture_get_data (CoglTexture *texture,
* the data for a sliced texture, and allows us to do the
* read-from-framebuffer logic here in a simple fashion rather than
* passing offsets down through the code. */
- _cogl_texture_foreach_sub_texture_in_region (texture,
- 0, 0, 1, 1,
- texture_get_cb,
- &tg_data);
+ cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
+ 0, 0, 1, 1,
+ COGL_PIPELINE_WRAP_MODE_REPEAT,
+ COGL_PIPELINE_WRAP_MODE_REPEAT,
+ texture_get_cb,
+ &tg_data);
_cogl_bitmap_unmap (target_bmp);
diff --git a/cogl/cogl.h b/cogl/cogl.h
index 1276c08..946fb1a 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -82,6 +82,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
#include <cogl/cogl-texture-2d.h>
#include <cogl/cogl-texture-3d.h>
#include <cogl/cogl-texture-2d-sliced.h>
+#include <cogl/cogl-meta-texture.h>
#include <cogl/cogl-index-buffer.h>
#include <cogl/cogl-attribute-buffer.h>
#include <cogl/cogl-indices.h>
diff --git a/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/winsys/cogl-texture-pixmap-x11.c
index 44ac4cd..97753ec 100644
--- a/cogl/winsys/cogl-texture-pixmap-x11.c
+++ b/cogl/winsys/cogl-texture-pixmap-x11.c
@@ -739,6 +739,33 @@ _cogl_texture_pixmap_x11_get_data (CoglTexture *tex,
return cogl_texture_get_data (child_tex, format, rowstride, data);
}
+typedef struct _NormalizeCoordsWrapperData
+{
+ int width;
+ int height;
+ CoglMetaTextureCallback callback;
+ void *user_data;
+} NormalizeCoordsWrapperData;
+
+static void
+normalize_coords_wrapper_cb (CoglTexture *child_texture,
+ const float *child_texture_coords,
+ const float *meta_coords,
+ void *user_data)
+{
+ NormalizeCoordsWrapperData *data = user_data;
+ float normalized_coords[4];
+
+ normalized_coords[0] = meta_coords[0] / data->width;
+ normalized_coords[1] = meta_coords[1] / data->height;
+ normalized_coords[2] = meta_coords[2] / data->width;
+ normalized_coords[3] = meta_coords[3] / data->height;
+
+ data->callback (child_texture,
+ child_texture_coords, normalized_coords,
+ data->user_data);
+}
+
static void
_cogl_texture_pixmap_x11_foreach_sub_texture_in_region
(CoglTexture *tex,
@@ -746,22 +773,54 @@ _cogl_texture_pixmap_x11_foreach_sub_texture_in_region
float virtual_ty_1,
float virtual_tx_2,
float virtual_ty_2,
- CoglTextureSliceCallback callback,
+ CoglPipelineWrapMode wrap_x,
+ CoglPipelineWrapMode wrap_y,
+ CoglMetaTextureCallback callback,
void *user_data)
{
CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
- CoglHandle child_tex;
-
- child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
+ CoglHandle child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
/* Forward on to the child texture */
- _cogl_texture_foreach_sub_texture_in_region (child_tex,
- virtual_tx_1,
- virtual_ty_1,
- virtual_tx_2,
- virtual_ty_2,
- callback,
- user_data);
+
+ /* tfp textures may be implemented in terms of a
+ * CoglTextureRectangle texture which uses un-normalized texture
+ * coordinates but we want to consistently deal with normalized
+ * texture coordinates with CoglTexturePixmapX11... */
+ if (_cogl_is_texture_rectangle (child_tex))
+ {
+ NormalizeCoordsWrapperData data;
+ int width = tex_pixmap->width;
+ int height = tex_pixmap->height;
+
+ virtual_tx_1 *= width;
+ virtual_ty_1 *= height;
+ virtual_tx_2 *= width;
+ virtual_ty_2 *= height;
+
+ data.width = width;
+ data.height = height;
+ data.callback = callback;
+ data.user_data = user_data;
+
+ cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex),
+ virtual_tx_1,
+ virtual_ty_1,
+ virtual_tx_2,
+ virtual_ty_2,
+ wrap_x, wrap_y,
+ normalize_coords_wrapper_cb,
+ &data);
+ }
+ else
+ cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex),
+ virtual_tx_1,
+ virtual_ty_1,
+ virtual_tx_2,
+ virtual_ty_2,
+ wrap_x, wrap_y,
+ callback,
+ user_data);
}
static int
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]