static bool dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable) { xcb_get_geometry_cookie_t geom_cookie; 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); if (scrn->drawable == drawable) return true; scrn->drawable = drawable; geom_cookie = xcb_get_geometry(scrn->conn, scrn->drawable); geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL); if (!geom_reply) return false; scrn->width = geom_reply->width; scrn->height = geom_reply->height; scrn->depth = geom_reply->depth; free(geom_reply); if (scrn->special_event) { xcb_unregister_for_special_event(scrn->conn, scrn->special_event); scrn->special_event = NULL; } scrn->is_pixmap = false; peid = xcb_generate_id(scrn->conn); cookie = xcb_present_select_input_checked(scrn->conn, peid, scrn->drawable, XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY | XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); error = xcb_request_check(scrn->conn, cookie); if (error) { if (error->error_code != BadWindow) ret = false; else { scrn->is_pixmap = true; if (scrn->front_buffer) { dri3_free_front_buffer(scrn, scrn->front_buffer); scrn->front_buffer = NULL; } } free(error); } else scrn->special_event = xcb_register_for_special_xge(scrn->conn, &xcb_present_id, peid, 0); dri3_flush_present_events(scrn); return ret; }
static VkResult x11_swapchain_destroy(struct wsi_swapchain *anv_chain, const VkAllocationCallbacks *pAllocator) { struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; xcb_void_cookie_t cookie; for (uint32_t i = 0; i < chain->image_count; i++) x11_image_finish(chain, pAllocator, &chain->images[i]); if (chain->threaded) { chain->status = VK_ERROR_OUT_OF_DATE_KHR; /* Push a UINT32_MAX to wake up the manager */ wsi_queue_push(&chain->present_queue, UINT32_MAX); pthread_join(chain->queue_manager, NULL); wsi_queue_destroy(&chain->acquire_queue); wsi_queue_destroy(&chain->present_queue); } xcb_unregister_for_special_event(chain->conn, chain->special_event); cookie = xcb_present_select_input_checked(chain->conn, chain->event_id, chain->window, XCB_PRESENT_EVENT_MASK_NO_EVENT); xcb_discard_reply(chain->conn, cookie.sequence); vk_free(pAllocator, chain); return VK_SUCCESS; }
static BOOL PRESENTPrivChangeWindow(PRESENTpriv *present_priv, XID window) { xcb_void_cookie_t cookie; xcb_generic_error_t *error; xcb_present_event_t eid; PRESENTForceReleases(present_priv); PRESENTFreeXcbQueue(present_priv); present_priv->window = window; if (window) { cookie = xcb_present_select_input_checked(present_priv->xcb_connection, (eid = xcb_generate_id(present_priv->xcb_connection)), window, XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY| XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); present_priv->special_event = xcb_register_for_special_xge(present_priv->xcb_connection, &xcb_present_id, eid, NULL); error = xcb_request_check(present_priv->xcb_connection, cookie); /* performs a flush */ if (error || !present_priv->special_event) { ERR("FAILED to use the X PRESENT extension. Was the destination a window ?\n"); if (present_priv->special_event) xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event); present_priv->special_event = NULL; present_priv->window = 0; } } return (present_priv->window != 0); }
void loader_dri3_drawable_fini(struct loader_dri3_drawable *draw) { int i; (draw->ext->core->destroyDrawable)(draw->dri_drawable); for (i = 0; i < LOADER_DRI3_NUM_BUFFERS; i++) { if (draw->buffers[i]) dri3_free_render_buffer(draw, draw->buffers[i]); } if (draw->special_event) { xcb_void_cookie_t cookie = xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable, XCB_PRESENT_EVENT_MASK_NO_EVENT); xcb_discard_reply(draw->conn, cookie.sequence); xcb_unregister_for_special_event(draw->conn, draw->special_event); } }
static void vl_dri3_screen_destroy(struct vl_screen *vscreen) { struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen; int i; assert(vscreen); dri3_flush_present_events(scrn); if (scrn->front_buffer) { dri3_free_front_buffer(scrn, scrn->front_buffer); scrn->front_buffer = NULL; } for (i = 0; i < BACK_BUFFER_NUM; ++i) { if (scrn->back_buffers[i]) { dri3_free_back_buffer(scrn, scrn->back_buffers[i]); scrn->back_buffers[i] = NULL; } } 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->pipe->destroy(scrn->pipe); scrn->base.pscreen->destroy(scrn->base.pscreen); pipe_loader_release(&scrn->base.dev, 1); FREE(scrn); return; }
/** loader_dri3_update_drawable * * Called the first time we use the drawable and then * after we receive present configure notify events to * track the geometry of the drawable */ static int dri3_update_drawable(__DRIdrawable *driDrawable, struct loader_dri3_drawable *draw) { if (draw->first_init) { xcb_get_geometry_cookie_t geom_cookie; xcb_get_geometry_reply_t *geom_reply; xcb_void_cookie_t cookie; xcb_generic_error_t *error; xcb_present_query_capabilities_cookie_t present_capabilities_cookie; xcb_present_query_capabilities_reply_t *present_capabilities_reply; draw->first_init = false; /* Try to select for input on the window. * * If the drawable is a window, this will get our events * delivered. * * Otherwise, we'll get a BadWindow error back from this request which * will let us know that the drawable is a pixmap instead. */ draw->eid = xcb_generate_id(draw->conn); cookie = xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable, XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY | XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); present_capabilities_cookie = xcb_present_query_capabilities(draw->conn, draw->drawable); /* Create an XCB event queue to hold present events outside of the usual * application event queue */ draw->special_event = xcb_register_for_special_xge(draw->conn, &xcb_present_id, draw->eid, draw->stamp); geom_cookie = xcb_get_geometry(draw->conn, draw->drawable); geom_reply = xcb_get_geometry_reply(draw->conn, geom_cookie, NULL); if (!geom_reply) return false; draw->width = geom_reply->width; draw->height = geom_reply->height; draw->depth = geom_reply->depth; draw->vtable->set_drawable_size(draw, draw->width, draw->height); free(geom_reply); draw->is_pixmap = false; /* Check to see if our select input call failed. If it failed with a * BadWindow error, then assume the drawable is a pixmap. Destroy the * special event queue created above and mark the drawable as a pixmap */ error = xcb_request_check(draw->conn, cookie); present_capabilities_reply = xcb_present_query_capabilities_reply(draw->conn, present_capabilities_cookie, NULL); if (present_capabilities_reply) { draw->present_capabilities = present_capabilities_reply->capabilities; free(present_capabilities_reply); } else draw->present_capabilities = 0; if (error) { if (error->error_code != BadWindow) { free(error); return false; } draw->is_pixmap = true; xcb_unregister_for_special_event(draw->conn, draw->special_event); draw->special_event = NULL; } } dri3_flush_present_events(draw); return true; }