From ab76ece17976d8c9ec7b7876b91a0c89bf37c465 Mon Sep 17 00:00:00 2001 From: Andreas Proschofsky Date: Sat, 20 Nov 2010 18:38:34 +0000 Subject: New clutter release with some extra performance patches svn path=/; revision=317 --- media-libs/clutter/Manifest | 10 +- media-libs/clutter/clutter-1.5.4.ebuild | 83 --- media-libs/clutter/clutter-1.5.6.ebuild | 93 ++++ .../clutter/files/clutter-9999-perfneu1.patch | 248 +++++++++ .../clutter/files/clutter-9999-perfneu2.patch | 123 +++++ .../clutter/files/clutter-9999-perfneu3.patch | 30 ++ .../clutter/files/clutter-9999-perfneu4.patch | 128 +++++ .../clutter/files/clutter-9999-perfneu5.patch | 566 +++++++++++++++++++++ .../clutter/files/clutter-9999-perfneu6.patch | 96 ++++ 9 files changed, 1292 insertions(+), 85 deletions(-) delete mode 100644 media-libs/clutter/clutter-1.5.4.ebuild create mode 100644 media-libs/clutter/clutter-1.5.6.ebuild create mode 100644 media-libs/clutter/files/clutter-9999-perfneu1.patch create mode 100644 media-libs/clutter/files/clutter-9999-perfneu2.patch create mode 100644 media-libs/clutter/files/clutter-9999-perfneu3.patch create mode 100644 media-libs/clutter/files/clutter-9999-perfneu4.patch create mode 100644 media-libs/clutter/files/clutter-9999-perfneu5.patch create mode 100644 media-libs/clutter/files/clutter-9999-perfneu6.patch 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.4.ebuild deleted file mode 100644 index 793c0e0..0000000 --- a/media-libs/clutter/clutter-1.5.4.ebuild +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 1999-2010 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI="2" - -inherit clutter - -DESCRIPTION="Clutter is a library for creating graphical user interfaces" - -SLOT="1.0" -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 - >=x11-libs/pango-1.20[introspection?] - >=dev-libs/json-glib-0.10[introspection?] - >=dev-libs/atk-1.7 - - virtual/opengl - x11-libs/libdrm - x11-libs/libX11 - x11-libs/libXext - x11-libs/libXdamage - x11-libs/libXi - x11-proto/inputproto - >=x11-libs/libXfixes-3 - >=x11-libs/libXcomposite-0.4 - - gtk? ( || ( - x11-libs/gdk-pixbuf - >=x11-libs/gtk+-2.0 ) ) - introspection? ( >=dev-libs/gobject-introspection-0.9.6 ) -" -DEPEND="${RDEPEND} - sys-devel/gettext - dev-util/pkgconfig - >=dev-util/gtk-doc-am-1.13 - doc? ( - >=dev-util/gtk-doc-1.13 - >=app-text/docbook-sgml-utils-0.6.14[jadetex] - dev-libs/libxslt ) -" - -src_configure() { - # We only need conformance tests, the rest are useless for us -# sed -e 's/^\(SUBDIRS =\).*/\1/g' \ -# -i tests/Makefile.{am,in} || die "tests sed failed" - - # XXX: Conformance test suite (and clutter itself) does not work under Xvfb - # XXX: Profiling, coverage disabled for now - # XXX: What do we do about eglx/eglnative/opengl-egl-xlib/osx/etc flavours? - local myconf=" - --enable-debug=minimum - --enable-cogl-debug=minimum - --enable-conformance=no - --disable-gcov - --enable-profile=no - --enable-maintainer-flags=no - --enable-xinput - --with-flavour=glx - --with-imagebackend=gdk-pixbuf - $(use_enable introspection) - $(use_enable doc docs)" - - if ! use gtk; then - myconf="${myconf} --with-imagebackend=internal" - # Internal image backend is experimental - ewarn "You have selected the experimental internal image backend" - fi - - if use debug; then - myconf="${myconf} - --enable-debug=yes - --enable-cogl-debug=yes" - fi - - touch ${S}/TODO - - econf ${myconf} -} diff --git a/media-libs/clutter/clutter-1.5.6.ebuild b/media-libs/clutter/clutter-1.5.6.ebuild new file mode 100644 index 0000000..551c348 --- /dev/null +++ b/media-libs/clutter/clutter-1.5.6.ebuild @@ -0,0 +1,93 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit clutter + +DESCRIPTION="Clutter is a library for creating graphical user interfaces" + +SLOT="1.0" +KEYWORDS="~amd64 ~ppc64 ~x86" +IUSE="debug doc +gtk +introspection" + +# NOTE: glx flavour uses libdrm + >=mesa-7.3 +RDEPEND=">=dev-libs/glib-2.26 + >=x11-libs/cairo-1.10 + >=x11-libs/pango-1.20[introspection?] + >=dev-libs/json-glib-0.12[introspection?] + >=dev-libs/atk-1.7 + + virtual/opengl + x11-libs/libdrm + x11-libs/libX11 + x11-libs/libXext + x11-libs/libXdamage + x11-libs/libXi + x11-proto/inputproto + >=x11-libs/libXfixes-3 + >=x11-libs/libXcomposite-0.4 + + gtk? ( || ( + x11-libs/gdk-pixbuf + >=x11-libs/gtk+-2.0 ) ) + introspection? ( >=dev-libs/gobject-introspection-0.9.6 ) +" +DEPEND="${RDEPEND} + sys-devel/gettext + dev-util/pkgconfig + >=dev-util/gtk-doc-am-1.13 + doc? ( + >=dev-util/gtk-doc-1.13 + >=app-text/docbook-sgml-utils-0.6.14[jadetex] + 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' \ +# -i tests/Makefile.{am,in} || die "tests sed failed" + + # XXX: Conformance test suite (and clutter itself) does not work under Xvfb + # XXX: Profiling, coverage disabled for now + # XXX: What do we do about eglx/eglnative/opengl-egl-xlib/osx/etc flavours? + local myconf=" + --enable-debug=minimum + --enable-cogl-debug=minimum + --enable-conformance=no + --disable-gcov + --enable-profile=no + --enable-maintainer-flags=no + --enable-xinput + --with-flavour=glx + --with-imagebackend=gdk-pixbuf + $(use_enable introspection) + $(use_enable doc docs)" + + if ! use gtk; then + myconf="${myconf} --with-imagebackend=internal" + # Internal image backend is experimental + ewarn "You have selected the experimental internal image backend" + fi + + if use debug; then + myconf="${myconf} + --enable-debug=yes + --enable-cogl-debug=yes" + fi + + touch ${S}/TODO + + econf ${myconf} +} 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 +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 +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 +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 +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 +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 +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 -- cgit v1.2.3-65-gdbad