diff options
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa_accel.c | 76 | ||||
-rw-r--r-- | exa/exa_priv.h | 25 | ||||
-rw-r--r-- | exa/exa_render.c | 17 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 50 |
4 files changed, 149 insertions, 19 deletions
diff --git a/exa/exa_accel.c b/exa/exa_accel.c index cc5dd18f2..326720f9f 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -359,8 +359,8 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, return TRUE; } -void -exaCopyNtoN (DrawablePtr pSrcDrawable, +Bool +exaHWCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, @@ -368,9 +368,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, int dx, int dy, Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure) + Bool upsidedown) { ExaScreenPriv (pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; @@ -380,10 +378,11 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, 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); @@ -492,15 +491,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, 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) { @@ -511,6 +502,52 @@ 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; + } + + /* We need a pGC to call our fallback. */ + if (!pGC) { + pExaScr->fallback_flags |= EXA_FALLBACK_NOGC; + pGC = CreateScratchGC(pDstDrawable->pScreen, pDstDrawable->depth); + if (!pGC) + return; + } + + /* fallback */ + ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure); + + if (pExaScr->fallback_flags & EXA_FALLBACK_NOGC) { + pExaScr->fallback_flags &= ~EXA_FALLBACK_NOGC; + FreeScratchGC(pGC); + } } RegionPtr @@ -865,6 +902,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; @@ -879,11 +917,19 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -pPixmap->screen_x, -pPixmap->screen_y); #endif + 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 diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 6d7c1dd63..588fdec54 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -127,6 +127,10 @@ typedef struct { #define EXA_NUM_GLYPH_CACHES 4 +#define EXA_FALLBACK_COPYWINDOW (1 << 0) +#define EXA_ACCEL_COPYWINDOW (1 << 1) +#define EXA_FALLBACK_NOGC (1 << 2) + typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); typedef struct { ExaDriverPtr info; @@ -155,6 +159,8 @@ typedef struct { unsigned disableFbCount; Bool optimize_migration; unsigned offScreenCounter; + /* Holds information on fallbacks that cannot be relayed otherwise. */ + unsigned int fallback_flags; ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; } ExaScreenPrivRec, *ExaScreenPrivPtr; @@ -316,6 +322,11 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits); +void +ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure); + RegionPtr ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty); @@ -361,6 +372,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, int w, int h, int x, int y); void +ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); @@ -465,6 +479,17 @@ RegionPtr exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); +Bool +exaHWCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown); + void exaCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, diff --git a/exa/exa_render.c b/exa/exa_render.c index 63ea5c158..17885317f 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -851,6 +851,7 @@ exaComposite(CARD8 op, !pSrc->repeat && !pSrc->transform) { + Bool ret; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; @@ -861,12 +862,20 @@ exaComposite(CARD8 op, yDst, width, height)) goto done; - - exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL, + ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL, REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), - xSrc - xDst, ySrc - yDst, - FALSE, FALSE, 0, NULL); + xSrc - xDst, ySrc - yDst, FALSE, FALSE); REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + + /* Reset values to their original values. */ + xDst -= pDst->pDrawable->x; + yDst -= pDst->pDrawable->y; + xSrc -= pSrc->pDrawable->x; + ySrc -= pSrc->pDrawable->y; + + if (!ret) + goto fallback; + goto done; } else if (pSrc->pDrawable != NULL && diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index e0f2ae9a9..978a32f59 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -116,6 +116,40 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, EXA_GC_EPILOGUE(pGC); } +/* Sometimes we need a pGC to call a function, but don't actually want the lower + * layer to do something with the contents of this fake GC. */ +static inline GCPtr +ExaCheckWantGC(DrawablePtr pDrawable, GCPtr pGC) +{ + ExaScreenPriv(pDrawable->pScreen); + + if (pExaScr->fallback_flags & EXA_FALLBACK_NOGC) + return NULL; + + return pGC; +} + +void +ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure) +{ + EXA_GC_PROLOGUE(pGC); + EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, + exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); + exaPrepareAccess (pDst, EXA_PREPARE_DEST); + exaPrepareAccess (pSrc, EXA_PREPARE_SRC); + /* This will eventually call fbCopyNtoN, with some calculation overhead. */ + while (nbox--) { + pGC->ops->CopyArea (pSrc, pDst, ExaCheckWantGC(pDst, pGC), pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y); + pbox++; + } + exaFinishAccess (pSrc, EXA_PREPARE_SRC); + exaFinishAccess (pDst, EXA_PREPARE_DEST); + EXA_GC_EPILOGUE(pGC); +} + RegionPtr ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) @@ -283,6 +317,22 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, } void +ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + DrawablePtr pDrawable = &pWin->drawable; + ScreenPtr pScreen = pDrawable->pScreen; + ExaScreenPriv(pScreen); + EXA_FALLBACK(("from %p\n", pWin)); + + /* being both src and dest, src is safest. */ + exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); + swap(pExaScr, pScreen, CopyWindow); + pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc); + swap(pExaScr, pScreen, CopyWindow); + exaFinishAccess (pDrawable, EXA_PREPARE_SRC); +} + +void ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { |