[PATCH] exa/mixed: fix gnome-panel corruption

Maarten Maathuis madman2003 at gmail.com
Fri Feb 12 10:02:47 PST 2010


- A mapped pixmap can't be used for acceleration, any decent memory manager
will refuse this.
- Source pixmaps with preg are incomplete (in the gpu pixmap), so also put them
on the deferred pixmap list.

Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
---
 exa/exa_migration_mixed.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 6816e6c..93f7332 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -115,6 +115,17 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	    if (pExaScr->deferred_mixed_pixmap == pPixmap &&
 		!pixmaps[i].as_dst && !pixmaps[i].pReg)
 		pExaScr->deferred_mixed_pixmap = NULL;
+
+	    /* Sources that are transferred only partially, need to be brought
+	     * up-to-date later, otherwise it may end up losing some data
+	     * forever if the system ram pixmap is removed.
+	     */
+	    if (pixmaps[i].as_src && pixmaps[i].pReg) {
+		if (pExaScr->deferred_mixed_pixmap &&
+			pExaScr->deferred_mixed_pixmap != pPixmap)
+		    exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+		pExaScr->deferred_mixed_pixmap = pPixmap;
+	    }
 	}
 
 	pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
@@ -167,9 +178,12 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
     ExaPixmapPriv(pPixmap);
 
     if (!ExaDoPrepareAccess(pPixmap, index)) {
-	Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+	Bool has_gpu_copy;
 	ExaMigrationRec pixmaps[1];
 
+late_failure:
+	has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+
 	/* Do we need to allocate our system buffer? */
 	if (!pExaPixmap->sys_ptr) {
 	    pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
@@ -233,10 +247,21 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
     } else if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
 	ExaScreenPriv(pPixmap->drawable.pScreen);
 
-	/* Copy back any deferred content if needed. */
 	if (pExaScr->deferred_mixed_pixmap &&
-	    pExaScr->deferred_mixed_pixmap == pPixmap)
+	    pExaScr->deferred_mixed_pixmap == pPixmap) {
+	    /* You cannot do accelerated operations while a buffer is mapped. */
+	    exaFinishAccess(&pPixmap->drawable, index);
+	    /* Deferred pixmaps include destinations that were used for software
+	     * rendering and sources that were migrated with a region (therefore
+	     * incomplete from the gpu point of view).
+	     */
 	    exaMoveInPixmap_mixed(pPixmap);
+	    /* You cannot assume prepare access will succeed twice,
+	     * however likely it may be.
+	     */
+	    if (!ExaDoPrepareAccess(pPixmap, index))
+		goto late_failure;
+	}
 
 	DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
 	DamageDestroy(pExaPixmap->pDamage);
-- 
1.6.6.1



More information about the xorg-devel mailing list