static void _cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
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:
* - it defines already deprecated symbols
size,
COGL_BUFFER_USAGE_HINT_DRAW,
COGL_BUFFER_UPDATE_HINT_STATIC);
- buffer->vtable = &cogl_pixel_buffer_vtable;
- GE( glGenBuffers (1, &buffer->gl_handle) );
- COGL_BUFFER_SET_FLAG (buffer, BUFFER_OBJECT);
+ if (cogl_features_available (COGL_FEATURE_PBOS))
+ {
+ /* 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;
_cogl_pixel_buffer_unmap,
_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,
+};
#include "cogl-bitmap.h"
#include "cogl-bitmap-private.h"
#include "cogl-buffer-private.h"
+#include "cogl-pixel-buffer-private.h"
#include "cogl-texture-private.h"
#include "cogl-texture-driver.h"
#include "cogl-texture-2d-sliced-private.h"
cogl_buffer = COGL_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)
rowstride = width * _cogl_get_format_bpp (format);
return COGL_INVALID_HANDLE;
}
- /* Wrap the data into a bitmap */
- bitmap.width = width;
- bitmap.height = height;
- bitmap.data = GUINT_TO_POINTER (offset);
- bitmap.format = format;
- bitmap.rowstride = rowstride;
-
- _cogl_buffer_bind (cogl_buffer, GL_PIXEL_UNPACK_BUFFER);
- texture = cogl_texture_new_from_bitmap (&bitmap, flags, internal_format);
- _cogl_buffer_bind (NULL, GL_PIXEL_UNPACK_BUFFER);
+ if (cogl_features_available (COGL_FEATURE_PBOS))
+ {
+ /* Wrap the data into a bitmap */
+ bitmap.width = width;
+ bitmap.height = height;
+ bitmap.data = GUINT_TO_POINTER (offset);
+ bitmap.format = format;
+ bitmap.rowstride = rowstride;
+
+ _cogl_buffer_bind (cogl_buffer, GL_PIXEL_UNPACK_BUFFER);
+ texture = cogl_texture_new_from_bitmap (&bitmap, flags, internal_format);
+ _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;
}
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
* @COGL_FEATURE_VBOS: VBO support
+ * @COGL_FEATURE_PBOS: PBO support
*
* Flags for the supported features.
*
COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8),
COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9),
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
- COGL_FEATURE_VBOS = (1 << 11)
+ COGL_FEATURE_VBOS = (1 << 11),
+ COGL_FEATURE_PBOS = (1 << 12)
} CoglFeatureFlags;
/**
GLsizei width,
GLsizei height))
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
just check for GL 2.0 */