[cogl] Add a public cogl_bitmap_new_for_data
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl] Add a public cogl_bitmap_new_for_data
- Date: Wed, 14 Mar 2012 13:50:13 +0000 (UTC)
commit d18b59d9e67f6ec2dd747da91d8c1380e1730d3e
Author: Neil Roberts <neil linux intel com>
Date: Tue Mar 13 14:46:18 2012 +0000
Add a public cogl_bitmap_new_for_data
This creates a CoglBitmap which points into an existing buffer in
system memory. That way it can be used to create a texture or to read
pixel data into. The function replaces the existing internal function
_cogl_bitmap_new_from_data but removes the destroy notify call back.
If the application wants notification of destruction it can just use
the cogl_object_set_user_data function as normal. Internally there is
now a convenience function to create a bitmap for system memory and
automatically free the buffer using that mechanism.
The name of the function is inspired by
cairo_image_surface_create_for_data which has similar semantics.
Reviewed-by: Robert Bragg <robert linux intel com>
cogl/cogl-atlas.c | 18 ++--
cogl/cogl-bitmap-conversion.c | 22 ++---
cogl/cogl-bitmap-pixbuf.c | 32 ++++---
cogl/cogl-bitmap-private.h | 48 ++++-------
cogl/cogl-bitmap.c | 94 +++++++++++--------
cogl/cogl-bitmap.h | 28 ++++++
cogl/cogl-context.c | 18 +++--
cogl/cogl-framebuffer.c | 20 +++--
cogl/cogl-texture-2d-sliced.c | 32 +++----
cogl/cogl-texture-2d.c | 11 +--
cogl/cogl-texture-3d.c | 45 ++++++----
cogl/cogl-texture.c | 129 +++++++++++---------------
cogl/cogl.c | 13 ++--
cogl/driver/gles/cogl-texture-driver-gles.c | 30 +++----
14 files changed, 276 insertions(+), 264 deletions(-)
---
diff --git a/cogl/cogl-atlas.c b/cogl/cogl-atlas.c
index 2a4e06e..bfa76dc 100644
--- a/cogl/cogl-atlas.c
+++ b/cogl/cogl-atlas.c
@@ -272,6 +272,8 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
{
CoglHandle tex;
+ _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
+
if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE))
{
guint8 *clear_data;
@@ -280,22 +282,22 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
/* Create a buffer of zeroes to initially clear the texture */
clear_data = g_malloc0 (width * height * bpp);
- clear_bmp = _cogl_bitmap_new_from_data (clear_data,
- atlas->texture_format,
- width,
- height,
- width * bpp,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ clear_bmp = cogl_bitmap_new_for_data (ctx,
+ width,
+ height,
+ atlas->texture_format,
+ width * bpp,
+ clear_data);
tex = _cogl_texture_2d_new_from_bitmap (clear_bmp, COGL_TEXTURE_NONE,
atlas->texture_format,
NULL);
cogl_object_unref (clear_bmp);
+
+ g_free (clear_data);
}
else
{
- _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
tex = cogl_texture_2d_new_with_size (ctx,
width, height,
atlas->texture_format,
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 64ce8cc..6a57dbf 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -27,6 +27,7 @@
#include "cogl-private.h"
#include "cogl-bitmap-private.h"
+#include "cogl-context-private.h"
#include <string.h>
@@ -470,26 +471,17 @@ CoglBitmap *
_cogl_bitmap_convert (CoglBitmap *src_bmp,
CoglPixelFormat dst_format)
{
- int dst_bpp;
- int dst_rowstride;
- guint8 *dst_data;
CoglBitmap *dst_bmp;
int width, height;
+ _COGL_GET_CONTEXT (ctx, NULL);
+
width = cogl_bitmap_get_width (src_bmp);
height = cogl_bitmap_get_height (src_bmp);
- dst_bpp = _cogl_pixel_format_get_bytes_per_pixel (dst_format);
- dst_rowstride = (sizeof (guint8) * dst_bpp * width + 3) & ~3;
-
- /* Allocate a new buffer to hold converted data */
- dst_data = g_malloc (height * dst_rowstride);
-
- dst_bmp = _cogl_bitmap_new_from_data (dst_data,
- dst_format,
- width, height,
- dst_rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+
+ dst_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
+ width, height,
+ dst_format);
if (!_cogl_bitmap_convert_into_bitmap (src_bmp, dst_bmp))
{
diff --git a/cogl/cogl-bitmap-pixbuf.c b/cogl/cogl-bitmap-pixbuf.c
index 3f56631..ada8e54 100644
--- a/cogl/cogl-bitmap-pixbuf.c
+++ b/cogl/cogl-bitmap-pixbuf.c
@@ -28,6 +28,7 @@
#include "cogl-util.h"
#include "cogl-internal.h"
#include "cogl-bitmap-private.h"
+#include "cogl-context-private.h"
#include <string.h>
@@ -166,17 +167,11 @@ _cogl_bitmap_get_size_from_file (const char *filename,
return FALSE;
}
-static void
-_cogl_bitmap_unref_pixbuf (guint8 *pixels,
- void *pixbuf)
-{
- g_object_unref (pixbuf);
-}
-
CoglBitmap *
_cogl_bitmap_from_file (const char *filename,
GError **error)
{
+ static CoglUserDataKey pixbuf_key;
GdkPixbuf *pixbuf;
gboolean has_alpha;
GdkColorspace color_space;
@@ -186,6 +181,9 @@ _cogl_bitmap_from_file (const char *filename,
int rowstride;
int bits_per_sample;
int n_channels;
+ CoglBitmap *bmp;
+
+ _COGL_GET_CONTEXT (ctx, NULL);
_COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, FALSE);
@@ -233,13 +231,19 @@ _cogl_bitmap_from_file (const char *filename,
to read past the end of bpp*width on the last row even if the
rowstride is much larger so we don't need to worry about
GdkPixbuf's semantics that it may under-allocate the buffer. */
- return _cogl_bitmap_new_from_data (gdk_pixbuf_get_pixels (pixbuf),
- pixel_format,
- width,
- height,
- rowstride,
- _cogl_bitmap_unref_pixbuf,
- pixbuf);
+ bmp = cogl_bitmap_new_for_data (ctx,
+ width,
+ height,
+ pixel_format,
+ rowstride,
+ gdk_pixbuf_get_pixels (pixbuf));
+
+ cogl_object_set_user_data (COGL_OBJECT (bmp),
+ &pixbuf_key,
+ pixbuf,
+ g_object_unref);
+
+ return bmp;
}
#else
diff --git a/cogl/cogl-bitmap-private.h b/cogl/cogl-bitmap-private.h
index ab80868..fc93406 100644
--- a/cogl/cogl-bitmap-private.h
+++ b/cogl/cogl-bitmap-private.h
@@ -33,43 +33,27 @@
#include "cogl-bitmap.h"
/*
- * CoglBitmapDestroyNotify:
- * @data: The image data
- * @destroy_data: The callback closure data that was given to
- * _cogl_bitmap_new_from_data().
+ * _cogl_bitmap_new_with_malloc_buffer:
+ * @context: A #CoglContext
+ * @width: width of the bitmap in pixels
+ * @height: height of the bitmap in pixels
+ * @format: the format of the pixels the array will store
*
- * Function prototype that is used to destroy the bitmap data when
- * _cogl_bitmap_new_from_data() is called.
- */
-typedef void (* CoglBitmapDestroyNotify) (guint8 *data, void *destroy_data);
-
-/*
- * _cogl_bitmap_new_from_data:
- * @data: A pointer to the data. The bitmap will take ownership of this data.
- * @format: The format of the pixel data.
- * @width: The width of the bitmap.
- * @height: The height of the bitmap.
- * @rowstride: The rowstride of the bitmap (the number of bytes from
- * the start of one row of the bitmap to the next).
- * @destroy_fn: A function to be called when the bitmap is
- * destroyed. This should free @data. %NULL can be used instead if
- * no free is needed.
- * @destroy_fn_data: This pointer will get passed to @destroy_fn.
+ * This is equivalent to cogl_bitmap_new_with_size() except that it
+ * allocated the buffer using g_malloc() instead of creating a
+ * #CoglPixelBuffer. The buffer will be automatically destroyed when
+ * the bitmap is freed.
*
- * Creates a bitmap using some existing data. The data is not copied
- * so the bitmap will take ownership of the data pointer. When the
- * bitmap is freed @destroy_fn will be called to free the data.
+ * Return value: a #CoglPixelBuffer representing the newly created array
*
- * Return value: A new %CoglBitmap.
+ * Since: 1.10
+ * Stability: Unstable
*/
CoglBitmap *
-_cogl_bitmap_new_from_data (guint8 *data,
- CoglPixelFormat format,
- int width,
- int height,
- int rowstride,
- CoglBitmapDestroyNotify destroy_fn,
- gpointer destroy_fn_data);
+_cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
+ unsigned int width,
+ unsigned int height,
+ CoglPixelFormat format);
/* The idea of this function is that it will create a bitmap that
shares the actual data with another bitmap. This is needed for the
diff --git a/cogl/cogl-bitmap.c b/cogl/cogl-bitmap.c
index 4d26305..b0c6ec7 100644
--- a/cogl/cogl-bitmap.c
+++ b/cogl/cogl-bitmap.c
@@ -31,6 +31,7 @@
#include "cogl-bitmap-private.h"
#include "cogl-buffer-private.h"
#include "cogl-pixel-buffer.h"
+#include "cogl-context-private.h"
#include <string.h>
@@ -43,8 +44,6 @@ struct _CoglBitmap
int rowstride;
guint8 *data;
- CoglBitmapDestroyNotify destroy_fn;
- void *destroy_fn_data;
gboolean mapped;
gboolean bound;
@@ -68,9 +67,6 @@ _cogl_bitmap_free (CoglBitmap *bmp)
g_assert (!bmp->mapped);
g_assert (!bmp->bound);
- if (bmp->destroy_fn)
- bmp->destroy_fn (bmp->data, bmp->destroy_fn_data);
-
if (bmp->shared_bmp)
cogl_object_unref (bmp->shared_bmp);
@@ -105,20 +101,15 @@ _cogl_bitmap_copy (CoglBitmap *src_bmp)
{
CoglBitmap *dst_bmp;
CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp);
- int bpp = _cogl_pixel_format_get_bytes_per_pixel (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;
+ _COGL_GET_CONTEXT (ctx, NULL);
- dst_bmp = _cogl_bitmap_new_from_data (g_malloc (dst_rowstride * height),
- src_format,
- width, height,
- dst_rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ dst_bmp =
+ _cogl_bitmap_new_with_malloc_buffer (ctx,
+ width, height,
+ src_format);
_cogl_bitmap_copy_subregion (src_bmp,
dst_bmp,
@@ -185,23 +176,23 @@ cogl_bitmap_get_size_from_file (const char *filename,
}
CoglBitmap *
-_cogl_bitmap_new_from_data (guint8 *data,
- CoglPixelFormat format,
- int width,
- int height,
- int rowstride,
- CoglBitmapDestroyNotify destroy_fn,
- void *destroy_fn_data)
+cogl_bitmap_new_for_data (CoglContext *context,
+ int width,
+ int height,
+ CoglPixelFormat format,
+ int rowstride,
+ guint8 *data)
{
- CoglBitmap *bmp = g_slice_new (CoglBitmap);
+ CoglBitmap *bmp;
+
+ g_return_val_if_fail (cogl_is_context (context), NULL);
+ bmp = g_slice_new (CoglBitmap);
bmp->format = format;
bmp->width = width;
bmp->height = height;
bmp->rowstride = rowstride;
bmp->data = data;
- bmp->destroy_fn = destroy_fn;
- bmp->destroy_fn_data = destroy_fn_data;
bmp->mapped = FALSE;
bmp->bound = FALSE;
bmp->shared_bmp = NULL;
@@ -211,19 +202,46 @@ _cogl_bitmap_new_from_data (guint8 *data,
}
CoglBitmap *
+_cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
+ unsigned int width,
+ unsigned int height,
+ CoglPixelFormat format)
+{
+ static CoglUserDataKey bitmap_free_key;
+ int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
+ int rowstride = ((width * bpp) + 3) & ~3;
+ guint8 *data = g_malloc (rowstride * height);
+ CoglBitmap *bitmap;
+
+ bitmap = cogl_bitmap_new_for_data (context,
+ width, height,
+ format,
+ rowstride,
+ data);
+ cogl_object_set_user_data (COGL_OBJECT (bitmap),
+ &bitmap_free_key,
+ data,
+ g_free);
+
+ return bitmap;
+}
+
+CoglBitmap *
_cogl_bitmap_new_shared (CoglBitmap *shared_bmp,
CoglPixelFormat format,
int width,
int height,
int rowstride)
{
- CoglBitmap *bmp = _cogl_bitmap_new_from_data (NULL, /* data */
- format,
- width,
- height,
- rowstride,
- NULL, /* destroy_fn */
- NULL /* destroy_fn_data */);
+ CoglBitmap *bmp;
+
+ _COGL_GET_CONTEXT (ctx, NULL);
+
+ bmp = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ format,
+ rowstride,
+ NULL /* data */);
bmp->shared_bmp = cogl_object_ref (shared_bmp);
@@ -251,13 +269,11 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
- bmp = _cogl_bitmap_new_from_data (NULL, /* data */
- format,
- width,
- height,
- rowstride,
- NULL, /* destroy_fn */
- NULL /* destroy_fn_data */);
+ bmp = cogl_bitmap_new_for_data (buffer->context,
+ width, height,
+ format,
+ rowstride,
+ NULL /* data */);
bmp->buffer = cogl_object_ref (buffer);
bmp->data = GINT_TO_POINTER (offset);
diff --git a/cogl/cogl-bitmap.h b/cogl/cogl-bitmap.h
index 3787d92..e2e2962 100644
--- a/cogl/cogl-bitmap.h
+++ b/cogl/cogl-bitmap.h
@@ -130,6 +130,34 @@ cogl_bitmap_new_with_size (CoglContext *context,
CoglPixelFormat format);
/**
+ * cogl_bitmap_new_for_data:
+ * @context: A #CoglContext
+ * @width: The width of the bitmap.
+ * @height: The height of the bitmap.
+ * @format: The format of the pixel data.
+ * @rowstride: The rowstride of the bitmap (the number of bytes from
+ * the start of one row of the bitmap to the next).
+ * @data: A pointer to the data. The bitmap will take ownership of this data.
+ *
+ * Creates a bitmap using some existing data. The data is not copied
+ * so the application must keep the buffer alive for the lifetime of
+ * the #CoglBitmap. This can be used for example with
+ * cogl_framebuffer_read_pixels_into_bitmap() to read data directly
+ * into an application buffer with the specified rowstride.
+ *
+ * Return value: A new #CoglBitmap.
+ * Since: 1.10
+ * Stability: unstable
+ */
+CoglBitmap *
+cogl_bitmap_new_for_data (CoglContext *context,
+ int width,
+ int height,
+ CoglPixelFormat format,
+ int rowstride,
+ guint8 *data);
+
+/**
* cogl_bitmap_get_format:
* @bitmap: A #CoglBitmap
*
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index b3c404e..8b1ea2b 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -158,6 +158,11 @@ cogl_context_new (CoglDisplay *display,
/* Allocate context memory */
context = g_malloc (sizeof (CoglContext));
+ /* Convert the context into an object immediately in case any of the
+ code below wants to verify that the context pointer is a valid
+ object */
+ _cogl_context_object_new (context);
+
/* XXX: Gross hack!
* Currently everything in Cogl just assumes there is a default
* context which it can access via _COGL_GET_CONTEXT() including
@@ -380,12 +385,11 @@ cogl_context_new (CoglDisplay *display,
_cogl_matrix_stack_init_cache (&_context->builtin_flushed_modelview);
default_texture_bitmap =
- _cogl_bitmap_new_from_data (default_texture_data,
- COGL_PIXEL_FORMAT_RGBA_8888_PRE,
- 1, 1, /* width/height */
- 4, /* rowstride */
- NULL, /* destroy function */
- NULL /* destroy function data */);
+ cogl_bitmap_new_for_data (_context,
+ 1, 1, /* width/height */
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ 4, /* rowstride */
+ default_texture_data);
/* Create default textures used for fall backs */
context->default_gl_texture_2d_tex =
@@ -430,7 +434,7 @@ cogl_context_new (CoglDisplay *display,
cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
GE (context, glEnable (GL_POINT_SPRITE));
- return _cogl_context_object_new (context);
+ return context;
}
static void
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index cdf5f8d..799f406 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -2036,9 +2036,9 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
(required_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT))
{
CoglBitmap *tmp_bmp;
- guint8 *tmp_data;
CoglPixelFormat read_format;
int bpp, rowstride;
+ guint8 *tmp_data;
int succeeded;
if (ctx->driver == COGL_DRIVER_GL)
@@ -2054,22 +2054,24 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
read_format = ((read_format & ~COGL_PREMULT_BIT) |
(framebuffer->format & COGL_PREMULT_BIT));
+ tmp_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
+ width, height,
+ read_format);
bpp = _cogl_pixel_format_get_bytes_per_pixel (read_format);
- rowstride = (width * bpp + 3) & ~3;
- tmp_data = g_malloc (rowstride * height);
-
- tmp_bmp = _cogl_bitmap_new_from_data (tmp_data,
- read_format,
- width, height, rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ rowstride = cogl_bitmap_get_rowstride (tmp_bmp);
ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp);
+ tmp_data = _cogl_bitmap_bind (tmp_bmp,
+ COGL_BUFFER_ACCESS_WRITE,
+ COGL_BUFFER_MAP_HINT_DISCARD);
+
GE( ctx, glReadPixels (x, y, width, height,
gl_format, gl_type,
tmp_data) );
+ _cogl_bitmap_unbind (tmp_bmp);
+
succeeded = _cogl_bitmap_convert_into_bitmap (tmp_bmp, bitmap);
cogl_object_unref (tmp_bmp);
diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c
index 73ed348..836caaf 100644
--- a/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl-texture-2d-sliced.c
@@ -175,6 +175,8 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
{
gboolean need_x, need_y;
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
/* If the x_span is sliced and the upload touches the
rightmost pixels then fill the waste with copies of the
pixels */
@@ -222,15 +224,13 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
src += bmp_rowstride;
}
- waste_bmp =
- _cogl_bitmap_new_from_data (waste_buf,
- source_format,
- x_span->waste,
- y_iter->intersect_end -
- y_iter->intersect_start,
- x_span->waste * bpp,
- NULL,
- NULL);
+ waste_bmp = cogl_bitmap_new_for_data (ctx,
+ x_span->waste,
+ y_iter->intersect_end -
+ y_iter->intersect_start,
+ source_format,
+ x_span->waste * bpp,
+ waste_buf);
cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
0, /* src_x */
@@ -279,14 +279,12 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds,
}
}
- waste_bmp =
- _cogl_bitmap_new_from_data (waste_buf,
- source_format,
- copy_width,
- y_span->waste,
- copy_width * bpp,
- NULL,
- NULL);
+ waste_bmp = cogl_bitmap_new_for_data (ctx,
+ copy_width,
+ y_span->waste,
+ source_format,
+ copy_width * bpp,
+ waste_buf);
cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex),
0, /* src_x */
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index da57cb4..93bb07c 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -313,12 +313,11 @@ cogl_texture_2d_new_from_data (CoglContext *ctx,
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
/* Wrap the data into a bitmap */
- bmp = _cogl_bitmap_new_from_data ((guint8 *)data,
- format,
- width,
- height,
- rowstride,
- NULL, NULL);
+ bmp = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ format,
+ rowstride,
+ (guint8 *) data);
tex =_cogl_texture_2d_new_from_bitmap (bmp, COGL_TEXTURE_NONE,
internal_format,
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c
index c2066f7..8662d5a 100644
--- a/cogl/cogl-texture-3d.c
+++ b/cogl/cogl-texture-3d.c
@@ -353,18 +353,26 @@ cogl_texture_3d_new_from_data (CoglContext *context,
recommends avoiding this situation. */
if (image_stride % rowstride != 0)
{
+ guint8 *bmp_data;
+ int bmp_rowstride;
int z, y;
- int bmp_rowstride =
- _cogl_pixel_format_get_bytes_per_pixel (format) * width;
- guint8 *bmp_data = g_malloc (bmp_rowstride * height * depth);
-
- bitmap = _cogl_bitmap_new_from_data (bmp_data,
- format,
- width,
- depth * height,
- bmp_rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL /* destroy_fn_data */);
+
+ bitmap = _cogl_bitmap_new_with_malloc_buffer (context,
+ width,
+ depth * height,
+ format);
+
+ bmp_data = _cogl_bitmap_map (bitmap,
+ COGL_BUFFER_ACCESS_WRITE,
+ COGL_BUFFER_MAP_HINT_DISCARD);
+
+ if (bmp_data == NULL)
+ {
+ cogl_object_unref (bitmap);
+ return NULL;
+ }
+
+ bmp_rowstride = cogl_bitmap_get_rowstride (bitmap);
/* Copy all of the images in */
for (z = 0; z < depth; z++)
@@ -373,15 +381,16 @@ cogl_texture_3d_new_from_data (CoglContext *context,
bmp_rowstride * y),
data + z * image_stride + rowstride * y,
bmp_rowstride);
+
+ _cogl_bitmap_unmap (bitmap);
}
else
- bitmap = _cogl_bitmap_new_from_data ((guint8 *) data,
- format,
- width,
- image_stride / rowstride * depth,
- rowstride,
- NULL, /* destroy_fn */
- NULL /* destroy_fn_data */);
+ bitmap = cogl_bitmap_new_for_data (context,
+ width,
+ image_stride / rowstride * depth,
+ format,
+ rowstride,
+ (guint8 *) data);
ret = _cogl_texture_3d_new_from_bitmap (context,
bitmap,
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 6d6a1f2..6b08ec5 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -329,6 +329,8 @@ cogl_texture_new_from_data (unsigned int width,
CoglBitmap *bmp;
CoglTexture *tex;
+ _COGL_GET_CONTEXT (ctx, NULL);
+
if (format == COGL_PIXEL_FORMAT_ANY)
return NULL;
@@ -340,12 +342,11 @@ cogl_texture_new_from_data (unsigned int width,
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
/* Wrap the data into a bitmap */
- bmp = _cogl_bitmap_new_from_data ((guint8 *) data,
- format,
- width,
- height,
- rowstride,
- NULL, NULL);
+ bmp = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ format,
+ rowstride,
+ (guint8 *) data);
tex = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
@@ -663,6 +664,8 @@ cogl_texture_set_region (CoglTexture *texture,
CoglBitmap *source_bmp;
gboolean ret;
+ _COGL_GET_CONTEXT (ctx, FALSE);
+
_COGL_RETURN_VAL_IF_FAIL ((width - src_x) >= dst_width, FALSE);
_COGL_RETURN_VAL_IF_FAIL ((height - src_y) >= dst_height, FALSE);
@@ -675,13 +678,11 @@ cogl_texture_set_region (CoglTexture *texture,
rowstride = _cogl_pixel_format_get_bytes_per_pixel (format) * width;
/* Init source bitmap */
- source_bmp = _cogl_bitmap_new_from_data ((guint8 *) data,
- format,
- width,
- height,
- rowstride,
- NULL, /* destroy_fn */
- NULL); /* destroy_fn_data */
+ source_bmp = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ format,
+ rowstride,
+ (guint8 *) data);
ret = cogl_texture_set_region_from_bitmap (texture,
src_x, src_y,
@@ -712,7 +713,6 @@ do_texture_draw_and_read (CoglTexture *texture,
CoglBitmap *target_bmp,
float *viewport)
{
- int bpp;
float rx1, ry1;
float rx2, ry2;
float tx1, ty1;
@@ -721,7 +721,7 @@ do_texture_draw_and_read (CoglTexture *texture,
CoglBitmap *rect_bmp;
unsigned int tex_width, tex_height;
- bpp = _cogl_pixel_format_get_bytes_per_pixel (COGL_PIXEL_FORMAT_RGBA_8888);
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
tex_width = cogl_texture_get_width (texture);
tex_height = cogl_texture_get_height (texture);
@@ -748,8 +748,6 @@ do_texture_draw_and_read (CoglTexture *texture,
{
int width;
int height;
- int rowstride;
- guint8 *data;
/* Rectangle X coords */
rx1 = rx2;
@@ -757,7 +755,6 @@ do_texture_draw_and_read (CoglTexture *texture,
width = rx2 - rx1;
height = ry2 - ry1;
- rowstride = width * bpp;
/* Normalized texture X coords */
tx1 = tx2;
@@ -770,24 +767,17 @@ do_texture_draw_and_read (CoglTexture *texture,
tx1, ty1,
tx2, ty2);
- data = g_malloc (height * rowstride);
-
/* Read into a temporary bitmap */
- rect_bmp =
- _cogl_bitmap_new_from_data (data,
- COGL_PIXEL_FORMAT_RGBA_8888,
- width,
- height,
- rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
-
- cogl_read_pixels (viewport[0], viewport[1],
- width,
- height,
- COGL_READ_PIXELS_COLOR_BUFFER,
- COGL_PIXEL_FORMAT_RGBA_8888_PRE,
- data);
+ rect_bmp = _cogl_bitmap_new_with_malloc_buffer
+ (ctx,
+ width, height,
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE);
+
+ cogl_framebuffer_read_pixels_into_bitmap
+ (cogl_get_draw_framebuffer (),
+ viewport[0], viewport[1],
+ COGL_READ_PIXELS_COLOR_BUFFER,
+ rect_bmp);
/* Copy to target bitmap */
_cogl_bitmap_copy_subregion (rect_bmp,
@@ -900,15 +890,12 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
COGL_BUFFER_MAP_HINT_DISCARD)) == NULL)
return FALSE;
- srcdata = g_malloc (alpha_rowstride * target_height);
-
/* Create temp bitmap for alpha values */
- alpha_bmp = _cogl_bitmap_new_from_data (srcdata,
- COGL_PIXEL_FORMAT_RGBA_8888,
- target_width, target_height,
- alpha_rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ alpha_bmp =
+ _cogl_bitmap_new_with_malloc_buffer (ctx,
+ target_width,
+ target_height,
+ COGL_PIXEL_FORMAT_RGBA_8888);
/* Draw alpha values into RGB channels */
cogl_pipeline_set_layer_combine (ctx->texture_download_pipeline,
@@ -920,6 +907,10 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
/* Copy temp R to target A */
+ srcdata = _cogl_bitmap_map (alpha_bmp,
+ COGL_BUFFER_ACCESS_READ,
+ 0 /* hints */);
+
for (y=0; y<target_height; ++y)
{
for (x=0; x<target_width; ++x)
@@ -932,6 +923,8 @@ _cogl_texture_draw_and_read (CoglTexture *texture,
dstdata += target_rowstride;
}
+ _cogl_bitmap_unmap (alpha_bmp);
+
_cogl_bitmap_unmap (target_bmp);
cogl_object_unref (alpha_bmp);
@@ -976,12 +969,11 @@ get_texture_bits_via_offscreen (CoglTexture *texture,
framebuffer = COGL_FRAMEBUFFER (offscreen);
- bitmap = _cogl_bitmap_new_from_data (dst_bits,
- dst_format,
- width, height,
- dst_rowstride,
- NULL, /* destroy_fn */
- NULL /* destroy_fn_data */);
+ bitmap = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ dst_format,
+ dst_rowstride,
+ dst_bits);
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
x, y,
COGL_READ_PIXELS_COLOR_BUFFER,
@@ -1125,7 +1117,6 @@ cogl_texture_get_data (CoglTexture *texture,
int bpp;
int byte_size;
CoglPixelFormat closest_format;
- int closest_bpp;
GLenum closest_gl_format;
GLenum closest_gl_type;
CoglBitmap *target_bmp;
@@ -1160,7 +1151,6 @@ cogl_texture_get_data (CoglTexture *texture,
ctx->texture_driver->find_best_gl_get_data_format (format,
&closest_gl_format,
&closest_gl_type);
- closest_bpp = _cogl_pixel_format_get_bytes_per_pixel (closest_format);
/* We can assume that whatever data GL gives us will have the
premult status of the original texture */
@@ -1171,24 +1161,16 @@ cogl_texture_get_data (CoglTexture *texture,
/* Is the requested format supported? */
if (closest_format == format)
/* Target user data directly */
- target_bmp = _cogl_bitmap_new_from_data (data,
- format,
- tex_width,
- tex_height,
- rowstride,
- NULL, NULL);
+ target_bmp = cogl_bitmap_new_for_data (ctx,
+ tex_width,
+ tex_height,
+ format,
+ rowstride,
+ data);
else
- {
- int target_rowstride = tex_width * closest_bpp;
- guint8 *target_data = g_malloc (tex_height * target_rowstride);
- target_bmp = _cogl_bitmap_new_from_data (target_data,
- closest_format,
- tex_width,
- tex_height,
- target_rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
- }
+ target_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
+ tex_width, tex_height,
+ closest_format);
tg_data.orig_width = tex_width;
tg_data.orig_height = tex_height;
@@ -1236,12 +1218,11 @@ cogl_texture_get_data (CoglTexture *texture,
gboolean result;
/* 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 */);
+ new_bmp = cogl_bitmap_new_for_data (ctx,
+ tex_width, tex_height,
+ format,
+ rowstride,
+ data);
result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp);
if (!result)
diff --git a/cogl/cogl.c b/cogl/cogl.c
index b60f838..95d8d5f 100644
--- a/cogl/cogl.c
+++ b/cogl/cogl.c
@@ -376,12 +376,13 @@ cogl_read_pixels (int x,
int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
CoglBitmap *bitmap;
- bitmap = _cogl_bitmap_new_from_data (pixels,
- format,
- width, height,
- bpp * width, /* rowstride */
- NULL, /* destroy_fn */
- NULL /* destroy_fn_data */);
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ bitmap = cogl_bitmap_new_for_data (ctx,
+ width, height,
+ format,
+ bpp * width, /* rowstride */
+ pixels);
cogl_framebuffer_read_pixels_into_bitmap (_cogl_get_read_framebuffer (),
x, y,
source,
diff --git a/cogl/driver/gles/cogl-texture-driver-gles.c b/cogl/driver/gles/cogl-texture-driver-gles.c
index df7a398..2bc596b 100644
--- a/cogl/driver/gles/cogl-texture-driver-gles.c
+++ b/cogl/driver/gles/cogl-texture-driver-gles.c
@@ -151,15 +151,10 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target,
width != cogl_bitmap_get_width (source_bmp) ||
height != cogl_bitmap_get_height (source_bmp))
{
- rowstride = bpp * width;
- rowstride = (rowstride + 3) & ~3;
slice_bmp =
- _cogl_bitmap_new_from_data (g_malloc (height * rowstride),
- source_format,
- width, height,
- rowstride,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ _cogl_bitmap_new_with_malloc_buffer (ctx,
+ width, height,
+ source_format);
_cogl_bitmap_copy_subregion (source_bmp,
slice_bmp,
src_x, src_y,
@@ -167,10 +162,9 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target,
width, height);
}
else
- {
- slice_bmp = prepare_bitmap_alignment_for_upload (source_bmp);
- rowstride = cogl_bitmap_get_rowstride (slice_bmp);
- }
+ slice_bmp = prepare_bitmap_alignment_for_upload (source_bmp);
+
+ rowstride = cogl_bitmap_get_rowstride (slice_bmp);
/* Setup gl alignment to match rowstride and top-left corner */
_cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);
@@ -263,6 +257,7 @@ _cogl_texture_driver_upload_to_gl_3d (GLenum gl_target,
{
CoglBitmap *bmp;
int image_height = bmp_height / depth;
+ CoglPixelFormat source_bmp_format = cogl_bitmap_get_format (source_bmp);
int i;
_cogl_texture_driver_prep_gl_for_pixels_upload (bmp_width * bpp, bpp);
@@ -281,13 +276,10 @@ _cogl_texture_driver_upload_to_gl_3d (GLenum gl_target,
source_gl_type,
NULL) );
- bmp = _cogl_bitmap_new_from_data (g_malloc (bpp * bmp_width * height),
- cogl_bitmap_get_format (source_bmp),
- bmp_width,
- height,
- bpp * bmp_width,
- (CoglBitmapDestroyNotify) g_free,
- NULL);
+ bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
+ bmp_width,
+ height,
+ source_bmp_format);
for (i = 0; i < depth; i++)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]