xf86-video-intel: src/sna/sna_present.c test/present-test.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Mar 24 18:32:30 UTC 2016


 src/sna/sna_present.c |   10 +++---
 test/present-test.c   |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 4 deletions(-)

New commits:
commit c186d4dda3b62b73af3caf2883a9cedfd97e3b45
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 24 18:22:20 2016 +0000

    sna/present: Restrict vblank.sequence range to 31bits
    
    The kernel checks for past vblanks using an int32_t comparison, so we
    can only program up to 31bits into the future (and similarly programing
    a timer that large would also overflow).
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=94685
    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 93c7f06..e08afe5 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -114,8 +114,10 @@ static void vblank_complete(struct sna_present_event *info,
 	int n;
 
 	if (msc < info->target_msc) {
-		DBG(("%s: %d too early, now %lld, expected %lld\n",
-		     __FUNCTION__, (long long)msc, (long long)info->target_msc));
+		DBG(("%s: event=%d too early, now %lld, expected %lld\n",
+		     __FUNCTION__,
+		     info->event_id[0],
+		     (long long)msc, (long long)info->target_msc));
 		if (sna_present_queue(info, msc))
 			return;
 	}
@@ -247,7 +249,7 @@ static bool sna_present_queue(struct sna_present_event *info,
 	     (long long)info->target_msc,
 	     (unsigned)info->target_msc,
 	     (long long)last_msc));
-	assert(info->target_msc - last_msc < 1ull<<32);
+	assert(info->target_msc - last_msc < 1ull<<31);
 
 	VG_CLEAR(vbl);
 	vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
@@ -360,7 +362,7 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
 		present_event_notify(event_id, swap_ust(swap), swap->msc);
 		return Success;
 	}
-	if (warn_unless(msc - swap->msc < 1ull<<32))
+	if (warn_unless(msc - swap->msc < 1ull<<31))
 		return BadValue;
 
 	list_for_each_entry(tmp, &sna->present.vblank_queue, link) {
diff --git a/test/present-test.c b/test/present-test.c
index f578adb..5a12a24 100644
--- a/test/present-test.c
+++ b/test/present-test.c
@@ -1089,6 +1089,86 @@ static int test_future_msc(Display *dpy, void *Q)
 	return ret;
 }
 
+static int test_wrap_msc(Display *dpy)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	Window root, win;
+	int x, y;
+	unsigned int width, height;
+	unsigned border, depth;
+	XSetWindowAttributes attr;
+	int ret = 0, n;
+	uint64_t msc, ust;
+	int complete;
+	uint64_t interval;
+	void *Q;
+
+	XGetGeometry(dpy, DefaultRootWindow(dpy),
+		     &root, &x, &y, &width, &height, &border, &depth);
+
+	attr.override_redirect = 1;
+	win = XCreateWindow(dpy, root,
+			    0, 0, width, height, 0, depth,
+			    InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
+			    CWOverrideRedirect, &attr);
+	XMapWindow(dpy, win);
+	XSync(dpy, True);
+	if (_x_error_occurred)
+		return 1;
+
+	printf("Testing wraparound notifies\n");
+	_x_error_occurred = 0;
+
+	Q = setup_msc(dpy, win);
+	interval = msc_interval(dpy, win, Q);
+	if (interval == 0) {
+		printf("Zero delay between frames\n");
+		return 1;
+	}
+	msc = check_msc(dpy, win, Q, 0, &ust);
+	printf("Initial msc=%llx, interval between frames %lldus\n",
+	       (long long)msc, (long long)interval);
+
+	for (n = 1; n <= 10; n++)
+		xcb_present_notify_msc(c, win, n,
+				       msc + ((long long)n<<32) + n,
+				       0, 0);
+	for (n = 1; n <= 10; n++)
+		xcb_present_notify_msc(c, win, -n,
+				       0, (long long)n << 32, 0);
+	xcb_present_notify_msc(c, win, 0xdeadbeef, msc + 60*10, 0, 0);
+	xcb_flush(c);
+
+	complete = 0;
+	do {
+		xcb_present_complete_notify_event_t *ce;
+		xcb_generic_event_t *ev;
+
+		ev = xcb_wait_for_special_event(c, Q);
+		if (ev == NULL)
+			break;
+
+		ce = (xcb_present_complete_notify_event_t *)ev;
+		assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC);
+
+		if (ce->serial == 0xdeadbeef) {
+			complete = 1;
+		} else {
+			fprintf(stderr,
+				"\tnotify %d recieved at +%llu\n",
+				ce->serial, ce->msc - msc);
+			ret++;
+		}
+		free(ev);
+	} while (!complete);
+
+	teardown_msc(dpy, Q);
+	XDestroyWindow(dpy, win);
+	XSync(dpy, True);
+
+	return ret;
+}
+
 static int test_exhaustion_msc(Display *dpy, void *Q)
 {
 #define N_VBLANKS 256 /* kernel event queue length: 128 vblanks */
@@ -2019,6 +2099,9 @@ int main(void)
 	error += test_future_msc(dpy, queue);
 	last_msc = check_msc(dpy, root, queue, last_msc, NULL);
 
+	error += test_wrap_msc(dpy);
+	last_msc = check_msc(dpy, root, queue, last_msc, NULL);
+
 	error += test_accuracy_msc(dpy, queue);
 	last_msc = check_msc(dpy, root, queue, last_msc, NULL);
 


More information about the xorg-commit mailing list