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);
}
Exemple #2
0
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);
}