summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2013-04-10 22:25:49 +0000
committerMartin Robinson <mrobinson@igalia.com>2013-04-26 15:03:46 -0700
commit8da704ca7c43dda796657e86c5221736b1983122 (patch)
treef4a7a21efbc3c65b75f1576c77bf1ac799b14b2e
parent793f8223d4a71f3fc7e74722fb60659e7100a39d (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.c98
-rw-r--r--src/cairo-gl-private.h9
-rw-r--r--src/cairo-gl-surface.c2
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);