Change API so that CoglPixelBuffer no longer knows its w/h/format

The idea is that CoglPixelBuffer should just be a buffer that can be
used for pixel data and it has no idea about the details of any images
that are stored in it. This is analogous to CoglAttributeBuffer which
itself does not have any information about the attributes. When you
want to use a pixel buffer you should create a CoglBitmap which points
to a region of the attribute buffer and provides the extra needed
information such as the width, height and format. That way it is also
possible to use a single CoglPixelBuffer with multiple bitmaps.

The changes that are made are:

• cogl_pixel_buffer_new_with_size has been removed and in its place is
  cogl_bitmap_new_with_size. This will create a pixel buffer at the
  right size and rowstride for the given width/height/format and
  immediately create a single CoglBitmap to point into it. The old
  function had an out-parameter for the stride of the image but with
  the new API this should be queriable from the bitmap (although there
  is no function for this yet).

• There is now a public cogl_pixel_buffer_new constructor. This takes
  a size in bytes and data pointer similarly to
  cogl_attribute_buffer_new.

• cogl_texture_new_from_buffer has been removed. If you want to create
  a texture from a pixel buffer you should wrap it up in a bitmap
  first. There is already API to create a texture from a bitmap.

This patch also does a bit of header juggling because cogl-context.h
was including cogl-texture.h and cogl-framebuffer.h which were causing
some circular dependencies when cogl-bitmap.h includes cogl-context.h.
These weren't actually needed in cogl-context.h itself but a few other
headers were relying on them being included so this adds the #includes
where necessary.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2012-02-25 20:04:45 +00:00
parent 10a38bb14f
commit 3700cc26a5
14 changed files with 101 additions and 172 deletions

View File

@ -30,6 +30,7 @@
#include "cogl-object-private.h"
#include "cogl-attribute.h"
#include "cogl-framebuffer.h"
typedef enum
{

View File

@ -30,6 +30,7 @@
#include "cogl-private.h"
#include "cogl-bitmap-private.h"
#include "cogl-buffer-private.h"
#include "cogl-pixel-buffer.h"
#include <string.h>
@ -264,6 +265,40 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
return bmp;
}
CoglBitmap *
cogl_bitmap_new_with_size (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format)
{
CoglPixelBuffer *pixel_buffer;
CoglBitmap *bitmap;
unsigned int rowstride;
/* creating a buffer to store "any" format does not make sense */
if (G_UNLIKELY (format == COGL_PIXEL_FORMAT_ANY))
return NULL;
/* for now we fallback to cogl_pixel_buffer_new, later, we could ask
* libdrm a tiled buffer for instance */
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
pixel_buffer = cogl_pixel_buffer_new (context, height * rowstride, NULL);
if (G_UNLIKELY (pixel_buffer == NULL))
return NULL;
bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer),
format,
width, height,
rowstride,
0 /* offset */);
cogl_object_unref (pixel_buffer);
return bitmap;
}
CoglPixelFormat
_cogl_bitmap_get_format (CoglBitmap *bitmap)
{

View File

@ -30,6 +30,7 @@
#include <cogl/cogl-types.h>
#include <cogl/cogl-buffer.h>
#include <cogl/cogl-context.h>
G_BEGIN_DECLS
@ -91,6 +92,42 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
int height,
int rowstride,
int offset);
/**
* cogl_bitmap_new_with_size:
* @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
*
* Creates a new #CoglBitmap with the given width, height and format.
* The initial contents of the bitmap are undefined.
*
* The data for the bitmap will be stored in a newly created
* #CoglPixelBuffer. You can get a pointer to the pixel buffer using
* cogl_bitmap_get_pixel_buffer(). The #CoglBuffer API can then be
* used to fill the bitmap with data.
*
* <note>Cogl will try its best to provide a hardware array you can
* map, write into and effectively do a zero copy upload when creating
* a texture from it with cogl_texture_new_from_bitmap(). For various
* reasons, such arrays are likely to have a stride larger than width
* * bytes_per_pixel. The user must take the stride into account when
* writing into it. The stride can be retrieved with
* cogl_bitmap_get_rowstride().</note>
*
* Return value: a #CoglPixelBuffer representing the newly created array or
* %NULL on failure
*
* Since: 1.10
* Stability: Unstable
*/
CoglBitmap *
cogl_bitmap_new_with_size (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format);
#endif
/**

View File

@ -27,6 +27,7 @@
#include "cogl2-path.h"
#include "cogl-matrix.h"
#include "cogl-primitive.h"
#include "cogl-framebuffer.h"
/* The clip stack works like a GSList where only a pointer to the top
of the stack is stored. The empty clip stack is represented simply

View File

@ -38,9 +38,7 @@ typedef struct _CoglContext CoglContext;
#include <cogl/cogl-defines.h>
#include <cogl/cogl-display.h>
#include <cogl/cogl-texture.h>
#include <cogl/cogl-primitive.h>
#include <cogl/cogl-framebuffer.h>
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
#include <android/native_window.h>
#endif

View File

@ -24,6 +24,7 @@
#ifndef __COGL_JOURNAL_PRIVATE_H
#define __COGL_JOURNAL_PRIVATE_H
#include "cogl-texture.h"
#include "cogl-handle.h"
#include "cogl-clip-stack.h"

View File

@ -40,11 +40,6 @@ G_BEGIN_DECLS
struct _CoglPixelBuffer
{
CoglBuffer _parent;
CoglPixelFormat format;
unsigned int width;
unsigned int height;
unsigned int stride;
};
G_END_DECLS

View File

@ -66,8 +66,10 @@ _cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
COGL_BUFFER_DEFINE (PixelBuffer, pixel_buffer)
static CoglPixelBuffer *
_cogl_pixel_buffer_new (CoglContext *context, unsigned int size)
CoglPixelBuffer *
cogl_pixel_buffer_new (CoglContext *context,
gsize size,
const void *data)
{
CoglPixelBuffer *pixel_buffer = g_slice_new0 (CoglPixelBuffer);
CoglBuffer *buffer = COGL_BUFFER (pixel_buffer);
@ -87,42 +89,15 @@ _cogl_pixel_buffer_new (CoglContext *context, unsigned int size)
COGL_BUFFER_USAGE_HINT_TEXTURE,
COGL_BUFFER_UPDATE_HINT_STATIC);
/* return COGL_INVALID_HANDLE; */
return _cogl_pixel_buffer_object_new (pixel_buffer);
}
_cogl_pixel_buffer_object_new (pixel_buffer);
CoglPixelBuffer *
cogl_pixel_buffer_new_with_size (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format,
unsigned int *rowstride)
{
CoglPixelBuffer *buffer;
CoglPixelBuffer *pixel_buffer;
unsigned int stride;
if (data)
cogl_buffer_set_data (COGL_BUFFER (pixel_buffer),
0,
data,
size);
/* creating a buffer to store "any" format does not make sense */
if (G_UNLIKELY (format == COGL_PIXEL_FORMAT_ANY))
return COGL_INVALID_HANDLE;
/* for now we fallback to cogl_pixel_buffer_new, later, we could ask
* libdrm a tiled buffer for instance */
stride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
if (rowstride)
*rowstride = stride;
buffer = _cogl_pixel_buffer_new (context, height * stride);
if (G_UNLIKELY (buffer == COGL_INVALID_HANDLE))
return COGL_INVALID_HANDLE;
pixel_buffer = COGL_PIXEL_BUFFER (buffer);
pixel_buffer->width = width;
pixel_buffer->height = height;
pixel_buffer->format = format;
pixel_buffer->stride = stride;
return buffer;
return pixel_buffer;
}
static void

View File

@ -54,34 +54,26 @@ G_BEGIN_DECLS
typedef struct _CoglPixelBuffer CoglPixelBuffer;
/**
* cogl_pixel_buffer_new_with_size:
* cogl_pixel_buffer_new:
* @context: A #CoglContext
* @width: width of the pixel array in pixels
* @height: height of the pixel array in pixels
* @format: the format of the pixels the array will store
* @stride: if not %NULL the function will return the stride of the array
* in bytes
* @size: The number of bytes to allocate for the pixel data.
* @data: An optional pointer to vertex data to upload immediately
*
* Creates a new array to store pixel data.
* Declares a new #CoglPixelBuffer of @size bytes to contain arrays of
* pixels. Once declared, data can be set using cogl_buffer_set_data()
* or by mapping it into the application's address space using
* cogl_buffer_map().
*
* <note>COGL will try its best to provide a hardware array you can map,
* write into and effectively do a zero copy upload when creating a texture
* from it with cogl_texture_new_from_buffer(). For various reasons, such
* arrays are likely to have a stride larger than width * bytes_per_pixel. The
* user must take the stride into account when writing into it.</note>
* If @data isn't %NULL then @size bytes will be read from @data and
* immediately copied into the new buffer.
*
* Return value: a #CoglPixelBuffer representing the newly created array or
* %NULL on failure
*
* Since: 1.2
* Stability: Unstable
* Since: 1.10
* Stability: unstable
*/
CoglPixelBuffer *
cogl_pixel_buffer_new_with_size (CoglContext *context,
unsigned int width,
unsigned int height,
CoglPixelFormat format,
unsigned int *stride);
cogl_pixel_buffer_new (CoglContext *context,
gsize size,
const void *data);
/**
* cogl_is_pixel_buffer:

View File

@ -29,6 +29,7 @@
#include "cogl-pipeline-private.h"
#include "cogl-spans.h"
#include "cogl-meta-texture.h"
#include "cogl-framebuffer.h"
typedef struct _CoglTextureVtable CoglTextureVtable;

View File

@ -497,62 +497,6 @@ cogl_texture_new_from_sub_texture (CoglTexture *full_texture,
sub_width, sub_height));
}
CoglTexture *
cogl_texture_new_from_buffer_EXP (CoglPixelBuffer *buffer,
unsigned int width,
unsigned int height,
CoglTextureFlags flags,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
const unsigned int offset)
{
CoglTexture *texture;
CoglBuffer *cogl_buffer;
CoglPixelBuffer *pixel_buffer;
CoglBitmap *bmp;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL);
if (format == COGL_PIXEL_FORMAT_ANY)
return NULL;
cogl_buffer = COGL_BUFFER (buffer);
pixel_buffer = COGL_PIXEL_BUFFER (buffer);
/* Rowstride from CoglBuffer or even width * bpp if not given */
if (rowstride == 0)
rowstride = pixel_buffer->stride;
if (rowstride == 0)
rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format);
/* use the CoglBuffer height and width as last resort */
if (width == 0)
width = pixel_buffer->width;
if (height == 0)
height = pixel_buffer->height;
if (width == 0 || height == 0)
{
/* no width or height specified, neither at creation time (because the
* array was created by cogl_pixel_buffer_new()) nor when calling this
* function */
return NULL;
}
/* Wrap the buffer into a bitmap */
bmp = cogl_bitmap_new_from_buffer (cogl_buffer,
format,
width, height,
rowstride,
offset);
texture = cogl_texture_new_from_bitmap (bmp, flags, internal_format);
cogl_object_unref (bmp);
return texture;
}
unsigned int
cogl_texture_get_width (CoglTexture *texture)
{

View File

@ -491,49 +491,6 @@ cogl_texture_new_from_sub_texture (CoglTexture *full_texture,
int sub_width,
int sub_height);
#if defined (COGL_ENABLE_EXPERIMENTAL_API)
#define cogl_texture_new_from_buffer cogl_texture_new_from_buffer_EXP
/**
* cogl_texture_new_from_buffer:
* @buffer: A #CoglPixelBuffer pointer
* @width: width of texture in pixels or 0
* @height: height of texture in pixels or 0
* @flags: optional flags for the texture, or %COGL_TEXTURE_NONE
* @format: the #CoglPixelFormat the buffer is stored in in RAM
* @internal_format: the #CoglPixelFormat that will be used for storing
* the buffer on the GPU. If %COGL_PIXEL_FORMAT_ANY is given then a
* premultiplied format similar to the format of the source data will
* be used. The default blending equations of Cogl expect premultiplied
* color data; the main use of passing a non-premultiplied format here
* is if you have non-premultiplied source data and are going to adjust
* the blend mode (see cogl_material_set_blend()) or use the data for
* something other than straight blending
* @rowstride: the memory offset in bytes between the starts of
* scanlines in @data. If 0 is given the row stride will be deduced from
* @width and @format or the stride given by cogl_pixel_buffer_new_for_size()
* @offset: offset in bytes in @buffer from where the texture data starts
*
* Creates a new texture using the buffer specified by @handle. If the buffer
* has been created using cogl_pixel_buffer_new_for_size() it's possible to omit
* the height and width values already specified at creation time.
*
* Return value: A newly created #CoglTexture or %NULL on failure
*
* Since: 1.2
* Stability: Unstable
*/
CoglTexture *
cogl_texture_new_from_buffer (CoglPixelBuffer *buffer,
unsigned int width,
unsigned int height,
CoglTextureFlags flags,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
unsigned int offset);
#endif
#ifndef COGL_DISABLE_DEPRECATED
/**

View File

@ -679,12 +679,8 @@ cogl_buffer_set_data
<SUBSECTION>
cogl_pixel_buffer_new
cogl_pixel_buffer_new_for_size
cogl_is_pixel_buffer
<SUBSECTION>
cogl_texture_new_from_buffer
<SUBSECTION Private>
cogl_buffer_access_get_type
cogl_buffer_update_hint_get_type

View File

@ -566,12 +566,8 @@ cogl_buffer_set_data
<SUBSECTION>
cogl_pixel_buffer_new
cogl_pixel_buffer_new_for_size
cogl_is_pixel_buffer
<SUBSECTION>
cogl_texture_new_from_buffer
<SUBSECTION Private>
cogl_buffer_access_get_type
cogl_buffer_update_hint_get_type