summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-07 10:19:37 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-12-07 10:22:25 +0000
commit5613b210fffccd74dc2c3039ca0f1b628e306411 (patch)
tree12bac8a415c7800cd0de5530658b758e96058b89
parentc7565eeda0bde4f388745c3c235053054059c1fa (diff)
gl: Defer stencil allocation until use
Allocating a stencil and a depth buffer for every destination surface is simply too expensive and causes major resource issues. So defer the allocation and attachment of a stencil buffer until just prior to first use. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-gl-device.c55
-rw-r--r--src/cairo-gl-msaa-compositor.c2
-rw-r--r--src/cairo-gl-private.h4
3 files changed, 42 insertions, 19 deletions
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index 01fa52a3..ce34779b 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -295,24 +295,6 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
glReadBuffer (GL_COLOR_ATTACHMENT0);
#endif
- if (ctx->has_packed_depth_stencil) {
-#if CAIRO_HAS_GL_SURFACE
- GLenum internal_format = GL_DEPTH_STENCIL;
-#elif CAIRO_HAS_GLESV2_SURFACE
- GLenum internal_format = GL_DEPTH24_STENCIL8_OES,
-#endif
-
- dispatch->GenRenderbuffers (1, &surface->depth_stencil);
- dispatch->BindRenderbuffer (GL_RENDERBUFFER, surface->depth_stencil);
- dispatch->RenderbufferStorage (GL_RENDERBUFFER, internal_format,
- surface->width, surface->height);
-
- ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, surface->depth_stencil);
- ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, surface->depth_stencil);
- }
-
status = dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
const char *str;
@@ -333,6 +315,43 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
}
}
+cairo_bool_t
+_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx,
+ cairo_gl_surface_t *surface)
+{
+ cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
+#if CAIRO_HAS_GL_SURFACE
+ GLenum internal_format = GL_DEPTH_STENCIL;
+#elif CAIRO_HAS_GLESV2_SURFACE
+ GLenum internal_format = GL_DEPTH24_STENCIL8_OES;
+#endif
+
+ if (surface->depth_stencil)
+ return TRUE;
+
+ if (! ctx->has_packed_depth_stencil)
+ return FALSE;
+
+ _cairo_gl_ensure_framebuffer (ctx, surface);
+
+ dispatch->GenRenderbuffers (1, &surface->depth_stencil);
+ dispatch->BindRenderbuffer (GL_RENDERBUFFER, surface->depth_stencil);
+ dispatch->RenderbufferStorage (GL_RENDERBUFFER, internal_format,
+ surface->width, surface->height);
+
+ ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, surface->depth_stencil);
+ ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, surface->depth_stencil);
+ if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
+ surface->depth_stencil = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/*
* Stores a parallel projection transformation in matrix 'm',
* using column-major order.
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index 5746513d..81b8277a 100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -176,7 +176,7 @@ _draw_clip_to_stencil_buffer (cairo_gl_context_t *ctx,
assert (! _cairo_clip_is_all_clipped (clip));
- if (! setup->dst->depth_stencil)
+ if (! _cairo_gl_ensure_stencil (ctx, setup->dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
glDepthMask (GL_TRUE);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 0851ad86..856f5220 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -440,6 +440,10 @@ _cairo_gl_context_activate (cairo_gl_context_t *ctx,
cairo_private cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op);
+cairo_private cairo_bool_t
+_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx,
+ cairo_gl_surface_t *surface);
+
cairo_private cairo_status_t
_cairo_gl_composite_init (cairo_gl_composite_t *setup,
cairo_operator_t op,