diff options
author | Martin Robinson <mrobinson@igalia.com> | 2013-04-10 22:25:49 +0000 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2013-04-26 15:03:46 -0700 |
commit | 8da704ca7c43dda796657e86c5221736b1983122 (patch) | |
tree | f4a7a21efbc3c65b75f1576c77bf1ac799b14b2e | |
parent | 793f8223d4a71f3fc7e74722fb60659e7100a39d (diff) |
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.
-rw-r--r-- | src/cairo-gl-device.c | 98 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 9 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 2 |
3 files changed, 63 insertions, 46 deletions
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c index b30c49cb..97e3fb89 100644 --- a/src/cairo-gl-device.c +++ b/src/cairo-gl-device.c @@ -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_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_gl_surface_is_texture (surface)) { + ctx->make_current (ctx, surface); #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)) diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index c99bd162..d49e3d93 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -492,14 +492,15 @@ _cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t 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); diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 144dccce..d7a7836b 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -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); |