diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-28 13:46:18 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-28 15:20:10 +0000 |
commit | 9105b7e03ab7e3602c7200ebdc44e89f873afe1f (patch) | |
tree | 558eeda4a0d6ec07f6d4a4e6ad35de75268a3daa | |
parent | a5583165da0d2ae5eb1e5a2e11ee6e245d4b5aa4 (diff) |
sna: Perform clip mask compositing inplace
Avoid the extra composite-in pass for simple clipmask construction.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_trapezoids.c | 167 |
1 files changed, 123 insertions, 44 deletions
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 81d43123..9222f2fb 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -2999,17 +2999,17 @@ struct inplace { }; static void -tor_blt_inplace(struct sna *sna, - struct sna_composite_spans_op *op, - pixman_region16_t *clip, - const BoxRec *box, - int coverage) +tor_blt_src(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) { struct inplace *in = (struct inplace *)op; uint8_t *ptr = in->ptr; int h, w; - coverage = (int)coverage * in->opacity / FAST_SAMPLES_XY; + coverage = coverage * in->opacity / FAST_SAMPLES_XY; ptr += box->y1 * in->stride + box->x1; @@ -3029,11 +3029,11 @@ tor_blt_inplace(struct sna *sna, } static void -tor_blt_inplace_clipped(struct sna *sna, - struct sna_composite_spans_op *op, - pixman_region16_t *clip, - const BoxRec *box, - int coverage) +tor_blt_src_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; @@ -3042,33 +3042,100 @@ tor_blt_inplace_clipped(struct sna *sna, RegionIntersect(®ion, ®ion, clip); n = REGION_NUM_RECTS(®ion); box = REGION_RECTS(®ion); - while (n--){ - tor_blt_inplace(sna, op, NULL, box, coverage); - box++; + while (n--) + tor_blt_src(sna, op, NULL, box++, coverage); + pixman_region_fini(®ion); +} + +static void +tor_blt_src_mono(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) +{ + tor_blt_src(sna, op, clip, box, + coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); +} + +static void +tor_blt_src_clipped_mono(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) +{ + tor_blt_src_clipped(sna, op, clip, box, + coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); +} + +static void +tor_blt_in(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) +{ + struct inplace *in = (struct inplace *)op; + uint8_t *ptr = in->ptr; + int h, w, i; + + coverage = coverage * in->opacity / FAST_SAMPLES_XY; + if (coverage == 0) { + tor_blt_src(sna, op, clip, box, 0); + return; } + + ptr += box->y1 * in->stride + box->x1; + + h = box->y2 - box->y1; + w = box->x2 - box->x1; + do { + for (i = 0; i < w; i++) + ptr[i] = (ptr[i] * coverage) >> 8; + ptr += in->stride; + } while (--h); +} + +static void +tor_blt_in_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--) + tor_blt_in(sna, op, NULL, box++, coverage); pixman_region_fini(®ion); } static void -tor_blt_inplace_mono(struct sna *sna, - struct sna_composite_spans_op *op, - pixman_region16_t *clip, - const BoxRec *box, - int coverage) +tor_blt_in_mono(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) { - tor_blt_inplace(sna, op, clip, box, - coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); + tor_blt_in(sna, op, clip, box, + coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); } static void -tor_blt_inplace_clipped_mono(struct sna *sna, - struct sna_composite_spans_op *op, - pixman_region16_t *clip, - const BoxRec *box, - int coverage) +tor_blt_in_clipped_mono(struct sna *sna, + struct sna_composite_spans_op *op, + pixman_region16_t *clip, + const BoxRec *box, + int coverage) { - tor_blt_inplace_clipped(sna, op, clip, box, - coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); + tor_blt_in_clipped(sna, op, clip, box, + coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); } static bool @@ -3100,7 +3167,11 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, return false; } - if (dst->format != PICT_a8 || op != PictOpSrc || + DBG(("%s: format=%x, op=%d, color=%x\n", + __FUNCTION__, dst->format, op, color)); + + if (dst->format != PICT_a8 || + !(op == PictOpSrc || op == PictOpIn) || !sna_picture_is_solid(src, &color)) { DBG(("%s: fallback -- can not perform operation in place\n", __FUNCTION__)); @@ -3163,16 +3234,30 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst, tor_add_edge(&tor, &t, &t.right, -1); } - if (dst->pCompositeClip->data) { - if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) - span = tor_blt_inplace_clipped_mono; - else - span = tor_blt_inplace_clipped; + if (op == PictOpSrc) { + if (dst->pCompositeClip->data) { + if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) + span = tor_blt_src_clipped_mono; + else + span = tor_blt_src_clipped; + } else { + if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) + span = tor_blt_src_mono; + else + span = tor_blt_src; + } } else { - if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) - span = tor_blt_inplace_mono; - else - span = tor_blt_inplace; + if (dst->pCompositeClip->data) { + if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) + span = tor_blt_in_clipped_mono; + else + span = tor_blt_in_clipped; + } else { + if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) + span = tor_blt_in_mono; + else + span = tor_blt_in; + } } region.data = NULL; @@ -3379,12 +3464,6 @@ sna_composite_trapezoids(CARD8 op, goto fallback; } - if (!is_gpu(dst->pDrawable)) { - if (trapezoid_span_inplace(op, src, dst, maskFormat, - xSrc, ySrc, ntrap, traps)) - return; - } - if (too_small(dst->pDrawable) && !picture_is_gpu(src)) { DBG(("%s: fallback -- dst is too small, %dx%d\n", __FUNCTION__, |