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;
}
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)
{
cogl_texture_set_region (data->dst_tex,
src_x, src_y,
@ -368,6 +372,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;
@ -405,12 +411,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);
}

View File

@ -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);

View File

@ -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);

View File

@ -1820,38 +1820,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);
@ -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
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
@ -1868,11 +1862,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

View File

@ -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,

View File

@ -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,

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
* 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);