diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-18 16:21:27 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-19 14:04:48 +0100 |
commit | 6921abd81017c9ed7f3b2413784068fbc609a0ea (patch) | |
tree | 2470a6b0af4eaefaa2d44c84a1dfc662f24a528e /src | |
parent | 4da830864983ffe482388e4e4cfee02d106c895e (diff) |
sna: Add a fast path for the most common fallback for CPU-CPU blits
This path will mostly be upload for individual glyph uploads, for which
the malloc overhead is significant.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_blt.c | 7 | ||||
-rw-r--r-- | src/sna/sna_composite.c | 39 | ||||
-rw-r--r-- | src/sna/sna_render.h | 7 |
3 files changed, 46 insertions, 7 deletions
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index beef9a65..b4ef083f 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -1953,13 +1953,6 @@ prepare_blt_put(struct sna *sna, return true; } -#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \ - PICT_FORMAT_TYPE(format), \ - 0, \ - PICT_FORMAT_R(format), \ - PICT_FORMAT_G(format), \ - PICT_FORMAT_B(format)) - static bool is_clear(PixmapPtr pixmap) { diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index ea4a1003..36e2bdee 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -470,6 +470,7 @@ sna_composite_fb(CARD8 op, int src_xoff, src_yoff; int msk_xoff, msk_yoff; int dst_xoff, dst_yoff; + int16_t tx, ty; unsigned flags; DBG(("%s -- op=%d, fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n", @@ -519,6 +520,44 @@ sna_composite_fb(CARD8 op, if (mask) validate_source(mask); + if (mask == NULL && + src->pDrawable && + src->filter != PictFilterConvolution && + (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) && + (dst->format == src->format || dst->format == alphaless(src->format)) && + sna_transform_is_integer_translation(src->transform, &tx, &ty) && + region->extents.x1 + src_x + tx >= 0 && + region->extents.y1 + src_y + ty >= 0 && + region->extents.x2 + src_x + tx <= src->pDrawable->width && + region->extents.x2 + src_y + ty <= src->pDrawable->height) { + PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable); + PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable); + int nbox = RegionNumRects(region); + BoxPtr box = RegionRects(region); + + src_x += tx; src_y += ty; + + get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty); + src_x += tx; src_y += ty; + + get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty); + dst_x += tx; dst_y += ty; + + do { + memcpy_blt(src_pixmap->devPrivate.ptr, + dst_pixmap->devPrivate.ptr, + dst_pixmap->drawable.bitsPerPixel, + src_pixmap->devKind, + dst_pixmap->devKind, + box->x1 + src_x, box->y1 + src_y, + box->x1 + dst_x, box->y1 + dst_y, + box->x2 - box->x1, box->y2 - box->y1); + box++; + } while (--nbox); + + return; + } + src_image = image_from_pict(src, FALSE, &src_xoff, &src_yoff); mask_image = image_from_pict(mask, FALSE, &msk_xoff, &msk_yoff); dest_image = image_from_pict(dst, TRUE, &dst_xoff, &dst_yoff); diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index aace869e..26363945 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -775,4 +775,11 @@ static inline bool sna_vertex_wait__locked(struct sna_render *r) return was_active; } +#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \ + PICT_FORMAT_TYPE(format), \ + 0, \ + PICT_FORMAT_R(format), \ + PICT_FORMAT_G(format), \ + PICT_FORMAT_B(format)) + #endif /* SNA_RENDER_H */ |