diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-18 10:40:50 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-07-18 10:44:35 +0100 |
commit | bb0303677c38076db14dfbceec3636197a971e8c (patch) | |
tree | 31fac72762cd41070dab8b60e2e20a5b8bf5ad24 /src/sna | |
parent | bee1a14618797b3d3a1c1a20eb72644fa907c048 (diff) |
sna/trapezoids: Use pixman from within the spans to reduce two-pass operations
Reduce the two pass CompositeTrapezoids if we can perform the operation
inplace by calling pixman_image_composite from the span. This step
enables this for xrgb32.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/sna_trapezoids.c | 158 |
1 files changed, 109 insertions, 49 deletions
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 634423e5..7124bafb 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -4824,10 +4824,50 @@ unbounded_pass: return true; } +static void +pixmask_span(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) +{ + struct pixman_inplace *pi = (struct pixman_inplace *)op; + pixman_image_t *mask = NULL; + if (coverage != FAST_SAMPLES_XY) { + coverage = coverage * 256 / FAST_SAMPLES_XY; + coverage -= coverage >> 8; + *pi->bits = coverage; + mask = pi->mask; + } + pixman_image_composite(pi->op, pi->source, mask, pi->image, + pi->sx + box->x1, pi->sy + box->y1, + 0, 0, + pi->dx + box->x1, pi->dy + box->y1, + box->x2 - box->x1, box->y2 - box->y1); +} +static void +pixmask_span__clipped(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) +{ + pixman_region16_t region; + int n; + + pixman_region_init_rects(®ion, box, 1); + RegionIntersect(®ion, ®ion, clip); + n = REGION_NUM_RECTS(®ion); + box = REGION_RECTS(®ion); + while (n--) + pixmask_span(sna, op, NULL, box++, coverage); + pixman_region_fini(®ion); +} + static bool trapezoid_span_inplace__x8r8g8b8(CARD8 op, - uint32_t color, PicturePtr dst, + PicturePtr src, int16_t src_x, int16_t src_y, PictFormatPtr maskFormat, int ntrap, xTrapezoid *traps) { @@ -4838,34 +4878,14 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, int dx, dy; int n; - if (op == PictOpOver && (color >> 24) == 0xff) - op = PictOpSrc; - if (op == PictOpOver) { - struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); - if (priv && priv->clear && priv->clear_color == 0) - op = PictOpSrc; - } - - switch (op) { - case PictOpSrc: - break; - default: - DBG(("%s: fallback -- can not perform op [%d] in place\n", - __FUNCTION__, op)); - return false; - } - - DBG(("%s: format=%x, op=%d, color=%x\n", - __FUNCTION__, dst->format, op, color)); - if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ - if (!trapezoid_span_inplace__x8r8g8b8(op, color, - dst, NULL, - 1, traps++)) + if (!trapezoid_span_inplace__x8r8g8b8(op, dst, + src, src_x, src_y, + NULL, 1, traps++)) return false; } while (--ntrap); return true; @@ -4915,37 +4935,76 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, tor_add_edge(&tor, &t, &t.right, -1); } - switch (op) { - case PictOpSrc: - if (dst->pCompositeClip->data) - span = tor_blt_lerp32_clipped; - else - span = tor_blt_lerp32; - break; - } - DBG(("%s: move-to-cpu\n", __FUNCTION__)); region.data = NULL; if (sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, MOVE_WRITE | MOVE_READ)) { PixmapPtr pixmap; - struct inplace inplace; + uint32_t color; pixmap = get_drawable_pixmap(dst->pDrawable); - get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y); - inplace.ptr = pixmap->devPrivate.ptr; - inplace.ptr += dst_y * pixmap->devKind + dst_x; - inplace.stride = pixmap->devKind; - inplace.color = color; + if (!sna_picture_is_solid(src, &color)) + goto pixman; + + if (op == PictOpOver && (color >> 24) == 0xff) + op = PictOpSrc; + if (op == PictOpOver) { + struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); + if (priv && priv->clear && priv->clear_color == 0) + op = PictOpSrc; + } + + DBG(("%s: format=%x, op=%d, color=%x\n", + __FUNCTION__, dst->format, op, color)); + + if (op == PictOpSrc) { + struct inplace inplace; + + inplace.ptr = pixmap->devPrivate.ptr; + inplace.ptr += dst_y * pixmap->devKind + dst_x; + inplace.stride = pixmap->devKind; + inplace.color = color; + + if (dst->pCompositeClip->data) + span = tor_blt_lerp32_clipped; + else + span = tor_blt_lerp32; + + DBG(("%s: render inplace op=%d, color=%08x\n", + __FUNCTION__, op, color)); + + tor_render(NULL, &tor, (void*)&inplace, + dst->pCompositeClip, span, false); + tor_fini(&tor); + } else { + struct pixman_inplace pi; + +pixman: + pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); + pi.source = image_from_pict(src, false, &pi.sx, &pi.sy); + pi.sx += src_x; + pi.sy += src_y; + pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0); + pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); + pi.bits = pixman_image_get_data(pi.mask); + pi.op = op; + + if (dst->pCompositeClip->data) + span = pixmask_span__clipped; + else + span = pixmask_span; - DBG(("%s: render inplace op=%d, color=%08x\n", - __FUNCTION__, op, color)); - tor_render(NULL, &tor, (void*)&inplace, - dst->pCompositeClip, span, false); + tor_render(NULL, &tor, (void*)&pi, + dst->pCompositeClip, span, + operator_is_bounded(op)); + tor_fini(&tor); - tor_fini(&tor); + pixman_image_unref(pi.mask); + pixman_image_unref(pi.source); + pixman_image_unref(pi.image); + } } return true; @@ -4994,17 +5053,18 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, return trapezoid_span_mono_inplace(op, src, dst, src_x, src_y, ntrap, traps); + if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) + return trapezoid_span_inplace__x8r8g8b8(op, dst, + src, src_x, src_y, + maskFormat, + ntrap, traps); + if (!sna_picture_is_solid(src, &color)) { DBG(("%s: fallback -- can not perform operation in place, requires solid source\n", __FUNCTION__)); return false; } - if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) - return trapezoid_span_inplace__x8r8g8b8(op, color, - dst, maskFormat, - ntrap, traps); - if (dst->format != PICT_a8) { DBG(("%s: fallback -- can not perform operation in place, format=%x\n", __FUNCTION__, dst->format)); |