exa: Use damage to optimise away useless copies.
This commit is contained in:
parent
03ecb164f2
commit
9d2a7128d3
|
@ -35,12 +35,28 @@ static void
|
||||||
exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch,
|
exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch,
|
||||||
CARD8 *dst, int dst_pitch)
|
CARD8 *dst, int dst_pitch)
|
||||||
{
|
{
|
||||||
int i;
|
ExaPixmapPriv(pPixmap);
|
||||||
|
RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
|
||||||
|
int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
|
||||||
|
int bytes, nbox;
|
||||||
|
BoxPtr pbox;
|
||||||
|
|
||||||
for (i = pPixmap->drawable.height; i; i--) {
|
pbox = REGION_RECTS(damage);
|
||||||
memcpy (dst, src, min(src_pitch, dst_pitch));
|
nbox = REGION_NUM_RECTS(damage);
|
||||||
src += src_pitch;
|
|
||||||
dst += dst_pitch;
|
while (nbox--) {
|
||||||
|
bytes = (pbox->x2 - pbox->x1) * cpp;
|
||||||
|
|
||||||
|
src += pbox->y1 * src_pitch + pbox->x1 * cpp;
|
||||||
|
dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
|
||||||
|
|
||||||
|
for (i = pbox->y2 - pbox->y1; i; i--) {
|
||||||
|
memcpy (dst, src, bytes);
|
||||||
|
src += src_pitch;
|
||||||
|
dst += dst_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbox++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,12 +66,15 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
ExaScreenPriv(pScreen);
|
ExaScreenPriv(pScreen);
|
||||||
ExaPixmapPriv(pPixmap);
|
ExaPixmapPriv(pPixmap);
|
||||||
|
RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
|
||||||
void *sys_buffer = pExaPixmap->sys_ptr;
|
void *sys_buffer = pExaPixmap->sys_ptr;
|
||||||
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
|
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
|
||||||
int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
|
int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
|
||||||
int usage_hint = pPixmap->usage_hint;
|
int usage_hint = pPixmap->usage_hint;
|
||||||
int sys_pitch = pExaPixmap->sys_pitch;
|
int sys_pitch = pExaPixmap->sys_pitch;
|
||||||
int paddedWidth = sys_pitch;
|
int paddedWidth = sys_pitch;
|
||||||
|
int nbox;
|
||||||
|
BoxPtr pbox;
|
||||||
|
|
||||||
/* Already done. */
|
/* Already done. */
|
||||||
if (pExaPixmap->driverPriv)
|
if (pExaPixmap->driverPriv)
|
||||||
|
@ -93,8 +112,18 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
|
||||||
if (!pExaScr->info->UploadToScreen)
|
if (!pExaScr->info->UploadToScreen)
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
|
||||||
if (pExaScr->info->UploadToScreen(pPixmap, 0, 0, w, h, sys_buffer, sys_pitch))
|
pbox = REGION_RECTS(damage);
|
||||||
goto finish;
|
nbox = REGION_NUM_RECTS(damage);
|
||||||
|
|
||||||
|
while (nbox--) {
|
||||||
|
if (!pExaScr->info->UploadToScreen(pPixmap, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
|
||||||
|
pbox->y2 - pbox->y1, (char *) (sys_buffer) + pbox->y1 * sys_pitch + pbox->x1 * (bpp / 8), sys_pitch))
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
|
pbox++;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto finish;
|
||||||
|
|
||||||
fallback:
|
fallback:
|
||||||
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
|
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
|
||||||
|
@ -104,6 +133,13 @@ fallback:
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
free(sys_buffer);
|
free(sys_buffer);
|
||||||
|
|
||||||
|
/* We no longer need this. */
|
||||||
|
if (pExaPixmap->pDamage) {
|
||||||
|
DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
|
||||||
|
DamageDestroy(pExaPixmap->pDamage);
|
||||||
|
pExaPixmap->pDamage = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -114,6 +114,23 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
|
||||||
|
|
||||||
/* We want to be able to copy the pixmap to driver memory later on. */
|
/* We want to be able to copy the pixmap to driver memory later on. */
|
||||||
pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
|
pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
|
||||||
|
|
||||||
|
/* Set up damage tracking */
|
||||||
|
pExaPixmap->pDamage = DamageCreate (NULL, NULL,
|
||||||
|
DamageReportNone, TRUE,
|
||||||
|
pScreen, pPixmap);
|
||||||
|
|
||||||
|
if (pExaPixmap->pDamage == NULL) {
|
||||||
|
swap(pExaScr, pScreen, DestroyPixmap);
|
||||||
|
pScreen->DestroyPixmap (pPixmap);
|
||||||
|
swap(pExaScr, pScreen, DestroyPixmap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
|
||||||
|
/* This ensures that pending damage reflects the current operation. */
|
||||||
|
/* This is used by exa to optimize migration. */
|
||||||
|
DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pPixmap;
|
return pPixmap;
|
||||||
|
@ -136,8 +153,16 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
|
|
||||||
if (pExaPixmap) {
|
if (pExaPixmap) {
|
||||||
if (pPixData) {
|
if (pPixData) {
|
||||||
if (!exaPixmapIsPinned(pPixmap))
|
if (!exaPixmapIsPinned(pPixmap)) {
|
||||||
free(pExaPixmap->sys_ptr);
|
free(pExaPixmap->sys_ptr);
|
||||||
|
|
||||||
|
/* We no longer need this. */
|
||||||
|
if (pExaPixmap->pDamage) {
|
||||||
|
DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
|
||||||
|
DamageDestroy(pExaPixmap->pDamage);
|
||||||
|
pExaPixmap->pDamage = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
pExaPixmap->sys_ptr = pPixData;
|
pExaPixmap->sys_ptr = pPixData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue