EXA: FillRegion{Solid,Tiled} improvements.
* Support planemasks, different ALUs and arbitrary tile origin. * Leave damage tracking and non-trivial fallbacks to callers. * Always migrate for fallbacks. This is in preparation for using these from more other functions.
This commit is contained in:
parent
e869573b52
commit
567f18a09b
|
@ -126,7 +126,7 @@ exaGetDrawablePixmap(DrawablePtr pDrawable)
|
||||||
* the backing drawable. These coordinates are nonzero only for redirected
|
* the backing drawable. These coordinates are nonzero only for redirected
|
||||||
* windows.
|
* windows.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
|
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
|
||||||
int *xp, int *yp)
|
int *xp, int *yp)
|
||||||
{
|
{
|
||||||
|
|
102
exa/exa_accel.c
102
exa/exa_accel.c
|
@ -1043,10 +1043,12 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||||
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
|
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Bool
|
||||||
exaFillRegionSolid (DrawablePtr pDrawable,
|
exaFillRegionSolid (DrawablePtr pDrawable,
|
||||||
RegionPtr pRegion,
|
RegionPtr pRegion,
|
||||||
Pixel pixel)
|
Pixel pixel,
|
||||||
|
CARD32 planemask,
|
||||||
|
CARD32 alu)
|
||||||
{
|
{
|
||||||
ExaScreenPriv(pDrawable->pScreen);
|
ExaScreenPriv(pDrawable->pScreen);
|
||||||
PixmapPtr pPixmap;
|
PixmapPtr pPixmap;
|
||||||
|
@ -1062,22 +1064,19 @@ exaFillRegionSolid (DrawablePtr pDrawable,
|
||||||
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)
|
||||||
{
|
{
|
||||||
exaDoMigration (pixmaps, 1, FALSE);
|
|
||||||
goto fallback;
|
goto fallback;
|
||||||
} else {
|
} else {
|
||||||
exaDoMigration (pixmaps, 1, TRUE);
|
exaDoMigration (pixmaps, 1, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
|
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
|
||||||
(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
|
(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
|
||||||
{
|
{
|
||||||
while (nbox--)
|
while (nbox--)
|
||||||
{
|
{
|
||||||
(*pExaScr->info->Solid) (pPixmap,
|
(*pExaScr->info->Solid) (pPixmap,
|
||||||
pBox->x1 + xoff, pBox->y1 + yoff,
|
pBox->x1 + xoff, pBox->y1 + yoff,
|
||||||
pBox->x2 + xoff, pBox->y2 + yoff);
|
pBox->x2 + xoff, pBox->y2 + yoff);
|
||||||
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
|
|
||||||
pBox->x2 + xoff, pBox->y2 + yoff);
|
|
||||||
pBox++;
|
pBox++;
|
||||||
}
|
}
|
||||||
(*pExaScr->info->DoneSolid) (pPixmap);
|
(*pExaScr->info->DoneSolid) (pPixmap);
|
||||||
|
@ -1086,27 +1085,30 @@ exaFillRegionSolid (DrawablePtr pDrawable,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fallback:
|
fallback:
|
||||||
|
if (alu != GXcopy || planemask != FB_ALLONES)
|
||||||
|
return FALSE;
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
||||||
exaDrawableLocation(pDrawable)));
|
exaDrawableLocation(pDrawable)));
|
||||||
|
exaDoMigration (pixmaps, 1, FALSE);
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
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);
|
||||||
while (nbox--)
|
|
||||||
{
|
|
||||||
exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
|
|
||||||
pBox++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
|
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
|
||||||
* Based on fbFillRegionTiled(), fbTile().
|
* Based on fbFillRegionTiled(), fbTile().
|
||||||
*/
|
*/
|
||||||
static void
|
Bool
|
||||||
exaFillRegionTiled (DrawablePtr pDrawable,
|
exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
RegionPtr pRegion,
|
RegionPtr pRegion,
|
||||||
PixmapPtr pTile)
|
PixmapPtr pTile,
|
||||||
|
DDXPointPtr pPatOrg,
|
||||||
|
CARD32 planemask,
|
||||||
|
CARD32 alu)
|
||||||
{
|
{
|
||||||
ExaScreenPriv(pDrawable->pScreen);
|
ExaScreenPriv(pDrawable->pScreen);
|
||||||
PixmapPtr pPixmap;
|
PixmapPtr pPixmap;
|
||||||
|
@ -1122,10 +1124,10 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
/* If we're filling with a solid color, grab it out and go to
|
/* If we're filling with a solid color, grab it out and go to
|
||||||
* FillRegionSolid, saving numerous copies.
|
* FillRegionSolid, saving numerous copies.
|
||||||
*/
|
*/
|
||||||
if (tileWidth == 1 && tileHeight == 1) {
|
if (tileWidth == 1 && tileHeight == 1)
|
||||||
exaFillRegionSolid(pDrawable, pRegion, exaGetPixmapFirstPixel (pTile));
|
return exaFillRegionSolid(pDrawable, pRegion,
|
||||||
return;
|
exaGetPixmapFirstPixel (pTile), planemask,
|
||||||
}
|
alu);
|
||||||
|
|
||||||
pixmaps[0].as_dst = TRUE;
|
pixmaps[0].as_dst = TRUE;
|
||||||
pixmaps[0].as_src = FALSE;
|
pixmaps[0].as_src = FALSE;
|
||||||
|
@ -1139,7 +1141,6 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
tileWidth > pExaScr->info->maxX ||
|
tileWidth > pExaScr->info->maxX ||
|
||||||
tileHeight > pExaScr->info->maxY)
|
tileHeight > pExaScr->info->maxY)
|
||||||
{
|
{
|
||||||
exaDoMigration (pixmaps, 2, FALSE);
|
|
||||||
goto fallback;
|
goto fallback;
|
||||||
} else {
|
} else {
|
||||||
exaDoMigration (pixmaps, 2, TRUE);
|
exaDoMigration (pixmaps, 2, TRUE);
|
||||||
|
@ -1153,8 +1154,9 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
if (!exaPixmapIsOffscreen(pTile))
|
if (!exaPixmapIsOffscreen(pTile))
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
|
||||||
if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile, &tileXoff, &tileYoff), pPixmap, 0, 0, GXcopy,
|
if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
|
||||||
FB_ALLONES))
|
&tileXoff, &tileYoff),
|
||||||
|
pPixmap, 0, 0, alu, planemask))
|
||||||
{
|
{
|
||||||
while (nbox--)
|
while (nbox--)
|
||||||
{
|
{
|
||||||
|
@ -1162,7 +1164,7 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
int dstY = pBox->y1;
|
int dstY = pBox->y1;
|
||||||
int tileY;
|
int tileY;
|
||||||
|
|
||||||
tileY = (dstY - pDrawable->y) % tileHeight;
|
tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
|
||||||
while (height > 0) {
|
while (height > 0) {
|
||||||
int width = pBox->x2 - pBox->x1;
|
int width = pBox->x2 - pBox->x1;
|
||||||
int dstX = pBox->x1;
|
int dstX = pBox->x1;
|
||||||
|
@ -1173,7 +1175,7 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
h = height;
|
h = height;
|
||||||
height -= h;
|
height -= h;
|
||||||
|
|
||||||
tileX = (dstX - pDrawable->x) % tileWidth;
|
tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
|
||||||
while (width > 0) {
|
while (width > 0) {
|
||||||
int w = tileWidth - tileX;
|
int w = tileWidth - tileX;
|
||||||
if (w > width)
|
if (w > width)
|
||||||
|
@ -1190,38 +1192,44 @@ exaFillRegionTiled (DrawablePtr pDrawable,
|
||||||
dstY += h;
|
dstY += h;
|
||||||
tileY = 0;
|
tileY = 0;
|
||||||
}
|
}
|
||||||
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
|
|
||||||
pBox->x2 + xoff, pBox->y2 + yoff);
|
|
||||||
pBox++;
|
pBox++;
|
||||||
}
|
}
|
||||||
(*pExaScr->info->DoneCopy) (pPixmap);
|
(*pExaScr->info->DoneCopy) (pPixmap);
|
||||||
exaMarkSync(pDrawable->pScreen);
|
exaMarkSync(pDrawable->pScreen);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fallback:
|
fallback:
|
||||||
|
if (alu != GXcopy || planemask != FB_ALLONES)
|
||||||
|
return FALSE;
|
||||||
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)));
|
||||||
|
exaDoMigration (pixmaps, 2, FALSE);
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
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);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
while (nbox--)
|
|
||||||
{
|
return TRUE;
|
||||||
exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
|
|
||||||
pBox++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
{
|
{
|
||||||
ExaScreenPriv (pWin->drawable.pScreen);
|
ExaScreenPriv (pWin->drawable.pScreen);
|
||||||
if (!REGION_NUM_RECTS(pRegion))
|
PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
|
||||||
|
int xoff, yoff;
|
||||||
|
BoxPtr pBox;
|
||||||
|
int nbox = REGION_NUM_RECTS(pRegion);
|
||||||
|
|
||||||
|
if (!nbox)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!pExaScr->swappedOut) {
|
if (!pExaScr->swappedOut) {
|
||||||
|
DDXPointRec zeros = { 0, 0 };
|
||||||
|
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case PW_BACKGROUND:
|
case PW_BACKGROUND:
|
||||||
switch (pWin->backgroundState) {
|
switch (pWin->backgroundState) {
|
||||||
|
@ -1235,25 +1243,41 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
what);
|
what);
|
||||||
return;
|
return;
|
||||||
case BackgroundPixel:
|
case BackgroundPixel:
|
||||||
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel);
|
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
|
||||||
return;
|
FB_ALLONES, GXcopy);
|
||||||
|
goto damage;
|
||||||
case BackgroundPixmap:
|
case BackgroundPixmap:
|
||||||
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap);
|
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
|
||||||
return;
|
&zeros, FB_ALLONES, GXcopy);
|
||||||
|
goto damage;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PW_BORDER:
|
case PW_BORDER:
|
||||||
if (pWin->borderIsPixel) {
|
if (pWin->borderIsPixel) {
|
||||||
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel);
|
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
|
||||||
return;
|
FB_ALLONES, GXcopy);
|
||||||
|
goto damage;
|
||||||
} else {
|
} else {
|
||||||
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap);
|
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
|
||||||
return;
|
&zeros, FB_ALLONES, GXcopy);
|
||||||
|
goto damage;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExaCheckPaintWindow (pWin, pRegion, what);
|
ExaCheckPaintWindow (pWin, pRegion, what);
|
||||||
|
|
||||||
|
damage:
|
||||||
|
exaGetDrawableDeltas((DrawablePtr)pWin, pPixmap, &xoff, &yoff);
|
||||||
|
|
||||||
|
pBox = REGION_RECTS(pRegion);
|
||||||
|
|
||||||
|
while (nbox--)
|
||||||
|
{
|
||||||
|
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
|
||||||
|
pBox->x2 + xoff, pBox->y2 + yoff);
|
||||||
|
pBox++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -288,6 +288,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap);
|
||||||
void
|
void
|
||||||
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
|
||||||
|
DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
|
||||||
|
|
||||||
void
|
void
|
||||||
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
||||||
|
|
||||||
|
@ -343,6 +347,10 @@ exaFinishAccess(DrawablePtr pDrawable, int index);
|
||||||
void
|
void
|
||||||
exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
|
exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
|
||||||
|
int *xp, int *yp);
|
||||||
|
|
||||||
void
|
void
|
||||||
exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
|
exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue