Workaround the incompatibility between DRI2 and xcb

When using DRI2, Mesa uses XESetWireToEvent to hook into Xlib's event
handling loop, so it can get notified when certain DRI2 event happens,
which is crucial to the normal functioning of GLX.

When xcb is owning the event queue (meaning libxcb is doing all the
event handling), those functions registered by Mesa will never be
called, thus GLX will malfunction, leading to screen flickers or visual
artifacts.

This commit uses a hack from Qt to manually call those functions in
compton.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2018-11-10 21:52:42 +00:00
parent 47377df04a
commit bcab5d1518
1 changed files with 26 additions and 0 deletions

View File

@ -11,6 +11,8 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <xcb/randr.h> #include <xcb/randr.h>
#include <xcb/present.h> #include <xcb/present.h>
#include <xcb/damage.h> #include <xcb/damage.h>
@ -28,6 +30,8 @@
#include "config.h" #include "config.h"
#include "diagnostic.h" #include "diagnostic.h"
#define auto __auto_type
static void static void
finish_destroy_win(session_t *ps, win **_w); finish_destroy_win(session_t *ps, win **_w);
@ -3236,6 +3240,28 @@ ev_handle(session_t *ps, xcb_generic_event_t *ev) {
} }
#endif #endif
// Check if a custom XEvent constructor was registered in xlib for this event
// type, and call it discarding the constructed XEvent if any. XESetWireToEvent
// might be used by libraries to intercept messages from the X server e.g. the
// OpenGL lib waiting for DRI2 events.
// XXX This exists to workaround compton issue #33, #34, #47
// For even more details, see:
// https://bugs.freedesktop.org/show_bug.cgi?id=35945
// https://lists.freedesktop.org/archives/xcb/2011-November/007337.html
auto proc = XESetWireToEvent(ps->dpy, ev->response_type, 0);
if (proc) {
XESetWireToEvent(ps->dpy, ev->response_type, proc);
XEvent dummy;
// Stop Xlib from complaining about lost sequence numbers.
// proc might also just be Xlib internal event processing functions, and
// because they probably won't see all X replies, they will complain about
// missing sequence numbers.
ev->sequence = LastKnownRequestProcessed(ps->dpy);
proc(ps->dpy, &dummy, (xEvent *)ev);
}
// XXX redraw needs to be more fine grained // XXX redraw needs to be more fine grained
queue_redraw(ps); queue_redraw(ps);