From 1ddff8aba35466fe6689536bc5f2d7eeefaea02c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 30 May 2010 21:25:20 +0200 Subject: gl: Only allocate a framebuffer if we need one This way, we don't clobber the current target when creating textures for image surfaces. --- src/cairo-gl-device.c | 26 ++++++++++++++++++++++++++ src/cairo-gl-private.h | 2 +- src/cairo-gl-surface.c | 20 ++------------------ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c index 1741ac07..2e6bfb94 100644 --- a/src/cairo-gl-device.c +++ b/src/cairo-gl-device.c @@ -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); diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index fe5be0c3..eaf11434 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -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 diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 1d264133..9a75e28d 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -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); -- cgit v1.2.3