xf86-video-intel: 2 commits - configure.ac src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Sat Jun 7 01:17:21 PDT 2014


 configure.ac          |   10 +++
 src/sna/sna.h         |    1 
 src/sna/sna_display.c |  131 ++++++++++++++++++++++----------------------------
 src/sna/sna_driver.c  |   14 +++--
 4 files changed, 79 insertions(+), 77 deletions(-)

New commits:
commit 717e00facd27696c6b8a1a6c343b2f94bfa2b59b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 7 09:07:16 2014 +0100

    sna: Allow TearFree to be enabled by default via configure
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 9aeeb81..8e3dbf7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -668,6 +668,16 @@ AC_MSG_RESULT($accel)
 
 xp_msg=""
 
+AC_ARG_ENABLE(tear-free,
+	      AS_HELP_STRING([--enable-tear-free],
+			     [Enable use of TearFree by default [default=no]]),
+	      [TEARFREE="$enableval"],
+	      [TEARFREE="no"])
+if test "x$TEARFREE" = "xyes"; then
+	AC_DEFINE(TEARFREE,1,[Enable "TearFree" by default])
+	xp_msg="$xp_msg TearFree"
+fi
+
 AC_ARG_ENABLE(rendernode,
 	      AS_HELP_STRING([--enable-rendernode],
 			     [Enable use of render nodes (experimental) [default=no]]),
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 3810090..97872a7 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -71,6 +71,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "git_version.h"
 #endif
 
+#ifdef TEARFREE
+#define ENABLE_TEAR_FREE TRUE
+#else
+#define ENABLE_TEAR_FREE FALSE
+#endif
+
 DevPrivateKeyRec sna_pixmap_key;
 DevPrivateKeyRec sna_gc_key;
 DevPrivateKeyRec sna_window_key;
@@ -627,10 +633,6 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		sna->flags |= SNA_TRIPLE_BUFFER;
 	DBG(("%s: triple buffer? %s\n", __FUNCTION__, sna->flags & SNA_TRIPLE_BUFFER ? "enabled" : "disabled"));
 
-	if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP)) == 0 &&
-	    xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, FALSE))
-		sna->flags |= SNA_TEAR_FREE;
-
 	if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE))
 		sna->flags |= SNA_FORCE_SHADOW;
 
@@ -654,6 +656,10 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 	}
 	scrn->currentMode = scrn->modes;
 
+	if (sna->flags & SNA_HAS_FLIP &&
+	    xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, ENABLE_TEAR_FREE))
+		sna->flags |= SNA_TEAR_FREE;
+
 	xf86SetGamma(scrn, zeros);
 	xf86SetDpi(scrn, 0, 0);
 
commit dcb64b55092ea3da6adf357305d65b58d848db7b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 7 08:30:38 2014 +0100

    sna: Fix TearFree for non-compositors
    
    The tearfree code forgot to update the shadow bo, so after the first
    flip it would be rendering to the scanout anyway and flip to itself
    periodically.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 0739f7b..31f80a0 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -290,6 +290,7 @@ struct sna {
 		bool dirty;
 
 		int max_crtc_width, max_crtc_height;
+		RegionRec shadow_region;
 
 		unsigned num_real_crtc;
 		unsigned num_real_output;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c6bb9cd..f81045d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1007,24 +1007,19 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	return true;
 }
 
-struct wait_for_shadow {
-	RegionRec region;
-	struct kgem_bo *bo;
-};
-
 static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
 {
-	struct wait_for_shadow *wait = priv->move_to_gpu_data;
-	struct kgem_bo *bo = wait->bo;
 	PixmapPtr pixmap = priv->pixmap;
 	DamagePtr damage;
+	struct kgem_bo *bo, *tmp;
 	bool ret = true;
 
-	DBG(("%s: flags=%x, flips=%d, handle=%d, wait=%d, old=%d\n",
+	DBG(("%s: flags=%x, flips=%d, handle=%d, shadow=%d\n",
 	     __FUNCTION__, flags, sna->mode.flip_active,
-	     priv->gpu_bo->handle, wait->bo->handle, sna->mode.shadow->handle));
+	     priv->gpu_bo->handle, sna->mode.shadow->handle));
 
-	assert(wait->bo != priv->gpu_bo);
+	assert(priv->move_to_gpu_data == sna);
+	assert(sna->mode.shadow != priv->gpu_bo);
 
 	if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_damage)
 		goto done;
@@ -1040,6 +1035,7 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 	while (sna->mode.flip_active && sna_mode_has_pending_events(sna))
 		sna_mode_wakeup(sna);
 
+	bo = sna->mode.shadow;
 	if (sna->mode.flip_active) {
 		bo = kgem_create_2d(&sna->kgem,
 				    pixmap->drawable.width,
@@ -1051,18 +1047,18 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 			DBG(("%s: replacing still-attached GPU bo\n",
 			     __FUNCTION__));
 
-			RegionUninit(&wait->region);
-			wait->region.extents.x1 = 0;
-			wait->region.extents.y1 = 0;
-			wait->region.extents.x2 = pixmap->drawable.width;
-			wait->region.extents.y2 = pixmap->drawable.height;
-			wait->region.data = NULL;
+			RegionUninit(&sna->mode.shadow_region);
+			sna->mode.shadow_region.extents.x1 = 0;
+			sna->mode.shadow_region.extents.y1 = 0;
+			sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
+			sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
+			sna->mode.shadow_region.data = NULL;
 		} else {
 			while (sna->mode.flip_active &&
 			       sna_mode_wait_for_event(sna))
 				sna_mode_wakeup(sna);
 
-			bo = wait->bo;
+			bo = sna->mode.shadow;
 		}
 	}
 
@@ -1077,28 +1073,30 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 			DBG(("%s: replacing exported GPU bo\n",
 			     __FUNCTION__));
 
-			RegionUninit(&wait->region);
-			wait->region.extents.x1 = 0;
-			wait->region.extents.y1 = 0;
-			wait->region.extents.x2 = pixmap->drawable.width;
-			wait->region.extents.y2 = pixmap->drawable.height;
-			wait->region.data = NULL;
+			RegionUninit(&sna->mode.shadow_region);
+			sna->mode.shadow_region.extents.x1 = 0;
+			sna->mode.shadow_region.extents.y1 = 0;
+			sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
+			sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
+			sna->mode.shadow_region.data = NULL;
 		} else
-			bo = wait->bo;
+			bo = sna->mode.shadow;
 	}
 
 	sna->mode.shadow_damage = damage;
 
-	if (flags & MOVE_READ && RegionNotEmpty(&wait->region)) {
+	if (flags & MOVE_READ && RegionNotEmpty(&sna->mode.shadow_region)) {
 		DBG(("%s: copying existing GPU damage: %ldx(%d, %d), (%d, %d)\n",
-		     __FUNCTION__, (long)REGION_NUM_RECTS(&wait->region),
-		     wait->region.extents.x1, wait->region.extents.y1,
-		     wait->region.extents.x2, wait->region.extents.y2));
+		     __FUNCTION__, (long)REGION_NUM_RECTS(&sna->mode.shadow_region),
+		     sna->mode.shadow_region.extents.x1,
+		     sna->mode.shadow_region.extents.y1,
+		     sna->mode.shadow_region.extents.x2,
+		     sna->mode.shadow_region.extents.y2));
 		ret = sna->render.copy_boxes(sna, GXcopy,
 					     pixmap, priv->gpu_bo, 0, 0,
 					     pixmap, bo, 0, 0,
-					     REGION_RECTS(&wait->region),
-					     REGION_NUM_RECTS(&wait->region),
+					     REGION_RECTS(&sna->mode.shadow_region),
+					     REGION_NUM_RECTS(&sna->mode.shadow_region),
 					     0);
 	}
 
@@ -1108,15 +1106,16 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 	sna_pixmap_unmap(pixmap, priv);
 
 	DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle));
-	kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-	priv->gpu_bo = bo == wait->bo ? kgem_bo_reference(bo) : bo;
+	tmp = priv->gpu_bo;
+	priv->gpu_bo = bo;
+	if (bo != sna->mode.shadow)
+		kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
+	sna->mode.shadow = tmp;
 
 	sna_dri2_pixmap_update_bo(sna, pixmap, bo);
 
 done:
-	kgem_bo_destroy(&sna->kgem, wait->bo);
-	RegionUninit(&wait->region);
-	free(wait);
+	RegionUninit(&sna->mode.shadow_region);
 
 	priv->move_to_gpu_data = NULL;
 	priv->move_to_gpu = NULL;
@@ -1127,25 +1126,27 @@ done:
 void sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
 				      RegionPtr region)
 {
-	struct wait_for_shadow *wait = priv->move_to_gpu_data;
+	struct sna *sna;
 
 	if (priv->move_to_gpu != wait_for_shadow)
 		return;
 
+	sna = priv->move_to_gpu_data;
 	DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n",
 	     __FUNCTION__,
 	     RegionNumRects(region),
 	     region->extents.x1, region->extents.y1,
 	     region->extents.x2, region->extents.y2,
-	     RegionNumRects(&wait->region),
-	     wait->region.extents.x1, wait->region.extents.y1,
-	     wait->region.extents.x2, wait->region.extents.y2));
+	     RegionNumRects(&sna->mode.shadow_region),
+	     sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
+	     sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
 
-	assert(wait);
 	if (region)
-		RegionSubtract(&wait->region, &wait->region, region);
+		RegionSubtract(&sna->mode.shadow_region,
+			       &sna->mode.shadow_region,
+			       region);
 	else
-		RegionEmpty(&wait->region);
+		RegionEmpty(&sna->mode.shadow_region);
 }
 
 static bool sna_mode_enable_shadow(struct sna *sna)
@@ -1526,43 +1527,31 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 	return false;
 }
 
-static void set_shadow(PixmapPtr pixmap, struct kgem_bo *bo, RegionPtr region)
+static void set_shadow(struct sna *sna, RegionPtr region)
 {
-	struct sna_pixmap *priv = sna_pixmap(pixmap);
-	struct wait_for_shadow *wait;
+	struct sna_pixmap *priv = sna_pixmap(sna->front);
+
+	assert(priv->gpu_bo);
+	assert(sna->mode.shadow);
 
-	DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)] on handle=%d\n",
+	DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n",
 	     __FUNCTION__,
 	     RegionNumRects(region),
 	     region->extents.x1, region->extents.y1,
 	     region->extents.x2, region->extents.y2,
-	     bo->handle));
+	     priv->gpu_bo->handle, sna->mode.shadow->handle));
 
+	assert(priv->pinned & PIN_SCANOUT);
 	assert((priv->pinned & PIN_PRIME) == 0);
-	assert(bo != priv->gpu_bo);
-	assert(priv->gpu_bo);
-
-	wait = priv->move_to_gpu_data;
-	if (wait != NULL) {
-		assert(priv->move_to_gpu = wait_for_shadow);
-		assert(priv->pinned & PIN_SCANOUT);
-		assert(wait->bo == bo);
-		RegionUnion(&wait->region, &wait->region, region);
-		return;
-	}
+	assert(sna->mode.shadow != priv->gpu_bo);
 
 	assert(priv->move_to_gpu == NULL);
-	wait = malloc(sizeof(*wait));
-	if (wait != NULL) {
-		wait->bo = kgem_bo_reference(bo);
-		RegionNull(&wait->region);
-		RegionCopy(&wait->region, region);
 
-		priv->move_to_gpu = wait_for_shadow;
-		priv->move_to_gpu_data = wait;
-	}
+	RegionNull(&sna->mode.shadow_region);
+	RegionCopy(&sna->mode.shadow_region, region);
 
-	priv->pinned |= PIN_SCANOUT;
+	priv->move_to_gpu = wait_for_shadow;
+	priv->move_to_gpu_data = sna;
 }
 
 static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
@@ -1666,7 +1655,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
 				}
 
 				sna->mode.shadow = shadow;
-				set_shadow(sna->front, shadow, &region);
+				set_shadow(sna, &region);
 			}
 		} else
 			sna_crtc_disable_shadow(sna, sna_crtc);
@@ -5943,11 +5932,7 @@ fixup_shadow:
 		if (sna->mode.flip_active) {
 			assert(old == sna->mode.shadow);
 			assert(old->refcnt >= 1);
-			set_shadow(sna->front, old, region);
-
-			assert(new->refcnt >= 1);
-			kgem_bo_destroy(&sna->kgem, old);
-			sna->mode.shadow = kgem_bo_reference(new);
+			set_shadow(sna, region);
 		}
 	} else
 		kgem_submit(&sna->kgem);


More information about the xorg-commit mailing list