summaryrefslogtreecommitdiff
path: root/uxa/uxa-accel.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-03-31 20:30:27 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-04-10 18:50:26 +0100
commit27195d7dba0f3ff08b92f3fd916cdf5113cbef58 (patch)
treeb8ea8453b8357e38b75506c192c498d7fa5fb5f5 /uxa/uxa-accel.c
parent385563417d10b5e8a005bed6ae4de9a8fac1b407 (diff)
uxa: Try using put_image when copying from a memory buffer.
Often, for example in the fallback for ShmPutImage, we will attempt to use uxa_copy_area() copying to a normal pixmap from a memory buffer. This triggers a fallback, and maps the destination pixmap back into the GTT. The accelerated put_image path will attempt to stream a blit to the destination pixmap if it is currently active, avoiding the stall.
Diffstat (limited to 'uxa/uxa-accel.c')
-rw-r--r--uxa/uxa-accel.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c
index 7fb4bf98..c022956c 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -470,18 +470,19 @@ uxa_copy_n_to_n(DrawablePtr pSrcDrawable,
goto fallback;
}
- if (!uxa_pixmap_is_offscreen(pSrcPixmap) ||
- !uxa_pixmap_is_offscreen(pDstPixmap) ||
- !(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap,
+ if (!uxa_pixmap_is_offscreen(pDstPixmap))
+ goto fallback;
+
+ if (uxa_pixmap_is_offscreen(pSrcPixmap)) {
+ if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap,
reverse ? -1 : 1,
upsidedown ? -1 : 1,
pGC ? pGC->alu : GXcopy,
pGC ? pGC->
- planemask : FB_ALLONES)) {
+ planemask : FB_ALLONES))
goto fallback;
- }
- while (nbox--) {
+ while (nbox--) {
(*uxa_screen->info->copy) (pDstPixmap,
pbox->x1 + dx + src_off_x,
pbox->y1 + dy + src_off_y,
@@ -490,9 +491,43 @@ uxa_copy_n_to_n(DrawablePtr pSrcDrawable,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
pbox++;
- }
+ }
+
+ (*uxa_screen->info->done_copy) (pDstPixmap);
+ } else {
+ int stride, bpp;
+ char *src;
- (*uxa_screen->info->done_copy) (pDstPixmap);
+ if (!uxa_screen->info->put_image)
+ goto fallback;
+
+ /* Don't bother with under 8bpp, XYPixmaps. */
+ bpp = pSrcPixmap->drawable.bitsPerPixel;
+ if (bpp != pDstDrawable->bitsPerPixel || bpp < 8)
+ goto fallback;
+
+ /* Only accelerate copies: no rop or planemask. */
+ if (pGC && (!UXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask) || pGC->alu != GXcopy))
+ goto fallback;
+
+ src = pSrcPixmap->devPrivate.ptr;
+ stride = pSrcPixmap->devKind;
+ bpp /= 8;
+ while (nbox--) {
+ if (!uxa_screen->info->put_image(pDstPixmap,
+ pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1,
+ (char *) src +
+ (pbox->y1 + dy + src_off_y) * stride +
+ (pbox->x1 + dx + src_off_x) * bpp,
+ stride))
+ goto fallback;
+
+ pbox++;
+ }
+ }
return;