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
This commit is contained in:
Neil Roberts 2010-11-17 15:38:20 +00:00
parent 05d8cc1223
commit e41e5efac0
2 changed files with 38 additions and 11 deletions

View File

@ -29,6 +29,16 @@ G_BEGIN_DECLS
void void
_cogl_clear (const CoglColor *color, unsigned long buffers); _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 G_END_DECLS
#endif /* __COGL_PRIVATE_H__ */ #endif /* __COGL_PRIVATE_H__ */

View File

@ -556,13 +556,14 @@ cogl_flush (void)
} }
void void
cogl_read_pixels (int x, _cogl_read_pixels_with_rowstride (int x,
int y, int y,
int width, int width,
int height, int height,
CoglReadPixelsFlags source, CoglReadPixelsFlags source,
CoglPixelFormat format, CoglPixelFormat format,
guint8 *pixels) guint8 *pixels,
int rowstride)
{ {
CoglFramebuffer *framebuffer; CoglFramebuffer *framebuffer;
int framebuffer_height; int framebuffer_height;
@ -572,7 +573,6 @@ cogl_read_pixels (int x,
GLenum gl_format; GLenum gl_format;
GLenum gl_type; GLenum gl_type;
CoglPixelFormat bmp_format; CoglPixelFormat bmp_format;
int rowstride;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -599,7 +599,6 @@ cogl_read_pixels (int x,
/* Initialise the CoglBitmap */ /* Initialise the CoglBitmap */
bpp = _cogl_get_format_bpp (format); bpp = _cogl_get_format_bpp (format);
rowstride = bpp * width;
bmp_format = format; bmp_format = format;
if ((format & COGL_A_BIT)) 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 to be more clever and check if the requested type matches that
but we would need some reliable functions to convert from GL but we would need some reliable functions to convert from GL
types to Cogl types. For now, lets just always read in 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 #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; CoglBitmap *tmp_bmp, *dst_bmp;
guint8 *tmp_data = g_malloc (width * height * 4); guint8 *tmp_data = g_malloc (width * height * 4);
@ -711,6 +713,21 @@ cogl_read_pixels (int x,
cogl_object_unref (bmp); 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 static void
_cogl_disable_other_texcoord_arrays_cb (int texcoord_array_num, gpointer data) _cogl_disable_other_texcoord_arrays_cb (int texcoord_array_num, gpointer data)
{ {