[PATCH] exa/mixed: Partially restore deferred pixmap handling for frontbuffer.

Maarten Maathuis madman2003 at gmail.com
Thu Feb 10 09:21:44 PST 2011


- It turns out that part of the problem was actually on the driver side.
- The performance loss is not worth the small visual improvement.
- This should ensure low latency at low throughput.
- Performance loss seems less than 10% instead of the previous 33%.
- It's not needed to set deferred_mixed_pixmap to NULL, because
  exaDoMigration_mixed will handle that.

Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
---
 exa/exa.c                 |    6 +++++-
 exa/exa_migration_mixed.c |   26 ++++++++++++++++----------
 exa/exa_priv.h            |    1 +
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index a4e294a..abda82e 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -721,9 +721,13 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
     ExaScreenPriv(pScreen);
 
     /* Move any deferred results from a software fallback to the driver pixmap */
-    if (pExaScr->deferred_mixed_pixmap)
+    if (pExaScr->deferred_mixed_pixmap) {
 	exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
 
+	if (pExaScr->deferred_mixed_pixmap == pScreen->GetScreenPixmap(pScreen))
+	    pExaScr->last_time_front_mixed_pixmap = GetTimeInMillis();
+    }
+
     unwrap(pExaScr, pScreen, BlockHandler);
     (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
     wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 4f49905..320aad9 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -150,18 +150,24 @@ exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
     if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
 	ExaScreenPriv(pPixmap->drawable.pScreen);
 
-	/* Front buffer: Don't wait for the block handler to copy back the data.
-	 * This avoids annoying latency if you encounter a lot of software rendering.
+	/* Front buffer: Don't wait for the block handler to copy back the data, unless
+	 * it has been moved back in the last 50 ms. This avoids high latency when
+	 * the xserver is busy, while maintaining a decent troughput.
 	 */
-	if (pPixmap == pScreen->GetScreenPixmap(pScreen))
-		exaMoveInPixmap_mixed(pPixmap);
-	else {
-		if (pExaScr->deferred_mixed_pixmap &&
-		    pExaScr->deferred_mixed_pixmap != pPixmap)
-		    exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
-
-		pExaScr->deferred_mixed_pixmap = pPixmap;
+	if (pPixmap == pScreen->GetScreenPixmap(pScreen)) {
+	    CARD32 now = GetTimeInMillis();
+	    if ((now - pExaScr->last_time_front_mixed_pixmap) > 50) {
+		    pExaScr->last_time_front_mixed_pixmap = now;
+		    exaMoveInPixmap_mixed(pPixmap);
+		    return;
+	    }
 	}
+
+	if (pExaScr->deferred_mixed_pixmap &&
+	    pExaScr->deferred_mixed_pixmap != pPixmap)
+	    exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+
+	pExaScr->deferred_mixed_pixmap = pPixmap;
     }
 }
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index e5d90d4..cb58a02 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -185,6 +185,7 @@ typedef struct {
     CARD32			 lastDefragment;
     CARD32			 nextDefragment;
     PixmapPtr			 deferred_mixed_pixmap;
+    CARD32			 last_time_front_mixed_pixmap;
 
     /* Reference counting for accessed pixmaps */
     struct {
-- 
1.7.4



More information about the xorg-devel mailing list