Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}