[PATCH] gl/msaa: Avoid the stencil buffer when possible during masking
Martin Robinson <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
commit d404ed57bc88042d6da0e64b72c7a976ae624ec5 Author: Alejandro G. Castro <[email protected]> Date: Wed Mar 7 14:38:52 2012 +0100 gl/msaa: Avoid the stencil buffer when possible during masking In this case we can draw the clip path and avoid the stencil buffer, which can be expensive. diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index 6731886..dbd4e02 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -550,7 +550,7 @@ _cairo_gl_composite_setup_painted_clipping (cairo_gl_composite_t *setup, cairo_gl_surface_t *dst = setup->dst; cairo_clip_t *clip = setup->clip; - if (clip->num_boxes == 1 && clip->path == NULL) { + if (_cairo_gl_can_use_scissor_for_clip (clip)) { _scissor_to_box (dst, &clip->boxes[0]); goto disable_stencil_buffer_and_return; } diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c index d96d746..03bc658 100644 --- a/src/cairo-gl-msaa-compositor.c +++ b/src/cairo-gl-msaa-compositor.c @@ -153,14 +153,11 @@ _draw_triangle_fan (cairo_gl_context_t *ctx, return CAIRO_STATUS_SUCCESS; } -cairo_int_status_t -_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_clip_t *clip) +static cairo_int_status_t +_clip_to_traps (cairo_clip_t *clip, + cairo_traps_t *traps) { cairo_int_status_t status; - cairo_traps_t traps; - cairo_polygon_t polygon; cairo_antialias_t antialias; cairo_fill_rule_t fill_rule; @@ -180,14 +177,24 @@ _cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, * option. */ - _cairo_traps_init (&traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&traps, + status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, fill_rule); - _cairo_polygon_fini (&polygon); + return status; +} + +cairo_int_status_t +_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + cairo_clip_t *clip) +{ + cairo_int_status_t status; + cairo_traps_t traps; + + _cairo_traps_init (&traps); + status = _clip_to_traps (clip, &traps); if (unlikely (status)) return status; - status = _draw_traps (ctx, setup, &traps); _cairo_traps_fini (&traps); @@ -303,6 +310,22 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos cairo_gl_context_t *ctx = NULL; cairo_int_status_t status; + cairo_clip_t *clip = composite->clip; + cairo_traps_t traps; + cairo_bool_t draw_clip_traps; + + /* If we have a non-rectangular clip, we can avoid using the stencil buffer + * for clipping and just draw the clip polygon. */ + draw_clip_traps = clip && ! _cairo_gl_can_use_scissor_for_clip (clip); + if (draw_clip_traps) { + _cairo_traps_init (&traps); + status = _clip_to_traps (clip, &traps); + if (unlikely (status)) { + _cairo_traps_fini (&traps); + return status; + } + } + status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_DEST_OUT, dst, @@ -315,13 +338,19 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos &composite->bounded); if (unlikely (status)) goto finish; - _cairo_gl_composite_set_clip (&setup, composite->clip); + + if (draw_clip_traps) + _cairo_gl_composite_set_clip (&setup, clip); + _cairo_gl_composite_set_multisample (&setup); status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto finish; - _draw_int_rect (ctx, &setup, &composite->bounded); + if (! draw_clip_traps) + status = _draw_int_rect (ctx, &setup, &composite->bounded); + else + status = _draw_traps (ctx, &setup, &traps); /* Now draw the second pass. */ _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD, @@ -344,12 +373,17 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos if (unlikely (status)) goto finish; - _draw_int_rect (ctx, &setup, &composite->bounded); + if (! draw_clip_traps) + status = _draw_int_rect (ctx, &setup, &composite->bounded); + else + status = _draw_traps (ctx, &setup, &traps); finish: _cairo_gl_composite_fini (&setup); if (ctx) status = _cairo_gl_context_release (ctx, status); + if (draw_clip_traps) + _cairo_traps_fini (&traps); return status; } @@ -364,6 +398,9 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, cairo_int_status_t status; cairo_operator_t op = composite->op; + cairo_clip_t *clip = composite->clip; + cairo_bool_t draw_clip_traps; + if (! can_use_msaa_compositor (dst, CAIRO_ANTIALIAS_DEFAULT)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -436,7 +473,11 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, if (unlikely (status)) goto finish; - _cairo_gl_msaa_compositor_set_clip (composite, &setup); + /* If we have a non-rectangular clip, we can avoid using the stencil buffer + * for clipping and just draw the clip polygon. */ + draw_clip_traps = clip && ! _cairo_gl_can_use_scissor_for_clip (clip); + if (! draw_clip_traps) + _cairo_gl_msaa_compositor_set_clip (composite, &setup); /* We always use multisampling here, because we do not yet have the smarts to calculate when the clip or the source requires it. */ @@ -446,7 +487,10 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, if (unlikely (status)) goto finish; - _draw_int_rect (ctx, &setup, &composite->bounded); + if (! draw_clip_traps) + status = _draw_int_rect (ctx, &setup, &composite->bounded); + else + status = _cairo_gl_msaa_compositor_draw_clip (ctx, &setup, clip); finish: _cairo_gl_composite_fini (&setup); diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 1a4d40e..56f55ea 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -802,6 +802,13 @@ _cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache) _cairo_rtree_unpin (&cache->rtree); } +static inline cairo_bool_t +_cairo_gl_can_use_scissor_for_clip (cairo_clip_t *clip) +{ + return clip->num_boxes == 1 && clip->path == NULL; +} + + slim_hidden_proto (cairo_gl_surface_create); slim_hidden_proto (cairo_gl_surface_create_for_texture); -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo