static void vl_dri2_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, void *context_private, struct pipe_box *sub_box) { struct vl_dri_screen *scrn = (struct vl_dri_screen *)context_private; uint32_t msc_hi, msc_lo; assert(screen); assert(resource); assert(context_private); free(vl_dri2_get_flush_reply(scrn)); msc_hi = scrn->next_msc >> 32; msc_lo = scrn->next_msc & 0xFFFFFFFF; scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable, msc_hi, msc_lo, 0, 0, 0, 0); scrn->wait_cookie = xcb_dri2_wait_sbc_unchecked(scrn->conn, scrn->drawable, 0, 0); scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable, 1, 1, attachments); scrn->flushed = true; scrn->current_buffer = !scrn->current_buffer; }
static void vl_dri2_destroy_drawable(struct vl_dri_screen *scrn) { xcb_void_cookie_t destroy_cookie; if (scrn->drawable) { free(vl_dri2_get_flush_reply(scrn)); destroy_cookie = xcb_dri2_destroy_drawable_checked(scrn->conn, scrn->drawable); /* ignore any error here, since the drawable can be destroyed long ago */ free(xcb_request_check(scrn->conn, destroy_cookie)); } }
vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable) { struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen; struct winsys_handle dri2_handle; struct pipe_resource template, *tex; xcb_dri2_get_buffers_reply_t *reply; xcb_dri2_dri2_buffer_t *buffers, *back_left; unsigned i; assert(scrn); vl_dri2_set_drawable(scrn, (Drawable)drawable); reply = vl_dri2_get_flush_reply(scrn); if (!reply) { xcb_dri2_get_buffers_cookie_t cookie; cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, (Drawable)drawable, 1, 1, attachments); reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL); } if (!reply) return NULL; buffers = xcb_dri2_get_buffers_buffers(reply); if (!buffers) { free(reply); return NULL; }
static struct pipe_resource * vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable) { struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen; struct winsys_handle dri2_handle; struct pipe_resource templ, *tex; xcb_dri2_get_buffers_reply_t *reply; xcb_dri2_dri2_buffer_t *buffers, *back_left; unsigned depth = ((xcb_screen_t *)(vscreen->xcb_screen))->root_depth; unsigned i; assert(scrn); vl_dri2_set_drawable(scrn, (Drawable)drawable); reply = vl_dri2_get_flush_reply(scrn); if (!reply) { xcb_dri2_get_buffers_cookie_t cookie; cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, (Drawable)drawable, 1, 1, attachments); reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL); } if (!reply) return NULL; buffers = xcb_dri2_get_buffers_buffers(reply); if (!buffers) { free(reply); return NULL; } for (i = 0; i < reply->count; ++i) { if (buffers[i].attachment == XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT) { back_left = &buffers[i]; break; } } if (i == reply->count) { free(reply); return NULL; } if (reply->width != scrn->width || reply->height != scrn->height) { vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); scrn->width = reply->width; scrn->height = reply->height; } else if (back_left->name != scrn->buffer_names[scrn->current_buffer]) { vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->current_buffer]); scrn->buffer_names[scrn->current_buffer] = back_left->name; } memset(&dri2_handle, 0, sizeof(dri2_handle)); dri2_handle.type = WINSYS_HANDLE_TYPE_SHARED; dri2_handle.handle = back_left->name; dri2_handle.stride = back_left->pitch; memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.format = vl_dri2_format_for_depth(vscreen, depth); templ.last_level = 0; templ.width0 = reply->width; templ.height0 = reply->height; templ.depth0 = 1; templ.array_size = 1; templ.usage = PIPE_USAGE_DEFAULT; templ.bind = PIPE_BIND_RENDER_TARGET; templ.flags = 0; tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &templ, &dri2_handle, PIPE_HANDLE_USAGE_READ_WRITE); free(reply); return tex; }