vl/dri3: Destroy Present event context when destroying drawable v2
authorMichel Dänzer <michel.daenzer@amd.com>
Thu, 28 Jul 2016 08:52:11 +0000 (17:52 +0900)
committerMichel Dänzer <michel@daenzer.net>
Thu, 4 Aug 2016 06:45:43 +0000 (15:45 +0900)
Without this, the X server may accumulate stale Present event contexts
if a client performs several video decoding sessions using the same
window.

v2: Based on Chris Wilson's review:
* Use xcb_discard_reply() instead of free(xcb_request_check())

Reviewed-and-Tested-by: Leo Liu <leo.liu@amd.com>
src/gallium/auxiliary/vl/vl_winsys_dri3.c

index 493e64574a6ca2a50803abbba1e947ea48e29c55..61d6205b3261ca2f21bdb57477261e7fb5be34f1 100644 (file)
@@ -66,6 +66,7 @@ struct vl_dri3_screen
 
    uint32_t width, height, depth;
 
+   xcb_present_event_t eid;
    xcb_special_event_t *special_event;
 
    struct vl_dri3_buffer *back_buffers[BACK_BUFFER_NUM];
@@ -322,7 +323,6 @@ dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable)
    xcb_get_geometry_reply_t *geom_reply;
    xcb_void_cookie_t cookie;
    xcb_generic_error_t *error;
-   xcb_present_event_t peid;
    bool ret = true;
 
    assert(drawable);
@@ -345,12 +345,16 @@ dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable)
    if (scrn->special_event) {
       xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
       scrn->special_event = NULL;
+      cookie = xcb_present_select_input_checked(scrn->conn, scrn->eid,
+                                                scrn->drawable,
+                                                XCB_PRESENT_EVENT_MASK_NO_EVENT);
+      xcb_discard_reply(scrn->conn, cookie.sequence);
    }
 
    scrn->is_pixmap = false;
-   peid = xcb_generate_id(scrn->conn);
+   scrn->eid = xcb_generate_id(scrn->conn);
    cookie =
-      xcb_present_select_input_checked(scrn->conn, peid, scrn->drawable,
+      xcb_present_select_input_checked(scrn->conn, scrn->eid, scrn->drawable,
                       XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
                       XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
                       XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
@@ -369,7 +373,7 @@ dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable)
       free(error);
    } else
       scrn->special_event =
-         xcb_register_for_special_xge(scrn->conn, &xcb_present_id, peid, 0);
+         xcb_register_for_special_xge(scrn->conn, &xcb_present_id, scrn->eid, 0);
 
    dri3_flush_present_events(scrn);
 
@@ -609,8 +613,15 @@ vl_dri3_screen_destroy(struct vl_screen *vscreen)
       }
    }
 
-   if (scrn->special_event)
+   if (scrn->special_event) {
+      xcb_void_cookie_t cookie =
+         xcb_present_select_input_checked(scrn->conn, scrn->eid,
+                                          scrn->drawable,
+                                          XCB_PRESENT_EVENT_MASK_NO_EVENT);
+
+      xcb_discard_reply(scrn->conn, cookie.sequence);
       xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
+   }
    scrn->base.pscreen->destroy(scrn->base.pscreen);
    pipe_loader_release(&scrn->base.dev, 1);
    FREE(scrn);