[PATCH 2/2] loader_dri3: Variant 2: Wait for pending swaps to complete before drawable_fini.

Mario Kleiner mario.kleiner.de at gmail.com
Fri May 4 13:45:42 UTC 2018


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.de at gmail.com>
Cc: xorg-devel at lists.x.org
Cc: daniel at fooishbar.org
Cc: eero.t.tamminen at intel.com
Cc: mike at 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



More information about the xorg-devel mailing list