From 91c16023066b3d71ed569e0dcb97bdd0fe8b4667 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Fri, 17 Dec 2010 14:52:25 +0000 Subject: [PATCH] cogl-texture: Don't use the source rowstride if we have to copy bitmap If we have to copy the bitmap to do the premultiplication then we were previously using the rowstride of the source image as the rowstride for the new image. This is wasteful if the source image is a subregion of a larger image which would make it use a large rowstride. If we have to copy the data anyway we might as well compact it to the smallest rowstride. This also prevents the copy from reading past the end of the last row of pixels. An internal function called _cogl_bitmap_copy has been added to do the copy. It creates a new bitmap with the smallest possible rowstride rounded up the nearest multiple of 4 bytes. There may be other places in Cogl that are currently assuming we can read height*rowstride of the source buffer so they may want to take advantage of this function too. http://bugzilla.clutter-project.org/show_bug.cgi?id=2491 --- clutter/cogl/cogl/cogl-bitmap-private.h | 4 ++++ clutter/cogl/cogl/cogl-bitmap.c | 29 +++++++++++++++++++++++++ clutter/cogl/cogl/cogl-texture.c | 22 +------------------ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/clutter/cogl/cogl/cogl-bitmap-private.h b/clutter/cogl/cogl/cogl-bitmap-private.h index d14293fad..bf21a5732 100644 --- a/clutter/cogl/cogl/cogl-bitmap-private.h +++ b/clutter/cogl/cogl/cogl-bitmap-private.h @@ -155,6 +155,10 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, int width, int height); +/* Creates a deep copy of the source bitmap */ +CoglBitmap * +_cogl_bitmap_copy (CoglBitmap *src_bmp); + gboolean _cogl_bitmap_get_size_from_file (const char *filename, int *width, diff --git a/clutter/cogl/cogl/cogl-bitmap.c b/clutter/cogl/cogl/cogl-bitmap.c index 355a2a253..cc83dda72 100644 --- a/clutter/cogl/cogl/cogl-bitmap.c +++ b/clutter/cogl/cogl/cogl-bitmap.c @@ -181,6 +181,35 @@ _cogl_bitmap_convert_format_and_premult (CoglBitmap *bmp, return dst_bmp; } +CoglBitmap * +_cogl_bitmap_copy (CoglBitmap *src_bmp) +{ + CoglBitmap *dst_bmp; + CoglPixelFormat src_format = _cogl_bitmap_get_format (src_bmp); + int bpp = _cogl_get_format_bpp (src_format); + int width = _cogl_bitmap_get_width (src_bmp); + int height = _cogl_bitmap_get_height (src_bmp); + int dst_rowstride = width * bpp; + + /* Round the rowstride up to the next nearest multiple of 4 bytes */ + dst_rowstride = (dst_rowstride + 3) & ~3; + + dst_bmp = _cogl_bitmap_new_from_data (g_malloc (dst_rowstride * height), + src_format, + width, height, + dst_rowstride, + (CoglBitmapDestroyNotify) g_free, + NULL); + + _cogl_bitmap_copy_subregion (src_bmp, + dst_bmp, + 0, 0, /* src_x/y */ + 0, 0, /* dst_x/y */ + width, height); + + return dst_bmp; +} + void _cogl_bitmap_copy_subregion (CoglBitmap *src, CoglBitmap *dst, diff --git a/clutter/cogl/cogl/cogl-texture.c b/clutter/cogl/cogl/cogl-texture.c index 15835aba7..bedde9091 100644 --- a/clutter/cogl/cogl/cogl-texture.c +++ b/clutter/cogl/cogl/cogl-texture.c @@ -184,27 +184,7 @@ _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp, if (_cogl_texture_needs_premult_conversion (src_format, dst_format)) { - guint8 *src_data; - guint8 *dst_data; - - if ((src_data = _cogl_bitmap_map (src_bmp, - COGL_BUFFER_ACCESS_READ, 0)) == NULL) - return NULL; - - dst_data = g_memdup (src_data, - _cogl_bitmap_get_height (src_bmp) * - _cogl_bitmap_get_rowstride (src_bmp)); - - _cogl_bitmap_unmap (src_bmp); - - dst_bmp = - _cogl_bitmap_new_from_data (dst_data, - src_format, - _cogl_bitmap_get_width (src_bmp), - _cogl_bitmap_get_height (src_bmp), - _cogl_bitmap_get_rowstride (src_bmp), - (CoglBitmapDestroyNotify) g_free, - NULL); + dst_bmp = _cogl_bitmap_copy (src_bmp); if (!_cogl_bitmap_convert_premult_status (dst_bmp, src_format ^