[Cogl] [PATCH] blit: avoid referring to framebuffer stack

Robert Bragg robert at sixbynine.org
Mon Nov 19 08:53:22 PST 2012


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

This make _cogl_framebuffer_blit take explicit src and dest framebuffer
pointers and updates all the texture blitting strategies in cogl-blit.c
to avoid pushing/popping to/from the the framebuffer stack.

The removes the last user of the framebuffer stack which we've been
aiming to remove before Cogl 2.0
---
 cogl/cogl-blit.c                    |   84 +++++++++++++++++++----------------
 cogl/cogl-blit.h                    |   27 ++++++-----
 cogl/cogl-framebuffer-private.h     |   16 ++++---
 cogl/cogl-framebuffer.c             |   48 +++++++++-----------
 cogl/cogl-texture-2d-private.h      |    4 +-
 cogl/cogl-texture-2d.c              |   10 +---
 cogl/driver/gl/cogl-texture-2d-gl.c |    2 +-
 7 files changed, 97 insertions(+), 94 deletions(-)

diff --git a/cogl/cogl-blit.c b/cogl/cogl-blit.c
index 7c495e4..d74356d 100644
--- a/cogl/cogl-blit.c
+++ b/cogl/cogl-blit.c
@@ -63,7 +63,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
       return FALSE;
     }
 
-  data->fb = fb;
+  data->dest_fb = fb;
 
   dst_width = cogl_texture_get_width (data->dst_tex);
   dst_height = cogl_texture_get_height (data->dst_tex);
@@ -103,14 +103,14 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
 
 static void
 _cogl_blit_texture_render_blit (CoglBlitData *data,
-                                unsigned int src_x,
-                                unsigned int src_y,
-                                unsigned int dst_x,
-                                unsigned int dst_y,
-                                unsigned int width,
-                                unsigned int height)
+                                int src_x,
+                                int src_y,
+                                int dst_x,
+                                int dst_y,
+                                int width,
+                                int height)
 {
-  cogl_framebuffer_draw_textured_rectangle (data->fb,
+  cogl_framebuffer_draw_textured_rectangle (data->dest_fb,
                                             data->pipeline,
                                             dst_x, dst_y,
                                             dst_x + width,
@@ -139,7 +139,7 @@ _cogl_blit_texture_render_end (CoglBlitData *data)
   cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0,
                                    data->dst_tex);
 
-  cogl_object_unref (data->fb);
+  cogl_object_unref (data->dest_fb);
 }
 
 static CoglBool
@@ -177,7 +177,8 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
   if (!cogl_framebuffer_allocate (src_fb, NULL))
     goto error;
 
-  _cogl_push_framebuffers (dst_fb, src_fb);
+  data->src_fb = src_fb;
+  data->dest_fb = dst_fb;
 
   return TRUE;
 
@@ -193,14 +194,16 @@ error:
 
 static void
 _cogl_blit_framebuffer_blit (CoglBlitData *data,
-                             unsigned int src_x,
-                             unsigned int src_y,
-                             unsigned int dst_x,
-                             unsigned int dst_y,
-                             unsigned int width,
-                             unsigned int height)
+                             int src_x,
+                             int src_y,
+                             int dst_x,
+                             int dst_y,
+                             int width,
+                             int height)
 {
-  _cogl_blit_framebuffer (src_x, src_y,
+  _cogl_blit_framebuffer (data->src_fb,
+                          data->dest_fb,
+                          src_x, src_y,
                           dst_x, dst_y,
                           width, height);
 }
@@ -208,7 +211,8 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data,
 static void
 _cogl_blit_framebuffer_end (CoglBlitData *data)
 {
-  cogl_pop_framebuffer ();
+  cogl_object_unref (data->src_fb);
+  cogl_object_unref (data->dest_fb);
 }
 
 static CoglBool
@@ -234,22 +238,22 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
       return FALSE;
     }
 
-  cogl_push_framebuffer (fb);
-  cogl_object_unref (fb);
+  data->src_fb = fb;
 
   return TRUE;
 }
 
 static void
 _cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data,
-                                    unsigned int src_x,
-                                    unsigned int src_y,
-                                    unsigned int dst_x,
-                                    unsigned int dst_y,
-                                    unsigned int width,
-                                    unsigned int height)
+                                    int src_x,
+                                    int src_y,
+                                    int dst_x,
+                                    int dst_y,
+                                    int width,
+                                    int height)
 {
   _cogl_texture_2d_copy_from_framebuffer (COGL_TEXTURE_2D (data->dst_tex),
+                                          data->src_fb,
                                           dst_x, dst_y,
                                           src_x, src_y,
                                           width, height);
@@ -258,7 +262,7 @@ _cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data,
 static void
 _cogl_blit_copy_tex_sub_image_end (CoglBlitData *data)
 {
-  cogl_pop_framebuffer ();
+  cogl_object_unref (data->src_fb);
 }
 
 static CoglBool
@@ -277,12 +281,12 @@ _cogl_blit_get_tex_data_begin (CoglBlitData *data)
 
 static void
 _cogl_blit_get_tex_data_blit (CoglBlitData *data,
-                              unsigned int src_x,
-                              unsigned int src_y,
-                              unsigned int dst_x,
-                              unsigned int dst_y,
-                              unsigned int width,
-                              unsigned int height)
+                              int src_x,
+                              int src_y,
+                              int dst_x,
+                              int dst_y,
+                              int width,
+                              int height)
 {
   CoglError *ignore = NULL;
   cogl_texture_set_region (data->dst_tex,
@@ -370,6 +374,8 @@ _cogl_blit_begin (CoglBlitData *data,
         _cogl_blit_default_mode = _cogl_blit_modes;
     }
 
+  memset (data, 0, sizeof (CoglBlitData));
+
   data->dst_tex = dst_tex;
   data->src_tex = src_tex;
 
@@ -407,12 +413,12 @@ _cogl_blit_begin (CoglBlitData *data,
 
 void
 _cogl_blit (CoglBlitData *data,
-            unsigned int src_x,
-            unsigned int src_y,
-            unsigned int dst_x,
-            unsigned int dst_y,
-            unsigned int width,
-            unsigned int height)
+            int src_x,
+            int src_y,
+            int dst_x,
+            int dst_y,
+            int width,
+            int height)
 {
   data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height);
 }
diff --git a/cogl/cogl-blit.h b/cogl/cogl-blit.h
index 364e9b1..190c1be 100644
--- a/cogl/cogl-blit.h
+++ b/cogl/cogl-blit.h
@@ -40,12 +40,12 @@ typedef CoglBool (* CoglBlitBeginFunc) (CoglBlitData *data);
 typedef void (* CoglBlitEndFunc) (CoglBlitData *data);
 
 typedef void (* CoglBlitFunc) (CoglBlitData *data,
-                               unsigned int src_x,
-                               unsigned int src_y,
-                               unsigned int dst_x,
-                               unsigned int dst_y,
-                               unsigned int width,
-                               unsigned int height);
+                               int src_x,
+                               int src_y,
+                               int dst_x,
+                               int dst_y,
+                               int width,
+                               int height);
 
 typedef struct
 {
@@ -71,7 +71,8 @@ struct _CoglBlitData
 
   int bpp;
 
-  CoglFramebuffer *fb;
+  CoglFramebuffer *src_fb;
+  CoglFramebuffer *dest_fb;
   CoglPipeline *pipeline;
 };
 
@@ -82,12 +83,12 @@ _cogl_blit_begin (CoglBlitData *data,
 
 void
 _cogl_blit (CoglBlitData *data,
-            unsigned int src_x,
-            unsigned int src_y,
-            unsigned int dst_x,
-            unsigned int dst_y,
-            unsigned int width,
-            unsigned int height);
+            int src_x,
+            int src_y,
+            int dst_x,
+            int dst_y,
+            int width,
+            int height);
 
 void
 _cogl_blit_end (CoglBlitData *data);
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 1dd83f0..be7470e 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -325,6 +325,8 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
 
 /*
  * _cogl_blit_framebuffer:
+ * @src: The source #CoglFramebuffer
+ * @dest: The destination #CoglFramebuffer
  * @src_x: Source x position
  * @src_y: Source y position
  * @dst_x: Destination x position
@@ -369,12 +371,14 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
  * a separate function to copy the entire buffer for a given mask.
  */
 void
-_cogl_blit_framebuffer (unsigned int src_x,
-                        unsigned int src_y,
-                        unsigned int dst_x,
-                        unsigned int dst_y,
-                        unsigned int width,
-                        unsigned int height);
+_cogl_blit_framebuffer (CoglFramebuffer *src,
+                        CoglFramebuffer *dest,
+                        int src_x,
+                        int src_y,
+                        int dst_x,
+                        int dst_y,
+                        int width,
+                        int height);
 
 void
 _cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 53e4b65..8d57f59 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -1783,38 +1783,32 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
 }
 
 void
-_cogl_blit_framebuffer (unsigned int src_x,
-                        unsigned int src_y,
-                        unsigned int dst_x,
-                        unsigned int dst_y,
-                        unsigned int width,
-                        unsigned int height)
+_cogl_blit_framebuffer (CoglFramebuffer *src,
+                        CoglFramebuffer *dest,
+                        int src_x,
+                        int src_y,
+                        int dst_x,
+                        int dst_y,
+                        int width,
+                        int height)
 {
-  CoglFramebuffer *draw_buffer;
-  CoglFramebuffer *read_buffer;
-  CoglContext *ctx;
-
-  /* FIXME: this function should take explit src and dst framebuffer
-   * arguments. */
-  draw_buffer = cogl_get_draw_framebuffer ();
-  read_buffer = _cogl_get_read_framebuffer ();
-  ctx = draw_buffer->context;
+  CoglContext *ctx = src->context;
 
   _COGL_RETURN_IF_FAIL (ctx->private_feature_flags &
-                    COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT);
+                        COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT);
 
   /* We can only support blitting between offscreen buffers because
      otherwise we would need to mirror the image and GLES2.0 doesn't
      support this */
-  _COGL_RETURN_IF_FAIL (cogl_is_offscreen (draw_buffer));
-  _COGL_RETURN_IF_FAIL (cogl_is_offscreen (read_buffer));
+  _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
+  _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
   /* The buffers must be the same format */
-  _COGL_RETURN_IF_FAIL (draw_buffer->format == read_buffer->format);
+  _COGL_RETURN_IF_FAIL (src->format == dest->format);
 
   /* Make sure the current framebuffers are bound. We explicitly avoid
      flushing the clip state so we can bind our own empty state */
-  _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
-                                 _cogl_get_read_framebuffer (),
+  _cogl_framebuffer_flush_state (dest,
+                                 src,
                                  COGL_FRAMEBUFFER_STATE_ALL &
                                  ~COGL_FRAMEBUFFER_STATE_CLIP);
 
@@ -1822,7 +1816,7 @@ _cogl_blit_framebuffer (unsigned int src_x,
      by the scissor and we want to hide this feature for the Cogl API
      because it's not obvious to an app how the clip state will affect
      the scissor */
-  _cogl_clip_stack_flush (NULL, draw_buffer);
+  _cogl_clip_stack_flush (NULL, dest);
 
   /* XXX: Because we are manually flushing clip state here we need to
    * make sure that the clip state gets updated the next time we flush
@@ -1831,11 +1825,11 @@ _cogl_blit_framebuffer (unsigned int src_x,
   ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
 
   ctx->glBlitFramebuffer (src_x, src_y,
-                     src_x + width, src_y + height,
-                     dst_x, dst_y,
-                     dst_x + width, dst_y + height,
-                     GL_COLOR_BUFFER_BIT,
-                     GL_NEAREST);
+                          src_x + width, src_y + height,
+                          dst_x, dst_y,
+                          dst_x + width, dst_y + height,
+                          GL_COLOR_BUFFER_BIT,
+                          GL_NEAREST);
 }
 
 void
diff --git a/cogl/cogl-texture-2d-private.h b/cogl/cogl-texture-2d-private.h
index 2a57081..aa5a35e 100644
--- a/cogl/cogl-texture-2d-private.h
+++ b/cogl/cogl-texture-2d-private.h
@@ -98,6 +98,7 @@ _cogl_texture_2d_externally_modified (CoglTexture *texture);
 /*
  * _cogl_texture_2d_copy_from_framebuffer:
  * @texture: A #CoglTexture2D pointer
+ * @src_fb: A source #CoglFramebuffer to copy from
  * @dst_x: X-position to store the image within the texture
  * @dst_y: Y-position to store the image within the texture
  * @src_x: X-position to within the framebuffer to read from
@@ -105,11 +106,12 @@ _cogl_texture_2d_externally_modified (CoglTexture *texture);
  * @width: width of the rectangle to copy
  * @height: height of the rectangle to copy
  *
- * This copies a portion of the current read framebuffer into the
+ * This copies a portion of the given @src_fb into the
  * texture.
  */
 void
 _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *texture,
+                                        CoglFramebuffer *src_fb,
                                         int dst_x,
                                         int dst_y,
                                         int src_x,
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 8517d23..853e646 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -343,6 +343,7 @@ _cogl_texture_2d_externally_modified (CoglTexture *texture)
 
 void
 _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d,
+                                        CoglFramebuffer *src_fb,
                                         int dst_x,
                                         int dst_y,
                                         int src_x,
@@ -350,15 +351,10 @@ _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d,
                                         int width,
                                         int height)
 {
-  CoglContext *ctx;
-  CoglFramebuffer *read_fb = _cogl_get_read_framebuffer ();
-
-  _COGL_RETURN_IF_FAIL (cogl_is_texture_2d (tex_2d));
-
-  ctx = COGL_TEXTURE (tex_2d)->context;
+  CoglContext *ctx = COGL_TEXTURE (tex_2d)->context;
 
   ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d,
-                                                        read_fb,
+                                                        src_fb,
                                                         dst_x,
                                                         dst_y,
                                                         src_x,
diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c
index d3c4274..41f8ae6 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -462,7 +462,7 @@ _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d,
   /* Make sure the current framebuffers are bound, though we don't need to
    * flush the clip state here since we aren't going to draw to the
    * framebuffer. */
-  _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
+  _cogl_framebuffer_flush_state (ctx->current_draw_buffer,
                                  src_fb,
                                  COGL_FRAMEBUFFER_STATE_ALL &
                                  ~COGL_FRAMEBUFFER_STATE_CLIP);
-- 
1.7.7.6



More information about the Cogl mailing list