[PATCH v3] EXA: Finish access to pixmap if it's prepared at destruction time.

Michel Dänzer michel at daenzer.net
Tue Jul 13 05:54:28 PDT 2010


From: Michel Dänzer <daenzer at vmware.com>

Previously we assumed every pixmap destroyed during a software fallback was
also created during a software fallback and had access prepared, but that's
not always true.

Fixes a server abort
Reported-by: 邓逸昕 <bupt.dengyixin at gmail.com>

Signed-off-by: Michel Dänzer <daenzer at vmware.com>
---
 exa/exa.c         |   23 +++++++++++++++++++++++
 exa/exa_classic.c |    4 +---
 exa/exa_driver.c  |    4 +---
 exa/exa_mixed.c   |    4 +---
 exa/exa_priv.h    |    3 +++
 5 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index 118a110..fc15c24 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -435,6 +435,29 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
     (*pExaScr->info->FinishAccess) (pPixmap, i);
 }
 
+
+/**
+ * Helper for things common to all schemes when a pixmap is destroyed
+ */
+void
+exaDestroyPixmap(PixmapPtr pPixmap)
+{
+    ExaScreenPriv(pPixmap->drawable.pScreen);
+    int i;
+
+    /* Finish access if it was prepared (e.g. pixmap created during
+     * software fallback)
+     */
+    for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
+	if (pExaScr->access[i].pixmap == pPixmap) {
+	    exaFinishAccess(&pPixmap->drawable, i);
+	    pExaScr->access[i].pixmap = NULL;
+	    break;
+	}
+    }
+}
+
+
 /**
  * Here begins EXA's GC code.
  * Do not ever access the fb/mi layer directly.
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 2cfeda5..169ce3a 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -221,9 +221,7 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
-	/* During a fallback we must finish access, but we don't know the index. */
-	if (pExaScr->fallback_counter)
-	    exaFinishAccess(&pPixmap->drawable, -1);
+	exaDestroyPixmap(pPixmap);
 
 	if (pExaPixmap->area)
 	{
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index abe79ba..a913cfb 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -193,9 +193,7 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
-	/* During a fallback we must finish access, but we don't know the index. */
-	if (pExaScr->fallback_counter)
-	    exaFinishAccess(&pPixmap->drawable, -1);
+	exaDestroyPixmap(pPixmap);
 
 	if (pExaPixmap->driverPriv)
 	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 7fa771d..ef20eb5 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -245,9 +245,7 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
-	/* During a fallback we must finish access, but we don't know the index. */
-	if (pExaScr->fallback_counter)
-	    exaFinishAccess(&pPixmap->drawable, -1);
+	exaDestroyPixmap(pPixmap);
 
 	if (pExaScr->deferred_mixed_pixmap == pPixmap)
 	    pExaScr->deferred_mixed_pixmap = NULL;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index afbe49c..53e792d 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -557,6 +557,9 @@ void
 exaFinishAccess(DrawablePtr pDrawable, int index);
 
 void
+exaDestroyPixmap(PixmapPtr pPixmap);
+
+void
 exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
 
 void
-- 
1.7.1



More information about the xorg-devel mailing list