This looks good to me:<div><br></div><div>Reviewed-by: Robert Bragg <<a href="mailto:robert@linux.intel.com">robert@linux.intel.com</a>></div><div><br></div><div>thanks,</div><div>- Robert</div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Nov 19, 2012 at 5:28 PM, Neil Roberts <span dir="ltr"><<a href="mailto:neil@linux.intel.com" target="_blank">neil@linux.intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The core profile of GL3 has removed support for component-alpha<br>
textures. Previously the GL3 driver would just ignore this and try to<br>
create them anyway. This would generate a GL error on Mesa.<br>
<br>
To fix this the GL texture driver will now create a GL_RED texture<br>
when GL_ALPHA textures are not supported natively. It will then set a<br>
texture swizzle using the GL_ARB_texture_swizzle extension so that the<br>
alpha component will be taken from the red component of the texture.<br>
The swizzle is part of the texture object state so it only needs to be<br>
set once when the texture is created.<br>
<br>
The ‘gen’ virtual function of the texture driver has been changed to<br>
also take the internal format as a parameter. The GL driver will now<br>
set the swizzle as appropriate here.<br>
<br>
The GL3 driver now reports an error if the texture swizzle extension<br>
is not available because Cogl can't really work properly without out<br>
it. The extension is part of GL 3.3 so it is quite likely that it has<br>
wide support from drivers. Eventually we could get rid of this<br>
requirement if we have our own GLSL front-end and we could generate<br>
the swizzle ourselves.<br>
<br>
When uploading or downloading texture data to or from a<br>
component-alpha texture, we can no longer rely on GL to do the<br>
conversion. The swizzle doesn't have any effect on the texture data<br>
functions. In these cases Cogl will now force an intermediate buffer<br>
to be used and it will manually do the conversion as it does for the<br>
GLES drivers.<br>
---<br>
cogl/cogl-internal.h | 4 +-<br>
cogl/cogl-texture-3d.c | 6 ++-<br>
cogl/cogl-texture-driver.h | 5 +-<br>
cogl/cogl-texture-rectangle.c | 16 +++---<br>
cogl/cogl-texture.c | 38 +++++++++++++-<br>
cogl/driver/gl/cogl-texture-2d-gl.c | 9 ++--<br>
cogl/driver/gl/gl/cogl-driver-gl.c | 39 ++++++++++++--<br>
cogl/driver/gl/gl/cogl-texture-driver-gl.c | 70 +++++++++++++++-----------<br>
cogl/driver/gl/gles/cogl-driver-gles.c | 3 +-<br>
cogl/driver/gl/gles/cogl-texture-driver-gles.c | 40 +++++++--------<br>
10 files changed, 159 insertions(+), 71 deletions(-)<br>
<br>
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h<br>
index 97f10d8..fa921a6 100644<br>
--- a/cogl/cogl-internal.h<br>
+++ b/cogl/cogl-internal.h<br>
@@ -114,7 +114,9 @@ typedef enum<br>
COGL_PRIVATE_FEATURE_BLEND_CONSTANT = 1L<<18,<br>
COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS = 1L<<19,<br>
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM = 1L<<20,<br>
- COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<21<br>
+ COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<21,<br>
+ COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<22,<br>
+ COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<23<br>
} CoglPrivateFeatureFlags;<br>
<br>
/* Sometimes when evaluating pipelines, either during comparisons or<br>
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c<br>
index 6000b37..de00cb1 100644<br>
--- a/cogl/cogl-texture-3d.c<br>
+++ b/cogl/cogl-texture-3d.c<br>
@@ -234,7 +234,8 @@ cogl_texture_3d_new_with_size (CoglContext *ctx,<br>
width, height, depth,<br>
internal_format);<br>
<br>
- ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, 1, &tex_3d->gl_texture);<br>
+ tex_3d->gl_texture =<br>
+ ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format);<br>
_cogl_bind_gl_texture_transient (GL_TEXTURE_3D,<br>
tex_3d->gl_texture,<br>
FALSE);<br>
@@ -308,7 +309,8 @@ cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,<br>
_cogl_bitmap_unmap (dst_bmp);<br>
}<br>
<br>
- ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, 1, &tex_3d->gl_texture);<br>
+ tex_3d->gl_texture =<br>
+ ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format);<br>
<br>
ctx->texture_driver->upload_to_gl_3d (ctx,<br>
GL_TEXTURE_3D,<br>
diff --git a/cogl/cogl-texture-driver.h b/cogl/cogl-texture-driver.h<br>
index d4b2b0d..7a186ba 100644<br>
--- a/cogl/cogl-texture-driver.h<br>
+++ b/cogl/cogl-texture-driver.h<br>
@@ -33,11 +33,10 @@ struct _CoglTextureDriver<br>
* non-mipmap filters when creating textures. This is to save some memory as<br>
* the driver will not allocate room for the mipmap tree.<br>
*/<br>
- void<br>
+ GLuint<br>
(* gen) (CoglContext *ctx,<br>
GLenum gl_target,<br>
- GLsizei n,<br>
- GLuint *textures);<br>
+ CoglPixelFormat internal_format);<br>
<br>
/*<br>
* This sets up the glPixelStore state for an upload to a destination with<br>
diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c<br>
index 3dca1ed..1ffeb83 100644<br>
--- a/cogl/cogl-texture-rectangle.c<br>
+++ b/cogl/cogl-texture-rectangle.c<br>
@@ -219,10 +219,10 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,<br>
width, height,<br>
internal_format);<br>
<br>
- ctx->texture_driver->gen (ctx,<br>
- GL_TEXTURE_RECTANGLE_ARB,<br>
- 1, /* num textures */<br>
- &tex_rect->gl_texture);<br>
+ tex_rect->gl_texture =<br>
+ ctx->texture_driver->gen (ctx,<br>
+ GL_TEXTURE_RECTANGLE_ARB,<br>
+ internal_format);<br>
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,<br>
tex_rect->gl_texture,<br>
tex_rect->is_foreign);<br>
@@ -274,10 +274,10 @@ cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,<br>
cogl_bitmap_get_height (bmp),<br>
internal_format);<br>
<br>
- ctx->texture_driver->gen (ctx,<br>
- GL_TEXTURE_RECTANGLE_ARB,<br>
- 1, /* num textures */<br>
- &tex_rect->gl_texture);<br>
+ tex_rect->gl_texture =<br>
+ ctx->texture_driver->gen (ctx,<br>
+ GL_TEXTURE_RECTANGLE_ARB,<br>
+ internal_format);<br>
ctx->texture_driver->upload_to_gl (ctx,<br>
GL_TEXTURE_RECTANGLE_ARB,<br>
tex_rect->gl_texture,<br>
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c<br>
index 12be86e..7fc796c 100644<br>
--- a/cogl/cogl-texture.c<br>
+++ b/cogl/cogl-texture.c<br>
@@ -176,7 +176,15 @@ _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,<br>
limited number of formats so we must convert using the Cogl<br>
bitmap code instead */<br>
<br>
- if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION))<br>
+ /* If the driver doesn't natively support alpha textures then it<br>
+ * won't work correctly to convert to/from component-alpha<br>
+ * textures */<br>
+<br>
+ if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&<br>
+ ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||<br>
+ (src_format != COGL_PIXEL_FORMAT_A_8 &&<br>
+ dst_format != COGL_PIXEL_FORMAT_A_8) ||<br>
+ src_format == dst_format))<br>
{<br>
/* If the source format does not have the same premult flag as the<br>
dst format then we need to copy and convert it */<br>
@@ -1146,6 +1154,34 @@ cogl_texture_get_data (CoglTexture *texture,<br>
closest_format = ((closest_format & ~COGL_PREMULT_BIT) |<br>
(texture_format & COGL_PREMULT_BIT));<br>
<br>
+ /* If the application is requesting a conversion from a<br>
+ * component-alpha texture and the driver doesn't support them<br>
+ * natively then we can only read into an alpha-format buffer. In<br>
+ * this case the driver will be faking the alpha textures with a<br>
+ * red-component texture and it won't swizzle to the correct format<br>
+ * while reading */<br>
+ if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)<br>
+ {<br>
+ if (texture_format == COGL_PIXEL_FORMAT_A_8)<br>
+ {<br>
+ closest_format = COGL_PIXEL_FORMAT_A_8;<br>
+ closest_gl_format = GL_RED;<br>
+ closest_gl_type = GL_UNSIGNED_BYTE;<br>
+ }<br>
+ else if (format == COGL_PIXEL_FORMAT_A_8)<br>
+ {<br>
+ /* If we are converting to a component-alpha texture then we<br>
+ * need to read all of the components to a temporary buffer<br>
+ * because there is no way to get just the 4th component.<br>
+ * Note: it doesn't matter whether the texture is<br>
+ * pre-multiplied here because we're only going to look at<br>
+ * the alpha component */<br>
+ closest_format = COGL_PIXEL_FORMAT_RGBA_8888;<br>
+ closest_gl_format = GL_RGBA;<br>
+ closest_gl_type = GL_UNSIGNED_BYTE;<br>
+ }<br>
+ }<br>
+<br>
/* Is the requested format supported? */<br>
if (closest_format == format)<br>
/* Target user data directly */<br>
diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c<br>
index ecb3d1e..8e07017 100644<br>
--- a/cogl/driver/gl/cogl-texture-2d-gl.c<br>
+++ b/cogl/driver/gl/cogl-texture-2d-gl.c<br>
@@ -108,7 +108,8 @@ _cogl_texture_2d_gl_new_with_size (CoglContext *ctx,<br>
width, height,<br>
internal_format);<br>
<br>
- ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);<br>
+ tex_2d->gl_texture =<br>
+ ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format);<br>
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,<br>
tex_2d->gl_texture,<br>
tex_2d->is_foreign);<br>
@@ -164,7 +165,8 @@ _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp,<br>
_cogl_bitmap_unmap (dst_bmp);<br>
}<br>
<br>
- ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);<br>
+ tex_2d->gl_texture =<br>
+ ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format);<br>
ctx->texture_driver->upload_to_gl (ctx,<br>
GL_TEXTURE_2D,<br>
tex_2d->gl_texture,<br>
@@ -198,7 +200,8 @@ _cogl_egl_texture_2d_gl_new_from_image (CoglContext *ctx,<br>
width, height,<br>
format);<br>
<br>
- ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, 1, &tex_2d->gl_texture);<br>
+ tex_2d->gl_texture =<br>
+ ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, format);<br>
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,<br>
tex_2d->gl_texture,<br>
FALSE);<br>
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c<br>
index 142260f..c944718 100644<br>
--- a/cogl/driver/gl/gl/cogl-driver-gl.c<br>
+++ b/cogl/driver/gl/gl/cogl-driver-gl.c<br>
@@ -54,6 +54,10 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,<br>
{<br>
case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8:<br>
case GL_ALPHA12: case GL_ALPHA16:<br>
+ /* Cogl only supports one single-component texture so if we have<br>
+ * ended up with a red texture then it is probably being used as<br>
+ * a component-alpha texture */<br>
+ case GL_RED:<br>
<br>
*out_format = COGL_PIXEL_FORMAT_A_8;<br>
return TRUE;<br>
@@ -98,8 +102,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,<br>
switch (format)<br>
{<br>
case COGL_PIXEL_FORMAT_A_8:<br>
- glintformat = GL_ALPHA;<br>
- glformat = GL_ALPHA;<br>
+ /* If the driver doesn't natively support alpha textures then we<br>
+ * will use a red component texture with a swizzle to implement<br>
+ * the texture */<br>
+ if ((context->private_feature_flags &<br>
+ COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)<br>
+ {<br>
+ glintformat = GL_RED;<br>
+ glformat = GL_RED;<br>
+ }<br>
+ else<br>
+ {<br>
+ glintformat = GL_ALPHA;<br>
+ glformat = GL_ALPHA;<br>
+ }<br>
gltype = GL_UNSIGNED_BYTE;<br>
break;<br>
case COGL_PIXEL_FORMAT_G_8:<br>
@@ -532,11 +548,17 @@ _cogl_driver_update_features (CoglContext *ctx,<br>
if (ctx->glGenSamplers)<br>
private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS;<br>
<br>
+ if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 3) ||<br>
+ _cogl_check_extension ("GL_ARB_texture_swizzle", gl_extensions) ||<br>
+ _cogl_check_extension ("GL_EXT_texture_swizzle", gl_extensions))<br>
+ private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE;<br>
+<br>
if (ctx->driver == COGL_DRIVER_GL)<br>
/* Features which are not available in GL 3 */<br>
private_flags |= (COGL_PRIVATE_FEATURE_FIXED_FUNCTION |<br>
COGL_PRIVATE_FEATURE_ALPHA_TEST |<br>
- COGL_PRIVATE_FEATURE_QUADS);<br>
+ COGL_PRIVATE_FEATURE_QUADS |<br>
+ COGL_PRIVATE_FEATURE_ALPHA_TEXTURES);<br>
<br>
private_flags |= (COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT |<br>
COGL_PRIVATE_FEATURE_ANY_GL |<br>
@@ -550,6 +572,17 @@ _cogl_driver_update_features (CoglContext *ctx,<br>
<br>
g_strfreev (gl_extensions);<br>
<br>
+ if ((private_flags & (COGL_PRIVATE_FEATURE_ALPHA_TEXTURES |<br>
+ COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) == 0)<br>
+ {<br>
+ _cogl_set_error (error,<br>
+ COGL_DRIVER_ERROR,<br>
+ COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND,<br>
+ "The GL_ARB_texture_swizzle extension is required "<br>
+ "to use the GL3 driver");<br>
+ return FALSE;<br>
+ }<br>
+<br>
return TRUE;<br>
}<br>
<br>
diff --git a/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/gl/cogl-texture-driver-gl.c<br>
index 3c681c3..87c33ba 100644<br>
--- a/cogl/driver/gl/gl/cogl-texture-driver-gl.c<br>
+++ b/cogl/driver/gl/gl/cogl-texture-driver-gl.c<br>
@@ -44,41 +44,55 @@<br>
#include <stdlib.h><br>
#include <math.h><br>
<br>
-static void<br>
+#ifndef GL_TEXTURE_SWIZZLE_RGBA<br>
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46<br>
+#endif<br>
+<br>
+static GLuint<br>
_cogl_texture_driver_gen (CoglContext *ctx,<br>
GLenum gl_target,<br>
- GLsizei n,<br>
- GLuint *textures)<br>
+ CoglPixelFormat internal_format)<br>
{<br>
- unsigned int i;<br>
+ GLuint tex;<br>
<br>
- GE (ctx, glGenTextures (n, textures));<br>
+ GE (ctx, glGenTextures (1, &tex));<br>
<br>
- for (i = 0; i < n; i++)<br>
+ _cogl_bind_gl_texture_transient (gl_target, tex, FALSE);<br>
+<br>
+ switch (gl_target)<br>
{<br>
- _cogl_bind_gl_texture_transient (gl_target,<br>
- textures[i],<br>
- FALSE);<br>
-<br>
- switch (gl_target)<br>
- {<br>
- case GL_TEXTURE_2D:<br>
- case GL_TEXTURE_3D:<br>
- /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */<br>
- GE( ctx, glTexParameteri (gl_target,<br>
- GL_TEXTURE_MIN_FILTER,<br>
- GL_LINEAR) );<br>
- break;<br>
-<br>
- case GL_TEXTURE_RECTANGLE_ARB:<br>
- /* Texture rectangles already default to GL_LINEAR so nothing<br>
- needs to be done */<br>
- break;<br>
-<br>
- default:<br>
- g_assert_not_reached();<br>
- }<br>
+ case GL_TEXTURE_2D:<br>
+ case GL_TEXTURE_3D:<br>
+ /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */<br>
+ GE( ctx, glTexParameteri (gl_target,<br>
+ GL_TEXTURE_MIN_FILTER,<br>
+ GL_LINEAR) );<br>
+ break;<br>
+<br>
+ case GL_TEXTURE_RECTANGLE_ARB:<br>
+ /* Texture rectangles already default to GL_LINEAR so nothing<br>
+ needs to be done */<br>
+ break;<br>
+<br>
+ default:<br>
+ g_assert_not_reached();<br>
}<br>
+<br>
+ /* If the driver doesn't support alpha textures directly then we'll<br>
+ * fake them by setting the swizzle parameters */<br>
+ if (internal_format == COGL_PIXEL_FORMAT_A_8 &&<br>
+ (ctx->private_feature_flags & (COGL_PRIVATE_FEATURE_ALPHA_TEXTURES |<br>
+ COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) ==<br>
+ COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)<br>
+ {<br>
+ static const GLint red_swizzle[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };<br>
+<br>
+ GE( ctx, glTexParameteriv (gl_target,<br>
+ GL_TEXTURE_SWIZZLE_RGBA,<br>
+ red_swizzle) );<br>
+ }<br>
+<br>
+ return tex;<br>
}<br>
<br>
/* OpenGL - unlike GLES - can upload a sub region of pixel data from a larger<br>
diff --git a/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/driver/gl/gles/cogl-driver-gles.c<br>
index 0e2b465..5630c66 100644<br>
--- a/cogl/driver/gl/gles/cogl-driver-gles.c<br>
+++ b/cogl/driver/gl/gles/cogl-driver-gles.c<br>
@@ -266,7 +266,8 @@ _cogl_driver_update_features (CoglContext *context,<br>
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM);<br>
<br>
private_flags |= (COGL_PRIVATE_FEATURE_VBOS |<br>
- COGL_PRIVATE_FEATURE_ANY_GL);<br>
+ COGL_PRIVATE_FEATURE_ANY_GL |<br>
+ COGL_PRIVATE_FEATURE_ALPHA_TEXTURES);<br>
<br>
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */<br>
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);<br>
diff --git a/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/driver/gl/gles/cogl-texture-driver-gles.c<br>
index 65407b6..1e45a53 100644<br>
--- a/cogl/driver/gl/gles/cogl-texture-driver-gles.c<br>
+++ b/cogl/driver/gl/gles/cogl-texture-driver-gles.c<br>
@@ -63,34 +63,32 @@<br>
#define GL_UNPACK_SKIP_PIXELS 0x0CF4<br>
#endif<br>
<br>
-static void<br>
+static GLuint<br>
_cogl_texture_driver_gen (CoglContext *ctx,<br>
GLenum gl_target,<br>
- GLsizei n,<br>
- GLuint *textures)<br>
+ CoglPixelFormat internal_format)<br>
{<br>
- unsigned int i;<br>
+ GLuint tex;<br>
<br>
- GE (ctx, glGenTextures (n, textures));<br>
+ GE (ctx, glGenTextures (1, &tex));<br>
<br>
- for (i = 0; i < n; i++)<br>
- {<br>
- _cogl_bind_gl_texture_transient (gl_target, textures[i], FALSE);<br>
+ _cogl_bind_gl_texture_transient (gl_target, tex, FALSE);<br>
<br>
- switch (gl_target)<br>
- {<br>
- case GL_TEXTURE_2D:<br>
- case GL_TEXTURE_3D:<br>
- /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */<br>
- GE( ctx, glTexParameteri (gl_target,<br>
- GL_TEXTURE_MIN_FILTER,<br>
- GL_LINEAR) );<br>
- break;<br>
-<br>
- default:<br>
- g_assert_not_reached();<br>
- }<br>
+ switch (gl_target)<br>
+ {<br>
+ case GL_TEXTURE_2D:<br>
+ case GL_TEXTURE_3D:<br>
+ /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */<br>
+ GE( ctx, glTexParameteri (gl_target,<br>
+ GL_TEXTURE_MIN_FILTER,<br>
+ GL_LINEAR) );<br>
+ break;<br>
+<br>
+ default:<br>
+ g_assert_not_reached();<br>
}<br>
+<br>
+ return tex;<br>
}<br>
<br>
static void<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.11.3.g3c3efa5<br>
<br>
_______________________________________________<br>
Cogl mailing list<br>
<a href="mailto:Cogl@lists.freedesktop.org">Cogl@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/cogl" target="_blank">http://lists.freedesktop.org/mailman/listinfo/cogl</a><br>
</font></span></blockquote></div><br></div>