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, ¤t_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