summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-06-02 20:04:57 +0200
committerBenjamin Otte <otte@redhat.com>2010-06-07 13:37:48 +0200
commit10e71806d2e1929aa127642a397fa6ccef434b5b (patch)
treeb24a661e96fa4e1ad74fad952f4a60ca99b21c87
parentf2f79ca1b3455000df4138ab500ae03b6584250c (diff)
gl: Switch to deferred rendering
1) call _cairo_gl_composite_flush() or cairo_surface_flush() where needed 2) Destroy texture operands when necessary 3) get rid of _cairo_gl_composite_end() With this patch, vertices are not flushed immediately anymore, but only when needed or when a new set of vertices is emitted that requires an incompatible setup. This improves performance a lot in particular for text. (gnome-terminal-vim gets 10x faster)
-rw-r--r--src/cairo-gl-composite.c40
-rw-r--r--src/cairo-gl-glyphs.c4
-rw-r--r--src/cairo-gl-private.h4
-rw-r--r--src/cairo-gl-surface.c12
4 files changed, 28 insertions, 32 deletions
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c77bd39d..4ced6f90 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -726,6 +726,11 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
operand,
vertex_offset);
+ if (needs_setup) {
+ _cairo_gl_composite_flush (ctx);
+ _cairo_gl_context_destroy_operand (ctx, tex_unit);
+ }
+
memcpy (&ctx->operands[tex_unit], operand, sizeof (cairo_gl_operand_t));
ctx->operands[tex_unit].vertex_offset = vertex_offset;
@@ -858,6 +863,9 @@ _cairo_gl_set_operator (cairo_gl_context_t *ctx,
GLenum src_factor, dst_factor;
assert (op < ARRAY_LENGTH (blend_factors));
+ /* different dst and component_alpha changes cause flushes elsewhere */
+ if (ctx->current_operator != op)
+ _cairo_gl_composite_flush (ctx);
ctx->current_operator = op;
src_factor = blend_factors[op].src;
@@ -1068,6 +1076,17 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
}
_cairo_gl_context_set_destination (ctx, setup->dst);
+
+ if (_cairo_gl_context_is_flushed (ctx)) {
+ glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
+
+ glVertexPointer (2, GL_FLOAT, ctx->vertex_size, NULL);
+ glEnableClientState (GL_VERTEX_ARRAY);
+ }
+
+ _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, dst_size, shader != NULL);
+ _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_MASK, &setup->mask, dst_size + src_size, shader != NULL);
+
_cairo_gl_set_operator (ctx,
setup->op,
component_alpha);
@@ -1079,16 +1098,11 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
}
_cairo_gl_set_shader (ctx, shader);
_cairo_gl_composite_bind_to_shader (ctx, setup);
-
- glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
-
- glVertexPointer (2, GL_FLOAT, ctx->vertex_size, NULL);
- glEnableClientState (GL_VERTEX_ARRAY);
}
- _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, dst_size, shader != NULL);
- _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_MASK, &setup->mask, dst_size + src_size, shader != NULL);
-
+ if (! _cairo_gl_context_is_flushed (ctx) &&
+ ! cairo_region_equal (ctx->clip_region, setup->clip_region))
+ _cairo_gl_composite_flush (ctx);
cairo_region_destroy (ctx->clip_region);
ctx->clip_region = cairo_region_reference (setup->clip_region);
if (ctx->clip_region)
@@ -1293,16 +1307,6 @@ _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
}
void
-_cairo_gl_composite_end (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup)
-{
- _cairo_gl_composite_flush (ctx);
-
- _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
- _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
-}
-
-void
_cairo_gl_composite_fini (cairo_gl_composite_t *setup)
{
_cairo_gl_operand_destroy (&setup->src);
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 91d3c20d..a19174d3 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -293,9 +293,6 @@ _render_glyphs (cairo_gl_surface_t *dst,
}
if (scaled_glyph->surface->format != last_format) {
- if (last_format != CAIRO_FORMAT_INVALID)
- _cairo_gl_composite_end (ctx, &setup);
-
cache = cairo_gl_context_get_glyph_cache (ctx,
scaled_glyph->surface->format);
@@ -350,7 +347,6 @@ _render_glyphs (cairo_gl_surface_t *dst,
status = CAIRO_STATUS_SUCCESS;
FINISH:
- _cairo_gl_composite_end (ctx, &setup);
_cairo_scaled_font_thaw_cache (scaled_font);
_cairo_gl_context_release (ctx);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 07333042..3554c67a 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -348,10 +348,6 @@ cairo_private void
_cairo_gl_composite_flush (cairo_gl_context_t *ctx);
cairo_private void
-_cairo_gl_composite_end (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup);
-
-cairo_private void
_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
cairo_gl_tex_t tex_unit);
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 59053a43..f7a16ae9 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -440,6 +440,8 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
if (_cairo_gl_context_acquire (surface->base.device, &ctx))
return;
+ cairo_surface_flush (abstract_surface);
+
ctx->swap_buffers (ctx, surface);
_cairo_gl_context_release (ctx);
@@ -553,11 +555,13 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
color.blue = 0.0;
color.alpha = 1.0;
+ _cairo_gl_composite_flush (ctx);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
_cairo_gl_surface_fill_rectangles (dst,
CAIRO_OPERATOR_SOURCE,
&color,
&rect, 1);
+ _cairo_gl_composite_flush (ctx);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
} else {
@@ -652,6 +656,8 @@ _cairo_gl_surface_get_image (cairo_gl_surface_t *surface,
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
+
+ _cairo_gl_composite_flush (ctx);
_cairo_gl_context_set_destination (ctx, surface);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
@@ -951,7 +957,6 @@ _cairo_gl_surface_composite (cairo_operator_t op,
0);
}
- _cairo_gl_composite_end (ctx, &setup);
_cairo_gl_context_release (ctx);
CLEANUP:
@@ -1063,7 +1068,6 @@ _cairo_gl_surface_fill_rectangles (void *abstract_dst,
0);
}
- _cairo_gl_composite_end (ctx, &setup);
_cairo_gl_context_release (ctx);
CLEANUP:
@@ -1166,10 +1170,6 @@ _cairo_gl_surface_span_renderer_destroy (void *abstract_renderer)
static cairo_status_t
_cairo_gl_surface_span_renderer_finish (void *abstract_renderer)
{
- cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
-
- _cairo_gl_composite_end (renderer->ctx, &renderer->setup);
-
return CAIRO_STATUS_SUCCESS;
}