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>
This commit is contained in:
Neil Roberts 2012-03-13 14:46:18 +00:00
parent f65a895b4f
commit d18b59d9e6
14 changed files with 273 additions and 261 deletions

View File

@ -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,

View File

@ -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))
{

View File

@ -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

View File

@ -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

View File

@ -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;
@ -210,6 +201,31 @@ _cogl_bitmap_new_from_data (guint8 *data,
return _cogl_bitmap_object_new (bmp);
}
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,
@ -217,13 +233,15 @@ _cogl_bitmap_new_shared (CoglBitmap *shared_bmp,
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);

View File

@ -129,6 +129,34 @@ cogl_bitmap_new_with_size (CoglContext *context,
unsigned int height,
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

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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,

View File

@ -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,

View File

@ -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);
rect_bmp = _cogl_bitmap_new_with_malloc_buffer
(ctx,
width, height,
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
cogl_read_pixels (viewport[0], viewport[1],
width,
height,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
data);
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)

View File

@ -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,

View File

@ -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++)
{