EXA: Track valid bits in Sys and FB separately.

Also consolidate exaCopyDirtyToFb/Sys.
This commit is contained in:
Michel Dänzer 2007-08-24 19:24:18 +02:00
parent 8cfcf9973c
commit 5c7ee3f47f
3 changed files with 74 additions and 92 deletions

View File

@ -186,7 +186,8 @@ exaDestroyPixmap (PixmapPtr pPixmap)
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch; pPixmap->devKind = pExaPixmap->sys_pitch;
} }
REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validReg); REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validSys);
REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
} }
return fbDestroyPixmap (pPixmap); return fbDestroyPixmap (pPixmap);
} }
@ -267,7 +268,8 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
/* None of the pixmap bits are valid initially */ /* None of the pixmap bits are valid initially */
REGION_NULL(pScreen, &pExaPixmap->validReg); REGION_NULL(pScreen, &pExaPixmap->validSys);
REGION_NULL(pScreen, &pExaPixmap->validFB);
return pPixmap; return pPixmap;
} }

View File

@ -90,7 +90,8 @@ exaPixmapIsDirty (PixmapPtr pPix)
ExaPixmapPriv (pPix); ExaPixmapPriv (pPix);
return pExaPixmap == NULL || return pExaPixmap == NULL ||
REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)); REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
} }
/** /**
@ -113,21 +114,34 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
/** /**
* If the pixmap is currently dirty, this copies at least the dirty area from * If the pixmap is currently dirty, this copies at least the dirty area from
* the framebuffer memory copy to the system memory copy. Both areas must be * FB to system or vice versa. Both areas must be allocated.
* allocated.
*/ */
static void static _X_INLINE void
exaCopyDirtyToSys (PixmapPtr pPixmap) exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
char *sys, int sys_pitch), CARD8 *fallback_src,
CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
int fallback_index, void (*sync) (ScreenPtr pScreen))
{ {
ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap); ExaPixmapPriv (pPixmap);
RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage); RegionPtr pDamageReg = DamageRegion (pExaPixmap->pDamage);
RegionRec CopyReg;
CARD8 *save_ptr; CARD8 *save_ptr;
int save_pitch; int save_pitch;
BoxPtr pBox = REGION_RECTS(pRegion); BoxPtr pBox;
int nbox = REGION_NUM_RECTS(pRegion); int nbox;
Bool do_sync = FALSE; Bool do_sync = FALSE;
/* Damaged bits are valid in source but invalid in destination */
REGION_UNION(pScreen, pValidSrc, pValidSrc, pDamageReg);
REGION_SUBTRACT(pScreen, pValidDst, pValidDst, pDamageReg);
/* Copy bits valid in ssource but not in destination */
REGION_NULL(pScreen, &CopyReg);
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
pBox = REGION_RECTS(&CopyReg);
nbox = REGION_NUM_RECTS(&CopyReg);
save_ptr = pPixmap->devPrivate.ptr; save_ptr = pPixmap->devPrivate.ptr;
save_pitch = pPixmap->devKind; save_pitch = pPixmap->devKind;
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
@ -142,21 +156,20 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
continue; continue;
if (pExaScr->info->DownloadFromScreen == NULL || if (!transfer || !transfer (pPixmap,
!pExaScr->info->DownloadFromScreen (pPixmap, pBox->x1, pBox->y1,
pBox->x1, pBox->y1, pBox->x2 - pBox->x1,
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
pBox->y2 - pBox->y1, pExaPixmap->sys_ptr
pExaPixmap->sys_ptr + pBox->y1 * pExaPixmap->sys_pitch
+ pBox->y1 * pExaPixmap->sys_pitch + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8, pExaPixmap->sys_pitch))
pExaPixmap->sys_pitch))
{ {
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
exaMemcpyBox (pPixmap, pBox, exaMemcpyBox (pPixmap, pBox,
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch, fallback_src, fallback_srcpitch,
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch); fallback_dst, fallback_dstpitch);
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); exaFinishAccess(&pPixmap->drawable, fallback_index);
} }
else else
do_sync = TRUE; do_sync = TRUE;
@ -164,19 +177,34 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
pBox++; pBox++;
} }
/* Make sure the bits have actually landed, since we don't necessarily sync
* when accessing pixmaps in system memory.
*/
if (do_sync) if (do_sync)
exaWaitSync (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 previously damaged bits are now no longer damaged but valid */ /* The copied bits are now no longer damaged but valid in destination */
REGION_UNION(pPixmap->drawable.pScreen, REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
&pExaPixmap->validReg, &pExaPixmap->validReg, pRegion); REGION_SUBTRACT(pScreen, pDamageReg, pDamageReg, &CopyReg);
DamageEmpty (pExaPixmap->pDamage);
REGION_NULL(pScreen, &CopyReg);
}
/**
* If the pixmap is currently dirty, this copies at least the dirty area from
* the framebuffer memory copy to the system memory copy. Both areas must be
* allocated.
*/
static void
exaCopyDirtyToSys (PixmapPtr pPixmap)
{
ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap);
exaCopyDirty(pPixmap, &pExaPixmap->validSys, &pExaPixmap->validFB,
pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
} }
/** /**
@ -189,59 +217,11 @@ exaCopyDirtyToFb (PixmapPtr pPixmap)
{ {
ExaScreenPriv (pPixmap->drawable.pScreen); ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap); ExaPixmapPriv (pPixmap);
RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
CARD8 *save_ptr;
int save_pitch;
BoxPtr pBox = REGION_RECTS(pRegion);
int nbox = REGION_NUM_RECTS(pRegion);
Bool do_sync = FALSE;
save_ptr = pPixmap->devPrivate.ptr; exaCopyDirty(pPixmap, &pExaPixmap->validFB, &pExaPixmap->validSys,
save_pitch = pPixmap->devKind; pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
pPixmap->devKind = pExaPixmap->fb_pitch; pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
while (nbox--) {
pBox->x1 = max(pBox->x1, 0);
pBox->y1 = max(pBox->y1, 0);
pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
continue;
if (pExaScr->info->UploadToScreen == NULL ||
!pExaScr->info->UploadToScreen (pPixmap,
pBox->x1, pBox->y1,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
pExaPixmap->sys_ptr
+ pBox->y1 * pExaPixmap->sys_pitch
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
pExaPixmap->sys_pitch))
{
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
exaMemcpyBox (pPixmap, pBox,
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
}
else
do_sync = TRUE;
pBox++;
}
if (do_sync)
exaMarkSync (pPixmap->drawable.pScreen);
pPixmap->devPrivate.ptr = save_ptr;
pPixmap->devKind = save_pitch;
/* The previously damaged bits are now no longer damaged but valid */
REGION_UNION(pPixmap->drawable.pScreen,
&pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
DamageEmpty (pExaPixmap->pDamage);
} }
/** /**
@ -254,7 +234,6 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
{ {
PixmapPtr pPixmap = area->privData; PixmapPtr pPixmap = area->privData;
ExaPixmapPriv(pPixmap); ExaPixmapPriv(pPixmap);
RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage);
DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap, DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
(void*)(ExaGetPixmapPriv(pPixmap)->area ? (void*)(ExaGetPixmapPriv(pPixmap)->area ?
@ -273,9 +252,9 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
pExaPixmap->fb_ptr = NULL; pExaPixmap->fb_ptr = NULL;
pExaPixmap->area = NULL; pExaPixmap->area = NULL;
/* Mark all valid bits as damaged, so they'll get copied to FB next time */ /* Mark all FB bits as invalid, so all valid system bits get copied to FB
REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg, * next time */
&pExaPixmap->validReg); REGION_NULL(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
} }
/** /**
@ -459,7 +438,8 @@ exaAssertNotDirty (PixmapPtr pPixmap)
{ {
ExaPixmapPriv (pPixmap); ExaPixmapPriv (pPixmap);
CARD8 *dst, *src; CARD8 *dst, *src;
RegionPtr pValidReg = &pExaPixmap->validReg; RegionPtr pValidReg = exaPixmapIsOffscreen(pPixmap) ? &pExaPixmap->validFB :
&pExaPixmap->validSys;
int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg); int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
BoxPtr pBox = REGION_RECTS(pValidReg); BoxPtr pBox = REGION_RECTS(pValidReg);
Bool ret = TRUE; Bool ret = TRUE;

View File

@ -175,10 +175,10 @@ typedef struct {
*/ */
DamagePtr pDamage; DamagePtr pDamage;
/** /**
* The valid region marks the valid bits of a drawable (at least, as it's * The valid regions mark the valid bits (at least, as they're derived from
* derived from damage, which may be overreported). * damage, which may be overreported) of a pixmap's system and FB copies.
*/ */
RegionRec validReg; RegionRec validSys, validFB;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr; } ExaPixmapPrivRec, *ExaPixmapPrivPtr;
typedef struct _ExaMigrationRec { typedef struct _ExaMigrationRec {