diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-09-28 18:26:42 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-09-28 18:57:01 +0100 |
commit | 2579d34713033c75deed3628a50dfcb164028310 (patch) | |
tree | 54aa23db77e832195038e2f918a1af2f5fe58660 /src | |
parent | 8f33f80100096f7790c7b819ce37a3ed8ce8b5fa (diff) |
sna: Handle GetImage planemask inplace
As found by Adam Jackson, we can perform the masking of the planemask on
the user buffer and so avoid hitting the fallback paths, so long as we
have no 24bpp Pixmaps.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/fb/fbimage.c | 12 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 15 |
2 files changed, 21 insertions, 6 deletions
diff --git a/src/sna/fb/fbimage.c b/src/sna/fb/fbimage.c index 5af23890..cc81c85b 100644 --- a/src/sna/fb/fbimage.c +++ b/src/sna/fb/fbimage.c @@ -229,13 +229,19 @@ fbGetImage(DrawablePtr drawable, FbBits pm; pm = fbReplicatePixel(planeMask, srcBpp); + dstStride = PixmapBytePad(w, drawable->depth); - if (pm != FB_ALLONES) - memset(d, 0, dstStride * h); dstStride /= sizeof(FbStip); + fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride, (x + srcXoff) * srcBpp, - dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp); + dst, dstStride, 0, w * srcBpp, h, GXcopy, FB_ALLONES, srcBpp); + + if (pm != FB_ALLONES) { + int i = dstStride * h; + while (i--) + *dst++ &= pm; + } } else { dstStride = BitmapBytePad(w) / sizeof(FbStip); fbBltPlane(src + (y + srcYoff) * srcStride, diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 30252982..9fe09fff 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -17191,8 +17191,7 @@ sna_get_image(DrawablePtr drawable, if (ACCEL_GET_IMAGE && !FORCE_FALLBACK && format == ZPixmap && - drawable->bitsPerPixel >= 8 && - PM_IS_SOLID(drawable, mask)) { + drawable->bitsPerPixel >= 8) { PixmapPtr pixmap = get_drawable_pixmap(drawable); int16_t dx, dy; @@ -17204,7 +17203,7 @@ sna_get_image(DrawablePtr drawable, region.data = NULL; if (sna_get_image__fast(pixmap, ®ion, dst, flags)) - return; + goto apply_planemask; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, flags)) @@ -17222,6 +17221,16 @@ sna_get_image(DrawablePtr drawable, region.extents.x1, region.extents.y1, 0, 0, w, h); sigtrap_put(); } + +apply_planemask: + if (!PM_IS_SOLID(drawable, mask)) { + FbStip pm = fbReplicatePixel(mask, drawable->bitsPerPixel); + FbStip *d = (FbStip *)dst; + int i, n = PixmapBytePad(w, drawable->depth) / sizeof(FbStip) * h; + + for (i = 0; i < n; i++) + d[i] &= pm; + } } else { region.extents.x1 = x + drawable->x; region.extents.y1 = y + drawable->y; |