summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-26 22:55:04 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-26 23:24:57 +0000
commit7ff40b572ec5cd860d7c7ff23beca0388f37c31c (patch)
tree7dd17cbc34ffb2539f4e544a5b78a552f08a65b7
parentadb1320bba15a3a3b4fa8e7d0fd0360fa696721d (diff)
sna: Avoid fbBlt for the easy GetImage cases
From (i5-2520m): 60000 trep @ 0.6145 msec ( 1630.0/sec): GetImage 500x500 square To: 60000 trep @ 0.4949 msec ( 2020.0/sec): GetImage 500x500 square Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 7fe06de0..cad8d660 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11154,11 +11154,13 @@ sna_get_image(DrawablePtr drawable,
char *dst)
{
RegionRec region;
+ DDXPointRec origin;
DBG(("%s (%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h));
- region.extents.x1 = x + drawable->x;
- region.extents.y1 = y + drawable->y;
+ /* XXX should be clipped already according to the spec... */
+ origin.x = region.extents.x1 = x + drawable->x;
+ origin.y = region.extents.y1 = y + drawable->y;
region.extents.x2 = region.extents.x1 + w;
region.extents.y2 = region.extents.y1 + h;
region.data = NULL;
@@ -11173,14 +11175,46 @@ sna_get_image(DrawablePtr drawable,
region.extents.y1 = drawable->y;
if (region.extents.y2 > drawable->y + drawable->height)
region.extents.y2 = drawable->y + drawable->height;
- } else
- RegionIntersect(&region, &region,
- &((WindowPtr)drawable)->borderClip);
+ } else {
+ pixman_box16_t *c = &((WindowPtr)drawable)->borderClip.extents;
+ pixman_box16_t *r = &region.extents;
+
+ if (r->x1 < c->x1)
+ r->x1 = c->x1;
+ if (r->x2 > c->x2)
+ r->x2 = c->x2;
+
+ if (r->y1 < c->y1)
+ r->y1 = c->y1;
+ if (r->y2 > c->y2)
+ r->y2 = c->y2;
+ }
if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_READ))
return;
- fbGetImage(drawable, x, y, w, h, format, mask, dst);
+ if (format == ZPixmap &&
+ drawable->bitsPerPixel >= 8 &&
+ PM_IS_SOLID(drawable, mask)) {
+ PixmapPtr pixmap = get_drawable_pixmap(drawable);
+ int16_t dx, dy;
+
+ DBG(("%s: copy box (%d, %d), (%d, %d), origin (%d, %d)\n",
+ __FUNCTION__,
+ region.extents.x1, region.extents.y1,
+ region.extents.x2, region.extents.y2,
+ origin.x, origin.y));
+ get_drawable_deltas(drawable, pixmap, &dx, &dy);
+ memcpy_blt(pixmap->devPrivate.ptr, dst, drawable->bitsPerPixel,
+ pixmap->devKind, PixmapBytePad(w, drawable->depth),
+ region.extents.x1 + dx,
+ region.extents.y1 + dy,
+ region.extents.x1 - origin.x,
+ region.extents.y1 - origin.y,
+ region.extents.x2 - region.extents.x1,
+ region.extents.y2 - region.extents.y1);
+ } else
+ fbGetImage(drawable, x, y, w, h, format, mask, dst);
}
static void