summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-09-28 18:26:42 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-09-28 18:57:01 +0100
commit2579d34713033c75deed3628a50dfcb164028310 (patch)
tree54aa23db77e832195038e2f918a1af2f5fe58660
parent8f33f80100096f7790c7b819ce37a3ed8ce8b5fa (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>
-rw-r--r--src/sna/fb/fbimage.c12
-rw-r--r--src/sna/sna_accel.c15
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, &region, dst, flags))
- return;
+ goto apply_planemask;
if (!sna_drawable_move_region_to_cpu(&pixmap->drawable,
&region, 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;