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

Reply via email to