diff options
author | Benjamin Otte <otte@redhat.com> | 2010-06-02 20:04:57 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-06-07 13:37:48 +0200 |
commit | 10e71806d2e1929aa127642a397fa6ccef434b5b (patch) | |
tree | b24a661e96fa4e1ad74fad952f4a60ca99b21c87 | |
parent | f2f79ca1b3455000df4138ab500ae03b6584250c (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.c | 40 | ||||
-rw-r--r-- | src/cairo-gl-glyphs.c | 4 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 4 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 12 |
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; } |