mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-19 09:00:41 +02:00
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>
This commit is contained in:
parent
c7565eeda0
commit
5613b210ff
3 changed files with 42 additions and 19 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue