summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-30 21:25:20 +0200
committerBenjamin Otte <otte@redhat.com>2010-06-07 13:37:48 +0200
commit1ddff8aba35466fe6689536bc5f2d7eeefaea02c (patch)
tree6833920da1afaeaa39c6947e3db4e2c4a5a560fd
parent1c15510c3d00553aba9ec4fd4e6764da3cdb0a41 (diff)
gl: Only allocate a framebuffer if we need one
This way, we don't clobber the current target when creating textures for image surfaces.
-rw-r--r--src/cairo-gl-device.c26
-rw-r--r--src/cairo-gl-private.h2
-rw-r--r--src/cairo-gl-surface.c20
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);