mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-23 02:50:38 +02:00
gl: Separate framebuffer bind from destination selection
Disentangle the action of binding the framebuffer from setting the destination. This straightens up the code a bit and avoids some redundant operations (such as reacquiring the context) when simply switching from the multi-sample framebuffer to the single-sample framebuffer and vice versa.
This commit is contained in:
parent
793f8223d4
commit
8da704ca7c
3 changed files with 63 additions and 46 deletions
|
|
@ -615,8 +615,8 @@ _gl_identity_ortho (GLfloat *m,
|
|||
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
static void
|
||||
_cairo_gl_activate_surface_as_multisampling (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
bind_multisample_framebuffer (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
{
|
||||
assert (surface->supports_msaa);
|
||||
assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP);
|
||||
|
|
@ -624,7 +624,6 @@ _cairo_gl_activate_surface_as_multisampling (cairo_gl_context_t *ctx,
|
|||
_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);
|
||||
|
|
@ -643,18 +642,17 @@ _cairo_gl_activate_surface_as_multisampling (cairo_gl_context_t *ctx,
|
|||
0, 0, surface->width, surface->height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
|
||||
surface->msaa_active = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_cairo_gl_activate_surface_as_nonmultisampling (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
static void
|
||||
bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface)
|
||||
{
|
||||
assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP);
|
||||
_cairo_gl_ensure_framebuffer (ctx, surface);
|
||||
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
if (! surface->msaa_active) {
|
||||
glDisable (GL_MULTISAMPLE);
|
||||
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
|
||||
|
|
@ -673,8 +671,38 @@ _cairo_gl_activate_surface_as_nonmultisampling (cairo_gl_context_t *ctx,
|
|||
0, 0, surface->width, surface->height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
|
||||
surface->msaa_active = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface,
|
||||
cairo_bool_t multisampling)
|
||||
{
|
||||
/* OpenGL ES surfaces only have either a multisample framebuffer or a
|
||||
* singlesample framebuffer, so we cannot switch back and forth. */
|
||||
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
|
||||
_cairo_gl_ensure_framebuffer (ctx, surface);
|
||||
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
|
||||
return;
|
||||
}
|
||||
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
if (_cairo_gl_surface_is_texture (surface)) {
|
||||
if (multisampling)
|
||||
bind_multisample_framebuffer (ctx, surface);
|
||||
else
|
||||
bind_singlesample_framebuffer (ctx, surface);
|
||||
} else {
|
||||
ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
if (multisampling)
|
||||
glEnable (GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable (GL_MULTISAMPLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
surface->msaa_active = multisampling;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -682,51 +710,39 @@ _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))
|
||||
cairo_bool_t changing_surface = ctx->current_target != surface;
|
||||
cairo_bool_t changing_sampling = surface->msaa_active != multisampling;
|
||||
if (! changing_surface && ! changing_sampling)
|
||||
return;
|
||||
|
||||
if (! changing_surface) {
|
||||
/* The decision whether or not to use multisampling happen when
|
||||
* we create an OpenGL ES surface, so switching modes is a no-op. */
|
||||
if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES)
|
||||
return;
|
||||
|
||||
_cairo_gl_composite_flush (ctx);
|
||||
_cairo_gl_context_bind_framebuffer (ctx, surface, 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_gl_surface_is_texture (surface)) {
|
||||
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);
|
||||
glDrawBuffer (GL_BACK_LEFT);
|
||||
glReadBuffer (GL_BACK_LEFT);
|
||||
#endif
|
||||
}
|
||||
|
||||
glDisable (GL_DITHER);
|
||||
_cairo_gl_context_bind_framebuffer (ctx, surface, multisampling);
|
||||
|
||||
glDisable (GL_DITHER);
|
||||
glViewport (0, 0, surface->width, surface->height);
|
||||
|
||||
if (_cairo_gl_surface_is_texture (surface))
|
||||
|
|
|
|||
|
|
@ -491,15 +491,16 @@ _cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t status)
|
|||
return status;
|
||||
}
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_activate_surface_as_nonmultisampling (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface,
|
||||
cairo_bool_t multisampling);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
|
||||
cairo_gl_surface_t *surface,
|
||||
cairo_bool_t multisampling);
|
||||
|
||||
cairo_private cairo_gl_emit_rect_t
|
||||
_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -1309,7 +1309,7 @@ _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
|
|||
ctx->current_target = surface;
|
||||
|
||||
#if CAIRO_HAS_GL_SURFACE
|
||||
_cairo_gl_activate_surface_as_nonmultisampling (ctx, surface);
|
||||
_cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
|
||||
#endif
|
||||
|
||||
status = _cairo_gl_context_release (ctx, status);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue