EXA: Support partial migration of pixmap contents between Sys and FB.
The initiator of migration can pass in a region that defines the relevant area of each source pixmap or the irrelevant area of the destination pixmap. By default, the pending damage region is assumed relevant for the destination pixmap, and everything for source pixmaps. Thanks to Jarno Manninen for reassuring me that my own ideas for this were feasible and for providing additional ideas.
This commit is contained in:
parent
f27931bdd2
commit
962eddd7a2
25
exa/exa.c
25
exa/exa.c
|
@ -363,6 +363,21 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
|
||||||
|
{
|
||||||
|
ExaMigrationRec pixmaps[1];
|
||||||
|
|
||||||
|
pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
|
||||||
|
pixmaps[0].as_src = index != EXA_PREPARE_DEST;
|
||||||
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = pReg;
|
||||||
|
|
||||||
|
exaDoMigration(pixmaps, 1, FALSE);
|
||||||
|
|
||||||
|
ExaDoPrepareAccess(pDrawable, index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
||||||
*
|
*
|
||||||
|
@ -372,15 +387,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
void
|
void
|
||||||
exaPrepareAccess(DrawablePtr pDrawable, int index)
|
exaPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
{
|
{
|
||||||
ExaMigrationRec pixmaps[1];
|
exaPrepareAccessReg(pDrawable, index, NULL);
|
||||||
|
|
||||||
pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
|
|
||||||
pixmaps[0].as_src = index != EXA_PREPARE_DEST;
|
|
||||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
|
||||||
|
|
||||||
exaDoMigration(pixmaps, 1, FALSE);
|
|
||||||
|
|
||||||
ExaDoPrepareAccess(pDrawable, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -55,6 +55,7 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
if (pExaScr->swappedOut ||
|
if (pExaScr->swappedOut ||
|
||||||
pGC->fillStyle != FillSolid ||
|
pGC->fillStyle != FillSolid ||
|
||||||
|
@ -153,6 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
/* Don't bother with under 8bpp, XYPixmaps. */
|
/* Don't bother with under 8bpp, XYPixmaps. */
|
||||||
if (format != ZPixmap || bpp < 8)
|
if (format != ZPixmap || bpp < 8)
|
||||||
|
@ -211,7 +213,8 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
int dstXoff, dstYoff;
|
int dstXoff, dstYoff;
|
||||||
|
|
||||||
if (!access_prepared) {
|
if (!access_prepared) {
|
||||||
exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg(pDrawable, EXA_PREPARE_DEST,
|
||||||
|
pixmaps[0].pReg);
|
||||||
|
|
||||||
access_prepared = TRUE;
|
access_prepared = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -232,6 +235,8 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
|
|
||||||
if (access_prepared)
|
if (access_prepared)
|
||||||
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
||||||
|
else
|
||||||
|
exaMarkSync(pDrawable->pScreen);
|
||||||
|
|
||||||
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
|
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
|
||||||
}
|
}
|
||||||
|
@ -420,9 +425,11 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
|
pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
pixmaps[1].as_dst = FALSE;
|
pixmaps[1].as_dst = FALSE;
|
||||||
pixmaps[1].as_src = TRUE;
|
pixmaps[1].as_src = TRUE;
|
||||||
pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
|
pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
|
||||||
|
pixmaps[1].pReg = NULL;
|
||||||
|
|
||||||
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
|
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
|
||||||
* violate the limits. The proper solution would be a temporary pixmap
|
* violate the limits. The proper solution would be a temporary pixmap
|
||||||
|
@ -463,7 +470,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||||
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
|
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
|
||||||
exaDrawableLocation(pSrcDrawable),
|
exaDrawableLocation(pSrcDrawable),
|
||||||
exaDrawableLocation(pDstDrawable)));
|
exaDrawableLocation(pDstDrawable)));
|
||||||
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
|
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
|
||||||
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
|
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
|
||||||
pbox, nbox, dx, dy, reverse, upsidedown,
|
pbox, nbox, dx, dy, reverse, upsidedown,
|
||||||
|
@ -682,7 +689,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap;
|
pixmaps[0].pPix = pPixmap;
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
|
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
|
||||||
|
|
||||||
if (pExaScr->swappedOut ||
|
if (pExaScr->swappedOut ||
|
||||||
|
@ -828,6 +836,7 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
if (pExaScr->swappedOut ||
|
if (pExaScr->swappedOut ||
|
||||||
pPixmap->drawable.width > pExaScr->info->maxX ||
|
pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||||
|
@ -846,7 +855,7 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
||||||
exaDrawableLocation(pDrawable)));
|
exaDrawableLocation(pDrawable)));
|
||||||
fallback = TRUE;
|
fallback = TRUE;
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
|
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
|
||||||
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
|
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
|
||||||
fbAnd (GXcopy, fg, pm),
|
fbAnd (GXcopy, fg, pm),
|
||||||
|
@ -949,6 +958,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = TRUE;
|
pixmaps[0].as_src = TRUE;
|
||||||
pixmaps[0].pPix = pPixmap;
|
pixmaps[0].pPix = pPixmap;
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
depthMask = FbFullMask(pDrawable->depth);
|
depthMask = FbFullMask(pDrawable->depth);
|
||||||
if ((pGC->planemask & depthMask) != depthMask)
|
if ((pGC->planemask & depthMask) != depthMask)
|
||||||
|
@ -987,7 +997,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
}
|
}
|
||||||
|
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
exaPrepareAccessGC (pGC);
|
exaPrepareAccessGC (pGC);
|
||||||
|
|
||||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||||
|
@ -1099,7 +1109,8 @@ exaFillRegionSolid (DrawablePtr pDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
pPixmap->drawable.height > pExaScr->info->maxY)
|
||||||
{
|
{
|
||||||
|
@ -1128,7 +1139,7 @@ fallback:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
||||||
exaDrawableLocation(pDrawable)));
|
exaDrawableLocation(pDrawable)));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
fbFillRegionSolid (pDrawable, pRegion, 0,
|
fbFillRegionSolid (pDrawable, pRegion, 0,
|
||||||
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
|
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
@ -1170,9 +1181,11 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
pixmaps[1].as_dst = FALSE;
|
pixmaps[1].as_dst = FALSE;
|
||||||
pixmaps[1].as_src = TRUE;
|
pixmaps[1].as_src = TRUE;
|
||||||
pixmaps[1].pPix = pTile;
|
pixmaps[1].pPix = pTile;
|
||||||
|
pixmaps[1].pReg = NULL;
|
||||||
|
|
||||||
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
if (pPixmap->drawable.width > pExaScr->info->maxX ||
|
||||||
pPixmap->drawable.height > pExaScr->info->maxY ||
|
pPixmap->drawable.height > pExaScr->info->maxY ||
|
||||||
|
@ -1243,7 +1256,7 @@ fallback:
|
||||||
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
|
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
|
||||||
exaDrawableLocation(&pTile->drawable),
|
exaDrawableLocation(&pTile->drawable),
|
||||||
exaDrawableLocation(pDrawable)));
|
exaDrawableLocation(pDrawable)));
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
|
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
|
||||||
fbFillRegionTiled (pDrawable, pRegion, pTile);
|
fbFillRegionTiled (pDrawable, pRegion, pTile);
|
||||||
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
|
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
|
||||||
|
|
|
@ -117,28 +117,62 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
|
||||||
* FB to system or vice versa. Both areas must be allocated.
|
* FB to system or vice versa. Both areas must be allocated.
|
||||||
*/
|
*/
|
||||||
static _X_INLINE void
|
static _X_INLINE void
|
||||||
exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
|
exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||||
Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
|
Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
|
||||||
char *sys, int sys_pitch), CARD8 *fallback_src,
|
char *sys, int sys_pitch), CARD8 *fallback_src,
|
||||||
CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
|
CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
|
||||||
int fallback_index, void (*sync) (ScreenPtr pScreen))
|
int fallback_index, void (*sync) (ScreenPtr pScreen))
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
RegionPtr pDamageReg = DamageRegion (pExaPixmap->pDamage);
|
RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
|
||||||
RegionRec CopyReg;
|
RegionRec CopyReg;
|
||||||
CARD8 *save_ptr;
|
CARD8 *save_ptr;
|
||||||
int save_pitch;
|
int save_pitch;
|
||||||
BoxPtr pBox;
|
BoxPtr pBox;
|
||||||
int nbox;
|
int nbox;
|
||||||
Bool do_sync = FALSE;
|
Bool access_prepared = FALSE;
|
||||||
|
|
||||||
/* Damaged bits are valid in source but invalid in destination */
|
/* Damaged bits are valid in current copy but invalid in other one */
|
||||||
REGION_UNION(pScreen, pValidSrc, pValidSrc, pDamageReg);
|
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||||
REGION_SUBTRACT(pScreen, pValidDst, pValidDst, pDamageReg);
|
REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
|
||||||
|
damage);
|
||||||
|
REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||||
|
damage);
|
||||||
|
} else {
|
||||||
|
REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||||
|
damage);
|
||||||
|
REGION_SUBTRACT(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
|
||||||
|
damage);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy bits valid in ssource but not in destination */
|
REGION_EMPTY(pScreen, damage);
|
||||||
|
|
||||||
|
/* Copy bits valid in source but not in destination */
|
||||||
REGION_NULL(pScreen, &CopyReg);
|
REGION_NULL(pScreen, &CopyReg);
|
||||||
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
|
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
|
||||||
|
|
||||||
|
if (migrate->as_dst) {
|
||||||
|
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
|
||||||
|
|
||||||
|
if (REGION_NIL(pending_damage)) {
|
||||||
|
static Bool firsttime = TRUE;
|
||||||
|
|
||||||
|
if (firsttime) {
|
||||||
|
ErrorF("%s: Pending damage region empty!\n", __func__);
|
||||||
|
firsttime = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
|
||||||
|
|
||||||
|
if (migrate->pReg)
|
||||||
|
REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
|
||||||
|
} else {
|
||||||
|
if (migrate->pReg)
|
||||||
|
REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
|
||||||
|
}
|
||||||
|
|
||||||
pBox = REGION_RECTS(&CopyReg);
|
pBox = REGION_RECTS(&CopyReg);
|
||||||
nbox = REGION_NUM_RECTS(&CopyReg);
|
nbox = REGION_NUM_RECTS(&CopyReg);
|
||||||
|
|
||||||
|
@ -165,29 +199,30 @@ exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||||
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
|
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
|
||||||
pExaPixmap->sys_pitch))
|
pExaPixmap->sys_pitch))
|
||||||
{
|
{
|
||||||
ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
|
if (!access_prepared) {
|
||||||
|
ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
|
||||||
|
access_prepared = TRUE;
|
||||||
|
}
|
||||||
exaMemcpyBox (pPixmap, pBox,
|
exaMemcpyBox (pPixmap, pBox,
|
||||||
fallback_src, fallback_srcpitch,
|
fallback_src, fallback_srcpitch,
|
||||||
fallback_dst, fallback_dstpitch);
|
fallback_dst, fallback_dstpitch);
|
||||||
exaFinishAccess(&pPixmap->drawable, fallback_index);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
do_sync = TRUE;
|
|
||||||
|
|
||||||
pBox++;
|
pBox++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_sync)
|
if (access_prepared)
|
||||||
|
exaFinishAccess(&pPixmap->drawable, fallback_index);
|
||||||
|
else
|
||||||
sync (pPixmap->drawable.pScreen);
|
sync (pPixmap->drawable.pScreen);
|
||||||
|
|
||||||
pPixmap->devPrivate.ptr = save_ptr;
|
pPixmap->devPrivate.ptr = save_ptr;
|
||||||
pPixmap->devKind = save_pitch;
|
pPixmap->devKind = save_pitch;
|
||||||
|
|
||||||
/* The copied bits are now no longer damaged but valid in destination */
|
/* The copied bits are now valid in destination */
|
||||||
REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
|
REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
|
||||||
REGION_SUBTRACT(pScreen, pDamageReg, pDamageReg, &CopyReg);
|
|
||||||
|
|
||||||
REGION_NULL(pScreen, &CopyReg);
|
REGION_UNINIT(pScreen, &CopyReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,12 +231,13 @@ exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exaCopyDirtyToSys (PixmapPtr pPixmap)
|
exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
exaCopyDirty(pPixmap, &pExaPixmap->validSys, &pExaPixmap->validFB,
|
exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
|
||||||
pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
|
pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
|
||||||
pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
|
pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
|
||||||
pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
|
pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
|
||||||
|
@ -213,50 +249,18 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exaCopyDirtyToFb (PixmapPtr pPixmap)
|
exaCopyDirtyToFb (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
exaCopyDirty(pPixmap, &pExaPixmap->validFB, &pExaPixmap->validSys,
|
exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
|
||||||
pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
|
pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
|
||||||
pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
|
pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
|
||||||
pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
|
pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies out important pixmap data and removes references to framebuffer area.
|
|
||||||
* Called when the memory manager decides it's time to kick the pixmap out of
|
|
||||||
* framebuffer entirely.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
|
||||||
{
|
|
||||||
PixmapPtr pPixmap = area->privData;
|
|
||||||
ExaPixmapPriv(pPixmap);
|
|
||||||
|
|
||||||
DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
|
|
||||||
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
|
|
||||||
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
|
|
||||||
pPixmap->drawable.width,
|
|
||||||
pPixmap->drawable.height,
|
|
||||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
|
||||||
|
|
||||||
if (exaPixmapIsOffscreen(pPixmap)) {
|
|
||||||
exaCopyDirtyToSys (pPixmap);
|
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
|
||||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
pExaPixmap->fb_ptr = NULL;
|
|
||||||
pExaPixmap->area = NULL;
|
|
||||||
|
|
||||||
/* Mark all FB bits as invalid, so all valid system bits get copied to FB
|
|
||||||
* next time */
|
|
||||||
REGION_NULL(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a framebuffer copy of the pixmap if necessary, and then copies
|
* Allocates a framebuffer copy of the pixmap if necessary, and then copies
|
||||||
* any necessary pixmap data into the framebuffer copy and points the pixmap at
|
* any necessary pixmap data into the framebuffer copy and points the pixmap at
|
||||||
|
@ -272,10 +276,11 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
||||||
* we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
|
* we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
|
||||||
* all the data, since it's almost surely all valid now.
|
* all the data, since it's almost surely all valid now.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
exaMoveInPixmap (PixmapPtr pPixmap)
|
exaDoMoveInPixmap (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
ExaScreenPriv (pScreen);
|
ExaScreenPriv (pScreen);
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
|
@ -283,10 +288,6 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
if (pExaScr->swappedOut)
|
if (pExaScr->swappedOut)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we're already in FB, our work is done. */
|
|
||||||
if (exaPixmapIsOffscreen(pPixmap))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If we're not allowed to move, then fail. */
|
/* If we're not allowed to move, then fail. */
|
||||||
if (exaPixmapIsPinned(pPixmap))
|
if (exaPixmapIsPinned(pPixmap))
|
||||||
return;
|
return;
|
||||||
|
@ -310,6 +311,11 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
pExaPixmap->area->offset;
|
pExaPixmap->area->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exaCopyDirtyToFb (migrate);
|
||||||
|
|
||||||
|
if (exaPixmapIsOffscreen(pPixmap))
|
||||||
|
return;
|
||||||
|
|
||||||
DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
|
DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
|
||||||
(ExaGetPixmapPriv(pPixmap)->area ?
|
(ExaGetPixmapPriv(pPixmap)->area ?
|
||||||
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
|
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
|
||||||
|
@ -317,8 +323,6 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
pPixmap->drawable.height,
|
pPixmap->drawable.height,
|
||||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||||
|
|
||||||
exaCopyDirtyToFb (pPixmap);
|
|
||||||
|
|
||||||
if (pExaScr->hideOffscreenPixmapData)
|
if (pExaScr->hideOffscreenPixmapData)
|
||||||
pPixmap->devPrivate.ptr = NULL;
|
pPixmap->devPrivate.ptr = NULL;
|
||||||
else
|
else
|
||||||
|
@ -327,18 +331,31 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
|
||||||
|
.pReg = NULL };
|
||||||
|
|
||||||
|
migrate.pPix = pPixmap;
|
||||||
|
exaDoMoveInPixmap (&migrate);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switches the current active location of the pixmap to system memory, copying
|
* Switches the current active location of the pixmap to system memory, copying
|
||||||
* updated data out if necessary.
|
* updated data out if necessary.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
exaMoveOutPixmap (PixmapPtr pPixmap)
|
exaDoMoveOutPixmap (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
if (exaPixmapIsPinned(pPixmap))
|
if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
exaCopyDirtyToSys (migrate);
|
||||||
|
|
||||||
if (exaPixmapIsOffscreen(pPixmap)) {
|
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||||
|
|
||||||
DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
|
DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
|
||||||
|
@ -348,21 +365,52 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
|
||||||
pPixmap->drawable.height,
|
pPixmap->drawable.height,
|
||||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||||
|
|
||||||
exaCopyDirtyToSys (pPixmap);
|
|
||||||
|
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exaMoveOutPixmap (PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
|
||||||
|
.pReg = NULL };
|
||||||
|
|
||||||
|
migrate.pPix = pPixmap;
|
||||||
|
exaDoMoveOutPixmap (&migrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies out important pixmap data and removes references to framebuffer area.
|
||||||
|
* Called when the memory manager decides it's time to kick the pixmap out of
|
||||||
|
* framebuffer entirely.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
||||||
|
{
|
||||||
|
PixmapPtr pPixmap = area->privData;
|
||||||
|
ExaPixmapPriv(pPixmap);
|
||||||
|
|
||||||
|
exaMoveOutPixmap(pPixmap);
|
||||||
|
|
||||||
|
pExaPixmap->fb_ptr = NULL;
|
||||||
|
pExaPixmap->area = NULL;
|
||||||
|
|
||||||
|
/* Mark all FB bits as invalid, so all valid system bits get copied to FB
|
||||||
|
* next time */
|
||||||
|
REGION_EMPTY(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the "greedy" migration scheme, pushes the pixmap toward being located in
|
* For the "greedy" migration scheme, pushes the pixmap toward being located in
|
||||||
* framebuffer memory.
|
* framebuffer memory.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exaMigrateTowardFb (PixmapPtr pPixmap)
|
exaMigrateTowardFb (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
if (pExaPixmap == NULL) {
|
if (pExaPixmap == NULL) {
|
||||||
|
@ -382,7 +430,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
||||||
(pointer)pPixmap, pExaPixmap->score));
|
(pointer)pPixmap, pExaPixmap->score));
|
||||||
|
|
||||||
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
|
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
|
||||||
exaMoveInPixmap(pPixmap);
|
exaDoMoveInPixmap(migrate);
|
||||||
pExaPixmap->score = 0;
|
pExaPixmap->score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +440,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
||||||
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
|
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
|
||||||
!exaPixmapIsOffscreen(pPixmap))
|
!exaPixmapIsOffscreen(pPixmap))
|
||||||
{
|
{
|
||||||
exaMoveInPixmap (pPixmap);
|
exaDoMoveInPixmap(migrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExaOffscreenMarkUsed (pPixmap);
|
ExaOffscreenMarkUsed (pPixmap);
|
||||||
|
@ -403,8 +451,9 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
||||||
* system memory.
|
* system memory.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
exaMigrateTowardSys (PixmapPtr pPixmap)
|
exaMigrateTowardSys (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
if (pExaPixmap == NULL) {
|
if (pExaPixmap == NULL) {
|
||||||
|
@ -426,7 +475,7 @@ exaMigrateTowardSys (PixmapPtr pPixmap)
|
||||||
pExaPixmap->score--;
|
pExaPixmap->score--;
|
||||||
|
|
||||||
if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
|
if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
|
||||||
exaMoveOutPixmap (pPixmap);
|
exaDoMoveOutPixmap(migrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,15 +487,24 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
ExaPixmapPriv (pPixmap);
|
ExaPixmapPriv (pPixmap);
|
||||||
CARD8 *dst, *src;
|
CARD8 *dst, *src;
|
||||||
RegionPtr pValidReg = exaPixmapIsOffscreen(pPixmap) ? &pExaPixmap->validFB :
|
RegionRec ValidReg;
|
||||||
&pExaPixmap->validSys;
|
int dst_pitch, src_pitch, cpp, y, nbox;
|
||||||
int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
|
BoxPtr pBox;
|
||||||
BoxPtr pBox = REGION_RECTS(pValidReg);
|
|
||||||
Bool ret = TRUE;
|
Bool ret = TRUE;
|
||||||
|
|
||||||
if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
|
if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
REGION_NULL(pScreen, &ValidReg);
|
||||||
|
REGION_INTERSECT(pScreen, &ValidReg, &pExaPixmap->validFB,
|
||||||
|
&pExaPixmap->validSys);
|
||||||
|
nbox = REGION_NUM_RECTS(&ValidReg);
|
||||||
|
|
||||||
|
if (!nbox)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
pBox = REGION_RECTS(&ValidReg);
|
||||||
|
|
||||||
dst_pitch = pExaPixmap->sys_pitch;
|
dst_pitch = pExaPixmap->sys_pitch;
|
||||||
src_pitch = pExaPixmap->fb_pitch;
|
src_pitch = pExaPixmap->fb_pitch;
|
||||||
cpp = pPixmap->drawable.bitsPerPixel / 8;
|
cpp = pPixmap->drawable.bitsPerPixel / 8;
|
||||||
|
@ -479,6 +537,8 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
||||||
}
|
}
|
||||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||||
|
|
||||||
|
out:
|
||||||
|
REGION_UNINIT(pScreen, &ValidReg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +593,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
{
|
{
|
||||||
for (i = 0; i < npixmaps; i++) {
|
for (i = 0; i < npixmaps; i++) {
|
||||||
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
||||||
exaMoveOutPixmap (pixmaps[i].pPix);
|
exaDoMoveOutPixmap (pixmaps + i);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -544,17 +604,17 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
*/
|
*/
|
||||||
if (!can_accel) {
|
if (!can_accel) {
|
||||||
for (i = 0; i < npixmaps; i++) {
|
for (i = 0; i < npixmaps; i++) {
|
||||||
exaMigrateTowardSys (pixmaps[i].pPix);
|
exaMigrateTowardSys (pixmaps + i);
|
||||||
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
||||||
exaMoveOutPixmap (pixmaps[i].pPix);
|
exaDoMoveOutPixmap (pixmaps + i);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, the acceleration path. Move them all in. */
|
/* Finally, the acceleration path. Move them all in. */
|
||||||
for (i = 0; i < npixmaps; i++) {
|
for (i = 0; i < npixmaps; i++) {
|
||||||
exaMigrateTowardFb(pixmaps[i].pPix);
|
exaMigrateTowardFb(pixmaps + i);
|
||||||
exaMoveInPixmap(pixmaps[i].pPix);
|
exaDoMoveInPixmap(pixmaps + i);
|
||||||
}
|
}
|
||||||
} else if (pExaScr->migration == ExaMigrationGreedy) {
|
} else if (pExaScr->migration == ExaMigrationGreedy) {
|
||||||
/* If we can't accelerate, either because the driver can't or because one of
|
/* If we can't accelerate, either because the driver can't or because one of
|
||||||
|
@ -570,7 +630,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
*/
|
*/
|
||||||
if (!can_accel) {
|
if (!can_accel) {
|
||||||
for (i = 0; i < npixmaps; i++)
|
for (i = 0; i < npixmaps; i++)
|
||||||
exaMigrateTowardSys (pixmaps[i].pPix);
|
exaMigrateTowardSys (pixmaps + i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,14 +638,14 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
|
if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
|
||||||
/* Found one in FB, so move all to FB. */
|
/* Found one in FB, so move all to FB. */
|
||||||
for (j = 0; j < npixmaps; j++)
|
for (j = 0; j < npixmaps; j++)
|
||||||
exaMigrateTowardFb(pixmaps[j].pPix);
|
exaMigrateTowardFb(pixmaps + i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nobody's in FB, so move all away from FB. */
|
/* Nobody's in FB, so move all away from FB. */
|
||||||
for (i = 0; i < npixmaps; i++)
|
for (i = 0; i < npixmaps; i++)
|
||||||
exaMigrateTowardSys(pixmaps[i].pPix);
|
exaMigrateTowardSys(pixmaps + i);
|
||||||
} else if (pExaScr->migration == ExaMigrationAlways) {
|
} else if (pExaScr->migration == ExaMigrationAlways) {
|
||||||
/* Always move the pixmaps out if we can't accelerate. If we can
|
/* Always move the pixmaps out if we can't accelerate. If we can
|
||||||
* accelerate, try to move them all in. If that fails, then move them
|
* accelerate, try to move them all in. If that fails, then move them
|
||||||
|
@ -593,13 +653,13 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
*/
|
*/
|
||||||
if (!can_accel) {
|
if (!can_accel) {
|
||||||
for (i = 0; i < npixmaps; i++)
|
for (i = 0; i < npixmaps; i++)
|
||||||
exaMoveOutPixmap(pixmaps[i].pPix);
|
exaDoMoveOutPixmap(pixmaps + i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, try to move them all into FB */
|
/* Now, try to move them all into FB */
|
||||||
for (i = 0; i < npixmaps; i++) {
|
for (i = 0; i < npixmaps; i++) {
|
||||||
exaMoveInPixmap(pixmaps[i].pPix);
|
exaDoMoveInPixmap(pixmaps + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we couldn't fit everything in, abort */
|
/* If we couldn't fit everything in, abort */
|
||||||
|
|
|
@ -185,6 +185,7 @@ typedef struct _ExaMigrationRec {
|
||||||
Bool as_dst;
|
Bool as_dst;
|
||||||
Bool as_src;
|
Bool as_src;
|
||||||
PixmapPtr pPix;
|
PixmapPtr pPix;
|
||||||
|
RegionPtr pReg;
|
||||||
} ExaMigrationRec, *ExaMigrationPtr;
|
} ExaMigrationRec, *ExaMigrationPtr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,6 +338,9 @@ ExaOffscreenFini (ScreenPtr pScreen);
|
||||||
void
|
void
|
||||||
ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
|
ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
|
||||||
|
|
||||||
void
|
void
|
||||||
exaPrepareAccess(DrawablePtr pDrawable, int index);
|
exaPrepareAccess(DrawablePtr pDrawable, int index);
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,7 @@ exaTryDriverSolidFill(PicturePtr pSrc,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
exaDoMigration(pixmaps, 1, TRUE);
|
exaDoMigration(pixmaps, 1, TRUE);
|
||||||
|
|
||||||
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||||
|
@ -381,13 +382,16 @@ exaTryDriverComposite(CARD8 op,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = exaOpReadsDestination(op);
|
pixmaps[0].as_src = exaOpReadsDestination(op);
|
||||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
pixmaps[1].as_dst = FALSE;
|
pixmaps[1].as_dst = FALSE;
|
||||||
pixmaps[1].as_src = TRUE;
|
pixmaps[1].as_src = TRUE;
|
||||||
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
||||||
|
pixmaps[1].pReg = NULL;
|
||||||
if (pMask) {
|
if (pMask) {
|
||||||
pixmaps[2].as_dst = FALSE;
|
pixmaps[2].as_dst = FALSE;
|
||||||
pixmaps[2].as_src = TRUE;
|
pixmaps[2].as_src = TRUE;
|
||||||
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
||||||
|
pixmaps[2].pReg = NULL;
|
||||||
exaDoMigration(pixmaps, 3, TRUE);
|
exaDoMigration(pixmaps, 3, TRUE);
|
||||||
} else {
|
} else {
|
||||||
exaDoMigration(pixmaps, 2, TRUE);
|
exaDoMigration(pixmaps, 2, TRUE);
|
||||||
|
@ -579,12 +583,14 @@ exaComposite(CARD8 op,
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = exaOpReadsDestination(op);
|
pixmaps[0].as_src = exaOpReadsDestination(op);
|
||||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
|
|
||||||
if (pSrc->pDrawable) {
|
if (pSrc->pDrawable) {
|
||||||
pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
|
pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
|
||||||
pixmaps[npixmaps].as_dst = FALSE;
|
pixmaps[npixmaps].as_dst = FALSE;
|
||||||
pixmaps[npixmaps].as_src = TRUE;
|
pixmaps[npixmaps].as_src = TRUE;
|
||||||
pixmaps[npixmaps].pPix = pSrcPixmap;
|
pixmaps[npixmaps].pPix = pSrcPixmap;
|
||||||
|
pixmaps[npixmaps].pReg = NULL;
|
||||||
npixmaps++;
|
npixmaps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,6 +598,7 @@ exaComposite(CARD8 op,
|
||||||
pixmaps[npixmaps].as_dst = FALSE;
|
pixmaps[npixmaps].as_dst = FALSE;
|
||||||
pixmaps[npixmaps].as_src = TRUE;
|
pixmaps[npixmaps].as_src = TRUE;
|
||||||
pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
||||||
|
pixmaps[npixmaps].pReg = NULL;
|
||||||
npixmaps++;
|
npixmaps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,8 +1166,9 @@ exaGlyphs (CARD8 op,
|
||||||
* it'll stick there.
|
* it'll stick there.
|
||||||
*/
|
*/
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = TRUE;
|
pixmaps[0].as_src = FALSE;
|
||||||
pixmaps[0].pPix = pPixmap;
|
pixmaps[0].pPix = pPixmap;
|
||||||
|
pixmaps[0].pReg = NULL;
|
||||||
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
|
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
|
|
Loading…
Reference in New Issue