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