static bool dri3_wait_present_events(struct vl_dri3_screen *scrn) { if (scrn->special_event) { xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(scrn->conn, scrn->special_event); if (!ev) return false; dri3_handle_present_event(scrn, (xcb_present_generic_event_t *)ev); return true; } return false; }
static bool dri3_wait_for_event(struct loader_dri3_drawable *draw) { xcb_generic_event_t *ev; xcb_present_generic_event_t *ge; xcb_flush(draw->conn); ev = xcb_wait_for_special_event(draw->conn, draw->special_event); if (!ev) return false; ge = (void *) ev; dri3_handle_present_event(draw, ge); return true; }
static void * x11_manage_fifo_queues(void *state) { struct x11_swapchain *chain = state; VkResult result; assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR); while (chain->status == VK_SUCCESS) { /* It should be safe to unconditionally block here. Later in the loop * we blocks until the previous present has landed on-screen. At that * point, we should have received IDLE_NOTIFY on all images presented * before that point so the client should be able to acquire any image * other than the currently presented one. */ uint32_t image_index; result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX); if (result != VK_SUCCESS) { goto fail; } else if (chain->status != VK_SUCCESS) { return NULL; } uint64_t target_msc = chain->last_present_msc + 1; result = x11_present_to_x11(chain, image_index, target_msc); if (result != VK_SUCCESS) goto fail; while (chain->last_present_msc < target_msc) { xcb_generic_event_t *event = xcb_wait_for_special_event(chain->conn, chain->special_event); if (!event) goto fail; result = x11_handle_dri3_present_event(chain, (void *)event); if (result != VK_SUCCESS) goto fail; } } fail: chain->status = result; wsi_queue_push(&chain->acquire_queue, UINT32_MAX); return NULL; }
static BOOL PRESENTwait_events(PRESENTpriv *present_priv, BOOL allow_other_threads) { xcb_generic_event_t *ev; if (allow_other_threads) { present_priv->xcb_wait = TRUE; pthread_mutex_lock(&present_priv->mutex_xcb_wait); pthread_mutex_unlock(&present_priv->mutex_present); } ev = xcb_wait_for_special_event(present_priv->xcb_connection, present_priv->special_event); if (allow_other_threads) { pthread_mutex_unlock(&present_priv->mutex_xcb_wait); pthread_mutex_lock(&present_priv->mutex_present); present_priv->xcb_wait = FALSE; } if (!ev) { ERR("FATAL error: xcb had an error\n"); return FALSE; } PRESENThandle_events(present_priv, (void *) ev); return TRUE; }