See previous patch in series for explanation of the problem. This method avoids a blocking loader_dri3_swapbuffer_barrier() call whenever a GL contexts drawables are changed via glXMakeCurrent et al.
Instead it filters out the "orphaned" PresentNotify events from previous incarnations of the loader_dri3_drawable. This should deal correctly with PixmapInvalidate, PixmapPresentCompleteNotify and MscCompleteNotify events, but i don't know a way to filter out WindowConfigureNotify events, or if it even matters to filter them. This PoC one is only meaningful if the first patch is omitted, and shows the spurious "ORPHAN" printouts which would hang KDE plasmashell if not filtered out. Test from a terminal: killall plasmashell; plasmashell Wiggly the mouse around, click etc. on the KDE taskbar, K-Menu, system tray icons, trigger volume/brightness feedback widgets to provoke the occassional ORPHAN event. Signed-off-by: Mario Kleiner <mario.kleiner...@gmail.com> Cc: xorg-de...@lists.x.org Cc: dan...@fooishbar.org Cc: eero.t.tammi...@intel.com Cc: m...@fireburn.co.uk --- src/loader/loader_dri3_helper.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 7bd79af..123a996 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -234,6 +234,10 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw) { int i; + printf("FINI: wxh = %d x %d, drawable %d eid %d recv_sbc %lu, send_sbc %lu PENDING %lu\n", + draw->width, draw->height, draw->drawable, draw->eid, draw->recv_sbc, draw->send_sbc, + draw->send_sbc - draw->recv_sbc); + if (draw->special_event) loader_dri3_swapbuffer_barrier(draw); @@ -373,6 +377,15 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw, * checking for wrap. */ if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) { + /* Filter out orphan events sent for a previous incarnation of draw. */ + if (!(draw->send_sbc & 0xffffffff00000000LL) && + ce->serial > draw->send_sbc) { + printf("ORPHAN-C: %d x %d, drawable %d: recv %u vs send_sbc %lu\n", + draw->width, draw->height, draw->drawable, ce->serial, + draw->send_sbc); + break; + } + draw->recv_sbc = (draw->send_sbc & 0xffffffff00000000LL) | ce->serial; if (draw->recv_sbc > draw->send_sbc) draw->recv_sbc -= 0x100000000; @@ -418,6 +431,15 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw, xcb_present_idle_notify_event_t *ie = (void *) ge; int b; + /* Filter out orphan events sent for a previous incarnation of draw. */ + if (!(draw->send_sbc & 0xffffffff00000000LL) && + ie->serial > draw->send_sbc) { + printf("ORPHAN-I: %d x %d, drawable %d: recv %u vs send_sbc %lu\n", + draw->width, draw->height, draw->drawable, ie->serial, + draw->send_sbc); + break; + } + for (b = 0; b < ARRAY_SIZE(draw->buffers); b++) { struct loader_dri3_buffer *buf = draw->buffers[b]; @@ -1435,6 +1457,8 @@ dri3_update_drawable(__DRIdrawable *driDrawable, xcb_unregister_for_special_event(draw->conn, draw->special_event); draw->special_event = NULL; } + + printf("INIT: wxh = %d x %d, drawable %d eid %d\n", draw->width, draw->height, draw->drawable, draw->eid); } dri3_flush_present_events(draw); mtx_unlock(&draw->mtx); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev