xf86-video-intel: 2 commits - src/sna/sna_display.c src/sna/sna.h src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Feb 14 14:50:41 PST 2015


 src/sna/sna.h         |    8 --
 src/sna/sna_display.c |   35 -----------
 src/sna/sna_present.c |  151 +++++---------------------------------------------
 3 files changed, 21 insertions(+), 173 deletions(-)

New commits:
commit 74553bf4d25f5876ef6e682d06f5825feb9e1da4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Feb 14 22:31:06 2015 +0000

    sna/present: Integrate into TearFree, take 2
    
    Following on from the previous attempt is the realisation that we can
    simply disable TearFree during a Present flip queue, and re-enable
    TearFree upon unflip.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 1bddf7a..bbcea08 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -311,13 +311,6 @@ struct sna {
 		Bool (*rrGetInfo)(ScreenPtr, Rotation *);
 	} mode;
 
-	struct sna_tearfree {
-		struct notifier {
-			void (*func)(struct sna *, void *);
-			void *data;
-		} hook[2];
-	} tearfree;
-
 	struct {
 		struct sna_cursor *cursors;
 		xf86CursorInfoPtr info;
@@ -363,6 +356,7 @@ struct sna {
 		bool open;
 #if HAVE_PRESENT
 		uint64_t unflip;
+		void *tearfree;
 #endif
 	} present;
 
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 286e470..ac130c7 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1398,39 +1398,24 @@ static bool sna_mode_enable_shadow(struct sna *sna)
 	if (!sna->mode.shadow_damage)
 		return false;
 
-	DamageRegister(&screen->GetScreenPixmap(screen)->drawable,
-		       sna->mode.shadow_damage);
+	DamageRegister(&sna->front->drawable, sna->mode.shadow_damage);
 	return true;
 }
 
-inline static PixmapPtr sna_screen_pixmap(struct sna *sna)
-{
-	return to_screen_from_sna(sna)->GetScreenPixmap(to_screen_from_sna(sna));
-}
-
 static void sna_mode_disable_shadow(struct sna *sna)
 {
 	struct sna_pixmap *priv;
-	struct notifier *nb;
 
 	if (!sna->mode.shadow_damage)
 		return;
 
 	DBG(("%s\n", __FUNCTION__));
 
-	nb = &sna->tearfree.hook[0];
-	if (nb->func) {
-		nb->func(sna, nb->data);
-		nb->func = NULL;
-	}
-	assert(sna->tearfree.hook[1].func == NULL);
-
 	priv = sna_pixmap(sna->front);
 	if (priv->move_to_gpu == wait_for_shadow)
 		priv->move_to_gpu(sna, priv, 0);
 
-	DamageUnregister(&sna_screen_pixmap(sna)->drawable,
-			 sna->mode.shadow_damage);
+	DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage);
 	DamageDestroy(sna->mode.shadow_damage);
 	sna->mode.shadow_damage = NULL;
 
@@ -7121,14 +7106,6 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
 static void shadow_flip_handler(struct drm_event_vblank *e,
 				void *data)
 {
-	struct sna *sna = data;
-
-	if (sna->tearfree.hook[0].func)
-		sna->tearfree.hook[0].func(sna, sna->tearfree.hook[0].data);
-
-	sna->tearfree.hook[0] = sna->tearfree.hook[1];
-	sna->tearfree.hook[1].func = NULL;
-
 	sna_mode_redisplay(data);
 }
 
@@ -7731,12 +7708,6 @@ fixup_flip:
 			assert(old == sna->mode.shadow);
 			assert(old->refcnt >= 1);
 			set_shadow(sna, region);
-		} else {
-			if (sna->tearfree.hook[0].func) {
-				sna->tearfree.hook[0].func(sna, sna->tearfree.hook[0].data);
-				sna->tearfree.hook[0].func = NULL;
-			}
-			assert(sna->tearfree.hook[1].func == NULL);
 		}
 	} else
 		kgem_submit(&sna->kgem);
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 266d743..613721c 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -503,128 +503,6 @@ get_flip_bo(PixmapPtr pixmap)
 	return priv->gpu_bo;
 }
 
-static bool set_front(struct sna *sna, PixmapPtr pixmap)
-{
-	RegionRec *damage;
-
-	DBG(("%s: pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber));
-
-	if (pixmap == sna->front)
-		return false;
-
-	sna_pixmap_discard_shadow_damage(sna_pixmap(sna->front), NULL);
-	sna->front = pixmap;
-
-	/* We rely on unflip restoring the real front before any drawing */
-	damage = DamageRegion(sna->mode.shadow_damage);
-	RegionUninit(damage);
-	damage->extents.x1 = 0;
-	damage->extents.y1 = 0;
-	damage->extents.x2 = pixmap->drawable.width;
-	damage->extents.y2 = pixmap->drawable.height;
-	damage->data = NULL;
-
-	return true;
-}
-
-static void
-xchg_handler(struct sna *sna, void *data)
-{
-	struct sna_present_event *info = data;
-	const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
-
-	DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
-	     sna_crtc_to_pipe(info->crtc),
-	     swap->tv_sec, swap->tv_usec,
-	     (long long)swap->msc,
-	     (long long)info->target_msc, (long long)info->event_id));
-	present_event_notify(info->event_id, swap_ust(swap), swap->msc);
-	free(info);
-}
-
-static Bool
-xchg(struct sna *sna,
-     RRCrtcPtr crtc,
-     uint64_t event_id,
-     uint64_t target_msc,
-     PixmapPtr pixmap,
-     Bool sync_flip)
-{
-	struct sna_present_event *info;
-	bool queued;
-
-	DBG(("%s(pipe=%d, event=%lld, sync_flip=%d)\n",
-	     __FUNCTION__,
-	     pipe_from_crtc(crtc),
-	     (long long)event_id,
-	     sync_flip));
-
-	assert(sna->flags & SNA_TEAR_FREE);
-	assert(sna->mode.shadow_damage);
-	assert(sna_pixmap(pixmap) && sna_pixmap(pixmap)->gpu_bo);
-	assert(sync_flip);
-
-	/* This effectively disables TearFree giving the client direct
-	 * access into the scanout with their Pixmap.
-	 */
-	queued = set_front(sna, pixmap);
-
-	info = malloc(sizeof(struct sna_present_event));
-	if (info == NULL)
-		return BadAlloc;
-
-	info->crtc = crtc->devPrivate;
-	info->sna = sna;
-	info->target_msc = target_msc;
-	info->event_id = event_id;
-
-	if (queued) {
-		struct notifier *nb;
-
-		nb = &sna->tearfree.hook[0];
-		if (nb->func)
-			nb++;
-		if (nb->func) {
-			DBG(("%s: executing existing notifier\n", __FUNCTION__));
-			nb->func(sna, nb->data);
-		}
-		DBG(("%s: queueing tearfree notifier: sequence %d\n",
-		     __FUNCTION__, nb - &sna->tearfree.hook[0]));
-		nb->func = xchg_handler;
-		nb->data = info;
-	} else {
-		union drm_wait_vblank vbl;
-
-		DBG(("%s: queueing vblank notifier\n", __FUNCTION__));
-
-		VG_CLEAR(vbl);
-		vbl.request.type =
-			DRM_VBLANK_ABSOLUTE |
-			DRM_VBLANK_EVENT |
-			DRM_VBLANK_NEXTONMISS;
-		vbl.request.sequence = target_msc;
-		vbl.request.signal = (uintptr_t)MARK_PRESENT(info);
-		if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(info->crtc))) {
-			DBG(("%s: vblank enqueue failed\n", __FUNCTION__));
-			if (!sna_fake_vblank(info)) {
-				free(info);
-				goto notify;
-			}
-		}
-	}
-
-	return TRUE;
-
-notify:
-	DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
-	     pipe_from_crtc(crtc),
-	     gettime_ust64() / 1000000, gettime_ust64() % 1000000,
-	     (long long)sna_crtc_last_swap(crtc->devPrivate)->msc,
-	     (long long)target_msc, (long long)event_id));
-	present_event_notify(event_id, gettime_ust64(), target_msc);
-	return TRUE;
-}
-
 static Bool
 sna_present_flip(RRCrtcPtr crtc,
 		 uint64_t event_id,
@@ -655,8 +533,11 @@ sna_present_flip(RRCrtcPtr crtc,
 		return FALSE;
 	}
 
-	if (sna->flags & SNA_TEAR_FREE)
-		return xchg(sna, crtc, event_id, target_msc, pixmap, sync_flip);
+	if (sna->flags & SNA_TEAR_FREE) {
+		sna->present.tearfree = sna->mode.shadow_damage;
+		sna->mode.shadow_damage = NULL;
+		sna->flags &= ~SNA_TEAR_FREE;
+	}
 
 	if (sna->mode.flip_active) {
 		DBG(("%s: flips still pending\n", __FUNCTION__));
@@ -674,6 +555,7 @@ sna_present_unflip(ScreenPtr screen, uint64_t event_id)
 {
 	struct sna *sna = to_sna_from_screen(screen);
 	struct kgem_bo *bo;
+	bool ok;
 
 	DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id));
 	if (sna->mode.front_active == 0 || sna->mode.rr_active) {
@@ -691,11 +573,6 @@ notify:
 		return;
 	}
 
-	if (sna->flags & SNA_TEAR_FREE) {
-		set_front(sna, screen->GetScreenPixmap(screen));
-		goto notify;
-	}
-
 	if (sna->mode.flip_active) {
 		DBG(("%s: %d outstanding flips, queueing unflip\n", __FUNCTION__, sna->mode.flip_active));
 		assert(sna->present.unflip == 0);
@@ -711,13 +588,21 @@ reset_mode:
 		goto notify;
 	}
 
+	ok = false;
 	if (sna->flags & SNA_HAS_ASYNC_FLIP) {
 		DBG(("%s: trying async flip restore\n", __FUNCTION__));
-		if (flip__async(sna, NULL, event_id, 0, bo))
-			return;
+		ok = flip__async(sna, NULL, event_id, 0, bo);
+	}
+	if (!ok)
+		ok = flip(sna, NULL, event_id, 0, bo);
+
+	if (sna->present.tearfree) {
+		sna->flags |= SNA_TEAR_FREE;
+		sna->mode.shadow_damage = sna->present.tearfree;
+		sna->present.tearfree = NULL;
 	}
 
-	if (!flip(sna, NULL, event_id, 0, bo))
+	if (!ok)
 		goto reset_mode;
 }
 
commit c30af937f8d634d0055358cb69db2896cf595983
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Feb 14 21:53:41 2015 +0000

    sna/present: Disable hardware async flips with TearFree
    
    These two don't mix, so remove the claim that we do support async flips
    when TearFree is enabled.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c95fe98..286e470 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5973,7 +5973,7 @@ probe_capabilities(struct sna *sna)
 	sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP);
 	if (has_flip(sna))
 		sna->flags |= SNA_HAS_FLIP;
-	if (has_flip__async(sna))
+	if (has_flip__async(sna) && (sna->flags & SNA_TEAR_FREE) == 0)
 		sna->flags |= SNA_HAS_ASYNC_FLIP;
 	DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__,
 	     sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled",
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 6cc9c2e..266d743 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -562,15 +562,13 @@ xchg(struct sna *sna,
 	assert(sna->flags & SNA_TEAR_FREE);
 	assert(sna->mode.shadow_damage);
 	assert(sna_pixmap(pixmap) && sna_pixmap(pixmap)->gpu_bo);
+	assert(sync_flip);
 
 	/* This effectively disables TearFree giving the client direct
 	 * access into the scanout with their Pixmap.
 	 */
 	queued = set_front(sna, pixmap);
 
-	if (!sync_flip)
-		goto notify; /* XXX We will claim that the scanout is idle */
-
 	info = malloc(sizeof(struct sna_present_event));
 	if (info == NULL)
 		return BadAlloc;


More information about the xorg-commit mailing list