summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry (Yu) Song <hsong@sisa.samsung.com>2011-12-23 08:44:16 -0800
committerMartin Robinson <mrobinson@igalia.com>2012-05-17 11:22:25 -0700
commit5ae53c933ae4baefdedb8ca795ee25dfcba9f5b0 (patch)
tree3ab6f5a86ea51a5d782ac4a409811cd8a5df365a
parent4d9064d578434cadfae2b248ef29075a1a1be8b8 (diff)
gl/msaa: Implement paint via masking
Instead of falling back to the spans compositor, let the msaa compositor handle painting. This ensure clipping is handled in a consistent way with the rest of the msaa compositor.
-rw-r--r--src/cairo-gl-msaa-compositor.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index 0080d142..392338c5 100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -278,6 +278,22 @@ _scissor_and_clip (cairo_gl_context_t *ctx,
return CAIRO_INT_STATUS_SUCCESS;
}
+static cairo_bool_t
+_should_use_unbounded_surface (cairo_composite_rectangles_t *composite)
+{
+ cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
+ cairo_rectangle_int_t *source = &composite->source;
+
+ if (composite->is_bounded)
+ return FALSE;
+
+ /* This isn't just an optimization. It also detects when painting is used
+ to paint back the unbounded surface, preventing infinite recursion. */
+ return ! (source->x <= 0 && source->y <= 0 &&
+ source->height + source->y >= dst->height &&
+ source->width + source->x >= dst->width);
+}
+
static cairo_surface_t*
_prepare_unbounded_surface (cairo_gl_surface_t *dst)
{
@@ -331,13 +347,6 @@ should_fall_back (cairo_gl_surface_t *surface,
}
static cairo_int_status_t
-_cairo_gl_msaa_compositor_paint (const cairo_compositor_t *compositor,
- cairo_composite_rectangles_t *composite)
-{
- return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
-static cairo_int_status_t
_cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *composite)
{
@@ -368,17 +377,26 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
- if (composite->is_bounded == FALSE) {
+ if (_should_use_unbounded_surface (composite)) {
cairo_surface_t* surface = _prepare_unbounded_surface (dst);
if (unlikely (surface == NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
+ /* This may be a paint operation. */
+ if (composite->original_mask_pattern == NULL) {
+ status = _cairo_compositor_paint (compositor, surface,
+ CAIRO_OPERATOR_SOURCE,
+ &composite->source_pattern.base,
+ NULL);
+ } else {
status = _cairo_compositor_mask (compositor, surface,
CAIRO_OPERATOR_SOURCE,
&composite->source_pattern.base,
&composite->mask_pattern.base,
NULL);
+ }
+
if (unlikely (status)) {
cairo_surface_destroy (surface);
return status;
@@ -401,10 +419,12 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
if (unlikely (status))
goto finish;
- status = _cairo_gl_composite_set_mask (&setup,
- &composite->mask_pattern.base,
- &composite->source_sample_area,
- &composite->bounded);
+ if (composite->original_mask_pattern != NULL) {
+ status = _cairo_gl_composite_set_mask (&setup,
+ &composite->mask_pattern.base,
+ &composite->mask_sample_area,
+ &composite->bounded);
+ }
if (unlikely (status))
goto finish;
@@ -433,6 +453,13 @@ finish:
return status;
}
+static cairo_int_status_t
+_cairo_gl_msaa_compositor_paint (const cairo_compositor_t *compositor,
+ cairo_composite_rectangles_t *composite)
+{
+ return _cairo_gl_msaa_compositor_mask (compositor, composite);
+}
+
static cairo_status_t
_stroke_shaper_add_triangle (void *closure,
const cairo_point_t triangle[3])