blit: avoid referring to framebuffer stack

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

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit 598ca33950a93dd7a201045c4abccda2a855e936)
This commit is contained in:
Robert Bragg 2012-11-08 23:35:45 +00:00
parent e8eb9793e6
commit 38921701e5
7 changed files with 97 additions and 94 deletions

View File

@ -63,7 +63,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
return FALSE; return FALSE;
} }
data->fb = fb; data->dest_fb = fb;
dst_width = cogl_texture_get_width (data->dst_tex); dst_width = cogl_texture_get_width (data->dst_tex);
dst_height = cogl_texture_get_height (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 static void
_cogl_blit_texture_render_blit (CoglBlitData *data, _cogl_blit_texture_render_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height) int height)
{ {
cogl_framebuffer_draw_textured_rectangle (data->fb, cogl_framebuffer_draw_textured_rectangle (data->dest_fb,
data->pipeline, data->pipeline,
dst_x, dst_y, dst_x, dst_y,
dst_x + width, dst_x + width,
@ -139,7 +139,7 @@ _cogl_blit_texture_render_end (CoglBlitData *data)
cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0, cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0,
data->dst_tex); data->dst_tex);
cogl_object_unref (data->fb); cogl_object_unref (data->dest_fb);
} }
static CoglBool static CoglBool
@ -177,7 +177,8 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
if (!cogl_framebuffer_allocate (src_fb, NULL)) if (!cogl_framebuffer_allocate (src_fb, NULL))
goto error; goto error;
_cogl_push_framebuffers (dst_fb, src_fb); data->src_fb = src_fb;
data->dest_fb = dst_fb;
return TRUE; return TRUE;
@ -193,14 +194,16 @@ error:
static void static void
_cogl_blit_framebuffer_blit (CoglBlitData *data, _cogl_blit_framebuffer_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height) 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, dst_x, dst_y,
width, height); width, height);
} }
@ -208,7 +211,8 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data,
static void static void
_cogl_blit_framebuffer_end (CoglBlitData *data) _cogl_blit_framebuffer_end (CoglBlitData *data)
{ {
cogl_pop_framebuffer (); cogl_object_unref (data->src_fb);
cogl_object_unref (data->dest_fb);
} }
static CoglBool static CoglBool
@ -234,22 +238,22 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
return FALSE; return FALSE;
} }
cogl_push_framebuffer (fb); data->src_fb = fb;
cogl_object_unref (fb);
return TRUE; return TRUE;
} }
static void static void
_cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data, _cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height) int height)
{ {
_cogl_texture_2d_copy_from_framebuffer (COGL_TEXTURE_2D (data->dst_tex), _cogl_texture_2d_copy_from_framebuffer (COGL_TEXTURE_2D (data->dst_tex),
data->src_fb,
dst_x, dst_y, dst_x, dst_y,
src_x, src_y, src_x, src_y,
width, height); width, height);
@ -258,7 +262,7 @@ _cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data,
static void static void
_cogl_blit_copy_tex_sub_image_end (CoglBlitData *data) _cogl_blit_copy_tex_sub_image_end (CoglBlitData *data)
{ {
cogl_pop_framebuffer (); cogl_object_unref (data->src_fb);
} }
static CoglBool static CoglBool
@ -277,12 +281,12 @@ _cogl_blit_get_tex_data_begin (CoglBlitData *data)
static void static void
_cogl_blit_get_tex_data_blit (CoglBlitData *data, _cogl_blit_get_tex_data_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height) int height)
{ {
cogl_texture_set_region (data->dst_tex, cogl_texture_set_region (data->dst_tex,
src_x, src_y, src_x, src_y,
@ -368,6 +372,8 @@ _cogl_blit_begin (CoglBlitData *data,
_cogl_blit_default_mode = _cogl_blit_modes; _cogl_blit_default_mode = _cogl_blit_modes;
} }
memset (data, 0, sizeof (CoglBlitData));
data->dst_tex = dst_tex; data->dst_tex = dst_tex;
data->src_tex = src_tex; data->src_tex = src_tex;
@ -405,12 +411,12 @@ _cogl_blit_begin (CoglBlitData *data,
void void
_cogl_blit (CoglBlitData *data, _cogl_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height) int height)
{ {
data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height); data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height);
} }

View File

@ -40,12 +40,12 @@ typedef CoglBool (* CoglBlitBeginFunc) (CoglBlitData *data);
typedef void (* CoglBlitEndFunc) (CoglBlitData *data); typedef void (* CoglBlitEndFunc) (CoglBlitData *data);
typedef void (* CoglBlitFunc) (CoglBlitData *data, typedef void (* CoglBlitFunc) (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height); int height);
typedef struct typedef struct
{ {
@ -71,7 +71,8 @@ struct _CoglBlitData
int bpp; int bpp;
CoglFramebuffer *fb; CoglFramebuffer *src_fb;
CoglFramebuffer *dest_fb;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@ -82,12 +83,12 @@ _cogl_blit_begin (CoglBlitData *data,
void void
_cogl_blit (CoglBlitData *data, _cogl_blit (CoglBlitData *data,
unsigned int src_x, int src_x,
unsigned int src_y, int src_y,
unsigned int dst_x, int dst_x,
unsigned int dst_y, int dst_y,
unsigned int width, int width,
unsigned int height); int height);
void void
_cogl_blit_end (CoglBlitData *data); _cogl_blit_end (CoglBlitData *data);

View File

@ -325,6 +325,8 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
/* /*
* _cogl_blit_framebuffer: * _cogl_blit_framebuffer:
* @src: The source #CoglFramebuffer
* @dest: The destination #CoglFramebuffer
* @src_x: Source x position * @src_x: Source x position
* @src_y: Source y position * @src_y: Source y position
* @dst_x: Destination x 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. * a separate function to copy the entire buffer for a given mask.
*/ */
void void
_cogl_blit_framebuffer (unsigned int src_x, _cogl_blit_framebuffer (CoglFramebuffer *src,
unsigned int src_y, CoglFramebuffer *dest,
unsigned int dst_x, int src_x,
unsigned int dst_y, int src_y,
unsigned int width, int dst_x,
unsigned int height); int dst_y,
int width,
int height);
void void
_cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer); _cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);

View File

@ -1820,38 +1820,32 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
} }
void void
_cogl_blit_framebuffer (unsigned int src_x, _cogl_blit_framebuffer (CoglFramebuffer *src,
unsigned int src_y, CoglFramebuffer *dest,
unsigned int dst_x, int src_x,
unsigned int dst_y, int src_y,
unsigned int width, int dst_x,
unsigned int height) int dst_y,
int width,
int height)
{ {
CoglFramebuffer *draw_buffer; CoglContext *ctx = src->context;
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;
_COGL_RETURN_IF_FAIL (ctx->private_feature_flags & _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 /* We can only support blitting between offscreen buffers because
otherwise we would need to mirror the image and GLES2.0 doesn't otherwise we would need to mirror the image and GLES2.0 doesn't
support this */ support this */
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (draw_buffer)); _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (read_buffer)); _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
/* The buffers must be the same format */ /* 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 /* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */ flushing the clip state so we can bind our own empty state */
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), _cogl_framebuffer_flush_state (dest,
_cogl_get_read_framebuffer (), src,
COGL_FRAMEBUFFER_STATE_ALL & COGL_FRAMEBUFFER_STATE_ALL &
~COGL_FRAMEBUFFER_STATE_CLIP); ~COGL_FRAMEBUFFER_STATE_CLIP);
@ -1859,7 +1853,7 @@ _cogl_blit_framebuffer (unsigned int src_x,
by the scissor and we want to hide this feature for the Cogl API 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 because it's not obvious to an app how the clip state will affect
the scissor */ 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 /* 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 * make sure that the clip state gets updated the next time we flush
@ -1868,11 +1862,11 @@ _cogl_blit_framebuffer (unsigned int src_x,
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
ctx->glBlitFramebuffer (src_x, src_y, ctx->glBlitFramebuffer (src_x, src_y,
src_x + width, src_y + height, src_x + width, src_y + height,
dst_x, dst_y, dst_x, dst_y,
dst_x + width, dst_y + height, dst_x + width, dst_y + height,
GL_COLOR_BUFFER_BIT, GL_COLOR_BUFFER_BIT,
GL_NEAREST); GL_NEAREST);
} }
void void

View File

@ -98,6 +98,7 @@ _cogl_texture_2d_externally_modified (CoglTexture *texture);
/* /*
* _cogl_texture_2d_copy_from_framebuffer: * _cogl_texture_2d_copy_from_framebuffer:
* @texture: A #CoglTexture2D pointer * @texture: A #CoglTexture2D pointer
* @src_fb: A source #CoglFramebuffer to copy from
* @dst_x: X-position to store the image within the texture * @dst_x: X-position to store the image within the texture
* @dst_y: Y-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 * @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 * @width: width of the rectangle to copy
* @height: height 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. * texture.
*/ */
void void
_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *texture, _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *texture,
CoglFramebuffer *src_fb,
int dst_x, int dst_x,
int dst_y, int dst_y,
int src_x, int src_x,

View File

@ -343,6 +343,7 @@ _cogl_texture_2d_externally_modified (CoglTexture *texture)
void void
_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d, _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d,
CoglFramebuffer *src_fb,
int dst_x, int dst_x,
int dst_y, int dst_y,
int src_x, int src_x,
@ -350,15 +351,10 @@ _cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d,
int width, int width,
int height) int height)
{ {
CoglContext *ctx; CoglContext *ctx = COGL_TEXTURE (tex_2d)->context;
CoglFramebuffer *read_fb = _cogl_get_read_framebuffer ();
_COGL_RETURN_IF_FAIL (cogl_is_texture_2d (tex_2d));
ctx = COGL_TEXTURE (tex_2d)->context;
ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d, ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d,
read_fb, src_fb,
dst_x, dst_x,
dst_y, dst_y,
src_x, src_x,

View File

@ -465,7 +465,7 @@ _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d,
/* Make sure the current framebuffers are bound, though we don't need to /* 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 * flush the clip state here since we aren't going to draw to the
* framebuffer. */ * framebuffer. */
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), _cogl_framebuffer_flush_state (ctx->current_draw_buffer,
src_fb, src_fb,
COGL_FRAMEBUFFER_STATE_ALL & COGL_FRAMEBUFFER_STATE_ALL &
~COGL_FRAMEBUFFER_STATE_CLIP); ~COGL_FRAMEBUFFER_STATE_CLIP);