gl: Only allocate a framebuffer if we need one

This way, we don't clobber the current target when creating textures for
image surfaces.
This commit is contained in:
Benjamin Otte 2010-05-30 21:25:20 +02:00
parent 1c15510c3d
commit 1ddff8aba3
3 changed files with 29 additions and 19 deletions

View file

@ -221,6 +221,31 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
cairo_gl_surface_t *surface)
{
GLenum status;
if (likely (surface->fb))
return;
/* Create a framebuffer object wrapping the texture so that we can render
* to it.
*/
glGenFramebuffersEXT (1, &surface->fb);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
ctx->tex_target,
surface->tex,
0);
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
fprintf (stderr, "destination is framebuffer incomplete\n");
}
void
_cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
cairo_gl_surface_t *surface)
@ -233,6 +258,7 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
ctx->current_target = surface;
if (_cairo_gl_surface_is_texture (surface)) {
_cairo_gl_ensure_framebuffer (ctx, surface);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);

View file

@ -235,7 +235,7 @@ _cairo_gl_surface_init (cairo_device_t *device,
static cairo_always_inline cairo_bool_t cairo_warn
_cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
{
return surface->fb != 0;
return surface->tex != 0;
}
cairo_private cairo_status_t

View file

@ -242,7 +242,6 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
{
cairo_gl_surface_t *surface;
GLenum format;
cairo_status_t status;
assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
@ -289,22 +288,6 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
glTexImage2D (ctx->tex_target, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, NULL);
/* Create a framebuffer object wrapping the texture so that we can render
* to it.
*/
glGenFramebuffersEXT (1, &surface->fb);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
ctx->tex_target,
surface->tex,
0);
ctx->current_target = NULL;
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
fprintf (stderr, "destination is framebuffer incomplete\n");
return &surface->base;
}
@ -707,7 +690,8 @@ _cairo_gl_surface_finish (void *abstract_surface)
if (ctx->current_target == surface)
ctx->current_target = NULL;
glDeleteFramebuffersEXT (1, &surface->fb);
if (surface->fb)
glDeleteFramebuffersEXT (1, &surface->fb);
glDeleteTextures (1, &surface->tex);
_cairo_gl_context_release (ctx);