diff options
Diffstat (limited to 'xorg-server/exa/exa_accel.c')
-rw-r--r-- | xorg-server/exa/exa_accel.c | 340 |
1 files changed, 195 insertions, 145 deletions
diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c index dac6e6c79..33fbb9843 100644 --- a/xorg-server/exa/exa_accel.c +++ b/xorg-server/exa/exa_accel.c @@ -50,12 +50,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, int fullX1, fullX2, fullY1; int partX1, partX2; int off_x, off_y; - ExaMigrationRec pixmaps[1]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; if (pExaScr->swappedOut || pGC->fillStyle != FillSolid || @@ -63,7 +57,16 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, { ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); return; - } else { + } + + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[1]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = NULL; + exaDoMigration (pixmaps, 1, TRUE); } @@ -148,9 +151,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int nbox; int xoff, yoff; int bpp = pDrawable->bitsPerPixel; - Bool access_prepared = FALSE; + Bool ret = TRUE; - if (pExaPixmap->accel_blocked) + if (pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) return FALSE; /* Don't bother with under 8bpp, XYPixmaps. */ @@ -164,10 +167,10 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, if (pExaScr->swappedOut) return FALSE; - if (pExaPixmap->pDamage) { + if (pExaScr->do_migration) { ExaMigrationRec pixmaps[1]; - pixmaps[0].as_dst = TRUE; + pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPix; pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); @@ -177,7 +180,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - if (!pPix || !pExaScr->info->UploadToScreen) + if (!pPix) return FALSE; x += pDrawable->x; @@ -210,42 +213,19 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, src = bits + (y1 - y) * src_stride + (x1 - x) * (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. + /* We have to fall back completely, and ignore what has already been completed. + * Messing with the fb layer directly like we used to is completely unacceptable. */ if (!ok) { - FbStip *dst; - FbStride dst_stride; - int dstBpp; - int dstXoff, dstYoff; - - if (!access_prepared) { - ExaDoPrepareAccess(pDrawable, EXA_PREPARE_DEST); - - access_prepared = TRUE; - } - - fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, - dstXoff, dstYoff); - - fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)), - src_stride / sizeof(FbStip), - (x1 - x) * dstBpp, - dst + (y1 + dstYoff) * dst_stride, - dst_stride, - (x1 + dstXoff) * dstBpp, - (x2 - x1) * dstBpp, - y2 - y1, - GXcopy, FB_ALLONES, dstBpp); + ret = FALSE; + break; } } - if (access_prepared) - exaFinishAccess(pDrawable, EXA_PREPARE_DEST); - else + if (ret) exaMarkSync(pDrawable->pScreen); - return TRUE; + return ret; } static void @@ -379,8 +359,8 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, return TRUE; } -void -exaCopyNtoN (DrawablePtr pSrcDrawable, +Bool +exaHWCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, @@ -388,22 +368,20 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, int dx, int dy, Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure) + Bool upsidedown) { ExaScreenPriv (pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; - ExaMigrationRec pixmaps[2]; RegionPtr srcregion = NULL, dstregion = NULL; xRectangle *rects; + Bool ret = TRUE; /* avoid doing copy operations if no boxes */ if (nbox == 0) - return; + return TRUE; pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable); pDstPixmap = exaGetDrawablePixmap (pDstDrawable); @@ -446,14 +424,6 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, } } - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pDstPixmap; - pixmaps[0].pReg = dstregion; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pSrcPixmap; - pixmaps[1].pReg = srcregion; pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap); pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); @@ -487,7 +457,20 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, } } - exaDoMigration (pixmaps, 2, TRUE); + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[2]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pDstPixmap; + pixmaps[0].pReg = dstregion; + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = pSrcPixmap; + pixmaps[1].pReg = srcregion; + + exaDoMigration (pixmaps, 2, TRUE); + } /* Mixed directions must be handled specially if the card is lame */ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && @@ -498,40 +481,64 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, goto fallback; } - if (!exaPixmapIsOffscreen(pSrcPixmap) || - !exaPixmapIsOffscreen(pDstPixmap) || - !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, - upsidedown ? -1 : 1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : FB_ALLONES)) { - goto fallback; - } + if (exaPixmapIsOffscreen(pDstPixmap)) { + /* Normal blitting. */ + if (exaPixmapIsOffscreen(pSrcPixmap)) { + if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, + upsidedown ? -1 : 1, + pGC ? pGC->alu : GXcopy, + pGC ? pGC->planemask : FB_ALLONES)) { + goto fallback; + } - while (nbox--) - { - (*pExaScr->info->Copy) (pDstPixmap, - pbox->x1 + dx + src_off_x, - pbox->y1 + dy + src_off_y, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pbox++; - } + while (nbox--) + { + (*pExaScr->info->Copy) (pDstPixmap, + pbox->x1 + dx + src_off_x, + pbox->y1 + dy + src_off_y, + pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + pbox++; + } - (*pExaScr->info->DoneCopy) (pDstPixmap); - exaMarkSync (pDstDrawable->pScreen); + (*pExaScr->info->DoneCopy) (pDstPixmap); + exaMarkSync (pDstDrawable->pScreen); + /* UTS: mainly for SHM PutImage's secondary path. */ + } else { + int bpp = pSrcDrawable->bitsPerPixel; + int src_stride = exaGetPixmapPitch(pSrcPixmap); + CARD8 *src = NULL; + + if (!pExaScr->info->UploadToScreen) + goto fallback; + + if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) + goto fallback; + + if (pSrcDrawable->bitsPerPixel < 8) + goto fallback; + + if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) + goto fallback; + + while (nbox--) + { + src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); + if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, + (char *) src, src_stride)) + goto fallback; + + pbox++; + } + } + } else + goto fallback; goto out; fallback: - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable, - exaDrawableLocation(pSrcDrawable), - exaDrawableLocation(pDstDrawable))); - exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, dstregion); - exaPrepareAccessReg (pSrcDrawable, EXA_PREPARE_SRC, srcregion); - fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, - upsidedown, bitplane, closure); - exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC); - exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST); + ret = FALSE; out: if (dstregion) { @@ -542,6 +549,39 @@ out: REGION_UNINIT(pScreen, srcregion); REGION_DESTROY(pScreen, srcregion); } + + return ret; +} + +void +exaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + ExaScreenPriv(pDstDrawable->pScreen); + + if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) + return; + + if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown)) + return; + + /* This is a CopyWindow, it's cleaner to fallback at the original call. */ + if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) { + pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; + return; + } + + /* fallback */ + ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } RegionPtr @@ -555,7 +595,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, srcx, srcy, width, height, dstx, dsty); } - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + return miDoCopy (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, exaCopyNtoN, 0, NULL); } @@ -730,7 +770,6 @@ exaPolyFillRect(DrawablePtr pDrawable, int xoff, yoff; int xorg, yorg; int n; - ExaMigrationRec pixmaps[2]; RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); /* Compute intersection of rects and clip region */ @@ -741,11 +780,6 @@ exaPolyFillRect(DrawablePtr pDrawable, goto out; } - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); if (pExaScr->swappedOut || pExaPixmap->accel_blocked) @@ -778,7 +812,16 @@ exaPolyFillRect(DrawablePtr pDrawable, goto fallback; } - exaDoMigration (pixmaps, 1, TRUE); + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[1]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = NULL; + + exaDoMigration (pixmaps, 1, TRUE); + } if (!exaPixmapIsOffscreen (pPixmap) || !(*pExaScr->info->PrepareSolid) (pPixmap, @@ -898,6 +941,7 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) RegionRec rgnDst; int dx, dy; PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); + ExaScreenPriv(pWin->drawable.pScreen); dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; @@ -912,11 +956,19 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -pPixmap->screen_x, -pPixmap->screen_y); #endif - fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW; + miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); + pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW; REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); + + if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) { + pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW; + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy); + ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc); + } } static Bool @@ -927,23 +979,23 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); ExaPixmapPriv (pPixmap); int xoff, yoff; - ExaMigrationRec pixmaps[1]; Bool ret = FALSE; - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, - alu, clientClipType) - ? NULL : pRegion; - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); if (pExaPixmap->accel_blocked) - { goto out; - } else { + + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[1]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, + alu, clientClipType) ? NULL : pRegion; + exaDoMigration (pixmaps, 1, TRUE); } @@ -965,7 +1017,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); - if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && + if (pExaPixmap->pDamage && pDrawable->width == 1 && pDrawable->height == 1 && pDrawable->bitsPerPixel != 24) { ExaPixmapPriv(pPixmap); @@ -1008,7 +1060,6 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile); int xoff, yoff; int tileWidth, tileHeight; - ExaMigrationRec pixmaps[2]; int nbox = REGION_NUM_RECTS (pRegion); BoxPtr pBox = REGION_RECTS (pRegion); Bool ret = FALSE; @@ -1025,23 +1076,25 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, exaGetPixmapFirstPixel (pTile), planemask, alu, clientClipType); - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); - pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled, - alu, clientClipType) - ? NULL : pRegion; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pTile; - pixmaps[1].pReg = NULL; - + pPixmap = exaGetDrawablePixmap (pDrawable); pExaPixmap = ExaGetPixmapPriv (pPixmap); if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) - { return FALSE; - } else { + + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[2]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled, + alu, clientClipType) ? NULL : pRegion; + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = pTile; + pixmaps[1].pReg = NULL; + exaDoMigration (pixmaps, 2, TRUE); } @@ -1180,31 +1233,36 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ExaScreenPriv (pDrawable->pScreen); - ExaMigrationRec pixmaps[1]; - BoxRec Box; - RegionRec Reg; - PixmapPtr pPix; + PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); int xoff, yoff; Bool ok; - pixmaps[0].as_dst = FALSE; - pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable); - pixmaps[0].pReg = &Reg; + if (pExaScr->swappedOut) + goto fallback; exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); - Box.x1 = pDrawable->y + x + xoff; - Box.y1 = pDrawable->y + y + yoff; - Box.x2 = Box.x1 + w; - Box.y2 = Box.y1 + h; + if (pExaScr->do_migration) { + BoxRec Box; + RegionRec Reg; + ExaMigrationRec pixmaps[1]; - REGION_INIT(pScreen, &Reg, &Box, 1); + Box.x1 = pDrawable->y + x + xoff; + Box.y1 = pDrawable->y + y + yoff; + Box.x2 = Box.x1 + w; + Box.y2 = Box.y1 + h; - if (pExaScr->swappedOut) - goto fallback; + REGION_INIT(pScreen, &Reg, &Box, 1); - exaDoMigration(pixmaps, 1, FALSE); + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = pPix; + pixmaps[0].pReg = &Reg; + + exaDoMigration(pixmaps, 1, FALSE); + + REGION_UNINIT(pScreen, &Reg); + } pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); @@ -1226,17 +1284,9 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); - goto out; + return; } fallback: - EXA_FALLBACK(("from %p (%c)\n", pDrawable, - exaDrawableLocation(pDrawable))); - - exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg); - fbGetImage (pDrawable, x, y, w, h, format, planeMask, d); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - -out: - REGION_UNINIT(pScreen, &Reg); + ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); } |