[ClutterCairoTexture] Use the right component ordering when uploading data

Cairo stores the image data in ARGB native byte order so we need to
upload this as BGRA on little endian architectures and ARGB on big
endian. ClutterTexture doesn't currently expose any flags to describe
ARGB format so until we can fix the Clutter API it now uses the Cogl
API directly.
This commit is contained in:
Neil Roberts 2009-06-15 12:41:13 +01:00
parent c6b4ea8b44
commit f95f4ba3cb

View File

@ -109,6 +109,15 @@ enum
#define CLUTTER_CAIRO_TEXTURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTexturePrivate)) #define CLUTTER_CAIRO_TEXTURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTexturePrivate))
/* Cairo stores the data in native byte order as ARGB but Cogl's pixel
formats specify the actual byte order. Therefore we need to use a
different format depending on the architecture */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define CLUTTER_CAIRO_TEXTURE_PIXEL_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
#else
#define CLUTTER_CAIRO_TEXTURE_PIXEL_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
#endif
struct _ClutterCairoTexturePrivate struct _ClutterCairoTexturePrivate
{ {
cairo_format_t format; cairo_format_t format;
@ -229,6 +238,7 @@ static inline void
clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo) clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
{ {
ClutterCairoTexturePrivate *priv = cairo->priv; ClutterCairoTexturePrivate *priv = cairo->priv;
CoglHandle cogl_texture;
if (priv->cr_surface) if (priv->cr_surface)
{ {
@ -294,12 +304,14 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
/* Create a blank Cogl texture /* Create a blank Cogl texture
*/ */
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (cairo), cogl_texture = cogl_texture_new_from_data (priv->width, priv->height,
priv->cr_surface_data, COGL_TEXTURE_NONE,
TRUE, priv->width, priv->height, CLUTTER_CAIRO_TEXTURE_PIXEL_FORMAT,
priv->rowstride, COGL_PIXEL_FORMAT_ANY,
4, CLUTTER_TEXTURE_RGB_FLAG_PREMULT, priv->rowstride,
NULL); priv->cr_surface_data);
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (cairo), cogl_texture);
cogl_handle_unref (cogl_texture);
} }
static void static void
@ -451,6 +463,7 @@ clutter_cairo_texture_context_destroy (void *data)
guchar *cairo_data; guchar *cairo_data;
gint cairo_width, cairo_height; gint cairo_width, cairo_height;
gint surface_width, surface_height; gint surface_width, surface_height;
CoglHandle cogl_texture;
if (!priv->cr_surface) if (!priv->cr_surface)
return; return;
@ -461,7 +474,9 @@ clutter_cairo_texture_context_destroy (void *data)
cairo_width = MIN (ctxt->rect.width, surface_width); cairo_width = MIN (ctxt->rect.width, surface_width);
cairo_height = MIN (ctxt->rect.height, surface_height); cairo_height = MIN (ctxt->rect.height, surface_height);
if (!cairo_width || !cairo_height) cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (cairo));
if (!cairo_width || !cairo_height || cogl_texture == COGL_INVALID_HANDLE)
{ {
g_free (ctxt); g_free (ctxt);
@ -472,15 +487,14 @@ clutter_cairo_texture_context_destroy (void *data)
+ (ctxt->rect.y * priv->rowstride) + (ctxt->rect.y * priv->rowstride)
+ (ctxt->rect.x * 4)); + (ctxt->rect.x * 4));
clutter_texture_set_area_from_rgb_data (CLUTTER_TEXTURE (cairo), cogl_texture_set_region (cogl_texture,
cairo_data, 0, 0,
TRUE, ctxt->rect.x, ctxt->rect.y,
ctxt->rect.x, cairo_width, cairo_height,
ctxt->rect.y, cairo_width, cairo_height,
cairo_width, cairo_height, CLUTTER_CAIRO_TEXTURE_PIXEL_FORMAT,
priv->rowstride, priv->rowstride,
4, CLUTTER_TEXTURE_RGB_FLAG_PREMULT, cairo_data);
NULL);
g_free (ctxt); g_free (ctxt);