diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-03-31 20:30:27 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-04-10 18:50:26 +0100 |
commit | 27195d7dba0f3ff08b92f3fd916cdf5113cbef58 (patch) | |
tree | b8ea8453b8357e38b75506c192c498d7fa5fb5f5 /uxa/uxa-accel.c | |
parent | 385563417d10b5e8a005bed6ae4de9a8fac1b407 (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.c | 51 |
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; |