summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Proschofsky <suka@gentoo.org>2010-11-20 18:38:34 +0000
committerAndreas Proschofsky <suka@gentoo.org>2010-11-20 18:38:34 +0000
commitab76ece17976d8c9ec7b7876b91a0c89bf37c465 (patch)
treeffbbf6f544b2f4b5904fb5e45ee3c2dc6aaffb0b
parentUpdate gnome-desktop, plus dep fixes (diff)
downloadsuka-ab76ece17976d8c9ec7b7876b91a0c89bf37c465.tar.gz
suka-ab76ece17976d8c9ec7b7876b91a0c89bf37c465.tar.bz2
suka-ab76ece17976d8c9ec7b7876b91a0c89bf37c465.zip
New clutter release with some extra performance patches
svn path=/; revision=317
-rw-r--r--media-libs/clutter/Manifest10
-rw-r--r--media-libs/clutter/clutter-1.5.6.ebuild (renamed from media-libs/clutter/clutter-1.5.4.ebuild)16
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu1.patch248
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu2.patch123
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu3.patch30
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu4.patch128
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu5.patch566
-rw-r--r--media-libs/clutter/files/clutter-9999-perfneu6.patch96
8 files changed, 1212 insertions, 5 deletions
diff --git a/media-libs/clutter/Manifest b/media-libs/clutter/Manifest
index 2410673..098be12 100644
--- a/media-libs/clutter/Manifest
+++ b/media-libs/clutter/Manifest
@@ -1,2 +1,8 @@
-DIST clutter-1.5.4.tar.bz2 4520746 RMD160 6b64a4dcddc4aad74dd701259689b6a08e7f87e6 SHA1 0c8ddb1af666caff5b8d0f40e216250f26e89b11 SHA256 6134d534184724648ee7aa5eba5ea7b35994185eee579bf136460a88e341bd02
-EBUILD clutter-1.5.4.ebuild 1985 RMD160 554a7a7df1879844a95d7f82e0254386d6efaecb SHA1 66d158178e49aaa73f6c3c9cd7387c3e16f094c6 SHA256 ee6faf5357fdf71e95401b2dc55c35c2e09b1e82916d8e51d1db9863df159366
+AUX clutter-9999-perfneu1.patch 9954 RMD160 01a2cde328ae679306ef9b22ec9c3379db69ac3e SHA1 b0744464efedd7ea0fb0fc3b52db69eabeed16d4 SHA256 34d1d29777a970cd5700d980a6b33384915fdc5b681e02900ba527341ac4ed7b
+AUX clutter-9999-perfneu2.patch 4273 RMD160 b959603a0ebd98a1730344b48d127ece18b2a1b8 SHA1 341b26fef9ab4c8ff940cc1dccdeca10178212df SHA256 8f6d90a3f314a691f3c0483783877fcbe396598f5e38c9ee33f676ace9352081
+AUX clutter-9999-perfneu3.patch 1279 RMD160 34707927a17f568f013d57bd4f548c1f997a1344 SHA1 6420c2cacd4dda2d4697a4d119d0681a355f7953 SHA256 6af62a96d225f57473cd405414e8b40acca98f673f22167ca7e3433172018472
+AUX clutter-9999-perfneu4.patch 5970 RMD160 b628417bc2eef56dd03f2333da64a7dca59b547d SHA1 5fb0021ad22501998de4dc6f69563a7e37dc1b4e SHA256 acf2e34ff4a0b7180bcd4cbf51c3a72c30245484994d2abcd640291b3e6f4755
+AUX clutter-9999-perfneu5.patch 20332 RMD160 1c74cdcbe46f2ae40ee94fe2e1f7d8614a90b8c6 SHA1 d64c677876bf1a9e3ad2e7a09f04def689cf1b57 SHA256 c1916661519a85fb8d40f97259ab3647378ec4609236fbf4438cdc67fe7c8472
+AUX clutter-9999-perfneu6.patch 3416 RMD160 168039d8e0363ce109fc9cc4285ca5717e46c884 SHA1 95fa439f4a7ed1a0a02d8556fa2b75981e195f78 SHA256 539bf54212b8dd65ccc68e9e199396efe4d25204dadd11d0f76aff665e2adf3c
+DIST clutter-1.5.6.tar.bz2 4736228 RMD160 2dc12cf36c9418aca67433d8448c418a5f8d110f SHA1 3a47f55dcc05ef7a6833059408b85f7f52635ff9 SHA256 32b50add2b73dc4726609b5a7e2b8ab7bbb52bb226348286b1f75255cfa64f8e
+EBUILD clutter-1.5.6.ebuild 2282 RMD160 f747576a806913ec32ac2de91808e137a031ae1b SHA1 4c737772d757c888bc69d844adcf5f9d0616abe1 SHA256 ba3573d96f6e828a0535e057f39c89677607b62dd3b0c91db415bfdd5fcbfba5
diff --git a/media-libs/clutter/clutter-1.5.4.ebuild b/media-libs/clutter/clutter-1.5.6.ebuild
index 793c0e0..551c348 100644
--- a/media-libs/clutter/clutter-1.5.4.ebuild
+++ b/media-libs/clutter/clutter-1.5.6.ebuild
@@ -13,10 +13,10 @@ KEYWORDS="~amd64 ~ppc64 ~x86"
IUSE="debug doc +gtk +introspection"
# NOTE: glx flavour uses libdrm + >=mesa-7.3
-RDEPEND=">=dev-libs/glib-2.18
- >=x11-libs/cairo-1.4
+RDEPEND=">=dev-libs/glib-2.26
+ >=x11-libs/cairo-1.10
>=x11-libs/pango-1.20[introspection?]
- >=dev-libs/json-glib-0.10[introspection?]
+ >=dev-libs/json-glib-0.12[introspection?]
>=dev-libs/atk-1.7
virtual/opengl
@@ -44,6 +44,16 @@ DEPEND="${RDEPEND}
dev-libs/libxslt )
"
+src_prepare() {
+ epatch ${FILESDIR}/${PN}-9999-perfneu1.patch
+ epatch ${FILESDIR}/${PN}-9999-perfneu2.patch
+ epatch ${FILESDIR}/${PN}-9999-perfneu3.patch
+ epatch ${FILESDIR}/${PN}-9999-perfneu4.patch
+ epatch ${FILESDIR}/${PN}-9999-perfneu5.patch
+ epatch ${FILESDIR}/${PN}-9999-perfneu6.patch
+
+}
+
src_configure() {
# We only need conformance tests, the rest are useless for us
# sed -e 's/^\(SUBDIRS =\).*/\1/g' \
diff --git a/media-libs/clutter/files/clutter-9999-perfneu1.patch b/media-libs/clutter/files/clutter-9999-perfneu1.patch
new file mode 100644
index 0000000..59b2d27
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu1.patch
@@ -0,0 +1,248 @@
+From 2b5eb9205ae85c8b459d993da803a31c847e5776 Mon Sep 17 00:00:00 2001
+From: Neil Roberts <neil@linux.intel.com>
+Date: Thu, 11 Nov 2010 15:28:44 +0000
+Subject: [PATCH] Add an internal _cogl_offscreen_new_to_texture_full function
+
+This function is the same as cogl_offscreen_new_to_texture but it
+takes a level parameter and a set of flags so that FBOs can be used to
+render to higher mipmap levels and to disable the depth and stencil
+buffers. cogl_offscreen_new_to_texture now just calls the new function
+with the level set to zero. This function could be useful in a few
+places in Cogl where we want to use FBOs as an implementation detail
+such as when copying between textures.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ clutter/cogl/cogl/cogl-framebuffer-private.h | 24 ++++++
+ clutter/cogl/cogl/cogl-framebuffer.c | 100 +++++++++++++++++++------
+ 2 files changed, 100 insertions(+), 24 deletions(-)
+
+diff --git a/clutter/cogl/cogl/cogl-framebuffer-private.h b/clutter/cogl/cogl/cogl-framebuffer-private.h
+index 1ae102e..803befd 100644
+--- a/clutter/cogl/cogl/cogl-framebuffer-private.h
++++ b/clutter/cogl/cogl/cogl-framebuffer-private.h
+@@ -66,6 +66,12 @@ typedef struct _CoglOffscreen
+ CoglHandle texture;
+ } CoglOffscreen;
+
++/* Flags to pass to _cogl_offscreen_new_to_texture_full */
++typedef enum
++{
++ COGL_OFFSCREEN_DISABLE_DEPTH_STENCIL = 1
++} CoglOffscreenFlags;
++
+ #define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X))
+
+ typedef struct _CoglOnscreen
+@@ -143,5 +149,23 @@ _cogl_create_framebuffer_stack (void);
+ void
+ _cogl_free_framebuffer_stack (GSList *stack);
+
++/*
++ * _cogl_offscreen_new_to_texture_full:
++ * @texhandle: A handle to the texture to target
++ * @create_flags: Flags specifying how to create the FBO
++ * @level: The mipmap level within the texture to target
++ *
++ * Creates a new offscreen buffer which will target the given
++ * texture. By default the buffer will have a depth and stencil
++ * buffer. This can be disabled by passing
++ * %COGL_OFFSCREEN_DISABLE_DEPTH_STENCIL in @create_flags.
++ *
++ * Return value: the new CoglOffscreen object.
++ */
++CoglHandle
++_cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
++ CoglOffscreenFlags create_flags,
++ unsigned int level);
++
+ #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
+
+diff --git a/clutter/cogl/cogl/cogl-framebuffer.c b/clutter/cogl/cogl/cogl-framebuffer.c
+index 2042c0a..5e832b1 100644
+--- a/clutter/cogl/cogl/cogl-framebuffer.c
++++ b/clutter/cogl/cogl/cogl-framebuffer.c
+@@ -324,10 +324,18 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
+ framebuffer->dirty_bitmasks = FALSE;
+ }
+
++typedef struct
++{
++ CoglHandle texture;
++ unsigned int level;
++ unsigned int level_width;
++ unsigned int level_height;
++} CoglFramebufferTryFBOData;
++
+ static gboolean
+ try_creating_fbo (CoglOffscreen *offscreen,
+ TryFBOFlags flags,
+- CoglHandle texture)
++ CoglFramebufferTryFBOData *data)
+ {
+ GLuint gl_depth_stencil_handle;
+ GLuint gl_depth_handle;
+@@ -339,7 +347,8 @@ try_creating_fbo (CoglOffscreen *offscreen,
+
+ _COGL_GET_CONTEXT (ctx, FALSE);
+
+- if (!cogl_texture_get_gl_texture (texture, &tex_gl_handle, &tex_gl_target))
++ if (!cogl_texture_get_gl_texture (data->texture,
++ &tex_gl_handle, &tex_gl_target))
+ return FALSE;
+
+ if (tex_gl_target != GL_TEXTURE_2D
+@@ -362,7 +371,7 @@ try_creating_fbo (CoglOffscreen *offscreen,
+ offscreen->fbo_handle = fbo_gl_handle;
+
+ GE (glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+- tex_gl_target, tex_gl_handle, 0));
++ tex_gl_target, tex_gl_handle, data->level));
+
+ if (flags & _TRY_DEPTH_STENCIL)
+ {
+@@ -370,8 +379,8 @@ try_creating_fbo (CoglOffscreen *offscreen,
+ GE (glGenRenderbuffers (1, &gl_depth_stencil_handle));
+ GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle));
+ GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_STENCIL,
+- cogl_texture_get_width (texture),
+- cogl_texture_get_height (texture)));
++ data->level_width,
++ data->level_height));
+ GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
+ GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+@@ -391,8 +400,8 @@ try_creating_fbo (CoglOffscreen *offscreen,
+ /* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's
+ * available under GLES */
+ GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+- cogl_texture_get_width (texture),
+- cogl_texture_get_height (texture)));
++ data->level_width,
++ data->level_height));
+ GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
+ GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+@@ -407,8 +416,8 @@ try_creating_fbo (CoglOffscreen *offscreen,
+ GE (glGenRenderbuffers (1, &gl_stencil_handle));
+ GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle));
+ GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+- cogl_texture_get_width (texture),
+- cogl_texture_get_height (texture)));
++ data->level_width,
++ data->level_height));
+ GE (glBindRenderbuffer (GL_RENDERBUFFER, 0));
+ GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+@@ -443,11 +452,16 @@ try_creating_fbo (CoglOffscreen *offscreen,
+ }
+
+ CoglHandle
+-cogl_offscreen_new_to_texture (CoglHandle texhandle)
++_cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
++ CoglOffscreenFlags create_flags,
++ unsigned int level)
+ {
+ CoglOffscreen *offscreen;
+ static TryFBOFlags flags;
+ static gboolean have_working_flags = FALSE;
++ unsigned int i;
++ CoglFramebufferTryFBOData data;
++ gboolean fbo_created;
+
+ _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
+
+@@ -462,6 +476,27 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
+ if (cogl_texture_is_sliced (texhandle))
+ return COGL_INVALID_HANDLE;
+
++ data.texture = texhandle;
++ data.level = level;
++
++ /* Calculate the size of the texture at this mipmap level to ensure
++ that it's a valid level */
++ data.level_width = cogl_texture_get_width (texhandle);
++ data.level_height = cogl_texture_get_height (texhandle);
++
++ for (i = 0; i < level; i++)
++ {
++ /* If neither dimension can be further divided then the level is
++ invalid */
++ if (data.level_width == 1 && data.level_height == 1)
++ return COGL_INVALID_HANDLE;
++
++ if (data.level_width > 1)
++ data.level_width >>= 1;
++ if (data.level_height > 1)
++ data.level_height >>= 1;
++ }
++
+ /* XXX: The framebuffer_object spec isn't clear in defining whether attaching
+ * a texture as a renderbuffer with mipmap filtering enabled while the
+ * mipmaps have not been uploaded should result in an incomplete framebuffer
+@@ -477,25 +512,36 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
+ offscreen = g_new0 (CoglOffscreen, 1);
+ offscreen->texture = cogl_handle_ref (texhandle);
+
+- if ((have_working_flags &&
+- try_creating_fbo (offscreen, flags, texhandle)) ||
++ if ((create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_STENCIL))
++ fbo_created = try_creating_fbo (offscreen, flags = 0, &data);
++ else
++ {
++ if ((have_working_flags &&
++ try_creating_fbo (offscreen, flags, &data)) ||
+ #ifdef HAVE_COGL_GL
+- try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, texhandle) ||
++ try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, &data) ||
+ #endif
+- try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL,
+- texhandle) ||
+- try_creating_fbo (offscreen, flags = _TRY_STENCIL, texhandle) ||
+- try_creating_fbo (offscreen, flags = _TRY_DEPTH, texhandle) ||
+- try_creating_fbo (offscreen, flags = 0, texhandle))
+- {
+- /* Record that the last set of flags succeeded so that we can
+- try that set first next time */
+- have_working_flags = TRUE;
++ try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL,
++ &data) ||
++ try_creating_fbo (offscreen, flags = _TRY_STENCIL, &data) ||
++ try_creating_fbo (offscreen, flags = _TRY_DEPTH, &data) ||
++ try_creating_fbo (offscreen, flags = 0, &data))
++ {
++ /* Record that the last set of flags succeeded so that we can
++ try that set first next time */
++ have_working_flags = TRUE;
++ fbo_created = TRUE;
++ }
++ else
++ fbo_created = FALSE;
++ }
+
++ if (fbo_created)
++ {
+ _cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen),
+ COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
+- cogl_texture_get_width (texhandle),
+- cogl_texture_get_height (texhandle));
++ data.level_width,
++ data.level_height);
+
+ return _cogl_offscreen_object_new (offscreen);
+ }
+@@ -508,6 +554,12 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
+ }
+ }
+
++CoglHandle
++cogl_offscreen_new_to_texture (CoglHandle texhandle)
++{
++ return _cogl_offscreen_new_to_texture_full (texhandle, 0, 0);
++}
++
+ static void
+ _cogl_offscreen_free (CoglOffscreen *offscreen)
+ {
+--
+1.7.3.16.g9464b \ No newline at end of file
diff --git a/media-libs/clutter/files/clutter-9999-perfneu2.patch b/media-libs/clutter/files/clutter-9999-perfneu2.patch
new file mode 100644
index 0000000..bb1eab1
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu2.patch
@@ -0,0 +1,123 @@
+From b52949949fff009e1e681bbce8027785b5cc7ac6 Mon Sep 17 00:00:00 2001
+From: Neil Roberts <neil@linux.intel.com>
+Date: Wed, 17 Nov 2010 15:38:20 +0000
+Subject: [PATCH] Add an internal _cogl_read_pixels_full
+
+This is the same as _cogl_read_pixels except that it takes a rowstride
+parameter for the destination buffer. Under OpenGL setting the
+rowstride this will end up calling GL_ROW_LENGTH so that the buffer
+region can be directly written to. Under GLES GL_ROW_LENGTH is not
+supported so it will use an intermediate buffer as it does if the
+format is not GL_RGBA.
+
+cogl_read_pixels now just calls the full version of the function with
+the rowstride set to width*bpp.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ clutter/cogl/cogl/cogl-private.h | 10 +++++++++
+ clutter/cogl/cogl/cogl.c | 39 +++++++++++++++++++++++++++----------
+ 2 files changed, 38 insertions(+), 11 deletions(-)
+
+diff --git a/clutter/cogl/cogl/cogl-private.h b/clutter/cogl/cogl/cogl-private.h
+index c2f6947..6c06cce 100644
+--- a/clutter/cogl/cogl/cogl-private.h
++++ b/clutter/cogl/cogl/cogl-private.h
+@@ -29,6 +29,16 @@ G_BEGIN_DECLS
+ void
+ _cogl_clear (const CoglColor *color, unsigned long buffers);
+
++void
++_cogl_read_pixels_full (int x,
++ int y,
++ int width,
++ int height,
++ CoglReadPixelsFlags source,
++ CoglPixelFormat format,
++ guint8 *pixels,
++ int rowstride);
++
+ G_END_DECLS
+
+ #endif /* __COGL_PRIVATE_H__ */
+diff --git a/clutter/cogl/cogl/cogl.c b/clutter/cogl/cogl/cogl.c
+index b1882ef..67827f3 100644
+--- a/clutter/cogl/cogl/cogl.c
++++ b/clutter/cogl/cogl/cogl.c
+@@ -556,13 +556,14 @@ cogl_flush (void)
+ }
+
+ void
+-cogl_read_pixels (int x,
+- int y,
+- int width,
+- int height,
+- CoglReadPixelsFlags source,
+- CoglPixelFormat format,
+- guint8 *pixels)
++_cogl_read_pixels_full (int x,
++ int y,
++ int width,
++ int height,
++ CoglReadPixelsFlags source,
++ CoglPixelFormat format,
++ guint8 *pixels,
++ int rowstride)
+ {
+ CoglFramebuffer *framebuffer;
+ int framebuffer_height;
+@@ -572,7 +573,6 @@ cogl_read_pixels (int x,
+ GLenum gl_format;
+ GLenum gl_type;
+ CoglPixelFormat bmp_format;
+- int rowstride;
+
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+@@ -599,7 +599,6 @@ cogl_read_pixels (int x,
+
+ /* Initialise the CoglBitmap */
+ bpp = _cogl_get_format_bpp (format);
+- rowstride = bpp * width;
+ bmp_format = format;
+
+ if ((format & COGL_A_BIT))
+@@ -630,9 +629,12 @@ cogl_read_pixels (int x,
+ to be more clever and check if the requested type matches that
+ but we would need some reliable functions to convert from GL
+ types to Cogl types. For now, lets just always read in
+- GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary */
++ GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need
++ to use this intermediate buffer if the rowstride has padding
++ because GLES does not support setting GL_ROW_LENGTH */
+ #ifndef COGL_HAS_GL
+- if (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE)
++ if (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE ||
++ rowstride != 4 * width)
+ {
+ CoglBitmap *tmp_bmp, *dst_bmp;
+ guint8 *tmp_data = g_malloc (width * height * 4);
+@@ -711,6 +713,21 @@ cogl_read_pixels (int x,
+ cogl_object_unref (bmp);
+ }
+
++void
++cogl_read_pixels (int x,
++ int y,
++ int width,
++ int height,
++ CoglReadPixelsFlags source,
++ CoglPixelFormat format,
++ guint8 *pixels)
++{
++ _cogl_read_pixels_full (x, y, width, height,
++ source, format, pixels,
++ /* rowstride */
++ _cogl_get_format_bpp (format) * width);
++}
++
+ static void
+ _cogl_disable_other_texcoord_arrays_cb (int texcoord_array_num, gpointer data)
+ {
+--
+1.7.3.16.g9464b \ No newline at end of file
diff --git a/media-libs/clutter/files/clutter-9999-perfneu3.patch b/media-libs/clutter/files/clutter-9999-perfneu3.patch
new file mode 100644
index 0000000..1a33716
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu3.patch
@@ -0,0 +1,30 @@
+From 533b61186f2b1ba71dba63167093a8e7ca45efbd Mon Sep 17 00:00:00 2001
+From: Neil Roberts <neil@linux.intel.com>
+Date: Wed, 17 Nov 2010 17:45:27 +0000
+Subject: [PATCH] cogl_read_pixels: Fix the format used in GLES2
+
+When converting the data in cogl_read_pixels it was using bmp_format
+instead of the format passed in to the function. bmp_format is the
+same as the passed in format except that it always has the premult bit
+set. Therefore the conversion would not handle premultiply correctly.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ clutter/cogl/cogl/cogl.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/clutter/cogl/cogl/cogl.c b/clutter/cogl/cogl/cogl.c
+index 67827f3..a2a4109 100644
+--- a/clutter/cogl/cogl/cogl.c
++++ b/clutter/cogl/cogl/cogl.c
+@@ -655,7 +655,7 @@ _cogl_read_pixels_full (int x,
+ allocating its own buffer so we have to copy the data
+ again */
+ if ((dst_bmp = _cogl_bitmap_convert_format_and_premult (tmp_bmp,
+- bmp_format)))
++ format)))
+ {
+ _cogl_bitmap_copy_subregion (dst_bmp,
+ bmp,
+--
+1.7.3.16.g9464b \ No newline at end of file
diff --git a/media-libs/clutter/files/clutter-9999-perfneu4.patch b/media-libs/clutter/files/clutter-9999-perfneu4.patch
new file mode 100644
index 0000000..fb7b55a
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu4.patch
@@ -0,0 +1,128 @@
+From c2a5d27a28e2bbf9f839f06a149253688e83071e Mon Sep 17 00:00:00 2001
+From: Neil Roberts <neil@linux.intel.com>
+Date: Wed, 17 Nov 2010 17:57:17 +0000
+Subject: [PATCH] cogl-framebuffer: Try to track format of the framebuffer
+
+Previously in cogl_read_pixels we assume the format of the framebuffer
+is always premultiplied because that is the most likely format with
+the default Cogl blend mode. However when the framebuffer is bound to
+a texture we should be able to make a better guess at the format
+because we know the texture keeps track of the premult status. This
+patch adds an internal format member to CoglFramebuffer. For onscreen
+framebuffers we still assume it is RGBA_8888_PRE but for offscreen to
+textures we copy the texture format. cogl_read_pixels uses this to
+determine whether the data returned by glReadPixels will be
+premultiplied.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ clutter/cogl/cogl/cogl-framebuffer-private.h | 3 +++
+ clutter/cogl/cogl/cogl-framebuffer.c | 15 +++++++++++++++
+ clutter/cogl/cogl/cogl.c | 22 ++++++++++------------
+ 3 files changed, 28 insertions(+), 12 deletions(-)
+
+diff --git a/clutter/cogl/cogl/cogl-framebuffer-private.h b/clutter/cogl/cogl/cogl-framebuffer-private.h
+index 803befd..a831ba7 100644
+--- a/clutter/cogl/cogl/cogl-framebuffer-private.h
++++ b/clutter/cogl/cogl/cogl-framebuffer-private.h
+@@ -39,6 +39,9 @@ struct _CoglFramebuffer
+ CoglFramebufferType type;
+ int width;
+ int height;
++ /* Format of the pixels in the framebuffer (including the expected
++ premult state) */
++ CoglPixelFormat format;
+
+ CoglMatrixStack *modelview_stack;
+ CoglMatrixStack *projection_stack;
+diff --git a/clutter/cogl/cogl/cogl-framebuffer.c b/clutter/cogl/cogl/cogl-framebuffer.c
+index 5e832b1..ade7344 100644
+--- a/clutter/cogl/cogl/cogl-framebuffer.c
++++ b/clutter/cogl/cogl/cogl-framebuffer.c
+@@ -139,12 +139,14 @@ _cogl_is_framebuffer (void *object)
+ static void
+ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
+ CoglFramebufferType type,
++ CoglPixelFormat format,
+ int width,
+ int height)
+ {
+ framebuffer->type = type;
+ framebuffer->width = width;
+ framebuffer->height = height;
++ framebuffer->format = format;
+ framebuffer->viewport_x = 0;
+ framebuffer->viewport_y = 0;
+ framebuffer->viewport_width = width;
+@@ -540,6 +542,7 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
+ {
+ _cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen),
+ COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
++ cogl_texture_get_format (texhandle),
+ data.level_width,
+ data.level_height);
+
+@@ -594,9 +597,21 @@ _cogl_onscreen_new (void)
+ * implement CoglOnscreen framebuffers, since we can't, e.g. keep track of
+ * the window size. */
+
++ /* FIXME: We are assuming onscreen buffers will always be
++ premultiplied so we'll set the premult flag on the bitmap
++ format. This will usually be correct because the result of the
++ default blending operations for Cogl ends up with premultiplied
++ data in the framebuffer. However it is possible for the
++ framebuffer to be in whatever format depending on what
++ CoglPipeline is used to render to it. Eventually we may want to
++ add a way for an application to inform Cogl that the framebuffer
++ is not premultiplied in case it is being used for some special
++ purpose. */
++
+ onscreen = g_new0 (CoglOnscreen, 1);
+ _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
+ COGL_FRAMEBUFFER_TYPE_ONSCREEN,
++ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ 0xdeadbeef, /* width */
+ 0xdeadbeef); /* height */
+
+diff --git a/clutter/cogl/cogl/cogl.c b/clutter/cogl/cogl/cogl.c
+index a2a4109..1aeef9e 100644
+--- a/clutter/cogl/cogl/cogl.c
++++ b/clutter/cogl/cogl/cogl.c
+@@ -603,17 +603,14 @@ _cogl_read_pixels_full (int x,
+
+ if ((format & COGL_A_BIT))
+ {
+- /* FIXME: We are assuming glReadPixels will always give us
+- premultiplied data so we'll set the premult flag on the
+- bitmap format. This will usually be correct because the
+- result of the default blending operations for Cogl ends up
+- with premultiplied data in the framebuffer. However it is
+- possible for the framebuffer to be in whatever format
+- depending on what CoglPipeline is used to render to
+- it. Eventually we may want to add a way for an application to
+- inform Cogl that the framebuffer is not premultiplied in case
+- it is being used for some special purpose. */
+- bmp_format |= COGL_PREMULT_BIT;
++ /* We match the premultiplied state of the target buffer to the
++ * premultiplied state of the framebuffer so that it will get
++ * converted to the right format below */
++
++ if ((framebuffer->format & COGL_PREMULT_BIT))
++ bmp_format |= COGL_PREMULT_BIT;
++ else
++ bmp_format &= ~COGL_PREMULT_BIT;
+ }
+
+ bmp = _cogl_bitmap_new_from_data (pixels,
+@@ -640,7 +637,8 @@ _cogl_read_pixels_full (int x,
+ guint8 *tmp_data = g_malloc (width * height * 4);
+
+ tmp_bmp = _cogl_bitmap_new_from_data (tmp_data,
+- COGL_PIXEL_FORMAT_RGBA_8888_PRE,
++ COGL_PIXEL_FORMAT_RGBA_8888 |
++ (bmp_format & COGL_PREMULT_BIT),
+ width, height, 4 * width,
+ (CoglBitmapDestroyNotify) g_free,
+ NULL);
+--
+1.7.3.16.g9464b \ No newline at end of file
diff --git a/media-libs/clutter/files/clutter-9999-perfneu5.patch b/media-libs/clutter/files/clutter-9999-perfneu5.patch
new file mode 100644
index 0000000..a86e2b6
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu5.patch
@@ -0,0 +1,566 @@
+From 5a39b19ccb80af0d92d3ce74772825729a13a9c7 Mon Sep 17 00:00:00 2001
+From: Owen W. Taylor <otaylor@fishsoup.net>
+Date: Fri, 12 Nov 2010 11:02:13 -0500
+Subject: [PATCH] Use FBOs and use cogl_read_pixels() to efficiently read partial textures
+
+* cogl_texture_get_data() is converted to use
+ _cogl_texture_foreach_sub_texture_in_region() to iterate
+ through the underlying textures.
+
+ * When we need to read only a portion of the underlying
+ texture, we set up a FBO and use _cogl_read_pixels()
+ to read the portion we need. This is enormously more
+ efficient for reading a small portion of a large atlas
+ texture.
+
+ * The CoglAtlasTexture, CoglSubTexture, and CoglTexture2dSliced
+ implementation of get_texture() are removed.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ clutter/cogl/cogl/cogl-atlas-texture.c | 17 +---
+ clutter/cogl/cogl/cogl-sub-texture.c | 70 +----------
+ clutter/cogl/cogl/cogl-texture-2d-sliced.c | 149 +---------------------
+ clutter/cogl/cogl/cogl-texture.c | 191 ++++++++++++++++++++++++++-
+ 4 files changed, 186 insertions(+), 241 deletions(-)
+
+diff --git a/clutter/cogl/cogl/cogl-atlas-texture.c b/clutter/cogl/cogl/cogl-atlas-texture.c
+index 2ad7445..9194da3 100644
+--- a/clutter/cogl/cogl/cogl-atlas-texture.c
++++ b/clutter/cogl/cogl/cogl-atlas-texture.c
+@@ -439,21 +439,6 @@ _cogl_atlas_texture_set_region (CoglTexture *tex,
+ bmp);
+ }
+
+-static gboolean
+-_cogl_atlas_texture_get_data (CoglTexture *tex,
+- CoglPixelFormat format,
+- unsigned int rowstride,
+- guint8 *data)
+-{
+- CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
+-
+- /* Forward on to the sub texture */
+- return cogl_texture_get_data (atlas_tex->sub_texture,
+- format,
+- rowstride,
+- data);
+-}
+-
+ static CoglPixelFormat
+ _cogl_atlas_texture_get_format (CoglTexture *tex)
+ {
+@@ -632,7 +617,7 @@ static const CoglTextureVtable
+ cogl_atlas_texture_vtable =
+ {
+ _cogl_atlas_texture_set_region,
+- _cogl_atlas_texture_get_data,
++ NULL, /* get_data */
+ _cogl_atlas_texture_foreach_sub_texture_in_region,
+ _cogl_atlas_texture_get_max_waste,
+ _cogl_atlas_texture_is_sliced,
+diff --git a/clutter/cogl/cogl/cogl-sub-texture.c b/clutter/cogl/cogl/cogl-sub-texture.c
+index 9260f13..1730c87 100644
+--- a/clutter/cogl/cogl/cogl-sub-texture.c
++++ b/clutter/cogl/cogl/cogl-sub-texture.c
+@@ -416,74 +416,6 @@ _cogl_sub_texture_set_region (CoglTexture *tex,
+ bmp);
+ }
+
+-static void
+-_cogl_sub_texture_copy_region (guint8 *dst,
+- const guint8 *src,
+- int dst_x, int dst_y,
+- int src_x, int src_y,
+- int width, int height,
+- int dst_rowstride,
+- int src_rowstride,
+- int bpp)
+-{
+- int y;
+-
+- dst += dst_x * bpp + dst_y * dst_rowstride;
+- src += src_x * bpp + src_y * src_rowstride;
+-
+- for (y = 0; y < height; y++)
+- {
+- memcpy (dst, src, bpp * width);
+- dst += dst_rowstride;
+- src += src_rowstride;
+- }
+-}
+-
+-static gboolean
+-_cogl_sub_texture_get_data (CoglTexture *tex,
+- CoglPixelFormat format,
+- unsigned int rowstride,
+- guint8 *data)
+-{
+- CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
+- unsigned int full_rowstride;
+- guint8 *full_data;
+- gboolean ret = TRUE;
+- int bpp;
+- int full_tex_width, full_tex_height;
+-
+- /* FIXME: This gets the full data from the full texture and then
+- copies a subregion of that. It would be better if there was a
+- texture_get_sub_data virtual and it can just munge the texture
+- coordinates */
+-
+- full_tex_width = cogl_texture_get_width (sub_tex->full_texture);
+- full_tex_height = cogl_texture_get_height (sub_tex->full_texture);
+-
+- bpp = _cogl_get_format_bpp (format);
+-
+- full_rowstride = _cogl_get_format_bpp (format) * full_tex_width;
+- full_data = g_malloc (full_rowstride * full_tex_height);
+-
+- if (cogl_texture_get_data (sub_tex->full_texture, format,
+- full_rowstride, full_data))
+- _cogl_sub_texture_copy_region (data, full_data,
+- 0, 0,
+- sub_tex->sub_x,
+- sub_tex->sub_y,
+- sub_tex->sub_width,
+- sub_tex->sub_height,
+- rowstride,
+- full_rowstride,
+- bpp);
+- else
+- ret = FALSE;
+-
+- g_free (full_data);
+-
+- return ret;
+-}
+-
+ static CoglPixelFormat
+ _cogl_sub_texture_get_format (CoglTexture *tex)
+ {
+@@ -520,7 +452,7 @@ static const CoglTextureVtable
+ cogl_sub_texture_vtable =
+ {
+ _cogl_sub_texture_set_region,
+- _cogl_sub_texture_get_data,
++ NULL, /* get_data */
+ _cogl_sub_texture_foreach_sub_texture_in_region,
+ _cogl_sub_texture_get_max_waste,
+ _cogl_sub_texture_is_sliced,
+diff --git a/clutter/cogl/cogl/cogl-texture-2d-sliced.c b/clutter/cogl/cogl/cogl-texture-2d-sliced.c
+index dbaa746..5e3f65a 100644
+--- a/clutter/cogl/cogl/cogl-texture-2d-sliced.c
++++ b/clutter/cogl/cogl/cogl-texture-2d-sliced.c
+@@ -1335,153 +1335,6 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
+ return TRUE;
+ }
+
+-static gboolean
+-_cogl_texture_2d_sliced_download_from_gl (
+- CoglTexture2DSliced *tex_2ds,
+- CoglBitmap *target_bmp,
+- GLuint target_gl_format,
+- GLuint target_gl_type)
+-{
+- CoglSpan *x_span;
+- CoglSpan *y_span;
+- CoglHandle slice_tex;
+- int bpp;
+- int x, y;
+- CoglBitmap *slice_bmp;
+- CoglPixelFormat target_format = _cogl_bitmap_get_format (target_bmp);
+-
+- bpp = _cogl_get_format_bpp (target_format);
+-
+- /* Iterate vertical slices */
+- for (y = 0; y < tex_2ds->slice_y_spans->len; ++y)
+- {
+- y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y);
+-
+- /* Iterate horizontal slices */
+- for (x = 0; x < tex_2ds->slice_x_spans->len; ++x)
+- {
+- /*if (x != 0 || y != 1) continue;*/
+- x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x);
+-
+- /* Pick the sliced texture */
+- slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle,
+- y * tex_2ds->slice_x_spans->len + x);
+-
+- /* If there's any waste we need to copy manually
+- (no glGetTexSubImage) */
+-
+- if (y_span->waste != 0 || x_span->waste != 0)
+- {
+- int rowstride = x_span->size * bpp;
+- guint8 *data = g_malloc (rowstride * y_span->size);
+-
+- /* Setup temp bitmap for slice subregion */
+- slice_bmp = _cogl_bitmap_new_from_data (data,
+- target_format,
+- x_span->size,
+- y_span->size,
+- rowstride,
+- (CoglBitmapDestroyNotify)
+- g_free,
+- NULL);
+-
+- /* Setup gl alignment to 0,0 top-left corner */
+- _cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp);
+-
+- if (!cogl_texture_get_data (slice_tex,
+- target_format,
+- rowstride,
+- data))
+- {
+- /* Free temp bitmap */
+- cogl_object_unref (slice_bmp);
+- return FALSE;
+- }
+-
+- /* Copy portion of slice from temp to target bmp */
+- _cogl_bitmap_copy_subregion (slice_bmp,
+- target_bmp,
+- 0, 0,
+- x_span->start,
+- y_span->start,
+- x_span->size - x_span->waste,
+- y_span->size - y_span->waste);
+- /* Free temp bitmap */
+- cogl_object_unref (slice_bmp);
+- }
+- else
+- {
+- guint8 *data;
+- GLvoid *dst;
+- gboolean ret;
+- int rowstride = _cogl_bitmap_get_rowstride (target_bmp);
+-
+- data = _cogl_bitmap_map (target_bmp,
+- COGL_BUFFER_ACCESS_WRITE,
+- 0);
+- if (data == NULL)
+- return FALSE;
+-
+- dst = data + x_span->start * bpp + y_span->start * rowstride;
+-
+- _cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp);
+-
+- /* Download slice image data */
+- ret = cogl_texture_get_data (slice_tex,
+- target_format,
+- rowstride,
+- dst);
+-
+- _cogl_bitmap_unmap (target_bmp);
+-
+- if (!ret)
+- return ret;
+- }
+- }
+- }
+-
+- return TRUE;
+-}
+-
+-static gboolean
+-_cogl_texture_2d_sliced_get_data (CoglTexture *tex,
+- CoglPixelFormat format,
+- unsigned int rowstride,
+- guint8 *data)
+-{
+- CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
+- int bpp;
+- GLenum gl_format;
+- GLenum gl_type;
+- CoglBitmap *target_bmp;
+- gboolean ret;
+-
+- bpp = _cogl_get_format_bpp (format);
+-
+- _cogl_pixel_format_to_gl (format,
+- NULL, /* internal format */
+- &gl_format,
+- &gl_type);
+-
+- target_bmp = _cogl_bitmap_new_from_data (data,
+- format,
+- tex_2ds->width,
+- tex_2ds->height,
+- rowstride,
+- NULL, /* destroy_fn */
+- NULL /* destroy_fn_data */);
+-
+- /* Retrieve data from slices */
+- ret = _cogl_texture_2d_sliced_download_from_gl (tex_2ds,
+- target_bmp,
+- gl_format,
+- gl_type);
+-
+- cogl_object_unref (target_bmp);
+-
+- return ret;
+-}
+-
+ static CoglPixelFormat
+ _cogl_texture_2d_sliced_get_format (CoglTexture *tex)
+ {
+@@ -1528,7 +1381,7 @@ static const CoglTextureVtable
+ cogl_texture_2d_sliced_vtable =
+ {
+ _cogl_texture_2d_sliced_set_region,
+- _cogl_texture_2d_sliced_get_data,
++ NULL, /* get_data */
+ _cogl_texture_2d_sliced_foreach_sub_texture_in_region,
+ _cogl_texture_2d_sliced_get_max_waste,
+ _cogl_texture_2d_sliced_is_sliced,
+diff --git a/clutter/cogl/cogl/cogl-texture.c b/clutter/cogl/cogl/cogl-texture.c
+index c4f40a1..58d96cf 100644
+--- a/clutter/cogl/cogl/cogl-texture.c
++++ b/clutter/cogl/cogl/cogl-texture.c
+@@ -4,6 +4,7 @@
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2007,2008,2009 Intel Corporation.
++ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+@@ -37,6 +38,7 @@
+ #include "cogl-bitmap-private.h"
+ #include "cogl-buffer-private.h"
+ #include "cogl-pixel-array-private.h"
++#include "cogl-private.h"
+ #include "cogl-texture-private.h"
+ #include "cogl-texture-driver.h"
+ #include "cogl-texture-2d-sliced-private.h"
+@@ -1181,6 +1183,169 @@ _cogl_texture_draw_and_read (CoglHandle handle,
+ return TRUE;
+ }
+
++static gboolean
++get_texture_bits_via_offscreen (CoglHandle texture_handle,
++ int x,
++ int y,
++ int width,
++ int height,
++ guint8 *dst_bits,
++ unsigned int dst_rowstride,
++ CoglPixelFormat dst_format)
++{
++ CoglFramebuffer *framebuffer;
++
++ _COGL_GET_CONTEXT (ctx, FALSE);
++
++ if (!cogl_features_available (COGL_FEATURE_OFFSCREEN))
++ return FALSE;
++
++ framebuffer =
++ _cogl_offscreen_new_to_texture_full (texture_handle,
++ COGL_OFFSCREEN_DISABLE_DEPTH_STENCIL,
++ 0);
++
++ if (framebuffer == NULL)
++ return FALSE;
++
++ cogl_push_framebuffer (framebuffer);
++
++ _cogl_read_pixels_full (x, y, width, height,
++ COGL_READ_PIXELS_COLOR_BUFFER,
++ dst_format, dst_bits, dst_rowstride);
++
++ cogl_pop_framebuffer ();
++
++ cogl_object_unref (framebuffer);
++
++ return TRUE;
++}
++
++static gboolean
++get_texture_bits_via_copy (CoglHandle texture_handle,
++ int x,
++ int y,
++ int width,
++ int height,
++ guint8 *dst_bits,
++ unsigned int dst_rowstride,
++ CoglPixelFormat dst_format)
++{
++ CoglTexture *tex = COGL_TEXTURE (texture_handle);
++ unsigned int full_rowstride;
++ guint8 *full_bits;
++ gboolean ret = TRUE;
++ int bpp;
++ int full_tex_width, full_tex_height;
++
++ full_tex_width = cogl_texture_get_width (texture_handle);
++ full_tex_height = cogl_texture_get_height (texture_handle);
++
++ bpp = _cogl_get_format_bpp (dst_format);
++
++ full_rowstride = bpp * full_tex_width;
++ full_bits = g_malloc (full_rowstride * full_tex_height);
++
++ if (tex->vtable->get_data (tex,
++ dst_format,
++ full_rowstride,
++ full_bits))
++ {
++ guint8 *dst = dst_bits;
++ guint8 *src = full_bits + x * bpp + y * full_rowstride;
++ int i;
++
++ for (i = 0; i < height; i++)
++ {
++ memcpy (dst, src, bpp * width);
++ dst += dst_rowstride;
++ src += full_rowstride;
++ }
++ }
++ else
++ ret = FALSE;
++
++ g_free (full_bits);
++
++ return ret;
++}
++
++typedef struct
++{
++ int orig_width;
++ int orig_height;
++ CoglBitmap *target_bmp;
++ guint8 *target_bits;
++ gboolean success;
++} CoglTextureGetData;
++
++static void
++texture_get_cb (CoglHandle texture_handle,
++ const float *subtexture_coords,
++ const float *virtual_coords,
++ void *user_data)
++{
++ CoglTexture *tex = COGL_TEXTURE (texture_handle);
++ CoglTextureGetData *tg_data = user_data;
++ CoglPixelFormat format = _cogl_bitmap_get_format (tg_data->target_bmp);
++ int bpp = _cogl_get_format_bpp (format);
++ unsigned int rowstride = _cogl_bitmap_get_rowstride (tg_data->target_bmp);
++ int subtexture_width = cogl_texture_get_width (texture_handle);
++ int subtexture_height = cogl_texture_get_height (texture_handle);
++
++ int x_in_subtexture = (int) (0.5 + subtexture_width * subtexture_coords[0]);
++ int y_in_subtexture = (int) (0.5 + subtexture_height * subtexture_coords[1]);
++ int width = ((int) (0.5 + subtexture_width * subtexture_coords[2])
++ - x_in_subtexture);
++ int height = ((int) (0.5 + subtexture_height * subtexture_coords[3])
++ - y_in_subtexture);
++ int x_in_bitmap = (int) (0.5 + tg_data->orig_width * virtual_coords[0]);
++ int y_in_bitmap = (int) (0.5 + tg_data->orig_height * virtual_coords[1]);
++
++ guint8 *dst_bits;
++
++ if (!tg_data->success)
++ return;
++
++ dst_bits = tg_data->target_bits + x_in_bitmap * bpp + y_in_bitmap * rowstride;
++
++ /* If we can read everything as a single slice, then go ahead and do that
++ * to avoid allocating an FBO. We'll leave it up to the GL implementation to
++ * do glGetTexImage as efficiently as possible. (GLES doesn't have that,
++ * so we'll fall through) */
++ if (x_in_subtexture == 0 && y_in_subtexture == 0 &&
++ width == subtexture_width && height == subtexture_height)
++ {
++ if (tex->vtable->get_data (tex,
++ format,
++ rowstride,
++ dst_bits))
++ return;
++ }
++
++ /* Next best option is a FBO and glReadPixels */
++ if (get_texture_bits_via_offscreen (texture_handle,
++ x_in_subtexture, y_in_subtexture,
++ width, height,
++ dst_bits,
++ rowstride,
++ format))
++ return;
++
++ /* Getting ugly: read the entire texture, copy out the part we want */
++ if (get_texture_bits_via_copy (texture_handle,
++ x_in_subtexture, y_in_subtexture,
++ width, height,
++ dst_bits,
++ rowstride,
++ format))
++ return;
++
++ /* No luck, the caller will fall back to the draw-to-backbuffer and
++ * read implementation */
++ tg_data->success = FALSE;
++}
++
+ int
+ cogl_texture_get_data (CoglHandle handle,
+ CoglPixelFormat format,
+@@ -1196,13 +1361,14 @@ cogl_texture_get_data (CoglHandle handle,
+ GLenum closest_gl_type;
+ CoglBitmap *target_bmp;
+ CoglBitmap *new_bmp;
+- gboolean success;
+ guint8 *src;
+ guint8 *dst;
+ int y;
+ int tex_width;
+ int tex_height;
+
++ CoglTextureGetData tg_data;
++
+ if (!cogl_is_texture (handle))
+ return 0;
+
+@@ -1253,17 +1419,26 @@ cogl_texture_get_data (CoglHandle handle,
+ NULL);
+ }
+
+- if ((dst = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE,
+- COGL_BUFFER_MAP_HINT_DISCARD)) == NULL)
++ tg_data.orig_width = tex_width;
++ tg_data.orig_height = tex_height;
++ tg_data.target_bmp = target_bmp;
++ tg_data.target_bits = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE,
++ COGL_BUFFER_MAP_HINT_DISCARD);
++ if (tg_data.target_bits == NULL)
+ {
+ cogl_object_unref (target_bmp);
+ return 0;
+ }
++ tg_data.success = TRUE;
+
+- success = tex->vtable->get_data (tex,
+- closest_format,
+- rowstride,
+- dst);
++ /* Iterating through the subtextures allows piecing together
++ * 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 (handle,
++ 0, 0, 1, 1,
++ texture_get_cb,
++ &tg_data);
+
+ _cogl_bitmap_unmap (target_bmp);
+
+@@ -1271,7 +1446,7 @@ cogl_texture_get_data (CoglHandle handle,
+ * to read back the texture data; such as for GLES which doesn't
+ * support glGetTexImage, so here we fallback to drawing the
+ * texture and reading the pixels from the framebuffer. */
+- if (!success)
++ if (!tg_data.success)
+ _cogl_texture_draw_and_read (tex, target_bmp,
+ closest_gl_format,
+ closest_gl_type);
+--
+1.7.3.16.g9464b \ No newline at end of file
diff --git a/media-libs/clutter/files/clutter-9999-perfneu6.patch b/media-libs/clutter/files/clutter-9999-perfneu6.patch
new file mode 100644
index 0000000..c579968
--- /dev/null
+++ b/media-libs/clutter/files/clutter-9999-perfneu6.patch
@@ -0,0 +1,96 @@
+From 13e13619f96b8840c24fe349799aaf8d87b065f5 Mon Sep 17 00:00:00 2001
+From: Neil Roberts <neil@linux.intel.com>
+Date: Wed, 17 Nov 2010 17:31:23 +0000
+Subject: [PATCH] test-cogl-texture-get-set-data: Test the alpha component
+
+Previously the alpha component of the test texture data was always set
+to 255 and the data was read back as RGB so that the alpha component
+is ignored. Now the alpha component is set to a generated value and
+the data is read back a second time as RGBA to verify that Cogl is not
+doing any premult conversions when the internal texture and target
+data is the same.
+
+http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
+---
+ tests/conform/test-cogl-texture-get-set-data.c | 39 ++++++++++++++++++++++--
+ 1 files changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/tests/conform/test-cogl-texture-get-set-data.c b/tests/conform/test-cogl-texture-get-set-data.c
+index 84206ff..26ba058 100644
+--- a/tests/conform/test-cogl-texture-get-set-data.c
++++ b/tests/conform/test-cogl-texture-get-set-data.c
+@@ -18,7 +18,7 @@ check_texture (int width, int height, CoglTextureFlags flags)
+ *(p++) = x;
+ *(p++) = y;
+ *(p++) = 128;
+- *(p++) = 255;
++ *(p++) = (x ^ y);
+ }
+
+ tex = cogl_texture_new_from_data (width, height,
+@@ -38,6 +38,7 @@ check_texture (int width, int height, CoglTextureFlags flags)
+ p[0] = ~p[0];
+ p[1] = ~p[1];
+ p[2] = ~p[2];
++ p[3] = ~p[3];
+ p += 4;
+ }
+ p += width * 2;
+@@ -55,14 +56,16 @@ check_texture (int width, int height, CoglTextureFlags flags)
+ width * 4, /* rowstride */
+ data);
+
+- memset (data, 0, width * height * 4);
+-
+ /* Check passing a NULL pointer and a zero rowstride. The texture
+ should calculate the needed data size and return it */
+ g_assert_cmpint (cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_ANY, 0, NULL),
+ ==,
+ width * height * 4);
+
++ /* Try first receiving the data as RGB. This should cause a
++ * conversion */
++ memset (data, 0, width * height * 4);
++
+ cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGB_888,
+ width * 3, data);
+
+@@ -86,6 +89,36 @@ check_texture (int width, int height, CoglTextureFlags flags)
+ p += 3;
+ }
+
++ /* Now try receiving the data as RGBA. This should not cause a
++ * conversion and no unpremultiplication because we explicitly set
++ * the internal format when we created the texture */
++ memset (data, 0, width * height * 4);
++
++ cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGBA_8888,
++ width * 4, data);
++
++ p = data;
++
++ for (y = 0; y < height; y++)
++ for (x = 0; x < width; x++)
++ {
++ if (x >= width / 2 && y >= height / 2)
++ {
++ g_assert_cmpint (p[0], ==, ~x & 0xff);
++ g_assert_cmpint (p[1], ==, ~y & 0xff);
++ g_assert_cmpint (p[2], ==, ~128 & 0xff);
++ g_assert_cmpint (p[3], ==, ~(x ^ y) & 0xff);
++ }
++ else
++ {
++ g_assert_cmpint (p[0], ==, x & 0xff);
++ g_assert_cmpint (p[1], ==, y & 0xff);
++ g_assert_cmpint (p[2], ==, 128);
++ g_assert_cmpint (p[3], ==, (x ^ y) & 0xff);
++ }
++ p += 4;
++ }
++
+ cogl_handle_unref (tex);
+ g_free (data);
+ }
+--
+1.7.3.16.g9464b \ No newline at end of file