diff options
author | Alejandro G. Castro <alex@igalia.com> | 2012-03-07 14:38:52 +0100 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2013-01-03 16:37:18 -0800 |
commit | 5e9083f882859201c5df18fc870577a224f88cbb (patch) | |
tree | bb098094fb6ea0f91497f6a7c078a29f08aa15be | |
parent | dd850583a7f57a666da6af218841bb10b536df46 (diff) |
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.
-rw-r--r-- | src/cairo-gl-msaa-compositor.c | 68 |
1 files changed, 53 insertions, 15 deletions
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c index 5de3449a..b2375e11 100644 --- a/src/cairo-gl-msaa-compositor.c +++ b/src/cairo-gl-msaa-compositor.c @@ -153,18 +153,23 @@ _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; + _cairo_traps_init (traps); + + if (clip->num_boxes == 1 && clip->path == NULL) { + cairo_boxes_t boxes; + _cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes); + return _cairo_traps_init_boxes (traps, &boxes); + } + status = _cairo_clip_get_polygon (clip, &polygon, &fill_rule, &antialias); if (unlikely (status)) return status; @@ -180,14 +185,24 @@ _cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, * option. */ - _cairo_traps_init (&traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&traps, + _cairo_traps_init (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; + + status = _clip_to_traps (clip, &traps); if (unlikely (status)) return status; - status = _draw_traps (ctx, setup, &traps); _cairo_traps_fini (&traps); @@ -303,6 +318,19 @@ _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; + + /* If we have a non-rectangular clip, we can avoid using the stencil buffer + * for clipping and just draw the clip polygon. */ + if (clip) { + 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, @@ -321,7 +349,10 @@ _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 (! clip) + 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 +375,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 (! clip) + 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 (clip) + _cairo_traps_fini (&traps); return status; } @@ -363,6 +399,7 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, cairo_gl_context_t *ctx = NULL; cairo_int_status_t status; cairo_operator_t op = composite->op; + cairo_clip_t *clip = composite->clip; if (! can_use_msaa_compositor (dst, CAIRO_ANTIALIAS_DEFAULT)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -436,8 +473,6 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, if (unlikely (status)) goto finish; - _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. */ _cairo_gl_composite_set_multisample (&setup); @@ -446,7 +481,10 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, if (unlikely (status)) goto finish; - _draw_int_rect (ctx, &setup, &composite->bounded); + if (! clip) + 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); |