EXA: CopyNtoN improvements.

* Centralize handling of fallbacks and damage tracking.
* Always migrate for fallbacks.
This commit is contained in:
Michel Dänzer 2007-04-29 23:48:59 +02:00
parent d2245386ee
commit 982d7c2c0b

View File

@ -390,6 +390,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int src_off_x, src_off_y; int src_off_x, src_off_y;
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
ExaMigrationRec pixmaps[2]; ExaMigrationRec pixmaps[2];
Bool fallback = FALSE;
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
@ -407,62 +408,64 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
pDstPixmap->drawable.width > pExaScr->info->maxX || pDstPixmap->drawable.width > pExaScr->info->maxX ||
pDstPixmap->drawable.height > pExaScr->info->maxY) pDstPixmap->drawable.height > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 2, FALSE); fallback = TRUE;
goto fallback;
} else { } else {
exaDoMigration (pixmaps, 2, TRUE); exaDoMigration (pixmaps, 2, TRUE);
} }
/* Mixed directions must be handled specially if the card is lame */ /* Mixed directions must be handled specially if the card is lame */
if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS && if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
reverse != upsidedown) { reverse != upsidedown) {
if (!exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy)) dx, dy))
goto fallback; return;
return; fallback = TRUE;
} }
if ((pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) && pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
(pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) && pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap,
reverse ? -1 : 1, upsidedown ? -1 : 1, exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
pGC ? pGC->alu : GXcopy, exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
pGC ? pGC->planemask : FB_ALLONES))
if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
!exaPixmapIsOffscreen(pDstPixmap) ||
!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
upsidedown ? -1 : 1,
pGC ? pGC->alu : GXcopy,
pGC ? pGC->planemask : FB_ALLONES)) {
fallback = TRUE;
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
exaDrawableLocation(pSrcDrawable),
exaDrawableLocation(pDstDrawable)));
exaDoMigration (pixmaps, 2, FALSE);
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
while (nbox--)
{ {
while (nbox--) if (!fallback)
{
(*pExaScr->info->Copy) (pDstPixmap, (*pExaScr->info->Copy) (pDstPixmap,
pbox->x1 + dx + src_off_x, pbox->x1 + dx + src_off_x,
pbox->y1 + dy + src_off_y, pbox->y1 + dy + src_off_y,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
pbox->y2 - pbox->y1); exaPixmapDirty (pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
exaPixmapDirty (pDstPixmap, pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++;
}
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
return;
}
fallback:
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
exaDrawableLocation(pSrcDrawable),
exaDrawableLocation(pDstDrawable)));
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
while (nbox--)
{
exaDrawableDirty (pDstDrawable, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
pbox++; pbox++;
} }
if (fallback)
return;
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync (pDstDrawable->pScreen);
} }
RegionPtr RegionPtr