exa: don't use fbCopyNtoN

This commit is contained in:
Maarten Maathuis 2009-02-05 17:07:31 +01:00
parent 2e76958d30
commit 68665d78e7
4 changed files with 149 additions and 19 deletions

View File

@ -359,8 +359,8 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
return TRUE; return TRUE;
} }
void Bool
exaCopyNtoN (DrawablePtr pSrcDrawable, exaHWCopyNtoN (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, GCPtr pGC,
BoxPtr pbox, BoxPtr pbox,
@ -368,9 +368,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dx, int dx,
int dy, int dy,
Bool reverse, Bool reverse,
Bool upsidedown, Bool upsidedown)
Pixel bitplane,
void *closure)
{ {
ExaScreenPriv (pDstDrawable->pScreen); ExaScreenPriv (pDstDrawable->pScreen);
PixmapPtr pSrcPixmap, pDstPixmap; PixmapPtr pSrcPixmap, pDstPixmap;
@ -380,10 +378,11 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
ExaMigrationRec pixmaps[2]; ExaMigrationRec pixmaps[2];
RegionPtr srcregion = NULL, dstregion = NULL; RegionPtr srcregion = NULL, dstregion = NULL;
xRectangle *rects; xRectangle *rects;
Bool ret = TRUE;
/* avoid doing copy operations if no boxes */ /* avoid doing copy operations if no boxes */
if (nbox == 0) if (nbox == 0)
return; return TRUE;
pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable); pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
pDstPixmap = exaGetDrawablePixmap (pDstDrawable); pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
@ -492,15 +491,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
goto out; goto out;
fallback: fallback:
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable, ret = FALSE;
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);
out: out:
if (dstregion) { if (dstregion) {
@ -511,6 +502,52 @@ out:
REGION_UNINIT(pScreen, srcregion); REGION_UNINIT(pScreen, srcregion);
REGION_DESTROY(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 RegionPtr
@ -865,6 +902,7 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
RegionRec rgnDst; RegionRec rgnDst;
int dx, dy; int dx, dy;
PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
ExaScreenPriv(pWin->drawable.pScreen);
dx = ptOldOrg.x - pWin->drawable.x; dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y; dy = ptOldOrg.y - pWin->drawable.y;
@ -879,11 +917,19 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-pPixmap->screen_x, -pPixmap->screen_y); -pPixmap->screen_x, -pPixmap->screen_y);
#endif #endif
pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
NULL, NULL,
&rgnDst, dx, dy, exaCopyNtoN, 0, NULL); &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); 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 static Bool

View File

@ -127,6 +127,10 @@ typedef struct {
#define EXA_NUM_GLYPH_CACHES 4 #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 void (*EnableDisableFBAccessProcPtr)(int, Bool);
typedef struct { typedef struct {
ExaDriverPtr info; ExaDriverPtr info;
@ -155,6 +159,8 @@ typedef struct {
unsigned disableFbCount; unsigned disableFbCount;
Bool optimize_migration; Bool optimize_migration;
unsigned offScreenCounter; unsigned offScreenCounter;
/* Holds information on fallbacks that cannot be relayed otherwise. */
unsigned int fallback_flags;
ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
} ExaScreenPrivRec, *ExaScreenPrivPtr; } 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, int x, int y, int w, int h, int leftPad, int format,
char *bits); 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 RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty); int srcx, int srcy, int w, int h, int dstx, int dsty);
@ -360,6 +371,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable, DrawablePtr pDrawable,
int w, int h, int x, int y); int w, int h, int x, int y);
void
ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void void
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d); unsigned int format, unsigned long planeMask, char *d);
@ -465,6 +479,17 @@ RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
int srcx, int srcy, int width, int height, int dstx, int dsty); 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 void
exaCopyNtoN (DrawablePtr pSrcDrawable, exaCopyNtoN (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable, DrawablePtr pDstDrawable,

View File

@ -851,6 +851,7 @@ exaComposite(CARD8 op,
!pSrc->repeat && !pSrc->repeat &&
!pSrc->transform) !pSrc->transform)
{ {
Bool ret;
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x; xSrc += pSrc->pDrawable->x;
@ -861,12 +862,20 @@ exaComposite(CARD8 op,
yDst, width, height)) yDst, width, height))
goto done; goto done;
ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
REGION_RECTS(&region), REGION_NUM_RECTS(&region), REGION_RECTS(&region), REGION_NUM_RECTS(&region),
xSrc - xDst, ySrc - yDst, xSrc - xDst, ySrc - yDst, FALSE, FALSE);
FALSE, FALSE, 0, NULL);
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_UNINIT(pDst->pDrawable->pScreen, &region);
/* 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; goto done;
} }
else if (pSrc->pDrawable != NULL && else if (pSrc->pDrawable != NULL &&

View File

@ -116,6 +116,40 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
EXA_GC_EPILOGUE(pGC); 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 RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty) int srcx, int srcy, int w, int h, int dstx, int dsty)
@ -282,6 +316,22 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
EXA_GC_EPILOGUE(pGC); EXA_GC_EPILOGUE(pGC);
} }
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 void
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d) unsigned int format, unsigned long planeMask, char *d)