From e41e5efac087baf14e2dcd500840ccb27a9a037f 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_with_rowstride 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 --- cogl/cogl-private.h | 10 ++++++++++ cogl/cogl.c | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/cogl/cogl-private.h b/cogl/cogl-private.h index c2f6947ac..afcfe4693 100644 --- a/cogl/cogl-private.h +++ b/cogl/cogl-private.h @@ -29,6 +29,16 @@ G_BEGIN_DECLS void _cogl_clear (const CoglColor *color, unsigned long buffers); +void +_cogl_read_pixels_with_rowstride (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/cogl/cogl.c b/cogl/cogl.c index b1882ef80..0dd4156b5 100644 --- a/cogl/cogl.c +++ b/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_with_rowstride (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_with_rowstride (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) {