mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
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:
parent
f65a895b4f
commit
d18b59d9e6
@ -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,
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
13
cogl/cogl.c
13
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,
|
||||
|
@ -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++)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user