static void vl_dri3_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, void *context_private, struct pipe_box *sub_box) { struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)context_private; uint32_t options = XCB_PRESENT_OPTION_NONE; struct vl_dri3_buffer *back; struct pipe_box src_box; xcb_xfixes_region_t region; xcb_rectangle_t rectangle; back = scrn->back_buffers[scrn->cur_back]; if (!back) return; while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc) if (!dri3_wait_present_events(scrn)) return; rectangle.x = 0; rectangle.y = 0; rectangle.width = (scrn->output_texture) ? scrn->clip_width : scrn->width; rectangle.height = (scrn->output_texture) ? scrn->clip_height : scrn->height; region = xcb_generate_id(scrn->conn); xcb_xfixes_create_region(scrn->conn, region, 2, &rectangle); if (scrn->is_different_gpu) { u_box_origin_2d(back->width, back->height, &src_box); scrn->pipe->resource_copy_region(scrn->pipe, back->linear_texture, 0, 0, 0, 0, back->texture, 0, &src_box); scrn->pipe->flush(scrn->pipe, NULL, 0); } xshmfence_reset(back->shm_fence); back->busy = true; xcb_present_pixmap(scrn->conn, scrn->drawable, back->pixmap, (uint32_t)(++scrn->send_sbc), 0, region, 0, 0, None, None, back->sync_fence, options, scrn->next_msc, 0, 0, 0, NULL); xcb_flush(scrn->conn); return; }
static VkResult x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index, uint32_t target_msc) { struct x11_image *image = &chain->images[image_index]; assert(image_index < chain->image_count); uint32_t options = XCB_PRESENT_OPTION_NONE; int64_t divisor = 0; int64_t remainder = 0; if (chain->base.present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) options |= XCB_PRESENT_OPTION_ASYNC; xshmfence_reset(image->shm_fence); ++chain->send_sbc; xcb_void_cookie_t cookie = xcb_present_pixmap(chain->conn, chain->window, image->pixmap, (uint32_t) chain->send_sbc, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ XCB_NONE, /* target_crtc */ XCB_NONE, image->sync_fence, options, target_msc, divisor, remainder, 0, NULL); xcb_discard_reply(chain->conn, cookie.sequence); image->busy = true; xcb_flush(chain->conn); return VK_SUCCESS; }
static void vl_dri3_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, void *context_private, struct pipe_box *sub_box) { struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)context_private; uint32_t options = XCB_PRESENT_OPTION_NONE; struct vl_dri3_buffer *back; back = scrn->back_buffers[scrn->cur_back]; if (!back) return; if (scrn->flushed) { while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc) if (!dri3_wait_present_events(scrn)) return; } xshmfence_reset(back->shm_fence); back->busy = true; xcb_present_pixmap(scrn->conn, scrn->drawable, back->pixmap, (uint32_t)(++scrn->send_sbc), 0, 0, 0, 0, None, None, back->sync_fence, options, scrn->next_msc, 0, 0, 0, NULL); xcb_flush(scrn->conn); scrn->flushed = true; return; }
static inline void dri3_fence_reset(xcb_connection_t *c, struct loader_dri3_buffer *buffer) { xshmfence_reset(buffer->shm_fence); }