EXA: Track valid bits in Sys and FB separately.
Also consolidate exaCopyDirtyToFb/Sys.
This commit is contained in:
parent
8cfcf9973c
commit
5c7ee3f47f
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue