diff options
Diffstat (limited to 'xorg-server/exa/exa_accel.c')
-rw-r--r-- | xorg-server/exa/exa_accel.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c index 7e2dd7079..1d88acbf0 100644 --- a/xorg-server/exa/exa_accel.c +++ b/xorg-server/exa/exa_accel.c @@ -51,7 +51,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, int partX1, partX2; int off_x, off_y; - if (pExaScr->swappedOut || + if (pExaScr->fallback_counter || + pExaScr->swappedOut || pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) { @@ -153,7 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int bpp = pDrawable->bitsPerPixel; Bool ret = TRUE; - if (pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) + if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) return FALSE; /* Don't bother with under 8bpp, XYPixmaps. */ @@ -481,9 +482,9 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, goto fallback; } - if (exaPixmapIsOffscreen(pDstPixmap)) { + if (exaPixmapHasGpuCopy(pDstPixmap)) { /* Normal blitting. */ - if (exaPixmapIsOffscreen(pSrcPixmap)) { + if (exaPixmapHasGpuCopy(pSrcPixmap)) { if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, @@ -503,8 +504,13 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, (*pExaScr->info->DoneCopy) (pDstPixmap); exaMarkSync (pDstDrawable->pScreen); - /* UTS: mainly for SHM PutImage's secondary path. */ - } else { + /* UTS: mainly for SHM PutImage's secondary path. + * + * Not taking this path for mixed pixmaps: It could only save one CPU + * copy between cached memory and risks causing a more expensive + * DownloadFromScreen later on. + */ + } else if (!(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) { int bpp = pSrcDrawable->bitsPerPixel; int src_stride = exaGetPixmapPitch(pSrcPixmap); CARD8 *src = NULL; @@ -531,7 +537,8 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, pbox++; } - } + } else + goto fallback; } else goto fallback; @@ -568,7 +575,8 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, { ExaScreenPriv(pDstDrawable->pScreen); - if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) + if (pExaScr->fallback_counter || + (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)) return; if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown)) @@ -590,7 +598,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, { ExaScreenPriv (pDstDrawable->pScreen); - if (pExaScr->swappedOut) { + if (pExaScr->fallback_counter || pExaScr->swappedOut) { return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty); } @@ -604,13 +612,14 @@ static void exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { + ExaScreenPriv (pDrawable->pScreen); int i; xRectangle *prect; /* If we can't reuse the current GC as is, don't bother accelerating the * points. */ - if (pGC->fillStyle != FillSolid) { + if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) { ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt); return; } @@ -639,10 +648,16 @@ static void exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { + ExaScreenPriv (pDrawable->pScreen); xRectangle *prect; int x1, x2, y1, y2; int i; + if (pExaScr->fallback_counter) { + ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); + return; + } + /* Don't try to do wide lines or non-solid fill style. */ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { @@ -700,12 +715,13 @@ static void exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg) { + ExaScreenPriv (pDrawable->pScreen); xRectangle *prect; int i; /* Don't try to do wide lines or non-solid fill style. */ - if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || - pGC->fillStyle != FillSolid) + if (pExaScr->fallback_counter || pGC->lineWidth != 0 || + pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); return; @@ -782,7 +798,8 @@ exaPolyFillRect(DrawablePtr pDrawable, exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - if (pExaScr->swappedOut || pExaPixmap->accel_blocked) + if (pExaScr->fallback_counter || pExaScr->swappedOut || + pExaPixmap->accel_blocked) { goto fallback; } @@ -823,7 +840,7 @@ exaPolyFillRect(DrawablePtr pDrawable, exaDoMigration (pixmaps, 1, TRUE); } - if (!exaPixmapIsOffscreen (pPixmap) || + if (!exaPixmapHasGpuCopy (pPixmap) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, @@ -956,12 +973,18 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -pPixmap->screen_x, -pPixmap->screen_y); #endif + if (pExaScr->fallback_counter) { + pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; + goto fallback; + } + pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW; miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW; +fallback: REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) { @@ -984,7 +1007,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); - if (pExaPixmap->accel_blocked) + if (pExaScr->fallback_counter || pExaPixmap->accel_blocked) goto out; if (pExaScr->do_migration) { @@ -999,7 +1022,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, exaDoMigration (pixmaps, 1, TRUE); } - if (exaPixmapIsOffscreen (pPixmap) && + if (exaPixmapHasGpuCopy (pPixmap) && (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) { int nbox; @@ -1080,7 +1103,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, pPixmap = exaGetDrawablePixmap (pDrawable); pExaPixmap = ExaGetPixmapPriv (pPixmap); - if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) + if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || + pTileExaPixmap->accel_blocked) return FALSE; if (pExaScr->do_migration) { @@ -1101,7 +1125,7 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - if (!pPixmap || !exaPixmapIsOffscreen(pTile)) + if (!pPixmap || !exaPixmapHasGpuCopy(pTile)) return FALSE; if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) @@ -1238,7 +1262,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, int xoff, yoff; Bool ok; - if (pExaScr->swappedOut) + if (pExaScr->fallback_counter || pExaScr->swappedOut) goto fallback; exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); |