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

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 30 01:54:40 PST 2015


 src/sna/sna_dri2.c |   36 ++++++++++++++++++++----------------
 test/dri2-race.c   |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 16 deletions(-)

New commits:
commit c0610c76b7164ee687092fec3602284f506816a7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 29 23:56:06 2015 +0000

    sna/dri2: Smooth out delivery of triple buffer SwapCompletions
    
    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 81ad9c6..de3ea5a 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2600,8 +2600,6 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 	uint64_t current_msc;
 
 	if (immediate_swap(sna, *target_msc, divisor, draw, crtc, &current_msc)) {
-		int type;
-
 		info = sna->dri2.flip_pending;
 		DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d, continuation? %d\n",
 		     __FUNCTION__, sna_crtc_to_pipe(crtc),
@@ -2622,7 +2620,8 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			    !info->flip_continue &&
 			    current_msc < *target_msc) {
 				DBG(("%s: chaining flip\n", __FUNCTION__));
-				info->flip_continue = FLIP_THROTTLE;
+				info->type = FLIP_THROTTLE;
+				info->flip_continue = FLIP_COMPLETE;
 				goto out;
 			} else
 				goto new_back;
@@ -2646,12 +2645,12 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			 */
 			DBG(("%s: queueing flip after pending completion\n",
 			     __FUNCTION__));
-			info->type = type = FLIP;
+			info->type = FLIP;
 			sna->dri2.flip_pending = info;
 			assert(!info->queued);
 			current_msc++;
 		} else {
-			info->type = type = use_triple_buffer(sna, client, *target_msc == 0);
+			info->type = use_triple_buffer(sna, client, *target_msc == 0);
 			if (!sna_dri2_flip(info)) {
 				DBG(("%s: flip failed, falling back\n", __FUNCTION__));
 				sna_dri2_event_free(info);
@@ -2659,8 +2658,8 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			}
 		}
 
-		swap_limit(draw, 1 + (type == FLIP_THROTTLE));
-		if (type >= FLIP_COMPLETE) {
+		swap_limit(draw, 1 + (info->type == FLIP_THROTTLE));
+		if (info->type >= FLIP_COMPLETE) {
 new_back:
 			if (!xorg_can_triple_buffer())
 				sna_dri2_get_back(sna, draw, back, info);
commit dc51886c0c637a1da94e6379f183fc32ac345df6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 29 23:55:19 2015 +0000

    sna/dri2: Fix use of stale flip_pending after removing window
    
    Testcase: dri2-race
    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 4056fbb..81ad9c6 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1330,6 +1330,9 @@ sna_dri2_event_free(struct sna_dri2_event *info)
 	DrawablePtr draw = info->draw;
 
 	DBG(("%s(draw?=%d)\n", __FUNCTION__, draw != NULL));
+	if (info->sna->dri2.flip_pending == info)
+		info->sna->dri2.flip_pending = info->chain;
+	assert(info->sna->dri2.flip_pending != info);
 	if (draw && draw->type == DRAWABLE_WINDOW)
 		sna_dri2_remove_event((WindowPtr)draw, info);
 
@@ -1501,6 +1504,7 @@ void sna_dri2_destroy_window(WindowPtr win)
 
 		chain = priv->chain;
 		while ((info = chain)) {
+			assert(info->draw == &win->drawable);
 			info->draw = NULL;
 			info->client = NULL;
 			list_del(&info->link);
@@ -2089,9 +2093,9 @@ static void chain_swap(struct sna_dri2_event *chain)
 	if (chain->queued) /* too early! */
 		return;
 
-	assert(chain == dri2_chain(chain->draw));
 	DBG(("%s: chaining draw=%ld, type=%d\n",
 	     __FUNCTION__, (long)chain->draw->id, chain->type));
+	assert(chain == dri2_chain(chain->draw));
 	chain->queued = true;
 
 	switch (chain->type) {
@@ -2392,8 +2396,8 @@ static void chain_flip(struct sna *sna)
 	struct sna_dri2_event *chain = sna->dri2.flip_pending;
 
 	assert(chain->type == FLIP);
-	DBG(("%s: chaining type=%d, cancelled?=%d\n",
-	     __FUNCTION__, chain->type, chain->draw == NULL));
+	DBG(("%s: chaining type=%d, cancelled?=%d window=%ld\n",
+	     __FUNCTION__, chain->type, chain->draw == NULL, chain->draw ? chain->draw->id : 0));
 
 	sna->dri2.flip_pending = NULL;
 	if (chain->draw == NULL) {
diff --git a/test/dri2-race.c b/test/dri2-race.c
index 8862c84..4f6d106 100644
--- a/test/dri2-race.c
+++ b/test/dri2-race.c
@@ -5,6 +5,10 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/Xfixes.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcb.h>
+#include <xcb/xcbext.h>
+#include <xcb/dri2.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
@@ -41,6 +45,25 @@ static int dri2_open(Display *dpy)
 	return fd;
 }
 
+static void swap_buffers(Display *dpy, Window win,
+			 unsigned int *attachments, int nattachments)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	unsigned int seq[2];
+
+	seq[0] = xcb_dri2_swap_buffers_unchecked(c, win,
+						 0, 0, 0, 0, 0, 0).sequence;
+
+
+	seq[1] = xcb_dri2_get_buffers_unchecked(c, win,
+						nattachments, nattachments,
+						attachments).sequence;
+
+	xcb_flush(c);
+	xcb_discard_reply(c, seq[0]);
+	xcb_discard_reply(c, seq[1]);
+}
+
 static void run(Display *dpy, int width, int height,
 		unsigned int *attachments, int nattachments,
 		const char *name)
@@ -77,6 +100,29 @@ static void run(Display *dpy, int width, int height,
 		XDestroyWindow(dpy, win);
 	} while (--loop);
 
+	loop = 100;
+	do {
+		win = XCreateWindow(dpy, DefaultRootWindow(dpy),
+				    0, 0, width, height, 0,
+				    DefaultDepth(dpy, DefaultScreen(dpy)),
+				    InputOutput,
+				    DefaultVisual(dpy, DefaultScreen(dpy)),
+				    CWOverrideRedirect, &attr);
+		XMapWindow(dpy, win);
+
+		DRI2CreateDrawable(dpy, win);
+
+		buffers = DRI2GetBuffers(dpy, win, &width, &height,
+					 attachments, nattachments, &count);
+		if (count != nattachments)
+			return;
+
+		free(buffers);
+		for (count = 0; count < loop; count++)
+			swap_buffers(dpy, win, attachments, nattachments);
+		XDestroyWindow(dpy, win);
+	} while (--loop);
+
 	XSync(dpy, 1);
 	sleep(2);
 	XSync(dpy, 1);
commit 1030705cdc7725ee821cf10be9c3cb0aeb31564c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 29 23:11:49 2015 +0000

    sna/dri2: Fix interoperation between keepalive and fake-triple-buffering
    
    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 6bb506e..4056fbb 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -2613,14 +2613,15 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			}
 			DBG(("%s: executing xchg of pending flip\n", __FUNCTION__));
 			sna_dri2_xchg(draw, front, back);
-			if (!info->flip_continue && current_msc < *target_msc) {
+			info->keepalive++;
+			if (xorg_can_triple_buffer() &&
+			    !info->flip_continue &&
+			    current_msc < *target_msc) {
 				DBG(("%s: chaining flip\n", __FUNCTION__));
 				info->flip_continue = FLIP_THROTTLE;
-				info->keepalive++;
-				if (xorg_can_triple_buffer())
-					goto out;
-			}
-			goto new_back;
+				goto out;
+			} else
+				goto new_back;
 		}
 
 		info = sna_dri2_add_event(sna, draw, client);


More information about the xorg-commit mailing list