cogl-pixel-buffer: Add a fallback path
First, let's add a new public feature called, surprisingly, COGL_FEATURE_PBOS to check the availability of PBOs and provide a fallback path when running on older GL implementations or on OpenGL ES In case the underlying OpenGL implementation does not provide PBOs, we need a fallback path (a malloc'ed buffer). The CoglPixelBufer constructors will instanciate a subclass of CoglBuffer that handles map/unmap and set_data() with a malloc'ed buffer. The public feature is useful to check before using set_data() on a buffer as it will mean doing a memcpy() when not supporting PBOs (in that case, it's better to create the texture directly instead of using a CoglBuffer).
This commit is contained in:
parent
cf960cfb3d
commit
ca80e8802b
@ -79,6 +79,7 @@
|
|||||||
static void _cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
|
static void _cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
|
||||||
|
|
||||||
static const CoglBufferVtable cogl_pixel_buffer_vtable;
|
static const CoglBufferVtable cogl_pixel_buffer_vtable;
|
||||||
|
static const CoglBufferVtable cogl_malloc_pixel_buffer_vtable;
|
||||||
|
|
||||||
/* we don't want to use the stock COGL_HANDLE_DEFINE * for 2 reasons:
|
/* we don't want to use the stock COGL_HANDLE_DEFINE * for 2 reasons:
|
||||||
* - it defines already deprecated symbols
|
* - it defines already deprecated symbols
|
||||||
@ -147,10 +148,24 @@ cogl_pixel_buffer_new_EXP (guint size)
|
|||||||
size,
|
size,
|
||||||
COGL_BUFFER_USAGE_HINT_DRAW,
|
COGL_BUFFER_USAGE_HINT_DRAW,
|
||||||
COGL_BUFFER_UPDATE_HINT_STATIC);
|
COGL_BUFFER_UPDATE_HINT_STATIC);
|
||||||
buffer->vtable = &cogl_pixel_buffer_vtable;
|
|
||||||
|
|
||||||
GE( glGenBuffers (1, &buffer->gl_handle) );
|
if (cogl_features_available (COGL_FEATURE_PBOS))
|
||||||
COGL_BUFFER_SET_FLAG (buffer, BUFFER_OBJECT);
|
{
|
||||||
|
/* PBOS */
|
||||||
|
buffer->vtable = &cogl_pixel_buffer_vtable;
|
||||||
|
|
||||||
|
GE( glGenBuffers (1, &buffer->gl_handle) );
|
||||||
|
COGL_BUFFER_SET_FLAG (buffer, BUFFER_OBJECT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* malloc fallback subclass */
|
||||||
|
buffer->vtable = &cogl_malloc_pixel_buffer_vtable;
|
||||||
|
|
||||||
|
/* create the buffer here as there's no point for a lazy allocation in
|
||||||
|
* the malloc case */
|
||||||
|
buffer->data = g_malloc (size);
|
||||||
|
}
|
||||||
|
|
||||||
pixel_buffer->flags = COGL_PIXEL_BUFFER_FLAG_NONE;
|
pixel_buffer->flags = COGL_PIXEL_BUFFER_FLAG_NONE;
|
||||||
|
|
||||||
@ -315,3 +330,38 @@ static const CoglBufferVtable cogl_pixel_buffer_vtable =
|
|||||||
_cogl_pixel_buffer_unmap,
|
_cogl_pixel_buffer_unmap,
|
||||||
_cogl_pixel_buffer_set_data,
|
_cogl_pixel_buffer_set_data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback path, buffer->data points to a malloc'ed buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static guchar *
|
||||||
|
_cogl_malloc_pixel_buffer_map (CoglBuffer *buffer,
|
||||||
|
CoglBufferAccess access)
|
||||||
|
{
|
||||||
|
COGL_BUFFER_SET_FLAG (buffer, MAPPED);
|
||||||
|
return buffer->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_malloc_pixel_buffer_unmap (CoglBuffer *buffer)
|
||||||
|
{
|
||||||
|
COGL_BUFFER_CLEAR_FLAG (buffer, MAPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_cogl_malloc_pixel_buffer_set_data (CoglBuffer *buffer,
|
||||||
|
guint offset,
|
||||||
|
const guchar *data,
|
||||||
|
guint size)
|
||||||
|
{
|
||||||
|
memcpy (buffer->data + offset, data, size);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const CoglBufferVtable cogl_malloc_pixel_buffer_vtable =
|
||||||
|
{
|
||||||
|
_cogl_malloc_pixel_buffer_map,
|
||||||
|
_cogl_malloc_pixel_buffer_unmap,
|
||||||
|
_cogl_malloc_pixel_buffer_set_data,
|
||||||
|
};
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "cogl-bitmap.h"
|
#include "cogl-bitmap.h"
|
||||||
#include "cogl-bitmap-private.h"
|
#include "cogl-bitmap-private.h"
|
||||||
#include "cogl-buffer-private.h"
|
#include "cogl-buffer-private.h"
|
||||||
|
#include "cogl-pixel-buffer-private.h"
|
||||||
#include "cogl-texture-private.h"
|
#include "cogl-texture-private.h"
|
||||||
#include "cogl-texture-driver.h"
|
#include "cogl-texture-driver.h"
|
||||||
#include "cogl-texture-2d-sliced-private.h"
|
#include "cogl-texture-2d-sliced-private.h"
|
||||||
@ -476,7 +477,9 @@ cogl_texture_new_from_buffer_EXP (CoglHandle buffer,
|
|||||||
cogl_buffer = COGL_BUFFER (buffer);
|
cogl_buffer = COGL_BUFFER (buffer);
|
||||||
pixel_buffer = COGL_PIXEL_BUFFER (buffer);
|
pixel_buffer = COGL_PIXEL_BUFFER (buffer);
|
||||||
|
|
||||||
/* Rowstride from width if not given */
|
/* Rowstride from CoglBuffer or even width * bpp if not given */
|
||||||
|
if (rowstride == 0)
|
||||||
|
rowstride = pixel_buffer->stride;
|
||||||
if (rowstride == 0)
|
if (rowstride == 0)
|
||||||
rowstride = width * _cogl_get_format_bpp (format);
|
rowstride = width * _cogl_get_format_bpp (format);
|
||||||
|
|
||||||
@ -493,16 +496,29 @@ cogl_texture_new_from_buffer_EXP (CoglHandle buffer,
|
|||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrap the data into a bitmap */
|
if (cogl_features_available (COGL_FEATURE_PBOS))
|
||||||
bitmap.width = width;
|
{
|
||||||
bitmap.height = height;
|
/* Wrap the data into a bitmap */
|
||||||
bitmap.data = GUINT_TO_POINTER (offset);
|
bitmap.width = width;
|
||||||
bitmap.format = format;
|
bitmap.height = height;
|
||||||
bitmap.rowstride = rowstride;
|
bitmap.data = GUINT_TO_POINTER (offset);
|
||||||
|
bitmap.format = format;
|
||||||
|
bitmap.rowstride = rowstride;
|
||||||
|
|
||||||
_cogl_buffer_bind (cogl_buffer, GL_PIXEL_UNPACK_BUFFER);
|
_cogl_buffer_bind (cogl_buffer, GL_PIXEL_UNPACK_BUFFER);
|
||||||
texture = cogl_texture_new_from_bitmap (&bitmap, flags, internal_format);
|
texture = cogl_texture_new_from_bitmap (&bitmap, flags, internal_format);
|
||||||
_cogl_buffer_bind (NULL, GL_PIXEL_UNPACK_BUFFER);
|
_cogl_buffer_bind (NULL, GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texture = cogl_texture_new_from_data (width,
|
||||||
|
height,
|
||||||
|
flags,
|
||||||
|
format,
|
||||||
|
internal_format,
|
||||||
|
rowstride,
|
||||||
|
cogl_buffer->data);
|
||||||
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,7 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
|
|||||||
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
|
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
|
||||||
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
|
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
|
||||||
* @COGL_FEATURE_VBOS: VBO support
|
* @COGL_FEATURE_VBOS: VBO support
|
||||||
|
* @COGL_FEATURE_PBOS: PBO support
|
||||||
*
|
*
|
||||||
* Flags for the supported features.
|
* Flags for the supported features.
|
||||||
*
|
*
|
||||||
@ -211,7 +212,8 @@ typedef enum
|
|||||||
COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8),
|
COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8),
|
||||||
COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9),
|
COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9),
|
||||||
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
|
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
|
||||||
COGL_FEATURE_VBOS = (1 << 11)
|
COGL_FEATURE_VBOS = (1 << 11),
|
||||||
|
COGL_FEATURE_PBOS = (1 << 12)
|
||||||
} CoglFeatureFlags;
|
} CoglFeatureFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,6 +99,11 @@ COGL_FEATURE_FUNCTION (void, glRenderbufferStorageMultisample,
|
|||||||
GLsizei width,
|
GLsizei width,
|
||||||
GLsizei height))
|
GLsizei height))
|
||||||
COGL_FEATURE_END ()
|
COGL_FEATURE_END ()
|
||||||
|
COGL_FEATURE_BEGIN (read_pixels_async, 2, 1,
|
||||||
|
"EXT\0",
|
||||||
|
"pixel_buffer_object\0",
|
||||||
|
COGL_FEATURE_PBOS)
|
||||||
|
COGL_FEATURE_END ()
|
||||||
|
|
||||||
/* The function names in OpenGL 2.0 are different so we can't easily
|
/* The function names in OpenGL 2.0 are different so we can't easily
|
||||||
just check for GL 2.0 */
|
just check for GL 2.0 */
|
||||||
|
Loading…
Reference in New Issue
Block a user