--- /dev/null
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Damien Lespiau <damien.lespiau@intel.com>
+ */
+
+#ifndef __COGL_PIXEL_BUFFER_PRIVATE_H__
+#define __COGL_PIXEL_BUFFER_PRIVATE_H__
+
+#include "cogl-handle.h"
+#include "cogl-buffer-private.h"
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define COGL_PIXEL_BUFFER(buffer) ((CoglPixelBuffer *)(buffer))
+
+#define COGL_PIXEL_BUFFER_SET_FLAG(buffer, flag) \
+ ((buffer)->flags |= (COGL_PIXEL_BUFFER_FLAG_ ## flag))
+
+#define COGL_PIXEL_BUFFER_CLEAR_FLAG(buffer, flag) \
+ ((buffer)->flags &= ~(COGL_PIXEL_BUFFER_FLAG_ ## flag))
+
+#define COGL_PIXEL_BUFFER_FLAG_IS_SET(buffer, flag) \
+ ((buffer)->flags & (COGL_PIXEL_BUFFER_FLAG_ ## flag))
+
+typedef enum _CoglPixelBufferFlags
+{
+ COGL_PIXEL_BUFFER_FLAG_NONE = 0,
+ COGL_PIXEL_BUFFER_FLAG_STORE_CREATED = 1 << 0,
+} CoglPixelBufferFlags;
+
+typedef struct _CoglPixelBuffer
+{
+ CoglBuffer _parent;
+
+ CoglPixelBufferFlags flags;
+
+ GLenum gl_target;
+ CoglPixelFormat format;
+ guint width;
+ guint height;
+ guint stride;
+
+} CoglPixelBuffer;
+
+GQuark _cogl_handle_pixel_buffer_get_type (void);
+
+G_END_DECLS
+
+#endif /* __COGL_PIXEL_BUFFER_PRIVATE_H__ */
--- /dev/null
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2010 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Damien Lespiau <damien.lespiau@intel.com>
+ */
+
+/* For an overview of the functionality implemented here, please see
+ * cogl-pixel-buffer.h, which contains the gtk-doc section overview for the
+ * Pixel Buffers API.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "cogl.h"
+#include "cogl-internal.h"
+#include "cogl-util.h"
+#include "cogl-context.h"
+#include "cogl-handle.h"
+#include "cogl-pixel-buffer-private.h"
+#include "cogl-pixel-buffer.h"
+
+/*
+ * GL/GLES compatibility defines for the buffer API:
+ */
+
+#if defined (HAVE_COGL_GL)
+
+#define glGenBuffers ctx->drv.pf_glGenBuffers
+#define glBindBuffer ctx->drv.pf_glBindBuffer
+#define glBufferData ctx->drv.pf_glBufferData
+#define glBufferSubData ctx->drv.pf_glBufferSubData
+#define glGetBufferSubData ctx->drv.pf_glGetBufferSubData
+#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
+#define glMapBuffer ctx->drv.pf_glMapBuffer
+#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
+#define glActiveTexture ctx->drv.pf_glActiveTexture
+#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
+
+#ifndef GL_PIXEL_UNPACK_BUFFER
+#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB
+#endif
+
+#ifndef GL_PIXEL_PACK_BUFFER
+#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB
+#endif
+
+#elif defined (HAVE_COGL_GLES2)
+
+#include "../gles/cogl-gles2-wrapper.h"
+
+#endif
+
+static void _cogl_pixel_buffer_free (CoglPixelBuffer *buffer);
+
+static const CoglBufferVtable cogl_pixel_buffer_vtable;
+
+/* we don't want to use the stock COGL_HANDLE_DEFINE * for 2 reasons:
+ * - it defines already deprecated symbols
+ * - we want to suffix the public symbols by _EXP */
+
+#define COGL_HANDLE_DEFINE_EXP(TypeName, type_name) \
+ \
+static CoglHandleClass _cogl_##type_name##_class; \
+ \
+GQuark \
+_cogl_handle_##type_name##_get_type (void) \
+{ \
+ static GQuark type = 0; \
+ if (!type) \
+ type = g_quark_from_static_string ("Cogl"#TypeName); \
+ return type; \
+} \
+ \
+static CoglHandle \
+_cogl_##type_name##_handle_new (Cogl##TypeName *new_obj) \
+{ \
+ CoglHandleObject *obj = (CoglHandleObject *)&new_obj->_parent;\
+ obj->ref_count = 1; \
+ \
+ obj->klass = &_cogl_##type_name##_class; \
+ if (!obj->klass->type) \
+ { \
+ obj->klass->type = _cogl_handle_##type_name##_get_type ();\
+ obj->klass->virt_free = _cogl_##type_name##_free; \
+ } \
+ \
+ _COGL_HANDLE_DEBUG_NEW (TypeName, obj); \
+ return (CoglHandle) new_obj; \
+} \
+ \
+Cogl##TypeName * \
+_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \
+{ \
+ return (Cogl##TypeName *) handle; \
+} \
+ \
+gboolean \
+cogl_is_##type_name##_EXP (CoglHandle handle) \
+{ \
+ CoglHandleObject *obj = (CoglHandleObject *)handle; \
+ \
+ if (handle == COGL_INVALID_HANDLE) \
+ return FALSE; \
+ \
+ return (obj->klass->type == \
+ _cogl_handle_##type_name##_get_type ()); \
+}
+
+COGL_HANDLE_DEFINE_EXP(PixelBuffer, pixel_buffer)
+
+CoglHandle
+cogl_pixel_buffer_new_EXP (guint size)
+{
+ CoglPixelBuffer *pixel_buffer = g_slice_new0 (CoglPixelBuffer);
+ CoglBuffer *buffer = COGL_BUFFER (pixel_buffer);
+
+ _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
+
+ /* parent's constructor */
+ _cogl_buffer_initialize (buffer,
+ 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);
+
+ pixel_buffer->flags = COGL_PIXEL_BUFFER_FLAG_NONE;
+
+ /* return COGL_INVALID_HANDLE; */
+ return _cogl_pixel_buffer_handle_new (pixel_buffer);
+}
+
+CoglHandle
+cogl_pixel_buffer_new_for_size_EXP (guint width,
+ guint height,
+ CoglPixelFormat format,
+ guint *rowstride)
+{
+ CoglHandle buffer;
+ CoglPixelBuffer *pixel_buffer;
+ guint stride;
+
+ /* 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_EXP, later, we could ask
+ * libdrm a tiled buffer for instance */
+ stride = width * _cogl_get_format_bpp (format);
+ if (rowstride)
+ *rowstride = stride;
+
+ buffer = cogl_pixel_buffer_new_EXP (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;
+}
+
+static void
+_cogl_pixel_buffer_free (CoglPixelBuffer *buffer)
+{
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ /* parent's destructor */
+ _cogl_buffer_fini (COGL_BUFFER (buffer));
+
+ GE( glDeleteBuffers (1, &(COGL_BUFFER (buffer)->gl_handle)) );
+
+ g_slice_free (CoglPixelBuffer, buffer);
+}
+
+static guchar *
+_cogl_pixel_buffer_map (CoglBuffer *buffer,
+ CoglBufferAccess access)
+{
+ CoglPixelBuffer *pixel_buffer = COGL_PIXEL_BUFFER (buffer);
+ GLenum gl_target;
+ guchar *data;
+
+ _COGL_GET_CONTEXT (ctx, NULL);
+
+ /* we determine the target lazily, on the first map */
+ gl_target = GL_PIXEL_UNPACK_BUFFER;
+ pixel_buffer->gl_target = gl_target;
+
+ _cogl_buffer_bind (buffer, gl_target);
+
+ /* create an empty store if we don't have one yet. creating the store
+ * lazily allows the user of the CoglBuffer to set a hint before the
+ * store is created. */
+ if (!COGL_PIXEL_BUFFER_FLAG_IS_SET (pixel_buffer, STORE_CREATED))
+ {
+ GE( glBufferData (gl_target,
+ buffer->size,
+ NULL,
+ _cogl_buffer_hints_to_gl_enum (buffer->usage_hint,
+ buffer->update_hint)) );
+ COGL_PIXEL_BUFFER_SET_FLAG (pixel_buffer, STORE_CREATED);
+ }
+
+ GE_RET( data, glMapBuffer (gl_target,
+ _cogl_buffer_access_to_gl_enum (access)) );
+ if (data)
+ COGL_BUFFER_SET_FLAG (buffer, MAPPED);
+
+ _cogl_buffer_bind (NULL, gl_target);
+
+ return data;
+}
+
+static void
+_cogl_pixel_buffer_unmap (CoglBuffer *buffer)
+{
+ CoglPixelBuffer *pixel_buffer = COGL_PIXEL_BUFFER (buffer);
+
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ _cogl_buffer_bind (buffer, pixel_buffer->gl_target);
+
+ GE( glUnmapBuffer (pixel_buffer->gl_target) );
+ COGL_BUFFER_CLEAR_FLAG (buffer, MAPPED);
+
+ _cogl_buffer_bind (NULL, pixel_buffer->gl_target);
+}
+
+static gboolean
+_cogl_pixel_buffer_set_data (CoglBuffer *buffer,
+ guint offset,
+ const guchar *data,
+ guint size)
+{
+ CoglPixelBuffer *pixel_buffer = COGL_PIXEL_BUFFER (buffer);
+
+ _COGL_GET_CONTEXT (ctx, FALSE);
+
+ pixel_buffer->gl_target = GL_PIXEL_UNPACK_BUFFER;
+
+ _cogl_buffer_bind (buffer, pixel_buffer->gl_target);
+
+ /* create an empty store if we don't have one yet. creating the store
+ * lazily allows the user of the CoglBuffer to set a hint before the
+ * store is created. */
+ if (!COGL_PIXEL_BUFFER_FLAG_IS_SET (pixel_buffer, STORE_CREATED))
+ {
+ GE( glBufferData (pixel_buffer->gl_target,
+ buffer->size,
+ NULL,
+ _cogl_buffer_hints_to_gl_enum (buffer->usage_hint,
+ buffer->update_hint)) );
+ COGL_PIXEL_BUFFER_SET_FLAG (pixel_buffer, STORE_CREATED);
+ }
+
+ GE( glBufferSubData (pixel_buffer->gl_target, offset, size, data) );
+
+ _cogl_buffer_bind (NULL, pixel_buffer->gl_target);
+
+ return TRUE;
+}
+
+#if 0
+gboolean
+cogl_pixel_buffer_set_region_EXP (CoglHandle buffer,
+ guchar *data,
+ guint src_width,
+ guint src_height,
+ guint src_rowstride,
+ guint dst_x,
+ guint dst_y)
+{
+ if (!cogl_is_pixel_buffer (buffer))
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
+static const CoglBufferVtable cogl_pixel_buffer_vtable =
+{
+ _cogl_pixel_buffer_map,
+ _cogl_pixel_buffer_unmap,
+ _cogl_pixel_buffer_set_data,
+};
--- /dev/null
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2008,2009 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Robert Bragg <robert@linux.intel.com>
+ */
+
+#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only <cogl/cogl.h> can be included directly."
+#endif
+
+#ifndef __COGL_PIXEL_BUFFER_H__
+#define __COGL_PIXEL_BUFFER_H__
+
+#include <glib.h>
+#include <cogl/cogl-types.h>
+
+G_BEGIN_DECLS
+
+/**
+ * cogl_pixel_buffer_new:
+ * @size: size of the buffer in bytes
+ *
+ * Creates a new buffer to store pixel data. You can create a new texture from
+ * this buffer using cogl_texture_new_from_buffer().
+ *
+ * Return value: a #CoglHandle representing the newly created buffer or
+ * %COGL_INVALID_HANDLE on failure
+ *
+ * Since: 1.2
+ * Stability: Unstable
+ */
+CoglHandle
+cogl_pixel_buffer_new (guint size);
+
+/**
+ * cogl_pixel_buffer_new_for_size:
+ * @width: width of the pixel buffer in pixels
+ * @height: height of the pixel buffer in pixels
+ * @format: the format of the pixels the buffer will store
+ * @stride: if not %NULL the function will return the stride of the buffer
+ * in bytes
+ *
+ * Creates a new buffer to store pixel data.
+ *
+ * <note>COGL will try its best to provide a hardware buffer 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
+ * buffers 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>
+ *
+ * Return value: a #CoglHandle representing the newly created buffer or
+ * %COGL_INVALID_HANDLE on failure
+ *
+ * Since: 1.2
+ * Stability: Unstable
+ */
+CoglHandle
+cogl_pixel_buffer_new_for_size (guint width,
+ guint height,
+ CoglPixelFormat format,
+ guint *stride);
+
+/**
+ * cogl_is_pixel_buffer:
+ * @handle: a #CoglHandle to test
+ *
+ * Checks whether @handle is a pixel buffer.
+ *
+ * Return value: %TRUE if the @handle is a pixel buffer, and %FALSE
+ * otherwise
+ *
+ * Since: 1.2
+ * Stability: Unstable
+ */
+gboolean
+cogl_is_pixel_buffer (CoglHandle handle);
+
+/*
+ * cogl_pixel_buffer_set_region:
+ * @buffer: the #CoglHandle of a pixel buffer
+ * @data: pixel data to upload to @buffer
+ * @src_width: width in pixels of the region to update
+ * @src_height: height in pixels of the region to update
+ * @src_rowstride: row stride in bytes of the source buffer
+ * @dst_x: upper left destination horizontal coordinate
+ * @dst_y: upper left destination vertical coordinate
+ *
+ * Uploads new data into a pixel buffer. The source data pointed by @data can
+ * have a different stride than @buffer in which case the function will do the
+ * right thing for you. For performance reasons, it is recommended for the
+ * source data to have the same stride than @buffer.
+ *
+ * Return value: %TRUE if the upload succeeded, %FALSE otherwise
+ *
+ * Since: 1.2
+ * Stability: Unstable
+ */
+#if 0
+gboolean
+cogl_pixel_buffer_set_region (CoglHandle buffer,
+ guchar *data,
+ guint src_width,
+ guint src_height,
+ guint src_rowstride,
+ guint dst_x,
+ guint dst_y);
+#endif
+
+/* the functions above are experimental, the actual symbols are suffixed by
+ * _EXP so we can ensure ABI compatibility and leave the cogl_buffer namespace
+ * free for future use. A bunch of defines translates the symbols documented
+ * above into the real symbols */
+
+CoglHandle
+cogl_pixel_buffer_new_EXP (guint size);
+
+CoglHandle
+cogl_pixel_buffer_new_for_size_EXP (guint width,
+ guint height,
+ CoglPixelFormat format,
+ guint *stride);
+gboolean
+cogl_is_pixel_buffer_EXP (CoglHandle handle);
+
+#if 0
+gboolean
+cogl_pixel_buffer_set_region_EXP (CoglHandle buffer,
+ guchar *data,
+ guint src_width,
+ guint src_height,
+ guint src_rowstride,
+ guint dst_x,
+ guint dst_y);
+#endif
+
+#define cogl_pixel_buffer_new cogl_pixel_buffer_new_EXP
+#define cogl_pixel_buffer_new_for_size cogl_pixel_buffer_new_for_size_EXP
+#define cogl_is_pixel_buffer cogl_is_pixel_buffer_EXP
+#if 0
+#define cogl_pixel_buffer_set_region cogl_pixel_buffer_set_region_EXP
+#endif
+
+G_END_DECLS
+
+#endif /* __COGL_PIXEL_BUFFER_H__ */