static void _cairo_gl_activate_surface_as_multisampling (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) { assert (surface->supports_msaa); assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); _cairo_gl_ensure_framebuffer (ctx, surface); _cairo_gl_ensure_multisampling (ctx, surface); if (surface->msaa_active) { glEnable (GL_MULTISAMPLE); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); return; } _cairo_gl_composite_flush (ctx); glEnable (GL_MULTISAMPLE); /* The last time we drew to the surface, we were not using multisampling, so we need to blit from the non-multisampling framebuffer into the multisampling framebuffer. */ ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb); ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb); ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height, 0, 0, surface->width, surface->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); surface->msaa_active = TRUE; }
static cairo_bool_t _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) { cairo_gl_dispatch_t *dispatch = &ctx->dispatch; _cairo_gl_ensure_framebuffer (ctx, surface); #if CAIRO_HAS_GL_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) _cairo_gl_ensure_multisampling (ctx, surface); #endif if (! ctx->shared_msaa_depth_stencil || ctx->shared_msaa_depth_stencil_width < surface->width || ctx->shared_msaa_depth_stencil_height < surface->height) { _cairo_gl_replace_msaa_depth_stencil_buffer (ctx, surface->width, surface->height); } assert (ctx->shared_msaa_depth_stencil); if (surface->msaa_depth_stencil == ctx->shared_msaa_depth_stencil) return TRUE; #if CAIRO_HAS_GL_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) { dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, ctx->shared_msaa_depth_stencil); } #endif #if CAIRO_HAS_GLESV2_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ctx->shared_msaa_depth_stencil); dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, ctx->shared_msaa_depth_stencil); } #endif surface->msaa_depth_stencil = ctx->shared_msaa_depth_stencil; if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { dispatch->DeleteRenderbuffers (1, &surface->msaa_depth_stencil); surface->msaa_depth_stencil = 0; return FALSE; } return TRUE; }
static cairo_bool_t _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) { cairo_gl_dispatch_t *dispatch = &ctx->dispatch; if (surface->msaa_depth_stencil) return TRUE; _cairo_gl_ensure_framebuffer (ctx, surface); #if CAIRO_HAS_GL_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) _cairo_gl_ensure_multisampling (ctx, surface); #endif dispatch->GenRenderbuffers (1, &surface->msaa_depth_stencil); dispatch->BindRenderbuffer (GL_RENDERBUFFER, surface->msaa_depth_stencil); dispatch->RenderbufferStorageMultisample (GL_RENDERBUFFER, ctx->num_samples, _get_depth_stencil_format (ctx), surface->width, surface->height); #if CAIRO_HAS_GL_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) { dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, surface->msaa_depth_stencil); } #endif #if CAIRO_HAS_GLESV2_SURFACE if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, surface->msaa_depth_stencil); dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, surface->msaa_depth_stencil); } #endif if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { dispatch->DeleteRenderbuffers (1, &surface->msaa_depth_stencil); surface->msaa_depth_stencil = 0; return FALSE; } return TRUE; }
static void bind_multisample_framebuffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) { cairo_bool_t stencil_test_enabled; cairo_bool_t scissor_test_enabled; assert (surface->supports_msaa); assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); _cairo_gl_ensure_framebuffer (ctx, surface); _cairo_gl_ensure_multisampling (ctx, surface); if (surface->msaa_active) { glEnable (GL_MULTISAMPLE); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); return; } _cairo_gl_composite_flush (ctx); stencil_test_enabled = glIsEnabled (GL_STENCIL_TEST); scissor_test_enabled = glIsEnabled (GL_SCISSOR_TEST); glDisable (GL_STENCIL_TEST); glDisable (GL_SCISSOR_TEST); glEnable (GL_MULTISAMPLE); /* The last time we drew to the surface, we were not using multisampling, so we need to blit from the non-multisampling framebuffer into the multisampling framebuffer. */ ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb); ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb); ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height, 0, 0, surface->width, surface->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); if (stencil_test_enabled) glEnable (GL_STENCIL_TEST); if (scissor_test_enabled) glEnable (GL_SCISSOR_TEST); }