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

Chris Wilson ickle at kemper.freedesktop.org
Fri Apr 8 19:59:41 UTC 2016


 src/sna/sna_present.c |   38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

New commits:
commit edcfb3efb87c5d70f821a65e8e197b1a607706ae
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 8 20:56:26 2016 +0100

    sna/present: Handle 64bit wraparound in msc comparisons
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 15cfb70..da64233 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -58,6 +58,11 @@ to_present_event(uintptr_t  data)
 	return (struct sna_present_event *)(data & ~3);
 }
 
+static inline bool msc_before(uint64_t msc, uint64_t target)
+{
+	return (int64_t)(msc - target) < 0;
+}
+
 #define MARK_PRESENT(x) ((void *)((uintptr_t)(x) | 2))
 
 static inline xf86CrtcPtr unmask_crtc(xf86CrtcPtr crtc)
@@ -114,7 +119,7 @@ static void vblank_complete(struct sna_present_event *info,
 {
 	int n;
 
-	if (msc < info->target_msc) {
+	if (msc_before(msc, info->target_msc)) {
 		DBG(("%s: event=%d too early, now %lld, expected %lld\n",
 		     __FUNCTION__,
 		     info->event_id[0],
@@ -187,7 +192,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data)
 		msc = sna_crtc_record_vblank(info->crtc, &vbl);
 		DBG(("%s: event=%lld, target msc=%lld, now %lld\n",
 		     __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc));
-		if (msc < info->target_msc) {
+		if (msc_before(msc, info->target_msc)) {
 			int delta = info->target_msc - msc;
 			uint32_t delay;
 
@@ -248,7 +253,7 @@ static bool sna_fake_vblank(struct sna_present_event *info)
 	const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
 	uint32_t delay;
 
-	if (swap->msc < info->target_msc)
+	if (msc_before(swap->msc, info->target_msc))
 		delay = msc_to_delay(info->crtc, info->target_msc);
 	else
 		delay = 0;
@@ -259,7 +264,7 @@ static bool sna_fake_vblank(struct sna_present_event *info)
 	if (delay == 0) {
 		uint64_t ust, msc;
 
-		if (swap->msc < info->target_msc) {
+		if (msc_before(swap->msc, info->target_msc)) {
 			/* Fixup and pretend it completed immediately */
 			msc = info->target_msc;
 			ust = gettime_ust64();
commit e5bbf519bd2a62f770f2bf964857855d45036256
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 8 20:49:13 2016 +0100

    sna/present: Fixup msc when reporting a fake vblank with 0 delay
    
    If we have to fake a vblank because the CRTC is off and we compute the
    delay as being 0, then we would report the event immediately - but with
    the earlier msc. Instead, we want to report the completion.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index e69aef2..15cfb70 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -145,6 +145,10 @@ static uint32_t msc_to_delay(xf86CrtcPtr crtc, uint64_t target)
 	const struct ust_msc *swap = sna_crtc_last_swap(crtc);
 	int64_t delay, subframe;
 
+	/* XXX How to handle CRTC being off? */
+	if (mode->Clock == 0)
+		return 0;
+
 	delay = target - swap->msc;
 	assert(delay >= 0);
 	if (delay > 1) { /* try to use the hw vblank for the last frame */
@@ -241,21 +245,30 @@ fixup:
 
 static bool sna_fake_vblank(struct sna_present_event *info)
 {
-	uint64_t msc = sna_crtc_last_swap(info->crtc)->msc;
+	const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
 	uint32_t delay;
 
-	if (msc < info->target_msc)
+	if (swap->msc < info->target_msc)
 		delay = msc_to_delay(info->crtc, info->target_msc);
 	else
 		delay = 0;
 
-	DBG(("%s(event=%lld, target_msc=%lld, msc=%lld, delay=%ums)\n",
-	     __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc, delay));
+	DBG(("%s(event=%lldx%d, target_msc=%lld, msc=%lld, delay=%ums)\n",
+	     __FUNCTION__, (long long)info->event_id[0], info->n_event_id,
+	     (long long)info->target_msc, (long long)swap->msc, delay));
 	if (delay == 0) {
-		const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
-		present_event_notify(info->event_id[0], swap_ust(swap), swap->msc);
-		list_del(&info->link);
-		free(info);
+		uint64_t ust, msc;
+
+		if (swap->msc < info->target_msc) {
+			/* Fixup and pretend it completed immediately */
+			msc = info->target_msc;
+			ust = gettime_ust64();
+		} else {
+			msc = swap->msc;
+			ust = swap_ust(swap);
+		}
+
+		vblank_complete(info, ust, msc);
 		return true;
 	}
 


More information about the xorg-commit mailing list