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
1 changed files with 15 additions and 34 deletions
|
@ -1129,10 +1129,6 @@ cogl_texture_get_data (CoglTexture *texture,
|
|||
GLenum closest_gl_format;
|
||||
GLenum closest_gl_type;
|
||||
CoglBitmap *target_bmp;
|
||||
CoglBitmap *new_bmp;
|
||||
guint8 *src;
|
||||
guint8 *dst;
|
||||
int y;
|
||||
int tex_width;
|
||||
int tex_height;
|
||||
CoglPixelFormat texture_format;
|
||||
|
@ -1236,42 +1232,27 @@ cogl_texture_get_data (CoglTexture *texture,
|
|||
/* Was intermediate used? */
|
||||
if (closest_format != format)
|
||||
{
|
||||
guint8 *new_bmp_data;
|
||||
int new_bmp_rowstride;
|
||||
CoglBitmap *new_bmp;
|
||||
gboolean result;
|
||||
|
||||
/* Convert to requested format */
|
||||
new_bmp = _cogl_bitmap_convert (target_bmp, format);
|
||||
/* Convert to requested format directly into the user's buffer */
|
||||
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);
|
||||
|
||||
/* Free intermediate data and return if failed */
|
||||
cogl_object_unref (target_bmp);
|
||||
if (!result)
|
||||
/* Return failure after cleaning up */
|
||||
byte_size = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
cogl_object_unref (target_bmp);
|
||||
|
||||
return byte_size;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue