xf86-video-intel: 2 commits - src/sna/sna_dri2.c test/dri2-race.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Mar 16 09:55:09 UTC 2016


 src/sna/sna_dri2.c |   15 ++-
 test/dri2-race.c   |  264 +++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 247 insertions(+), 32 deletions(-)

New commits:
commit e042b5d82558293ef06847f4833efc91a95b5d40
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 16 09:31:20 2016 +0000

    tests: Add DRI2 race against window resize + Composite redirection
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/dri2-race.c b/test/dri2-race.c
index d75293b..4e5187c 100644
--- a/test/dri2-race.c
+++ b/test/dri2-race.c
@@ -5,6 +5,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xcomposite.h>
 #include <X11/Xlib-xcb.h>
 #include <xcb/xcb.h>
 #include <xcb/xcbext.h>
@@ -102,15 +103,38 @@ static void swap_buffers(Display *dpy, Window win, int divisor,
 	xcb_discard_reply(c, seq[1]);
 }
 
+#define COMPOSITE 1
+
+static int has_composite(Display *dpy)
+{
+	Display *dummy = NULL;
+	int event, error;
+	int major = -1, minor = -1;
+
+	if (dpy == NULL)
+		dummy = dpy = XOpenDisplay(NULL);
+
+	if (XCompositeQueryExtension(dpy, &event, &error))
+		XCompositeQueryVersion(dpy, &major, &minor);
+
+	if (dummy)
+		XCloseDisplay(dummy);
+
+	return major > 0 || minor >= 4;
+}
+
 static void race_window(Display *dpy, int width, int height,
 			unsigned int *attachments, int nattachments,
-			const char *name)
+			unsigned flags, const char *name)
 {
 	Window win;
 	XSetWindowAttributes attr;
 	int count, loop, n;
 	DRI2Buffer *buffers;
 
+	if (flags & COMPOSITE && !has_composite(dpy))
+		return;
+
 	printf("%s(%s)\n", __func__, name);
 
 	/* Be nasty and install a fullscreen window on top so that we
@@ -127,6 +151,8 @@ static void race_window(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -155,6 +181,8 @@ static void race_window(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -186,6 +214,8 @@ static void race_window(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -211,9 +241,140 @@ static void race_window(Display *dpy, int width, int height,
 	XSync(dpy, 1);
 }
 
+static int rand_size(int max)
+{
+	return 1 + (rand() % (max - 1));
+}
+
+static void race_resize(Display *dpy, int width, int height,
+			unsigned int *attachments, int nattachments,
+			unsigned flags, const char *name)
+{
+	Window win;
+	XSetWindowAttributes attr;
+	int count, loop, n;
+	DRI2Buffer *buffers;
+
+	if (flags & COMPOSITE && !has_composite(dpy))
+		return;
+
+	printf("%s(%s)\n", __func__, name);
+
+	attr.override_redirect = 1;
+	for (n = 0; n < N_DIVISORS; n++) {
+		win = XCreateWindow(dpy, DefaultRootWindow(dpy),
+				    0, 0, width, height, 0,
+				    DefaultDepth(dpy, DefaultScreen(dpy)),
+				    InputOutput,
+				    DefaultVisual(dpy, DefaultScreen(dpy)),
+				    CWOverrideRedirect, &attr);
+		if (flags & COMPOSITE)
+			XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
+		XMapWindow(dpy, win);
+
+		DRI2CreateDrawable(dpy, win);
+
+		loop = 256 >> ffs(divisors[n]);
+		printf("DRI2SwapBuffers(divisor=%d), loop=%d", divisors[n], loop);
+		do {
+			int w, h;
+
+			buffers = DRI2GetBuffers(dpy, win, &w, &h,
+					attachments, nattachments, &count);
+			if (count != nattachments)
+				return;
+
+			free(buffers);
+			for (count = 0; count < loop; count++)
+				DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1));
+			XResizeWindow(dpy, win, rand_size(width), rand_size(height));
+			printf("."); fflush(stdout);
+		} while (--loop);
+		XDestroyWindow(dpy, win);
+		XSync(dpy, True);
+		printf("*\n");
+	}
+
+	for (n = 0; n < N_DIVISORS; n++) {
+		win = XCreateWindow(dpy, DefaultRootWindow(dpy),
+				    0, 0, width, height, 0,
+				    DefaultDepth(dpy, DefaultScreen(dpy)),
+				    InputOutput,
+				    DefaultVisual(dpy, DefaultScreen(dpy)),
+				    CWOverrideRedirect, &attr);
+		if (flags & COMPOSITE)
+			XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
+		XMapWindow(dpy, win);
+
+		DRI2CreateDrawable(dpy, win);
+
+		loop = 256 >> ffs(divisors[n]);
+		printf("xcb_dri2_swap_buffers(divisor=%d), loops=%d", divisors[n], loop);
+		do {
+			int w, h;
+
+			buffers = DRI2GetBuffers(dpy, win, &w, &h,
+					attachments, nattachments, &count);
+			if (count != nattachments)
+				return;
+
+			free(buffers);
+			for (count = 0; count < loop; count++)
+				swap_buffers(dpy, win, divisors[n], attachments, nattachments);
+			XResizeWindow(dpy, win, rand_size(width), rand_size(height));
+			printf("."); fflush(stdout);
+		} while (--loop);
+		XDestroyWindow(dpy, win);
+		XSync(dpy, True);
+		printf("*\n");
+	}
+
+	for (n = 0; n < N_DIVISORS; n++) {
+		win = XCreateWindow(dpy, DefaultRootWindow(dpy),
+				    0, 0, width, height, 0,
+				    DefaultDepth(dpy, DefaultScreen(dpy)),
+				    InputOutput,
+				    DefaultVisual(dpy, DefaultScreen(dpy)),
+				    CWOverrideRedirect, &attr);
+		if (flags & COMPOSITE)
+			XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
+		XMapWindow(dpy, win);
+
+		DRI2CreateDrawable(dpy, win);
+
+		loop = 256 >> ffs(divisors[n]);
+		printf("DRI2WaitMsc(divisor=%d), loop=%d", divisors[n], loop);
+		do {
+			uint64_t ignore, msc;
+			xcb_connection_t *c = XGetXCBConnection(dpy);
+
+			DRI2GetMSC(dpy, win, &ignore, &msc, &ignore);
+			msc++;
+			for (count = 0; count < loop; count++) {
+				xcb_discard_reply(c,
+						xcb_dri2_wait_msc(c, win,
+							upper_32_bits(msc),
+							lower_32_bits(msc),
+							0, 0, 0, 0).sequence);
+				msc += divisors[n];
+			}
+			XFlush(dpy);
+			XResizeWindow(dpy, win, rand_size(width), rand_size(height));
+			printf("."); fflush(stdout);
+		} while (--loop);
+		XDestroyWindow(dpy, win);
+		XSync(dpy, True);
+		printf("*\n");
+	}
+
+	XSync(dpy, 1);
+	sleep(2);
+	XSync(dpy, 1);
+}
+
 static void race_manager(Display *dpy, int width, int height,
 			 unsigned int *attachments, int nattachments,
-			 const char *name)
+			 unsigned flags, const char *name)
 {
 	Display *mgr = XOpenDisplay(NULL);
 	Window win;
@@ -221,6 +382,9 @@ static void race_manager(Display *dpy, int width, int height,
 	int count, loop, n;
 	DRI2Buffer *buffers;
 
+	if (flags & COMPOSITE && !has_composite(dpy))
+		return;
+
 	printf("%s(%s)\n", __func__, name);
 
 	/* Be nasty and install a fullscreen window on top so that we
@@ -237,6 +401,8 @@ static void race_manager(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -267,6 +433,8 @@ static void race_manager(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -300,6 +468,8 @@ static void race_manager(Display *dpy, int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -332,11 +502,14 @@ static void race_manager(Display *dpy, int width, int height,
 
 static void race_close(int width, int height,
 		       unsigned int *attachments, int nattachments,
-		       const char *name)
+		       unsigned flags, const char *name)
 {
 	XSetWindowAttributes attr;
 	int count, loop, n;
 
+	if (flags & COMPOSITE && !has_composite(NULL))
+		return;
+
 	printf("%s(%s)\n", __func__, name);
 
 	/* Be nasty and install a fullscreen window on top so that we
@@ -354,7 +527,8 @@ static void race_close(int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
-
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -382,7 +556,8 @@ static void race_close(int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
-
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -412,7 +587,8 @@ static void race_close(int width, int height,
 					InputOutput,
 					DefaultVisual(dpy, DefaultScreen(dpy)),
 					CWOverrideRedirect, &attr);
-
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -436,12 +612,15 @@ static void race_close(int width, int height,
 
 static void race_client(int width, int height,
 			unsigned int *attachments, int nattachments,
-			const char *name)
+			unsigned flags, const char *name)
 {
 	Display *mgr = XOpenDisplay(NULL);
 	XSetWindowAttributes attr;
 	int count, loop, n;
 
+	if (flags & COMPOSITE && !has_composite(NULL))
+		return;
+
 	printf("%s(%s)\n", __func__, name);
 
 	/* Be nasty and install a fullscreen window on top so that we
@@ -467,6 +646,8 @@ static void race_client(int width, int height,
 					    InputOutput,
 					    DefaultVisual(dpy, DefaultScreen(dpy)),
 					    CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -509,6 +690,8 @@ static void race_client(int width, int height,
 					    InputOutput,
 					    DefaultVisual(dpy, DefaultScreen(dpy)),
 					    CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -553,6 +736,8 @@ static void race_client(int width, int height,
 					    InputOutput,
 					    DefaultVisual(dpy, DefaultScreen(dpy)),
 					    CWOverrideRedirect, &attr);
+			if (flags & COMPOSITE)
+				XCompositeRedirectWindow(dpy, win, CompositeRedirectManual);
 			XMapWindow(dpy, win);
 
 			DRI2CreateDrawable(dpy, win);
@@ -605,31 +790,52 @@ int main(void)
 
 	width = WidthOfScreen(DefaultScreenOfDisplay(dpy));
 	height = HeightOfScreen(DefaultScreenOfDisplay(dpy));
-	race_window(dpy, width, height, attachments, 1, "fullscreen");
-	race_window(dpy, width, height, attachments, 2, "fullscreen (with front)");
-
-	race_manager(dpy, width, height, attachments, 1, "fullscreen");
-	race_manager(dpy, width, height, attachments, 2, "fullscreen (with front)");
-
-	race_close(width, height, attachments, 1, "fullscreen");
-	race_close(width, height, attachments, 2, "fullscreen (with front)");
-
-	race_client(width, height, attachments, 1, "fullscreen");
-	race_client(width, height, attachments, 2, "fullscreen (with front)");
+	race_window(dpy, width, height, attachments, 1, 0, "fullscreen");
+	race_window(dpy, width, height, attachments, 1, COMPOSITE, "composite fullscreen");
+	race_window(dpy, width, height, attachments, 2, 0, "fullscreen (with front)");
+	race_window(dpy, width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)");
+
+	race_resize(dpy, width, height, attachments, 1, 0, "");
+	race_resize(dpy, width, height, attachments, 1, COMPOSITE, "composite");
+	race_resize(dpy, width, height, attachments, 2, 0, "with front");
+	race_resize(dpy, width, height, attachments, 2, COMPOSITE, "composite with front");
+
+	race_manager(dpy, width, height, attachments, 1, 0, "fullscreen");
+	race_manager(dpy, width, height, attachments, 1, COMPOSITE, "composite fullscreen");
+	race_manager(dpy, width, height, attachments, 2, 0, "fullscreen (with front)");
+	race_manager(dpy, width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)");
+
+	race_close(width, height, attachments, 1, 0, "fullscreen");
+	race_close(width, height, attachments, 1, COMPOSITE, "composite fullscreen");
+	race_close(width, height, attachments, 2, 0, "fullscreen (with front)");
+	race_close(width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)");
+
+	race_client(width, height, attachments, 1, 0, "fullscreen");
+	race_client(width, height, attachments, 1, COMPOSITE, "composite fullscreen");
+	race_client(width, height, attachments, 2, 0, "fullscreen (with front)");
+	race_client(width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)");
 
 	width /= 2;
 	height /= 2;
-	race_window(dpy, width, height, attachments, 1, "windowed");
-	race_window(dpy, width, height, attachments, 2, "windowed (with front)");
-
-	race_manager(dpy, width, height, attachments, 1, "windowed");
-	race_manager(dpy, width, height, attachments, 2, "windowed (with front)");
-
-	race_close(width, height, attachments, 1, "windowed");
-	race_close(width, height, attachments, 2, "windowed (with front)");
-
-	race_client(width, height, attachments, 1, "windowed");
-	race_client(width, height, attachments, 2, "windowed (with front)");
+	race_window(dpy, width, height, attachments, 1, 0, "windowed");
+	race_window(dpy, width, height, attachments, 1, COMPOSITE, "composite windowed");
+	race_window(dpy, width, height, attachments, 2, 0, "windowed (with front)");
+	race_window(dpy, width, height, attachments, 2, COMPOSITE, "composite windowed (with front)");
+
+	race_manager(dpy, width, height, attachments, 1, 0, "windowed");
+	race_manager(dpy, width, height, attachments, 1, COMPOSITE, "composite windowed");
+	race_manager(dpy, width, height, attachments, 2, 0, "windowed (with front)");
+	race_manager(dpy, width, height, attachments, 2, COMPOSITE, "composite windowed (with front)");
+
+	race_close(width, height, attachments, 1, 0, "windowed");
+	race_close(width, height, attachments, 1, COMPOSITE, "composite windowed");
+	race_close(width, height, attachments, 2, 0, "windowed (with front)");
+	race_close(width, height, attachments, 2, COMPOSITE, "composite windowed (with front)");
+
+	race_client(width, height, attachments, 1, 0, "windowed");
+	race_client(width, height, attachments, 1, COMPOSITE, "composite windowed");
+	race_client(width, height, attachments, 2, 0, "windowed (with front)");
+	race_client(width, height, attachments, 2, COMPOSITE, "composite windowed (with front)");
 
 	return 0;
 }
commit 3f56c3d50cc668e51ee649db8191da28bed3c582
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 16 09:39:10 2016 +0000

    sna/dri2: Flush outstanding signals when decoupling inflight events
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index c30e0fa..afd2603 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1819,7 +1819,8 @@ sna_dri2_add_event(struct sna *sna,
 
 static void decouple_window(WindowPtr win,
 			    struct dri2_window *priv,
-			    struct sna *sna)
+			    struct sna *sna,
+			    bool signal)
 {
 	if (priv->front) {
 		DBG(("%s: decouple private front\n", __FUNCTION__));
@@ -1843,6 +1844,12 @@ static void decouple_window(WindowPtr win,
 			assert(info->draw == &win->drawable);
 
 			if (info->pending.bo) {
+				if (signal) {
+					bool was_signalling = info->signal;
+					info->signal = true;
+					frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE);
+					info->signal = was_signalling;
+				}
 				assert(info->pending.bo->active_scanout > 0);
 				info->pending.bo->active_scanout--;
 
@@ -1850,6 +1857,8 @@ static void decouple_window(WindowPtr win,
 				info->pending.bo = NULL;
 			}
 
+			if (info->signal && signal)
+				frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE);
 			info->signal = false;
 			info->draw = NULL;
 			info->keepalive = 1;
@@ -1877,7 +1886,7 @@ void sna_dri2_decouple_window(WindowPtr win)
 		return;
 
 	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id));
-	decouple_window(win, priv, to_sna_from_drawable(&win->drawable));
+	decouple_window(win, priv, to_sna_from_drawable(&win->drawable), true);
 
 	priv->scanout = -1;
 }
@@ -1893,7 +1902,7 @@ void sna_dri2_destroy_window(WindowPtr win)
 
 	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id));
 	sna = to_sna_from_drawable(&win->drawable);
-	decouple_window(win, priv, sna);
+	decouple_window(win, priv, sna, false);
 
 	while (!list_is_empty(&priv->cache)) {
 		struct dri_bo *c;


More information about the xorg-commit mailing list