image: Enable use of LERP_SRC for masked source composition

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-09-27 12:27:49 +01:00
parent 2994b0c634
commit 719bef0c90
3 changed files with 40 additions and 12 deletions

View file

@ -465,7 +465,32 @@ composite_boxes (void *_dst,
/* XXX consider using a region? saves multiple prepare-composite */
op = _pixman_operator (op);
if (((cairo_surface_t *)_dst)->is_clear &&
(op == CAIRO_OPERATOR_SOURCE ||
op == CAIRO_OPERATOR_OVER ||
op == CAIRO_OPERATOR_ADD)) {
op = PIXMAN_OP_SRC;
} else if (mask) {
if (op == CAIRO_OPERATOR_CLEAR) {
#if PIXMAN_HAS_OP_LERP
op = PIXMAN_OP_LERP_CLEAR;
#else
src = _pixman_image_for_color (CAIRO_COLOR_WHITE);
op = PIXMAN_OP_OUT_REVERSE;
#endif
} else if (op == CAIRO_OPERATOR_SOURCE) {
#if PIXMAN_HAS_OP_LERP
op = PIXMAN_OP_LERP_SRC;
#else
return CAIRO_INT_STATUS_UNSUPPORTED;
#endif
} else {
op = _pixman_operator (op);
}
} else {
op = _pixman_operator (op);
}
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
@ -1533,6 +1558,11 @@ _cairo_image_spans_compositor_get (void)
_cairo_spans_compositor_init (&compositor,
_cairo_image_traps_compositor_get());
compositor.flags = 0;
#if PIXMAN_HAS_OP_LERP
compositor.flags |= CAIRO_SPANS_COMPOSITOR_HAS_LERP;
#endif
//compositor.acquire = acquire;
//compositor.release = release;
compositor.fill_boxes = fill_boxes;

View file

@ -52,6 +52,9 @@ typedef struct _cairo_abstract_span_renderer {
struct cairo_spans_compositor {
cairo_compositor_t base;
unsigned int flags;
#define CAIRO_SPANS_COMPOSITOR_HAS_LERP 0x1
/* pixel-aligned fast paths */
cairo_int_status_t (*fill_boxes) (void *surface,
cairo_operator_t op,

View file

@ -231,8 +231,8 @@ fixup_unbounded_mask (const cairo_spans_compositor_t *compositor,
status = _cairo_composite_rectangles_init_for_boxes (&composite,
extents->surface,
CAIRO_OPERATOR_DEST_OUT,
&_cairo_pattern_white.base,
CAIRO_OPERATOR_CLEAR,
&_cairo_pattern_clear.base,
boxes,
NULL);
if (unlikely (status))
@ -282,8 +282,8 @@ fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor,
status = _cairo_composite_rectangles_init_for_polygon (&composite,
extents->surface,
CAIRO_OPERATOR_DEST_OUT,
&_cairo_pattern_white.base,
CAIRO_OPERATOR_CLEAR,
&_cairo_pattern_clear.base,
&polygon,
NULL);
if (unlikely (status))
@ -464,8 +464,8 @@ composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
if (op == CAIRO_OPERATOR_SOURCE && (need_clip_mask || ! no_mask)) {
/* SOURCE with a mask is actually a LERP in cairo semantics */
/* XXX push this choice down to the backend */
return CAIRO_INT_STATUS_UNSUPPORTED;
if ((compositor->flags & CAIRO_SPANS_COMPOSITOR_HAS_LERP) == 0)
return CAIRO_INT_STATUS_UNSUPPORTED;
}
/* Are we just copying a recording surface? */
@ -551,11 +551,6 @@ composite_aligned_boxes (const cairo_spans_compositor_t *compositor,
}
}
if (mask && op == CAIRO_OPERATOR_CLEAR) {
source = &_cairo_pattern_white.base;
op = CAIRO_OPERATOR_DEST_OUT;
}
src = compositor->pattern_to_surface (dst, source, FALSE,
&extents->bounded,
&extents->source_sample_area,