mirror of
https://github.com/brl/mutter.git
synced 2025-03-31 15:43:48 +00:00
texture: When reading, convert data directly into user's buffer
On GLES, when reading texture data back it may need to allocate a temporary CoglBitmap if the requested format is not supported by the driver. Previously it would then copy this temporary buffer back into the user's buffer by calling _cogl_bitmap_convert which would allocate a second temporary buffer. It would then copy that data into the user's buffer. This patch changes it to create a CoglBitmap which points to the user's data and then convert directly into that buffer using the new _cogl_bitmap_convert_into_bitmap. This also fixes a small leak where target_bmp would not get freed if the target format and the closest supported format do match. Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
parent
de5d55ae93
commit
f65a895b4f
@ -1129,10 +1129,6 @@ cogl_texture_get_data (CoglTexture *texture,
|
|||||||
GLenum closest_gl_format;
|
GLenum closest_gl_format;
|
||||||
GLenum closest_gl_type;
|
GLenum closest_gl_type;
|
||||||
CoglBitmap *target_bmp;
|
CoglBitmap *target_bmp;
|
||||||
CoglBitmap *new_bmp;
|
|
||||||
guint8 *src;
|
|
||||||
guint8 *dst;
|
|
||||||
int y;
|
|
||||||
int tex_width;
|
int tex_width;
|
||||||
int tex_height;
|
int tex_height;
|
||||||
CoglPixelFormat texture_format;
|
CoglPixelFormat texture_format;
|
||||||
@ -1236,42 +1232,27 @@ cogl_texture_get_data (CoglTexture *texture,
|
|||||||
/* Was intermediate used? */
|
/* Was intermediate used? */
|
||||||
if (closest_format != format)
|
if (closest_format != format)
|
||||||
{
|
{
|
||||||
guint8 *new_bmp_data;
|
CoglBitmap *new_bmp;
|
||||||
int new_bmp_rowstride;
|
gboolean result;
|
||||||
|
|
||||||
/* Convert to requested format */
|
/* Convert to requested format directly into the user's buffer */
|
||||||
new_bmp = _cogl_bitmap_convert (target_bmp, format);
|
new_bmp = _cogl_bitmap_new_from_data (data,
|
||||||
|
format,
|
||||||
|
tex_width, tex_height,
|
||||||
|
rowstride,
|
||||||
|
NULL, /* destroy_fn */
|
||||||
|
NULL /* destroy_fn_data */);
|
||||||
|
result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
/* Return failure after cleaning up */
|
||||||
|
byte_size = 0;
|
||||||
|
|
||||||
|
cogl_object_unref (new_bmp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free intermediate data and return if failed */
|
|
||||||
cogl_object_unref (target_bmp);
|
cogl_object_unref (target_bmp);
|
||||||
|
|
||||||
if (new_bmp == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
new_bmp_rowstride = cogl_bitmap_get_rowstride (new_bmp);
|
|
||||||
new_bmp_data = _cogl_bitmap_map (new_bmp, COGL_BUFFER_ACCESS_WRITE,
|
|
||||||
COGL_BUFFER_MAP_HINT_DISCARD);
|
|
||||||
|
|
||||||
if (new_bmp_data == NULL)
|
|
||||||
{
|
|
||||||
cogl_object_unref (new_bmp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy to user buffer */
|
|
||||||
for (y = 0; y < tex_height; ++y)
|
|
||||||
{
|
|
||||||
src = new_bmp_data + y * new_bmp_rowstride;
|
|
||||||
dst = data + y * rowstride;
|
|
||||||
memcpy (dst, src, tex_width * bpp);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cogl_bitmap_unmap (new_bmp);
|
|
||||||
|
|
||||||
/* Free converted data */
|
|
||||||
cogl_object_unref (new_bmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return byte_size;
|
return byte_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user