[Cogl] [PATCH] framebuffer: move fb stack under cogl/deprecated/

Robert Bragg robert at sixbynine.org
Thu Jan 2 07:09:34 PST 2014


From: Robert Bragg <robert at linux.intel.com>

This moves the framebuffer stack apis out of cogl-framebuffer.c into
cogl/deprecated/cogl-framebuffer-deprecated.c so cogl-framebuffer.c is
more in-line with the master branch to ease cherry picking patches.
---
 cogl/cogl-context.c                           |   2 +
 cogl/cogl-framebuffer.c                       | 252 -------------------------
 cogl/cogl1-context.h                          | 198 --------------------
 cogl/deprecated/cogl-framebuffer-deprecated.c | 255 +++++++++++++++++++++++++-
 cogl/deprecated/cogl-framebuffer-deprecated.h | 199 ++++++++++++++++++++
 5 files changed, 455 insertions(+), 451 deletions(-)

diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index 026df1c..75cfdb3 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -50,6 +50,8 @@
 #include "cogl-config-private.h"
 #include "cogl-error-private.h"
 
+#include "cogl/deprecated/cogl-framebuffer-deprecated.h"
+
 #include <string.h>
 #include <stdlib.h>
 
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index ef80edf..cb55dbe 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -50,12 +50,6 @@
 #include "cogl-error-private.h"
 #include "cogl-texture-gl-private.h"
 
-typedef struct _CoglFramebufferStackEntry
-{
-  CoglFramebuffer *draw_buffer;
-  CoglFramebuffer *read_buffer;
-} CoglFramebufferStackEntry;
-
 extern CoglObjectClass _cogl_onscreen_class;
 
 #ifdef COGL_ENABLE_DEBUG
@@ -801,252 +795,6 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
   return TRUE;
 }
 
-static CoglFramebufferStackEntry *
-create_stack_entry (CoglFramebuffer *draw_buffer,
-                    CoglFramebuffer *read_buffer)
-{
-  CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry);
-
-  entry->draw_buffer = draw_buffer;
-  entry->read_buffer = read_buffer;
-
-  return entry;
-}
-
-GSList *
-_cogl_create_framebuffer_stack (void)
-{
-  CoglFramebufferStackEntry *entry;
-  GSList *stack = NULL;
-
-  entry = create_stack_entry (NULL, NULL);
-
-  return g_slist_prepend (stack, entry);
-}
-
-void
-_cogl_free_framebuffer_stack (GSList *stack)
-{
-  GSList *l;
-
-  for (l = stack; l != NULL; l = l->next)
-    {
-      CoglFramebufferStackEntry *entry = l->data;
-
-      if (entry->draw_buffer)
-        cogl_object_unref (entry->draw_buffer);
-
-      if (entry->read_buffer)
-        cogl_object_unref (entry->draw_buffer);
-
-      g_slice_free (CoglFramebufferStackEntry, entry);
-    }
-  g_slist_free (stack);
-}
-
-static void
-notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
-                        CoglFramebuffer *new_draw_buffer,
-                        CoglFramebuffer *old_read_buffer,
-                        CoglFramebuffer *new_read_buffer)
-{
-  /* XXX: To support the deprecated cogl_set_draw_buffer API we keep
-   * track of the last onscreen framebuffer that was set so that it
-   * can be restored if the COGL_WINDOW_BUFFER enum is used. A
-   * reference isn't taken to the framebuffer because otherwise we
-   * would have a circular reference between the context and the
-   * framebuffer. Instead the pointer is set to NULL in
-   * _cogl_onscreen_free as a kind of a cheap weak reference */
-  if (new_draw_buffer &&
-      new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
-    new_draw_buffer->context->window_buffer = new_draw_buffer;
-}
-
-/* Set the current framebuffer without checking if it's already the
- * current framebuffer. This is used by cogl_pop_framebuffer while
- * the top of the stack is currently not up to date. */
-static void
-_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer,
-                             CoglFramebuffer *read_buffer)
-{
-  CoglFramebufferStackEntry *entry;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  _COGL_RETURN_IF_FAIL (ctx != NULL);
-  _COGL_RETURN_IF_FAIL (draw_buffer && read_buffer ?
-                    draw_buffer->context == read_buffer->context : TRUE);
-
-  entry = ctx->framebuffer_stack->data;
-
-  notify_buffers_changed (entry->draw_buffer,
-                          draw_buffer,
-                          entry->read_buffer,
-                          read_buffer);
-
-  if (draw_buffer)
-    cogl_object_ref (draw_buffer);
-  if (entry->draw_buffer)
-    cogl_object_unref (entry->draw_buffer);
-
-  if (read_buffer)
-    cogl_object_ref (read_buffer);
-  if (entry->read_buffer)
-    cogl_object_unref (entry->read_buffer);
-
-  entry->draw_buffer = draw_buffer;
-  entry->read_buffer = read_buffer;
-}
-
-static void
-_cogl_set_framebuffers (CoglFramebuffer *draw_buffer,
-                        CoglFramebuffer *read_buffer)
-{
-  CoglFramebuffer *current_draw_buffer;
-  CoglFramebuffer *current_read_buffer;
-
-  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer));
-  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer));
-
-  current_draw_buffer = cogl_get_draw_framebuffer ();
-  current_read_buffer = _cogl_get_read_framebuffer ();
-
-  if (current_draw_buffer != draw_buffer ||
-      current_read_buffer != read_buffer)
-    _cogl_set_framebuffers_real (draw_buffer, read_buffer);
-}
-
-void
-cogl_set_framebuffer (CoglFramebuffer *framebuffer)
-{
-  _cogl_set_framebuffers (framebuffer, framebuffer);
-}
-
-/* XXX: deprecated API */
-void
-cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle)
-{
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  if (target == COGL_WINDOW_BUFFER)
-    handle = ctx->window_buffer;
-
-  /* This is deprecated public API. The public API doesn't currently
-     really expose the concept of separate draw and read buffers so
-     for the time being this actually just sets both buffers */
-  cogl_set_framebuffer (handle);
-}
-
-CoglFramebuffer *
-cogl_get_draw_framebuffer (void)
-{
-  CoglFramebufferStackEntry *entry;
-
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  g_assert (ctx->framebuffer_stack);
-
-  entry = ctx->framebuffer_stack->data;
-
-  return entry->draw_buffer;
-}
-
-CoglFramebuffer *
-_cogl_get_read_framebuffer (void)
-{
-  CoglFramebufferStackEntry *entry;
-
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  g_assert (ctx->framebuffer_stack);
-
-  entry = ctx->framebuffer_stack->data;
-
-  return entry->read_buffer;
-}
-
-void
-_cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
-                         CoglFramebuffer *read_buffer)
-{
-  CoglContext *ctx;
-  CoglFramebuffer *old_draw_buffer, *old_read_buffer;
-
-  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer));
-  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer));
-
-  ctx = draw_buffer->context;
-  _COGL_RETURN_IF_FAIL (ctx != NULL);
-  _COGL_RETURN_IF_FAIL (draw_buffer->context == read_buffer->context);
-
-  _COGL_RETURN_IF_FAIL (ctx->framebuffer_stack != NULL);
-
-  /* Copy the top of the stack so that when we call cogl_set_framebuffer
-     it will still know what the old framebuffer was */
-  old_draw_buffer = cogl_get_draw_framebuffer ();
-  if (old_draw_buffer)
-    cogl_object_ref (old_draw_buffer);
-  old_read_buffer = _cogl_get_read_framebuffer ();
-  if (old_read_buffer)
-    cogl_object_ref (old_read_buffer);
-  ctx->framebuffer_stack =
-    g_slist_prepend (ctx->framebuffer_stack,
-                     create_stack_entry (old_draw_buffer,
-                                         old_read_buffer));
-
-  _cogl_set_framebuffers (draw_buffer, read_buffer);
-}
-
-void
-cogl_push_framebuffer (CoglFramebuffer *buffer)
-{
-  _cogl_push_framebuffers (buffer, buffer);
-}
-
-/* XXX: deprecated API */
-void
-cogl_push_draw_buffer (void)
-{
-  cogl_push_framebuffer (cogl_get_draw_framebuffer ());
-}
-
-void
-cogl_pop_framebuffer (void)
-{
-  CoglFramebufferStackEntry *to_pop;
-  CoglFramebufferStackEntry *to_restore;
-
-  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
-  g_assert (ctx->framebuffer_stack != NULL);
-  g_assert (ctx->framebuffer_stack->next != NULL);
-
-  to_pop = ctx->framebuffer_stack->data;
-  to_restore = ctx->framebuffer_stack->next->data;
-
-  if (to_pop->draw_buffer != to_restore->draw_buffer ||
-      to_pop->read_buffer != to_restore->read_buffer)
-    notify_buffers_changed (to_pop->draw_buffer,
-                            to_restore->draw_buffer,
-                            to_pop->read_buffer,
-                            to_restore->read_buffer);
-
-  cogl_object_unref (to_pop->draw_buffer);
-  cogl_object_unref (to_pop->read_buffer);
-  g_slice_free (CoglFramebufferStackEntry, to_pop);
-
-  ctx->framebuffer_stack =
-    g_slist_delete_link (ctx->framebuffer_stack,
-                         ctx->framebuffer_stack);
-}
-
-/* XXX: deprecated API */
-void
-cogl_pop_draw_buffer (void)
-{
-  cogl_pop_framebuffer ();
-}
-
 static unsigned long
 _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a,
                                           CoglFramebuffer *b)
diff --git a/cogl/cogl1-context.h b/cogl/cogl1-context.h
index 53c9783..754dfb9 100644
--- a/cogl/cogl1-context.h
+++ b/cogl/cogl1-context.h
@@ -732,204 +732,6 @@ void
 cogl_set_source_texture (CoglTexture *texture);
 
 /**
- * cogl_set_framebuffer:
- * @buffer: A #CoglFramebuffer object, either onscreen or offscreen.
- *
- * This redirects all subsequent drawing to the specified framebuffer. This can
- * either be an offscreen buffer created with cogl_offscreen_new_to_texture ()
- * or in the future it may be an onscreen framebuffers too.
- *
- * Since: 1.2
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_set_framebuffer (CoglFramebuffer *buffer);
-
-/**
- * cogl_push_framebuffer:
- * @buffer: A #CoglFramebuffer object, either onscreen or offscreen.
- *
- * Redirects all subsequent drawing to the specified framebuffer. This can
- * either be an offscreen buffer created with cogl_offscreen_new_to_texture ()
- * or in the future it may be an onscreen framebuffer too.
- *
- * You should understand that a framebuffer owns the following state:
- * <itemizedlist>
- *  <listitem><simpara>The projection matrix</simpara></listitem>
- *  <listitem><simpara>The modelview matrix stack</simpara></listitem>
- *  <listitem><simpara>The viewport</simpara></listitem>
- *  <listitem><simpara>The clip stack</simpara></listitem>
- * </itemizedlist>
- * So these items will automatically be saved and restored when you
- * push and pop between different framebuffers.
- *
- * Also remember a newly allocated framebuffer will have an identity matrix for
- * the projection and modelview matrices which gives you a coordinate space
- * like OpenGL with (-1, -1) corresponding to the top left of the viewport,
- * (1, 1) corresponding to the bottom right and +z coming out towards the
- * viewer.
- *
- * If you want to set up a coordinate space like Clutter does with (0, 0)
- * corresponding to the top left and (framebuffer_width, framebuffer_height)
- * corresponding to the bottom right you can do so like this:
- *
- * |[
- * static void
- * setup_viewport (unsigned int width,
- *                 unsigned int height,
- *                 float fovy,
- *                 float aspect,
- *                 float z_near,
- *                 float z_far)
- * {
- *   float z_camera;
- *   CoglMatrix projection_matrix;
- *   CoglMatrix mv_matrix;
- *
- *   cogl_set_viewport (0, 0, width, height);
- *   cogl_perspective (fovy, aspect, z_near, z_far);
- *
- *   cogl_get_projection_matrix (&projection_matrix);
- *   z_camera = 0.5 * projection_matrix.xx;
- *
- *   cogl_matrix_init_identity (&mv_matrix);
- *   cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera);
- *   cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width);
- *   cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f);
- *   cogl_set_modelview_matrix (&mv_matrix);
- * }
- *
- * static void
- * my_init_framebuffer (ClutterStage *stage,
- *                      CoglFramebuffer *framebuffer,
- *                      unsigned int framebuffer_width,
- *                      unsigned int framebuffer_height)
- * {
- *   ClutterPerspective perspective;
- *
- *   clutter_stage_get_perspective (stage, &perspective);
- *
- *   cogl_push_framebuffer (framebuffer);
- *   setup_viewport (framebuffer_width,
- *                   framebuffer_height,
- *                   perspective.fovy,
- *                   perspective.aspect,
- *                   perspective.z_near,
- *                   perspective.z_far);
- * }
- * ]|
- *
- * The previous framebuffer can be restored by calling cogl_pop_framebuffer()
- *
- * Since: 1.2
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_push_framebuffer (CoglFramebuffer *buffer);
-
-/**
- * cogl_pop_framebuffer:
- *
- * Restores the framebuffer that was previously at the top of the stack.
- * All subsequent drawing will be redirected to this framebuffer.
- *
- * Since: 1.2
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_pop_framebuffer (void);
-
-/**
- * cogl_set_draw_buffer:
- * @target: A #CoglBufferTarget that specifies what kind of framebuffer you
- *          are setting as the render target.
- * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER
- *             then this is a CoglHandle for the offscreen buffer.
- *
- * Redirects all subsequent drawing to the specified framebuffer. This
- * can either be an offscreen buffer created with
- * cogl_offscreen_new_to_texture () or you can revert to your original
- * on screen window buffer.
- *
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_set_draw_buffer (CoglBufferTarget target,
-                      CoglHandle offscreen);
-
-/**
- * cogl_push_draw_buffer:
- *
- * Save cogl_set_draw_buffer() state.
- *
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_push_draw_buffer (void);
-
-/**
- * cogl_pop_draw_buffer:
- *
- * Restore cogl_set_draw_buffer() state.
- *
- * Deprecated: 1.16: The latest drawing apis take explicit
- *                   #CoglFramebuffer arguments so this stack of
- *                   framebuffers shouldn't be used anymore.
- */
-COGL_DEPRECATED_IN_1_16
-void
-cogl_pop_draw_buffer (void);
-
-/**
- * cogl_read_pixels:
- * @x: The window x position to start reading from
- * @y: The window y position to start reading from
- * @width: The width of the rectangle you want to read
- * @height: The height of the rectangle you want to read
- * @source: Identifies which auxillary buffer you want to read
- *          (only COGL_READ_PIXELS_COLOR_BUFFER supported currently)
- * @format: The pixel format you want the result in
- *          (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently)
- * @pixels: The location to write the pixel data.
- *
- * This reads a rectangle of pixels from the current framebuffer where
- * position (0, 0) is the top left. The pixel at (x, y) is the first
- * read, and the data is returned with a rowstride of (width * 4).
- *
- * Currently Cogl assumes that the framebuffer is in a premultiplied
- * format so if @format is non-premultiplied it will convert it. To
- * read the pixel values without any conversion you should either
- * specify a format that doesn't use an alpha channel or use one of
- * the formats ending in PRE.
- *
- * Deprecated: 1.16: Use cogl_framebuffer_read_pixels() instead
- */
-COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_read_pixels)
-void
-cogl_read_pixels (int x,
-                  int y,
-                  int width,
-                  int height,
-                  CoglReadPixelsFlags source,
-                  CoglPixelFormat format,
-                  uint8_t *pixels);
-
-/**
  * cogl_flush:
  *
  * This function should only need to be called in exceptional circumstances.
diff --git a/cogl/deprecated/cogl-framebuffer-deprecated.c b/cogl/deprecated/cogl-framebuffer-deprecated.c
index dc099d9..fe314ee 100644
--- a/cogl/deprecated/cogl-framebuffer-deprecated.c
+++ b/cogl/deprecated/cogl-framebuffer-deprecated.c
@@ -25,12 +25,265 @@
 #include <config.h>
 
 #include "cogl-types.h"
+#include "cogl-context-private.h"
 #include "cogl-framebuffer-private.h"
 #include "cogl-framebuffer-deprecated.h"
 
+typedef struct _CoglFramebufferStackEntry
+{
+  CoglFramebuffer *draw_buffer;
+  CoglFramebuffer *read_buffer;
+} CoglFramebufferStackEntry;
+
+
+static CoglFramebufferStackEntry *
+create_stack_entry (CoglFramebuffer *draw_buffer,
+                    CoglFramebuffer *read_buffer)
+{
+  CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry);
+
+  entry->draw_buffer = draw_buffer;
+  entry->read_buffer = read_buffer;
+
+  return entry;
+}
+
+GSList *
+_cogl_create_framebuffer_stack (void)
+{
+  CoglFramebufferStackEntry *entry;
+  GSList *stack = NULL;
+
+  entry = create_stack_entry (NULL, NULL);
+
+  return g_slist_prepend (stack, entry);
+}
+
+void
+_cogl_free_framebuffer_stack (GSList *stack)
+{
+  GSList *l;
+
+  for (l = stack; l != NULL; l = l->next)
+    {
+      CoglFramebufferStackEntry *entry = l->data;
+
+      if (entry->draw_buffer)
+        cogl_object_unref (entry->draw_buffer);
+
+      if (entry->read_buffer)
+        cogl_object_unref (entry->draw_buffer);
+
+      g_slice_free (CoglFramebufferStackEntry, entry);
+    }
+  g_slist_free (stack);
+}
+
+static void
+notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
+                        CoglFramebuffer *new_draw_buffer,
+                        CoglFramebuffer *old_read_buffer,
+                        CoglFramebuffer *new_read_buffer)
+{
+  /* XXX: To support the deprecated cogl_set_draw_buffer API we keep
+   * track of the last onscreen framebuffer that was set so that it
+   * can be restored if the COGL_WINDOW_BUFFER enum is used. A
+   * reference isn't taken to the framebuffer because otherwise we
+   * would have a circular reference between the context and the
+   * framebuffer. Instead the pointer is set to NULL in
+   * _cogl_onscreen_free as a kind of a cheap weak reference */
+  if (new_draw_buffer &&
+      new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+    new_draw_buffer->context->window_buffer = new_draw_buffer;
+}
+
+/* Set the current framebuffer without checking if it's already the
+ * current framebuffer. This is used by cogl_pop_framebuffer while
+ * the top of the stack is currently not up to date. */
+static void
+_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer,
+                             CoglFramebuffer *read_buffer)
+{
+  CoglFramebufferStackEntry *entry;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  _COGL_RETURN_IF_FAIL (ctx != NULL);
+  _COGL_RETURN_IF_FAIL (draw_buffer && read_buffer ?
+                    draw_buffer->context == read_buffer->context : TRUE);
+
+  entry = ctx->framebuffer_stack->data;
+
+  notify_buffers_changed (entry->draw_buffer,
+                          draw_buffer,
+                          entry->read_buffer,
+                          read_buffer);
+
+  if (draw_buffer)
+    cogl_object_ref (draw_buffer);
+  if (entry->draw_buffer)
+    cogl_object_unref (entry->draw_buffer);
+
+  if (read_buffer)
+    cogl_object_ref (read_buffer);
+  if (entry->read_buffer)
+    cogl_object_unref (entry->read_buffer);
+
+  entry->draw_buffer = draw_buffer;
+  entry->read_buffer = read_buffer;
+}
+
+static void
+_cogl_set_framebuffers (CoglFramebuffer *draw_buffer,
+                        CoglFramebuffer *read_buffer)
+{
+  CoglFramebuffer *current_draw_buffer;
+  CoglFramebuffer *current_read_buffer;
+
+  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer));
+  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer));
+
+  current_draw_buffer = cogl_get_draw_framebuffer ();
+  current_read_buffer = _cogl_get_read_framebuffer ();
+
+  if (current_draw_buffer != draw_buffer ||
+      current_read_buffer != read_buffer)
+    _cogl_set_framebuffers_real (draw_buffer, read_buffer);
+}
+
+void
+cogl_set_framebuffer (CoglFramebuffer *framebuffer)
+{
+  _cogl_set_framebuffers (framebuffer, framebuffer);
+}
+
+/* XXX: deprecated API */
+void
+cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle)
+{
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  if (target == COGL_WINDOW_BUFFER)
+    handle = ctx->window_buffer;
+
+  /* This is deprecated public API. The public API doesn't currently
+     really expose the concept of separate draw and read buffers so
+     for the time being this actually just sets both buffers */
+  cogl_set_framebuffer (handle);
+}
+
+CoglFramebuffer *
+cogl_get_draw_framebuffer (void)
+{
+  CoglFramebufferStackEntry *entry;
+
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  g_assert (ctx->framebuffer_stack);
+
+  entry = ctx->framebuffer_stack->data;
+
+  return entry->draw_buffer;
+}
+
+CoglFramebuffer *
+_cogl_get_read_framebuffer (void)
+{
+  CoglFramebufferStackEntry *entry;
+
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  g_assert (ctx->framebuffer_stack);
+
+  entry = ctx->framebuffer_stack->data;
+
+  return entry->read_buffer;
+}
+
+void
+_cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
+                         CoglFramebuffer *read_buffer)
+{
+  CoglContext *ctx;
+  CoglFramebuffer *old_draw_buffer, *old_read_buffer;
+
+  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer));
+  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer));
+
+  ctx = draw_buffer->context;
+  _COGL_RETURN_IF_FAIL (ctx != NULL);
+  _COGL_RETURN_IF_FAIL (draw_buffer->context == read_buffer->context);
+
+  _COGL_RETURN_IF_FAIL (ctx->framebuffer_stack != NULL);
+
+  /* Copy the top of the stack so that when we call cogl_set_framebuffer
+     it will still know what the old framebuffer was */
+  old_draw_buffer = cogl_get_draw_framebuffer ();
+  if (old_draw_buffer)
+    cogl_object_ref (old_draw_buffer);
+  old_read_buffer = _cogl_get_read_framebuffer ();
+  if (old_read_buffer)
+    cogl_object_ref (old_read_buffer);
+  ctx->framebuffer_stack =
+    g_slist_prepend (ctx->framebuffer_stack,
+                     create_stack_entry (old_draw_buffer,
+                                         old_read_buffer));
+
+  _cogl_set_framebuffers (draw_buffer, read_buffer);
+}
+
+void
+cogl_push_framebuffer (CoglFramebuffer *buffer)
+{
+  _cogl_push_framebuffers (buffer, buffer);
+}
+
+/* XXX: deprecated API */
+void
+cogl_push_draw_buffer (void)
+{
+  cogl_push_framebuffer (cogl_get_draw_framebuffer ());
+}
+
+void
+cogl_pop_framebuffer (void)
+{
+  CoglFramebufferStackEntry *to_pop;
+  CoglFramebufferStackEntry *to_restore;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  g_assert (ctx->framebuffer_stack != NULL);
+  g_assert (ctx->framebuffer_stack->next != NULL);
+
+  to_pop = ctx->framebuffer_stack->data;
+  to_restore = ctx->framebuffer_stack->next->data;
+
+  if (to_pop->draw_buffer != to_restore->draw_buffer ||
+      to_pop->read_buffer != to_restore->read_buffer)
+    notify_buffers_changed (to_pop->draw_buffer,
+                            to_restore->draw_buffer,
+                            to_pop->read_buffer,
+                            to_restore->read_buffer);
+
+  cogl_object_unref (to_pop->draw_buffer);
+  cogl_object_unref (to_pop->read_buffer);
+  g_slice_free (CoglFramebufferStackEntry, to_pop);
+
+  ctx->framebuffer_stack =
+    g_slist_delete_link (ctx->framebuffer_stack,
+                         ctx->framebuffer_stack);
+}
+
+/* XXX: deprecated API */
+void
+cogl_pop_draw_buffer (void)
+{
+  cogl_pop_framebuffer ();
+}
+
 CoglPixelFormat
 cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer)
 {
   return framebuffer->internal_format;
 }
-
diff --git a/cogl/deprecated/cogl-framebuffer-deprecated.h b/cogl/deprecated/cogl-framebuffer-deprecated.h
index 92962bd..eccfecb 100644
--- a/cogl/deprecated/cogl-framebuffer-deprecated.h
+++ b/cogl/deprecated/cogl-framebuffer-deprecated.h
@@ -27,6 +27,205 @@
 
 #include <cogl/cogl-macros.h>
 
+/**
+ * cogl_set_framebuffer:
+ * @buffer: A #CoglFramebuffer object, either onscreen or offscreen.
+ *
+ * This redirects all subsequent drawing to the specified framebuffer. This can
+ * either be an offscreen buffer created with cogl_offscreen_new_to_texture ()
+ * or in the future it may be an onscreen framebuffers too.
+ *
+ * Since: 1.2
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_set_framebuffer (CoglFramebuffer *buffer);
+
+/**
+ * cogl_push_framebuffer:
+ * @buffer: A #CoglFramebuffer object, either onscreen or offscreen.
+ *
+ * Redirects all subsequent drawing to the specified framebuffer. This can
+ * either be an offscreen buffer created with cogl_offscreen_new_to_texture ()
+ * or in the future it may be an onscreen framebuffer too.
+ *
+ * You should understand that a framebuffer owns the following state:
+ * <itemizedlist>
+ *  <listitem><simpara>The projection matrix</simpara></listitem>
+ *  <listitem><simpara>The modelview matrix stack</simpara></listitem>
+ *  <listitem><simpara>The viewport</simpara></listitem>
+ *  <listitem><simpara>The clip stack</simpara></listitem>
+ * </itemizedlist>
+ * So these items will automatically be saved and restored when you
+ * push and pop between different framebuffers.
+ *
+ * Also remember a newly allocated framebuffer will have an identity matrix for
+ * the projection and modelview matrices which gives you a coordinate space
+ * like OpenGL with (-1, -1) corresponding to the top left of the viewport,
+ * (1, 1) corresponding to the bottom right and +z coming out towards the
+ * viewer.
+ *
+ * If you want to set up a coordinate space like Clutter does with (0, 0)
+ * corresponding to the top left and (framebuffer_width, framebuffer_height)
+ * corresponding to the bottom right you can do so like this:
+ *
+ * |[
+ * static void
+ * setup_viewport (unsigned int width,
+ *                 unsigned int height,
+ *                 float fovy,
+ *                 float aspect,
+ *                 float z_near,
+ *                 float z_far)
+ * {
+ *   float z_camera;
+ *   CoglMatrix projection_matrix;
+ *   CoglMatrix mv_matrix;
+ *
+ *   cogl_set_viewport (0, 0, width, height);
+ *   cogl_perspective (fovy, aspect, z_near, z_far);
+ *
+ *   cogl_get_projection_matrix (&projection_matrix);
+ *   z_camera = 0.5 * projection_matrix.xx;
+ *
+ *   cogl_matrix_init_identity (&mv_matrix);
+ *   cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera);
+ *   cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width);
+ *   cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f);
+ *   cogl_set_modelview_matrix (&mv_matrix);
+ * }
+ *
+ * static void
+ * my_init_framebuffer (ClutterStage *stage,
+ *                      CoglFramebuffer *framebuffer,
+ *                      unsigned int framebuffer_width,
+ *                      unsigned int framebuffer_height)
+ * {
+ *   ClutterPerspective perspective;
+ *
+ *   clutter_stage_get_perspective (stage, &perspective);
+ *
+ *   cogl_push_framebuffer (framebuffer);
+ *   setup_viewport (framebuffer_width,
+ *                   framebuffer_height,
+ *                   perspective.fovy,
+ *                   perspective.aspect,
+ *                   perspective.z_near,
+ *                   perspective.z_far);
+ * }
+ * ]|
+ *
+ * The previous framebuffer can be restored by calling cogl_pop_framebuffer()
+ *
+ * Since: 1.2
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_push_framebuffer (CoglFramebuffer *buffer);
+
+/**
+ * cogl_pop_framebuffer:
+ *
+ * Restores the framebuffer that was previously at the top of the stack.
+ * All subsequent drawing will be redirected to this framebuffer.
+ *
+ * Since: 1.2
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_pop_framebuffer (void);
+
+/**
+ * cogl_set_draw_buffer:
+ * @target: A #CoglBufferTarget that specifies what kind of framebuffer you
+ *          are setting as the render target.
+ * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER
+ *             then this is a CoglHandle for the offscreen buffer.
+ *
+ * Redirects all subsequent drawing to the specified framebuffer. This
+ * can either be an offscreen buffer created with
+ * cogl_offscreen_new_to_texture () or you can revert to your original
+ * on screen window buffer.
+ *
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_set_draw_buffer (CoglBufferTarget target,
+                      CoglHandle offscreen);
+
+/**
+ * cogl_push_draw_buffer:
+ *
+ * Save cogl_set_draw_buffer() state.
+ *
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_push_draw_buffer (void);
+
+/**
+ * cogl_pop_draw_buffer:
+ *
+ * Restore cogl_set_draw_buffer() state.
+ *
+ * Deprecated: 1.16: The latest drawing apis take explicit
+ *                   #CoglFramebuffer arguments so this stack of
+ *                   framebuffers shouldn't be used anymore.
+ */
+COGL_DEPRECATED_IN_1_16
+void
+cogl_pop_draw_buffer (void);
+
+/**
+ * cogl_read_pixels:
+ * @x: The window x position to start reading from
+ * @y: The window y position to start reading from
+ * @width: The width of the rectangle you want to read
+ * @height: The height of the rectangle you want to read
+ * @source: Identifies which auxillary buffer you want to read
+ *          (only COGL_READ_PIXELS_COLOR_BUFFER supported currently)
+ * @format: The pixel format you want the result in
+ *          (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently)
+ * @pixels: The location to write the pixel data.
+ *
+ * This reads a rectangle of pixels from the current framebuffer where
+ * position (0, 0) is the top left. The pixel at (x, y) is the first
+ * read, and the data is returned with a rowstride of (width * 4).
+ *
+ * Currently Cogl assumes that the framebuffer is in a premultiplied
+ * format so if @format is non-premultiplied it will convert it. To
+ * read the pixel values without any conversion you should either
+ * specify a format that doesn't use an alpha channel or use one of
+ * the formats ending in PRE.
+ *
+ * Deprecated: 1.16: Use cogl_framebuffer_read_pixels() instead
+ */
+COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_read_pixels)
+void
+cogl_read_pixels (int x,
+                  int y,
+                  int width,
+                  int height,
+                  CoglReadPixelsFlags source,
+                  CoglPixelFormat format,
+                  uint8_t *pixels);
+
+
 /* XXX: Since this api was marked unstable, maybe we can just
  * remove this api if we can't find anyone is using it. */
 /**
-- 
1.8.5.2



More information about the Cogl mailing list