diff options
author | Eric Anholt <anholt@freebsd.org> | 2006-03-30 05:24:27 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2006-03-30 05:24:27 +0000 |
commit | 2153fa97482bae5737def3ecd4fe1cdc03834991 (patch) | |
tree | 2193047013d29a0b57ddc52de97d235001f63710 /exa | |
parent | 3cf46cc1e32efc0e4be1d88be111ba0438e0f021 (diff) |
Bug #2986: Add PutImage acceleration for the ZPixmap, planeMask ~=
FB_ALLONES, bitsPerPixel >= 8, GXcopy cases. With the radeon driver on
my machine, this gives about 10% speedup in PutImage
10x10 and 500x500, and 40% speedup for 10x10 ShmPutImage, up to 65%
improvement in 500x500 ShmPutImage. Also fixes a crasher in GetImage
that slipped in at the last minute.
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa_accel.c | 101 |
1 files changed, 99 insertions, 2 deletions
diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 6ab3a3cc4..bae755970 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -132,6 +132,103 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, exaMarkSync(pScreen); } +static void +exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + ExaScreenPriv (pDrawable->pScreen); + PixmapPtr pPix; + ExaMigrationRec pixmaps[1]; + RegionPtr pClip; + BoxPtr pbox; + int nbox; + int xoff, yoff; + int src_stride, bpp = pDrawable->bitsPerPixel; + + if (pExaScr->swappedOut || pExaScr->info->UploadToScreen == NULL) + goto migrate_and_fallback; + + /* Don't bother with under 8bpp, XYPixmaps. */ + if (format != ZPixmap || bpp < 8) + goto migrate_and_fallback; + + /* Only accelerate copies: no rop or planemask. */ + if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) + goto migrate_and_fallback; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + exaDoMigration (pixmaps, 1, TRUE); + pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); + + if (pPix == NULL) + goto fallback; + + pClip = fbGetCompositeClip(pGC); + src_stride = PixmapBytePad(w, pDrawable->depth); + for (nbox = REGION_NUM_RECTS(pClip), + pbox = REGION_RECTS(pClip); + nbox--; + pbox++) + { + int x1 = x; + int y1 = y; + int x2 = x + w; + int y2 = y + h; + char *src; + Bool ok; + + if (x1 < pbox->x1) + x1 = pbox->x1; + if (y1 < pbox->y1) + y1 = pbox->y1; + if (x2 > pbox->x2) + x2 = pbox->x2; + if (y2 > pbox->y2) + y2 = pbox->y2; + if (x1 >= x2 || y1 >= y2) + continue; + + src = bits + (y1 - y + yoff) * src_stride + (x1 - x + xoff) * (bpp / 8); + ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, + x2 - x1, y2 - y1, src, src_stride); + /* If we fail to accelerate the upload, fall back to using unaccelerated + * fb calls. + */ + if (!ok) { + FbStip *dst; + FbStride dst_stride; + int dstBpp; + int dstXoff, dstYoff; + + fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, + dstXoff, dstYoff); + + fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)), + src_stride / sizeof(FbStip), + (x1 - x) * bpp, + dst + (y1 + yoff) * dst_stride, + dst_stride, + (x1 + xoff) * bpp, + (x2 - x1) * bpp, + y2 - y1, + GXcopy, FB_ALLONES, bpp); + } + } + + return; + +migrate_and_fallback: + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + exaDoMigration (pixmaps, 1, FALSE); + +fallback: + ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); +} + static Bool inline exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) @@ -689,7 +786,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable, const GCOps exaOps = { exaFillSpans, ExaCheckSetSpans, - ExaCheckPutImage, + exaPutImage, exaCopyArea, ExaCheckCopyPlane, ExaCheckPolyPoint, @@ -992,7 +1089,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, yoff += pDrawable->y; ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d, - PixmapBytePad(pDrawable, w)); + PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); return; |