diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-07 10:19:37 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-07 10:22:25 +0000 |
commit | 5613b210fffccd74dc2c3039ca0f1b628e306411 (patch) | |
tree | 12bac8a415c7800cd0de5530658b758e96058b89 | |
parent | c7565eeda0bde4f388745c3c235053054059c1fa (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.c | 55 | ||||
-rw-r--r-- | src/cairo-gl-msaa-compositor.c | 2 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 4 |
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, |