[cairo-commit] src/cairo-gl-device.c src/cairo-gl-msaa-compositor.c src/cairo-gl-private.h

Chris Wilson ickle at kemper.freedesktop.org
Wed Dec 7 02:26:10 PST 2011


 src/cairo-gl-device.c          |   55 +++++++++++++++++++++++++++--------------
 src/cairo-gl-msaa-compositor.c |    2 -
 src/cairo-gl-private.h         |    4 ++
 3 files changed, 42 insertions(+), 19 deletions(-)

New commits:
commit 5613b210fffccd74dc2c3039ca0f1b628e306411
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Dec 7 10:19:37 2011 +0000

    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 at chris-wilson.co.uk>

diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index 01fa52a..ce34779 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 5746513..81b8277 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 0851ad8..856f522 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,


More information about the cairo-commit mailing list