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); }
void _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface, cairo_bool_t multisampling) { /* OpenGL ES surfaces are always in MSAA mode once it's been turned on, * so we don't need to check whether we are switching modes for that * surface type. */ if (ctx->current_target == surface && ! surface->needs_update && (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES || surface->msaa_active == multisampling)) return; _cairo_gl_composite_flush (ctx); ctx->current_target = surface; surface->needs_update = FALSE; if (_cairo_gl_surface_is_texture (surface)) { if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { _cairo_gl_ensure_framebuffer (ctx, surface); ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); #if CAIRO_HAS_GL_SURFACE } else if (multisampling) _cairo_gl_activate_surface_as_multisampling (ctx, surface); else { _cairo_gl_activate_surface_as_nonmultisampling (ctx, surface); #endif } } else { ctx->make_current (ctx, surface); #if CAIRO_HAS_GL_SURFACE if (multisampling) glEnable(GL_MULTISAMPLE); else glDisable(GL_MULTISAMPLE); #endif surface->msaa_active = multisampling; ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, 0); #if CAIRO_HAS_GL_SURFACE glDrawBuffer (GL_BACK_LEFT); glReadBuffer (GL_BACK_LEFT); #endif } if (ctx->states_cache.viewport_box.width != surface->width || ctx->states_cache.viewport_box.height != surface->height) { glViewport (0, 0, surface->width, surface->height); ctx->states_cache.viewport_box.width = surface->width; ctx->states_cache.viewport_box.height = surface->height; } if (_cairo_gl_surface_is_texture (surface)) _gl_identity_ortho (ctx->modelviewprojection_matrix, 0, surface->width, 0, surface->height); else _gl_identity_ortho (ctx->modelviewprojection_matrix, 0, surface->width, surface->height, 0); }