[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