diff --git a/clutter/clutter-cairo-texture.c b/clutter/clutter-cairo-texture.c index 82c614cb5..f3884c6bb 100644 --- a/clutter/clutter-cairo-texture.c +++ b/clutter/clutter-cairo-texture.c @@ -292,14 +292,13 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo) cairo, clutter_cairo_texture_surface_destroy); - /* The texture data will be all zeroes so we can use it to create a - * blank Cogl texture even though its in a different format + /* Create a blank Cogl texture */ clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (cairo), priv->cr_surface_data, TRUE, priv->width, priv->height, priv->rowstride, - 4, 0, NULL); + 4, CLUTTER_TEXTURE_RGB_FLAG_PREMULT, NULL); } static void @@ -451,9 +450,7 @@ clutter_cairo_texture_context_destroy (void *data) gint cairo_width, cairo_height, cairo_rowstride; gint surface_width, surface_height; - guchar *pixbuf_data, *dst, *cairo_data; - guint *src, pixbuf_rowstride; - gint x, y; + guchar *cairo_data; priv = CLUTTER_CAIRO_TEXTURE_GET_PRIVATE (cairo); @@ -473,56 +470,19 @@ clutter_cairo_texture_context_destroy (void *data) } cairo_rowstride = priv->rowstride; - cairo_data = priv->cr_surface_data; - pixbuf_data = g_malloc (cairo_width * cairo_height * 4); - pixbuf_rowstride = cairo_width * 4; - - /* BAH BAH BAH ! un-pre-multiply alpha... - * - * FIXME: Need to figure out if GL has a premult texture - * format, or we need to change the order of the - * paint sequence in Clutter. or go back to battling - * glitz (ugh). - * - * in theory, this could be moved to a shader, but apparently - * the performance gain is not really worth it. - */ - for (y = 0; y < cairo_height; y++) - { - src = (unsigned int *) (cairo_data - + ((y + ctxt->rect.y) * cairo_rowstride) - + (ctxt->rect.x * 4)); - dst = pixbuf_data + y * pixbuf_rowstride; - - for (x = 0; x < cairo_width; x++) - { - guchar alpha = (*src >> 24) & 0xff; - - if (alpha == 0) - dst[0] = dst[1] = dst[2] = dst[3] = alpha; - else - { - dst[0] = (((*src >> 16) & 0xff) * 255 ) / alpha; - dst[1] = (((*src >> 8) & 0xff) * 255 ) / alpha; - dst[2] = (((*src >> 0) & 0xff) * 255 ) / alpha; - dst[3] = alpha; - } - - dst += 4; - src++; - } - } + cairo_data = (priv->cr_surface_data + + ctxt->rect.y * cairo_rowstride + + ctxt->rect.x * 4); clutter_texture_set_area_from_rgb_data (CLUTTER_TEXTURE (cairo), - pixbuf_data, + cairo_data, TRUE, ctxt->rect.x, ctxt->rect.y, cairo_width, cairo_height, - pixbuf_rowstride, - 4, 0, NULL); + cairo_rowstride, + 4, CLUTTER_TEXTURE_RGB_FLAG_PREMULT, NULL); - g_free (pixbuf_data); g_free (ctxt); if (CLUTTER_ACTOR_IS_VISIBLE (cairo)) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index eaf9c4902..f457cd2af 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -1788,6 +1788,16 @@ clutter_stage_set_use_fog (ClutterStage *stage, * } * ]| * + * Note: The fogging functions only work correctly when the visible actors use + * unmultiplied alpha colors. By default Cogl will premultiply textures + * and cogl_set_source_color will premultiply colors, so unless you + * explicitly load your textures requesting an unmultiplied + * internal_format and use cogl_material_set_color you can only use + * fogging with fully opaque actors. + * + * We can look to improve this in the future when we can depend on + * fragment shaders. + * * Since: 0.6 */ void diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index c619cbabb..c5a2d7b81 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -296,7 +296,7 @@ clutter_texture_realize (ClutterActor *actor) tex = cogl_texture_new_with_size (priv->width, priv->height, flags, - COGL_PIXEL_FORMAT_RGBA_8888); + COGL_PIXEL_FORMAT_RGBA_8888_PRE); cogl_material_set_layer (priv->material, 0, tex); @@ -608,7 +608,8 @@ clutter_texture_paint (ClutterActor *self) clutter_actor_get_name (self) ? clutter_actor_get_name (self) : "unknown"); - cogl_material_set_color4ub (priv->material, 0xff, 0xff, 0xff, paint_opacity); + cogl_material_set_color4ub (priv->material, + paint_opacity, paint_opacity, paint_opacity, paint_opacity); clutter_actor_get_allocation_box (self, &box); @@ -1224,7 +1225,7 @@ clutter_texture_save_to_local_data (ClutterTexture *texture) if (cogl_texture_get_data (cogl_texture, priv->local_data_has_alpha - ? COGL_PIXEL_FORMAT_RGBA_8888 + ? COGL_PIXEL_FORMAT_RGBA_8888_PRE : COGL_PIXEL_FORMAT_RGB_888, priv->local_data_rowstride, priv->local_data) == 0) @@ -1251,7 +1252,7 @@ clutter_texture_load_from_local_data (ClutterTexture *texture) priv->local_data_height, priv->local_data_rowstride, priv->local_data_has_alpha ? 4: 3, - 0, NULL); + CLUTTER_TEXTURE_RGB_FLAG_PREMULT, NULL); g_free (priv->local_data); priv->local_data = NULL; @@ -2243,7 +2244,7 @@ on_fbo_source_size_change (GObject *object, tex = cogl_texture_new_with_size (MAX (priv->width, 1), MAX (priv->height, 1), flags, - COGL_PIXEL_FORMAT_RGBA_8888); + COGL_PIXEL_FORMAT_RGBA_8888_PRE); cogl_material_set_layer (priv->material, 0, tex); diff --git a/clutter/cogl/cogl-color.h b/clutter/cogl/cogl-color.h index 0cbc479a4..73de891de 100644 --- a/clutter/cogl/cogl-color.h +++ b/clutter/cogl/cogl-color.h @@ -228,6 +228,18 @@ float cogl_color_get_blue (const CoglColor *color); */ float cogl_color_get_alpha (const CoglColor *color); +/** + * cogl_color_premultiply: + * @color: the color to premultiply + * + * Converts a non-premultiplied color to a pre-multiplied color. For + * example, semi-transparent red is (1.0, 0, 0, 0.5) when non-premultiplied + * and (0.5, 0, 0, 0.5) when premultiplied. + * + * Since: 1.0 + */ +void cogl_color_premultiply (CoglColor *color); + G_END_DECLS #endif /* __COGL_COLOR_H__ */ diff --git a/clutter/cogl/cogl-material.h b/clutter/cogl/cogl-material.h index 497d7f852..786ff344a 100644 --- a/clutter/cogl/cogl-material.h +++ b/clutter/cogl/cogl-material.h @@ -138,6 +138,11 @@ gboolean cogl_is_material (CoglHandle handle); * * This is the basic color of the material, used when no lighting is enabled. * + * Note that if you don't add any layers to the material then the color + * will be blended unmodified with the destination; the default blend + * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for + * semi-transparent red. See cogl_color_premultiply(). + * * The default value is (1.0, 1.0, 1.0, 1.0) * * Since 1.0 @@ -475,6 +480,11 @@ void cogl_material_set_alpha_test_function (CoglHandle material, * * * + * The default blend string is: + * "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" + * That gives normal alpha-blending when the calculated color for the material + * is in premultiplied form. + * * Returns: TRUE if the blend string was successfully parsed, and the described * blending is supported by the underlying driver/hardware. If there * was an error, it returns FALSE. diff --git a/clutter/cogl/cogl-texture.h b/clutter/cogl/cogl-texture.h index 15cadc879..e3a2264a1 100644 --- a/clutter/cogl/cogl-texture.h +++ b/clutter/cogl/cogl-texture.h @@ -68,7 +68,13 @@ CoglHandle cogl_texture_new_with_size (guint width, * @filename: the file to load * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture + * texture. If COGL_PIXEL_FORMAT_ANY is given then a premultiplied + * format similar to the format of the source data will be used. The + * default blending equations of Cogl expect premultiplied color data; + * the main use of passing a non-premultiplied format here is if you + * have non-premultiplied source data and are going to adjust the blend + * mode (see cogl_material_set_blend()) or use the data for something + * other than straight blending. * @error: return location for a #GError or %NULL * * Creates a COGL texture from an image file. @@ -90,7 +96,13 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename, * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE * @format: the #CoglPixelFormat the buffer is stored in in RAM * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU + * the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a + * premultiplied format similar to the format of the source data will + * be used. The default blending equations of Cogl expect premultiplied + * color data; the main use of passing a non-premultiplied format here + * is if you have non-premultiplied source data and are going to adjust + * the blend mode (see cogl_material_set_blend()) or use the data for + * something other than straight blending. * @rowstride: the memory offset in bytes between the starts of * scanlines in @data * @data: pointer the memory region where the source buffer resides diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in index 9425a1267..c1cc10f29 100644 --- a/clutter/cogl/cogl.h.in +++ b/clutter/cogl/cogl.h.in @@ -386,13 +386,22 @@ gboolean cogl_get_backface_culling_enabled (void); * @z_near: Position along z-axis where no fogging should be applied * @z_far: Position along z-axes where full fogging should be applied * - * Enables fogging. Fogging causes vertices that are further away from - * the eye to be rendered with a different color. The color is determined - * according to the chosen fog mode; at it's simplest the color is - * linearly interpolated so that vertices at @z_near are drawn fully - * with their original color and vertices at @z_far are drawn fully - * with @fog_color. Fogging will remain enabled until you call - * cogl_disable_fog(). + * Enables fogging. Fogging causes vertices that are further away from the eye + * to be rendered with a different color. The color is determined according to + * the chosen fog mode; at it's simplest the color is linearly interpolated so + * that vertices at @z_near are drawn fully with their original color and + * vertices at @z_far are drawn fully with @fog_color. Fogging will remain + * enabled until you call cogl_disable_fog(). + * + * Note: The fogging functions only work correctly when primitives use + * unmultiplied alpha colors. By default Cogl will premultiply textures + * and cogl_set_source_color will premultiply colors, so unless you + * explicitly load your textures requesting an unmultiplied + * internal_format and use cogl_material_set_color you can only use + * fogging with fully opaque primitives. + * + * We can look to improve this in the future when we can depend on + * fragment shaders. */ void cogl_set_fog (const CoglColor *fog_color, CoglFogMode mode, @@ -455,8 +464,13 @@ void cogl_set_source (CoglHandle material); * cogl_set_source_color: * @color: a #CoglColor * - * Sets the source color using normalized values for each component. - * This color will be used for any subsequent drawing operation. + * This is a convenience function for creating a solid fill source material + * from the given color. This color will be used for any subsequent drawing + * operation. + * + * The color will be premultiplied by Cogl, so the color should be + * non-premultiplied. For example: use (1.0, 0.0, 0.0, 0.5) for + * semi-transparent red. * * See also cogl_set_source_color4ub() and cogl_set_source_color4f() * if you already have the color components. diff --git a/clutter/cogl/common/cogl-bitmap-fallback.c b/clutter/cogl/common/cogl-bitmap-fallback.c index e118459e1..ddff6ea40 100644 --- a/clutter/cogl/common/cogl-bitmap-fallback.c +++ b/clutter/cogl/common/cogl-bitmap-fallback.c @@ -163,9 +163,9 @@ _cogl_unpremult_alpha_last (const guchar *src, guchar *dst) { guchar alpha = src[3]; - dst[0] = ((((gulong) src[0] >> 16) & 0xff) * 255 ) / alpha; - dst[1] = ((((gulong) src[1] >> 8) & 0xff) * 255 ) / alpha; - dst[2] = ((((gulong) src[2] >> 0) & 0xff) * 255 ) / alpha; + dst[0] = (src[0] * 255) / alpha; + dst[1] = (src[1] * 255) / alpha; + dst[2] = (src[2] * 255) / alpha; dst[3] = alpha; } @@ -175,11 +175,46 @@ _cogl_unpremult_alpha_first (const guchar *src, guchar *dst) guchar alpha = src[0]; dst[0] = alpha; - dst[1] = ((((gulong) src[1] >> 16) & 0xff) * 255 ) / alpha; - dst[2] = ((((gulong) src[2] >> 8) & 0xff) * 255 ) / alpha; - dst[3] = ((((gulong) src[3] >> 0) & 0xff) * 255 ) / alpha; + dst[1] = (src[1] * 255) / alpha; + dst[2] = (src[2] * 255) / alpha; + dst[3] = (src[3] * 255) / alpha; } +/* No division form of floor((c*a + 128)/255) (I first encountered + * this in the RENDER implementation in the X server.) Being exact + * is important for a == 255 - we want to get exactly c. + */ +#define MULT(d,c,a,t) G_STMT_START { t = c * a + 128; d = ((t >> 8) + t) >> 8; } G_STMT_END + +inline static void +_cogl_premult_alpha_last (const guchar *src, guchar *dst) +{ + guchar alpha = src[3]; + /* Using a separate temporary per component has given slightly better + * code generation with GCC in the past; it shouldn't do any worse in + * any case. + */ + guint t1, t2, t3; + MULT(dst[0], src[0], alpha, t1); + MULT(dst[1], src[1], alpha, t2); + MULT(dst[2], src[2], alpha, t3); + dst[3] = alpha; +} + +inline static void +_cogl_premult_alpha_first (const guchar *src, guchar *dst) +{ + guchar alpha = src[0]; + guint t1, t2, t3; + + dst[0] = alpha; + MULT(dst[1], src[1], alpha, t1); + MULT(dst[2], src[2], alpha, t2); + MULT(dst[3], src[3], alpha, t3); +} + +#undef MULT + gboolean _cogl_bitmap_fallback_can_convert (CoglPixelFormat src, CoglPixelFormat dst) { @@ -211,6 +246,12 @@ _cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format) return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32); } +gboolean +_cogl_bitmap_fallback_can_premult (CoglPixelFormat format) +{ + return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32); +} + gboolean _cogl_bitmap_fallback_convert (const CoglBitmap *bmp, CoglBitmap *dst_bmp, @@ -324,34 +365,86 @@ _cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp, * dst_bmp->height * dst_bmp->rowstride); - /* FIXME: Optimize */ for (y = 0; y < bmp->height; y++) { src = (guchar*)bmp->data + y * bmp->rowstride; dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride; - for (x = 0; x < bmp->width; x++) - { - /* FIXME: Would be nice to at least remove this inner - * branching, but not sure it can be done without - * rewriting of the whole loop */ - if (bmp->format & COGL_AFIRST_BIT) - { - if (src[0] == 0) - _cogl_unpremult_alpha_0 (src, dst); - else - _cogl_unpremult_alpha_first (src, dst); - } - else - { - if (src[3] == 0) - _cogl_unpremult_alpha_0 (src, dst); - else - _cogl_unpremult_alpha_last (src, dst); - } + if (bmp->format & COGL_AFIRST_BIT) + { + for (x = 0; x < bmp->width; x++) + { + if (src[0] == 0) + _cogl_unpremult_alpha_0 (src, dst); + else + _cogl_unpremult_alpha_first (src, dst); + src += bpp; + dst += bpp; + } + } + else + { + for (x = 0; x < bmp->width; x++) + { + if (src[0] == 0) + _cogl_unpremult_alpha_0 (src, dst); + else + _cogl_unpremult_alpha_last (src, dst); + src += bpp; + dst += bpp; + } + } + } - src += bpp; - dst += bpp; + return TRUE; +} + +gboolean +_cogl_bitmap_fallback_premult (const CoglBitmap *bmp, + CoglBitmap *dst_bmp) +{ + guchar *src; + guchar *dst; + gint bpp; + gint x,y; + + /* Make sure format supported for un-premultiplication */ + if (!_cogl_bitmap_fallback_can_premult (bmp->format)) + return FALSE; + + bpp = _cogl_get_format_bpp (bmp->format); + + /* Initialize destination bitmap */ + *dst_bmp = *bmp; + dst_bmp->format |= COGL_PREMULT_BIT; + + /* Allocate a new buffer to hold converted data */ + dst_bmp->data = g_malloc (sizeof(guchar) + * dst_bmp->height + * dst_bmp->rowstride); + + for (y = 0; y < bmp->height; y++) + { + src = (guchar*)bmp->data + y * bmp->rowstride; + dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride; + + if (bmp->format & COGL_AFIRST_BIT) + { + for (x = 0; x < bmp->width; x++) + { + _cogl_premult_alpha_first (src, dst); + src += bpp; + dst += bpp; + } + } + else + { + for (x = 0; x < bmp->width; x++) + { + _cogl_premult_alpha_last (src, dst); + src += bpp; + dst += bpp; + } } } diff --git a/clutter/cogl/common/cogl-bitmap-pixbuf.c b/clutter/cogl/common/cogl-bitmap-pixbuf.c index f1e500534..1b75cd0ba 100644 --- a/clutter/cogl/common/cogl-bitmap-pixbuf.c +++ b/clutter/cogl/common/cogl-bitmap-pixbuf.c @@ -49,6 +49,12 @@ _cogl_bitmap_can_unpremult (CoglPixelFormat format) return FALSE; } +gboolean +_cogl_bitmap_can_premult (CoglPixelFormat format) +{ + return FALSE; +} + gboolean _cogl_bitmap_convert (const CoglBitmap *bmp, CoglBitmap *dst_bmp, @@ -64,6 +70,13 @@ _cogl_bitmap_unpremult (const CoglBitmap *bmp, return FALSE; } +gboolean +_cogl_bitmap_premult (const CoglBitmap *bmp, + CoglBitmap *dst_bmp) +{ + return FALSE; +} + #ifdef USE_QUARTZ /* lacking GdkPixbuf and other useful GError domains, define one of our own */ diff --git a/clutter/cogl/common/cogl-bitmap-private.h b/clutter/cogl/common/cogl-bitmap-private.h index f54961bd0..b6e425733 100644 --- a/clutter/cogl/common/cogl-bitmap-private.h +++ b/clutter/cogl/common/cogl-bitmap-private.h @@ -52,6 +52,12 @@ _cogl_bitmap_can_unpremult (CoglPixelFormat format); gboolean _cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format); +gboolean +_cogl_bitmap_can_premult (CoglPixelFormat format); + +gboolean +_cogl_bitmap_fallback_can_premult (CoglPixelFormat format); + gboolean _cogl_bitmap_convert (const CoglBitmap *bmp, CoglBitmap *dst_bmp, @@ -69,6 +75,14 @@ gboolean _cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp, CoglBitmap *dst_bmp); +gboolean +_cogl_bitmap_premult (const CoglBitmap *bmp, + CoglBitmap *dst_bmp); + +gboolean +_cogl_bitmap_fallback_premult (const CoglBitmap *bmp, + CoglBitmap *dst_bmp); + gboolean _cogl_bitmap_from_file (CoglBitmap *bmp, const gchar *filename, diff --git a/clutter/cogl/common/cogl-bitmap.c b/clutter/cogl/common/cogl-bitmap.c index f4c322abb..3dc7fd534 100644 --- a/clutter/cogl/common/cogl-bitmap.c +++ b/clutter/cogl/common/cogl-bitmap.c @@ -87,8 +87,8 @@ _cogl_bitmap_convert_and_premult (const CoglBitmap *bmp, } /* Do we need to unpremultiply */ - if ((bmp->format & COGL_PREMULT_BIT) == 0 && - (dst_format & COGL_PREMULT_BIT) > 0) + if ((bmp->format & COGL_PREMULT_BIT) > 0 && + (dst_format & COGL_PREMULT_BIT) == 0) { /* Try unpremultiplying using imaging library */ if (!_cogl_bitmap_unpremult (&new_bmp, &tmp_bmp)) @@ -112,14 +112,28 @@ _cogl_bitmap_convert_and_premult (const CoglBitmap *bmp, } /* Do we need to premultiply */ - if ((bmp->format & COGL_PREMULT_BIT) > 0 && - (dst_format & COGL_PREMULT_BIT) == 0) + if ((bmp->format & COGL_PREMULT_BIT) == 0 && + (dst_format & COGL_PREMULT_BIT) > 0) { - /* FIXME: implement premultiplication */ + /* Try premultiplying using imaging library */ + if (!_cogl_bitmap_premult (&new_bmp, &tmp_bmp)) + { + /* ... or try fallback */ + if (!_cogl_bitmap_fallback_premult (&new_bmp, &tmp_bmp)) + { + if (new_bmp_owner) + g_free (new_bmp.data); + + return FALSE; + } + } + + /* Update bitmap with new data */ if (new_bmp_owner) g_free (new_bmp.data); - return FALSE; + new_bmp = tmp_bmp; + new_bmp_owner = TRUE; } /* Output new bitmap info */ diff --git a/clutter/cogl/common/cogl-color.c b/clutter/cogl/common/cogl-color.c index 306005f2f..df338fcc4 100644 --- a/clutter/cogl/common/cogl-color.c +++ b/clutter/cogl/common/cogl-color.c @@ -153,6 +153,14 @@ cogl_color_get_alpha (const CoglColor *color) return ((float) color->alpha / 255.0); } +void +cogl_color_premultiply (CoglColor *color) +{ + color->red = (color->red * color->alpha + 128) / 255; + color->green = (color->green * color->alpha + 128) / 255; + color->blue = (color->blue * color->alpha + 128) / 255; +} + void cogl_set_source_color4ub (guint8 red, guint8 green, diff --git a/clutter/cogl/common/cogl-material.c b/clutter/cogl/common/cogl-material.c index 831fa30f1..7e3935bff 100644 --- a/clutter/cogl/common/cogl-material.c +++ b/clutter/cogl/common/cogl-material.c @@ -109,7 +109,7 @@ cogl_material_new (void) material->blend_constant[2] = 0; material->blend_constant[3] = 0; #endif - material->blend_src_factor_rgb = GL_SRC_ALPHA; + material->blend_src_factor_rgb = GL_ONE; material->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA; material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC; diff --git a/clutter/cogl/common/cogl.c b/clutter/cogl/common/cogl.c index 336303917..5857db2d3 100644 --- a/clutter/cogl/common/cogl.c +++ b/clutter/cogl/common/cogl.c @@ -250,12 +250,17 @@ cogl_get_backface_culling_enabled (void) void cogl_set_source_color (const CoglColor *color) { + CoglColor premultiplied; + _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* In case cogl_set_source_texture was previously used... */ cogl_material_remove_layer (ctx->default_material, 0); - cogl_material_set_color (ctx->default_material, color); + premultiplied = *color; + cogl_color_premultiply (&premultiplied); + cogl_material_set_color (ctx->default_material, &premultiplied); + cogl_set_source (ctx->default_material); } diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c index 3af78f9a0..877107d3c 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -1085,18 +1085,12 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, GLenum glformat = 0; GLenum gltype = 0; - /* No premultiplied formats accepted by GL - * (FIXME: latest hardware?) */ + /* FIXME: check YUV support */ - if (format & COGL_PREMULT_BIT) - format = (format & COGL_UNPREMULT_MASK); - - /* Everything else accepted - * (FIXME: check YUV support) */ required_format = format; /* Find GL equivalents */ - switch (format) + switch (format & COGL_UNPREMULT_MASK) { case COGL_PIXEL_FORMAT_A_8: glintformat = GL_ALPHA; @@ -1195,9 +1189,15 @@ _cogl_texture_bitmap_prepare (CoglTexture *tex, CoglPixelFormat new_data_format; gboolean success; - /* Was there any internal conversion requested? */ + /* Was there any internal conversion requested? + * By default Cogl will use a premultiplied internal format. Later we will + * add control over this. */ if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = tex->bitmap.format; + { + if ((tex->bitmap.format & COGL_A_BIT) && + tex->bitmap.format != COGL_PIXEL_FORMAT_A_8) + internal_format = tex->bitmap.format | COGL_PREMULT_BIT; + } /* Find closest format accepted by GL */ new_data_format = _cogl_pixel_format_to_gl (internal_format, diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c index ae3e437b8..ab1653e07 100644 --- a/clutter/cogl/gles/cogl-texture.c +++ b/clutter/cogl/gles/cogl-texture.c @@ -1184,18 +1184,12 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, GLenum glformat = 0; GLenum gltype = 0; - /* No premultiplied formats accepted by GL - * (FIXME: latest hardware?) */ + /* FIXME: check YUV support */ - if (format & COGL_PREMULT_BIT) - format = (format & COGL_UNPREMULT_MASK); - - /* Everything else accepted - * (FIXME: check YUV support) */ required_format = format; /* Find GL equivalents */ - switch (format) + switch (format & COGL_UNPREMULT_MASK) { case COGL_PIXEL_FORMAT_A_8: glintformat = GL_ALPHA; @@ -1226,6 +1220,7 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, glformat = GL_RGBA; gltype = GL_UNSIGNED_BYTE; required_format = COGL_PIXEL_FORMAT_RGBA_8888; + required_format |= (format & COGL_PREMULT_BIT); break; /* The following three types of channel ordering @@ -1270,9 +1265,15 @@ _cogl_texture_bitmap_prepare (CoglTexture *tex, CoglPixelFormat new_data_format; gboolean success; - /* Was there any internal conversion requested? */ + /* Was there any internal conversion requested? + * By default Cogl will use a premultiplied internal format. Later we will + * add control over this. */ if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = tex->bitmap.format; + { + if ((tex->bitmap.format & COGL_A_BIT) && + tex->bitmap.format != COGL_PIXEL_FORMAT_A_8) + internal_format = tex->bitmap.format | COGL_PREMULT_BIT; + } /* Find closest format accepted by GL */ new_data_format = _cogl_pixel_format_to_gl (internal_format, diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index fb174fd6b..aab75f658 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -359,14 +359,16 @@ create_cogl_texture (ClutterTexture *texture, handle = cogl_texture_new_from_foreign (tex, CGL_TEXTURE_RECTANGLE_ARB, width, height, 0, 0, - cogl_format | COGL_BGR_BIT); + cogl_format | COGL_BGR_BIT | + COGL_PREMULT_BIT); } else { handle = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NO_SLICING, - cogl_format | COGL_BGR_BIT); + cogl_format | COGL_BGR_BIT | + COGL_PREMULT_BIT); using_rectangle = FALSE; } diff --git a/clutter/pango/cogl-pango-display-list.c b/clutter/pango/cogl-pango-display-list.c index 1e16a76f3..6a3b29c60 100644 --- a/clutter/pango/cogl-pango-display-list.c +++ b/clutter/pango/cogl-pango-display-list.c @@ -239,8 +239,10 @@ _cogl_pango_display_list_render_texture (CoglHandle material, const CoglColor *color, CoglPangoDisplayListNode *node) { + CoglColor premult_color = *color; cogl_material_set_layer (material, 0, node->d.texture.texture); - cogl_material_set_color (material, color); + cogl_color_premultiply (&premult_color); + cogl_material_set_color (material, &premult_color); cogl_set_source (material); if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE) @@ -311,6 +313,7 @@ _cogl_pango_display_list_render (CoglPangoDisplayList *dl, cogl_color_get_alpha_byte (color)); else draw_color = *color; + cogl_color_premultiply (&draw_color); switch (node->type) { diff --git a/clutter/pango/cogl-pango-render.c b/clutter/pango/cogl-pango-render.c index ffa224e65..c98ddca1f 100644 --- a/clutter/pango/cogl-pango-render.c +++ b/clutter/pango/cogl-pango-render.c @@ -124,16 +124,20 @@ cogl_pango_renderer_init (CoglPangoRenderer *priv) /* The default combine mode of materials is to modulate (A x B) the texture * RGBA channels with the RGBA channels of the previous layer (which in our - * case is just the solid font color) + * case is just the font color) * - * Since our glyph cache textures are component alpha textures, and so the - * RGB channels are defined as (0, 0, 0) we don't want to modulate the RGB - * channels, instead we want to simply replace them with our solid font - * color... + * Since the RGB for an alpha texture is defined as 0, this gives us: + * + * result.rgb = color.rgb * 0 + * result.a = color.a * texture.a + * + * What we want is premultiplied rgba values: + * + * result.rgba = color.rgb * texture.a + * result.a = color.a * texture.a */ cogl_material_set_layer_combine (priv->glyph_material, 0, /* layer */ - "RGB = REPLACE (PREVIOUS)" - "A = MODULATE (PREVIOUS, TEXTURE)", + "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", NULL); priv->solid_material = cogl_material_new (); diff --git a/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/x11/clutter-x11-texture-pixmap.c index cb0c38529..a09ab1f9d 100644 --- a/clutter/x11/clutter-x11-texture-pixmap.c +++ b/clutter/x11/clutter-x11-texture-pixmap.c @@ -871,7 +871,8 @@ clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, width, height, bytes_per_line, 4, - CLUTTER_TEXTURE_RGB_FLAG_BGR, + CLUTTER_TEXTURE_RGB_FLAG_BGR | + CLUTTER_TEXTURE_RGB_FLAG_PREMULT, &error); else clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (texture), @@ -880,7 +881,8 @@ clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, width, height, bytes_per_line, 4, - CLUTTER_TEXTURE_RGB_FLAG_BGR, + CLUTTER_TEXTURE_RGB_FLAG_BGR | + CLUTTER_TEXTURE_RGB_FLAG_PREMULT, &error); diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index ecbcb1f8f..e44680238 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -29,6 +29,7 @@ test_conformance_SOURCES = \ test-blend-strings.c \ test-color.c \ test-clutter-units.c \ + test-premult.c \ $(NULL) # For convenience, this provides a way to easily run individual unit tests: diff --git a/tests/conform/test-blend-strings.c b/tests/conform/test-blend-strings.c index 12ada130f..14b7fbcc0 100644 --- a/tests/conform/test-blend-strings.c +++ b/tests/conform/test-blend-strings.c @@ -172,11 +172,13 @@ make_texture (guint32 color) *(--p) = r; } + /* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here + * since we don't want to allow Cogl to premultiply our data. */ tex = cogl_texture_new_from_data (QUAD_WIDTH, QUAD_WIDTH, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_RGBA_8888, - COGL_PIXEL_FORMAT_ANY, + COGL_PIXEL_FORMAT_RGBA_8888, QUAD_WIDTH * 4, tex_data); diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 05e5e7b4c..faa46a6e2 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -136,6 +136,7 @@ main (int argc, char **argv) TEST_CONFORM_SIMPLE ("/texture", test_backface_culling); TEST_CONFORM_SIMPLE ("/texture", test_npot_texture); + TEST_CONFORM_SIMPLE ("/texture", test_premult); TEST_CONFORM_SIMPLE ("/path", test_path); diff --git a/tests/conform/test-premult.c b/tests/conform/test-premult.c new file mode 100644 index 000000000..93b28784a --- /dev/null +++ b/tests/conform/test-premult.c @@ -0,0 +1,388 @@ + +#include +#include +#include + +#include "test-conform-common.h" + +static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; + +#define QUAD_WIDTH 20 + +#define RED 0 +#define GREEN 1 +#define BLUE 2 +#define ALPHA 3 + +#define MASK_RED(COLOR) ((COLOR & 0xff000000) >> 24); +#define MASK_GREEN(COLOR) ((COLOR & 0xff0000) >> 16); +#define MASK_BLUE(COLOR) ((COLOR & 0xff00) >> 8); +#define MASK_ALPHA(COLOR) (COLOR & 0xff); + +#define SKIP_FRAMES 2 + +typedef struct _TestState +{ + guint frame; + ClutterGeometry stage_geom; + CoglHandle passthrough_material; +} TestState; + + +static void +check_pixel (GLubyte *pixel, guint32 color) +{ + guint8 r = MASK_RED (color); + guint8 g = MASK_GREEN (color); + guint8 b = MASK_BLUE (color); + guint8 a = MASK_ALPHA (color); + + if (g_test_verbose ()) + g_print (" expected = %x, %x, %x, %x\n", + r, g, b, a); + /* FIXME - allow for hardware in-precision */ + g_assert (pixel[RED] == r); + g_assert (pixel[GREEN] == g); + g_assert (pixel[BLUE] == b); + + /* FIXME + * We ignore the alpha, since we don't know if our render target is + * RGB or RGBA */ + /* g_assert (pixel[ALPHA] == a); */ +} + +static guchar * +gen_tex_data (guint32 color) +{ + guchar *tex_data, *p; + guint8 r = MASK_RED (color); + guint8 g = MASK_GREEN (color); + guint8 b = MASK_BLUE (color); + guint8 a = MASK_ALPHA (color); + + tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 4); + + for (p = tex_data + QUAD_WIDTH * QUAD_WIDTH * 4; p > tex_data;) + { + *(--p) = a; + *(--p) = b; + *(--p) = g; + *(--p) = r; + } + + return tex_data; +} + +static CoglHandle +make_texture (guint32 color, + CoglPixelFormat src_format, + CoglPixelFormat internal_format) +{ + CoglHandle tex; + guchar *tex_data = gen_tex_data (color); + + tex = cogl_texture_new_from_data (QUAD_WIDTH, + QUAD_WIDTH, + COGL_TEXTURE_NONE, + src_format, + internal_format, + QUAD_WIDTH * 4, + tex_data); + + g_free (tex_data); + + return tex; +} + +static void +check_texture (TestState *state, + int x, + int y, + CoglHandle tex, + guint32 expected_result) +{ + GLubyte pixel[4]; + GLint y_off; + GLint x_off; + + cogl_material_set_layer (state->passthrough_material, 0, tex); + + cogl_set_source (state->passthrough_material); + cogl_rectangle (x * QUAD_WIDTH, + y * QUAD_WIDTH, + x * QUAD_WIDTH + QUAD_WIDTH, + y * QUAD_WIDTH + QUAD_WIDTH); + + /* See what we got... */ + + /* NB: glReadPixels is done in GL screen space so y = 0 is at the bottom */ + y_off = state->stage_geom.height - y * QUAD_WIDTH - (QUAD_WIDTH / 2); + x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2); + + /* XXX: + * We haven't always had good luck with GL drivers implementing glReadPixels + * reliably and skipping the first two frames improves our chances... */ + if (state->frame <= SKIP_FRAMES) + return; + + glReadPixels (x_off, y_off, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); + if (g_test_verbose ()) + { + g_print ("check texture (%d, %d):\n", x, y); + g_print (" result = %02x, %02x, %02x, %02x\n", + pixel[RED], pixel[GREEN], pixel[BLUE], pixel[ALPHA]); + } + + check_pixel (pixel, expected_result); +} + +static void +on_paint (ClutterActor *actor, TestState *state) +{ + int frame_num; + CoglHandle tex; + guchar *tex_data; + + /* If the user explicitly specifies an unmultiplied internal format then + * Cogl shouldn't automatically premultiply the given texture data... */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xff00ff80, " + "src = RGBA_8888, internal = RGBA_8888)\n"); + tex = make_texture (0xff00ff80, + COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */ + check_texture (state, 0, 0, /* position */ + tex, + 0xff00ff80); /* expected */ + + /* If the user explicitly requests a premultiplied internal format and + * gives unmultiplied src data then Cogl should always premultiply that + * for us */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xff00ff80, " + "src = RGBA_8888, internal = RGBA_8888_PRE)\n"); + tex = make_texture (0xff00ff80, + COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */ + check_texture (state, 1, 0, /* position */ + tex, + 0x80008080); /* expected */ + + /* If the user gives COGL_PIXEL_FORMAT_ANY for the internal format then + * by default Cogl should premultiply the given texture data... + * (In the future there will be additional Cogl API to control this + * behaviour) */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xff00ff80, " + "src = RGBA_8888, internal = ANY)\n"); + tex = make_texture (0xff00ff80, + COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ + COGL_PIXEL_FORMAT_ANY); /* internal format */ + check_texture (state, 2, 0, /* position */ + tex, + 0x80008080); /* expected */ + + /* If the user requests a premultiplied internal texture format and supplies + * premultiplied source data, Cogl should never modify that source data... + */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0x80008080, " + "src = RGBA_8888_PRE, " + "internal = RGBA_8888_PRE)\n"); + tex = make_texture (0x80008080, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */ + check_texture (state, 3, 0, /* position */ + tex, + 0x80008080); /* expected */ + + /* If the user requests an unmultiplied internal texture format, but + * supplies premultiplied source data, then Cogl should always + * un-premultiply the source data... */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0x80008080, " + "src = RGBA_8888_PRE, internal = RGBA_8888)\n"); + tex = make_texture (0x80008080, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */ + check_texture (state, 4, 0, /* position */ + tex, + 0xff00ff80); /* expected */ + + /* If the user allows any internal texture format and provides premultipled + * source data then by default Cogl shouldn't modify the source data... + * (In the future there will be additional Cogl API to control this + * behaviour) */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0x80008080, " + "src = RGBA_8888_PRE, internal = ANY)\n"); + tex = make_texture (0x80008080, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ + COGL_PIXEL_FORMAT_ANY); /* internal format */ + check_texture (state, 5, 0, /* position */ + tex, + 0x80008080); /* expected */ + + /* + * Test cogl_texture_set_region() .... + */ + + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xDEADBEEF, " + "src = RGBA_8888, internal = RGBA_8888)\n"); + tex = make_texture (0xDEADBEEF, + COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("set_region (0xff00ff80, RGBA_8888)\n"); + tex_data = gen_tex_data (0xff00ff80); + cogl_texture_set_region (tex, + 0, 0, /* src x, y */ + 0, 0, /* dst x, y */ + QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */ + QUAD_WIDTH, QUAD_WIDTH, /* src width, height */ + COGL_PIXEL_FORMAT_RGBA_8888, + 0, /* auto compute row stride */ + tex_data); + check_texture (state, 6, 0, /* position */ + tex, + 0xff00ff80); /* expected */ + + /* Updating a texture region for an unmultiplied texture using premultiplied + * region data should result in Cogl unmultiplying the given region data... + */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xDEADBEEF, " + "src = RGBA_8888, internal = RGBA_8888)\n"); + tex = make_texture (0xDEADBEEF, + COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("set_region (0x80008080, RGBA_8888_PRE)\n"); + tex_data = gen_tex_data (0x80008080); + cogl_texture_set_region (tex, + 0, 0, /* src x, y */ + 0, 0, /* dst x, y */ + QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */ + QUAD_WIDTH, QUAD_WIDTH, /* src width, height */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + 0, /* auto compute row stride */ + tex_data); + check_texture (state, 7, 0, /* position */ + tex, + 0xff00ff80); /* expected */ + + + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xDEADBEEF, " + "src = RGBA_8888_PRE, " + "internal = RGBA_8888_PRE)\n"); + tex = make_texture (0xDEADBEEF, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("set_region (0x80008080, RGBA_8888_PRE)\n"); + tex_data = gen_tex_data (0x80008080); + cogl_texture_set_region (tex, + 0, 0, /* src x, y */ + 0, 0, /* dst x, y */ + QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */ + QUAD_WIDTH, QUAD_WIDTH, /* src width, height */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + 0, /* auto compute row stride */ + tex_data); + check_texture (state, 8, 0, /* position */ + tex, + 0x80008080); /* expected */ + + + /* Updating a texture region for a premultiplied texture using unmultiplied + * region data should result in Cogl premultiplying the given region data... + */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("make_texture (0xDEADBEEF, " + "src = RGBA_8888_PRE, " + "internal = RGBA_8888_PRE)\n"); + tex = make_texture (0xDEADBEEF, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ + COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */ + if (state->frame > SKIP_FRAMES && g_test_verbose ()) + g_print ("set_region (0xff00ff80, RGBA_8888)\n"); + tex_data = gen_tex_data (0xff00ff80); + cogl_texture_set_region (tex, + 0, 0, /* src x, y */ + 0, 0, /* dst x, y */ + QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */ + QUAD_WIDTH, QUAD_WIDTH, /* src width, height */ + COGL_PIXEL_FORMAT_RGBA_8888, + 0, /* auto compute row stride */ + tex_data); + check_texture (state, 9, 0, /* position */ + tex, + 0x80008080); /* expected */ + + + /* XXX: Experiments have shown that for some buggy drivers, when using + * glReadPixels there is some kind of race, so we delay our test for a + * few frames and a few seconds: + */ + frame_num = state->frame++; + if (frame_num < SKIP_FRAMES) + g_usleep (G_USEC_PER_SEC); + + /* Comment this out if you want visual feedback for what this test paints */ +#if 1 + if (frame_num > SKIP_FRAMES) + clutter_main_quit (); +#endif +} + +static gboolean +queue_redraw (gpointer stage) +{ + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); + + return TRUE; +} + +void +test_premult (TestConformSimpleFixture *fixture, + gconstpointer data) +{ + TestState state; + ClutterActor *stage; + ClutterActor *group; + guint idle_source; + + state.frame = 0; + state.passthrough_material = cogl_material_new (); + cogl_material_set_blend (state.passthrough_material, + "RGBA = ADD (SRC_COLOR, 0)", NULL); + cogl_material_set_layer_combine (state.passthrough_material, 0, + "RGBA = REPLACE (TEXTURE)", NULL); + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + clutter_actor_get_geometry (stage, &state.stage_geom); + + group = clutter_group_new (); + clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); + + /* We force continuous redrawing of the stage, since we need to skip + * the first few frames, and we wont be doing anything else that + * will trigger redrawing. */ + idle_source = g_idle_add (queue_redraw, stage); + + g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); + + clutter_actor_show_all (stage); + + clutter_main (); + + g_source_remove (idle_source); + + if (g_test_verbose ()) + g_print ("OK\n"); +} + diff --git a/tests/interactive/test-cogl-offscreen.c b/tests/interactive/test-cogl-offscreen.c index 8b9d8e8f7..2aa5e79f6 100644 --- a/tests/interactive/test-cogl-offscreen.c +++ b/tests/interactive/test-cogl-offscreen.c @@ -106,7 +106,7 @@ test_coglbox_paint(ClutterActor *self) cogl_set_draw_buffer (COGL_WINDOW_BUFFER, 0); material = cogl_material_new (); - cogl_material_set_color4ub (material, 0xff, 0xff, 0xff, 0x88); + cogl_material_set_color4ub (material, 0x88, 0x88, 0x88, 0x88); cogl_material_set_layer (material, 0, priv->texture_id); cogl_set_source (material); cogl_rectangle_with_texture_coords (100, 100, diff --git a/tests/interactive/test-depth.c b/tests/interactive/test-depth.c index 7f5d1edd0..c06337c58 100644 --- a/tests/interactive/test-depth.c +++ b/tests/interactive/test-depth.c @@ -119,15 +119,12 @@ test_depth_main (int argc, char *argv[]) ClutterActor *group, *hand, *label, *rect, *janus, *box; ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff }; ClutterColor rect_color = { 0, 0, 0, 0x88 }; - ClutterFog stage_fog = { 10.0, -50.0 }; GError *error; clutter_init (&argc, &argv); stage = clutter_stage_get_default (); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - clutter_stage_set_fog (CLUTTER_STAGE (stage), &stage_fog); - clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "button-press-event", G_CALLBACK (clutter_main_quit),