From 5c7ee3f47fa0c067102a17dee3f75a51cc0bdb3a Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 24 Aug 2007 19:24:18 +0200 Subject: EXA: Track valid bits in Sys and FB separately. Also consolidate exaCopyDirtyToFb/Sys. --- exa/exa.c | 6 +- exa/exa_migration.c | 154 +++++++++++++++++++++++----------------------------- exa/exa_priv.h | 6 +- 3 files changed, 74 insertions(+), 92 deletions(-) (limited to 'exa') diff --git a/exa/exa.c b/exa/exa.c index 514b88ba7..ecdb76139 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -186,7 +186,8 @@ exaDestroyPixmap (PixmapPtr pPixmap) pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; 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); } @@ -267,7 +268,8 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); /* 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; } diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 661ff40e3..99058f138 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -90,7 +90,8 @@ exaPixmapIsDirty (PixmapPtr pPix) ExaPixmapPriv (pPix); 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 - * the framebuffer memory copy to the system memory copy. Both areas must be - * allocated. + * FB to system or vice versa. Both areas must be allocated. */ -static void -exaCopyDirtyToSys (PixmapPtr pPixmap) +static _X_INLINE void +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); - RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage); + RegionPtr pDamageReg = DamageRegion (pExaPixmap->pDamage); + RegionRec CopyReg; CARD8 *save_ptr; int save_pitch; - BoxPtr pBox = REGION_RECTS(pRegion); - int nbox = REGION_NUM_RECTS(pRegion); + BoxPtr pBox; + int nbox; 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_pitch = pPixmap->devKind; pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; @@ -142,21 +156,20 @@ exaCopyDirtyToSys (PixmapPtr pPixmap) if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) continue; - if (pExaScr->info->DownloadFromScreen == NULL || - !pExaScr->info->DownloadFromScreen (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)) + if (!transfer || !transfer (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_SRC); + ExaDoPrepareAccess(&pPixmap->drawable, fallback_index); exaMemcpyBox (pPixmap, pBox, - pExaPixmap->fb_ptr, pExaPixmap->fb_pitch, - pExaPixmap->sys_ptr, pExaPixmap->sys_pitch); - exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + fallback_src, fallback_srcpitch, + fallback_dst, fallback_dstpitch); + exaFinishAccess(&pPixmap->drawable, fallback_index); } else do_sync = TRUE; @@ -164,84 +177,51 @@ exaCopyDirtyToSys (PixmapPtr pPixmap) pBox++; } - /* Make sure the bits have actually landed, since we don't necessarily sync - * when accessing pixmaps in system memory. - */ if (do_sync) - exaWaitSync (pPixmap->drawable.pScreen); + sync (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); + /* The copied bits are now no longer damaged but valid in destination */ + REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg); + REGION_SUBTRACT(pScreen, pDamageReg, pDamageReg, &CopyReg); + + REGION_NULL(pScreen, &CopyReg); } /** * If the pixmap is currently dirty, this copies at least the dirty area from - * the system memory copy to the framebuffer memory copy. Both areas must be + * the framebuffer memory copy to the system memory copy. Both areas must be * allocated. */ static void -exaCopyDirtyToFb (PixmapPtr pPixmap) +exaCopyDirtyToSys (PixmapPtr pPixmap) { ExaScreenPriv (pPixmap->drawable.pScreen); 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; - save_pitch = pPixmap->devKind; - pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; - pPixmap->devKind = pExaPixmap->fb_pitch; - - 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); + 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); +} - pPixmap->devPrivate.ptr = save_ptr; - pPixmap->devKind = save_pitch; +/** + * If the pixmap is currently dirty, this copies at least the dirty area from + * the system memory copy to the framebuffer memory copy. Both areas must be + * allocated. + */ +static void +exaCopyDirtyToFb (PixmapPtr pPixmap) +{ + ExaScreenPriv (pPixmap->drawable.pScreen); + ExaPixmapPriv (pPixmap); - /* The previously damaged bits are now no longer damaged but valid */ - REGION_UNION(pPixmap->drawable.pScreen, - &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion); - DamageEmpty (pExaPixmap->pDamage); + exaCopyDirty(pPixmap, &pExaPixmap->validFB, &pExaPixmap->validSys, + pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr, + pExaPixmap->fb_ptr, pExaPixmap->sys_pitch, + pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync); } /** @@ -254,7 +234,6 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area) { PixmapPtr pPixmap = area->privData; ExaPixmapPriv(pPixmap); - RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage); DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap, (void*)(ExaGetPixmapPriv(pPixmap)->area ? @@ -273,9 +252,9 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area) pExaPixmap->fb_ptr = NULL; pExaPixmap->area = NULL; - /* Mark all valid bits as damaged, so they'll get copied to FB next time */ - REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg, - &pExaPixmap->validReg); + /* Mark all FB bits as invalid, so all valid system bits get copied to FB + * next time */ + REGION_NULL(pPixmap->drawable.pScreen, &pExaPixmap->validFB); } /** @@ -459,7 +438,8 @@ exaAssertNotDirty (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); 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); BoxPtr pBox = REGION_RECTS(pValidReg); Bool ret = TRUE; diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 409bc4d7d..b9e501625 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -175,10 +175,10 @@ typedef struct { */ DamagePtr pDamage; /** - * The valid region marks the valid bits of a drawable (at least, as it's - * derived from damage, which may be overreported). + * The valid regions mark the valid bits (at least, as they're derived from + * damage, which may be overreported) of a pixmap's system and FB copies. */ - RegionRec validReg; + RegionRec validSys, validFB; } ExaPixmapPrivRec, *ExaPixmapPrivPtr; typedef struct _ExaMigrationRec { -- cgit v1.2.3