static __DRIbuffer * dri2_get_buffers(__DRIdrawable * driDrawable, int *width, int *height, unsigned int *attachments, int count, int *out_count, void *loaderPrivate) { struct dri2_egl_surface *dri2_surf = loaderPrivate; struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); xcb_dri2_dri2_buffer_t *buffers; xcb_dri2_get_buffers_reply_t *reply; xcb_dri2_get_buffers_cookie_t cookie; (void) driDrawable; cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, dri2_surf->drawable, count, count, attachments); reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL); buffers = xcb_dri2_get_buffers_buffers (reply); if (buffers == NULL) return NULL; *out_count = reply->count; dri2_surf->base.Width = *width = reply->width; dri2_surf->base.Height = *height = reply->height; dri2_process_buffers(dri2_surf, buffers, *out_count); free(reply); return dri2_surf->buffers; }
xcb_dri2_dri2_buffer_t * QDri2Context::backBuffer() { Q_D(QDri2Context); unsigned int backBufferAttachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT; xcb_dri2_get_buffers_cookie_t cookie = xcb_dri2_get_buffers_unchecked (d->xcbConnection(), d->xcbWindow(), 1, 1, &backBufferAttachment); xcb_dri2_get_buffers_reply_t *reply = xcb_dri2_get_buffers_reply (d->xcbConnection(), cookie, NULL); if (!reply) { qDebug() << "failed to get buffers reply"; return 0; } xcb_dri2_dri2_buffer_t *buffers = xcb_dri2_get_buffers_buffers (reply); if (!buffers) { qDebug() << "failed to get buffers"; return 0; } Q_ASSERT(reply->count == 1); delete reply; return buffers; }
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 _EGLImage * dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, EGLClientBuffer buffer, const EGLint *attr_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_image *dri2_img; unsigned int attachments[1]; xcb_drawable_t drawable; xcb_dri2_get_buffers_cookie_t buffers_cookie; xcb_dri2_get_buffers_reply_t *buffers_reply; xcb_dri2_dri2_buffer_t *buffers; xcb_get_geometry_cookie_t geometry_cookie; xcb_get_geometry_reply_t *geometry_reply; xcb_generic_error_t *error; int stride, format; (void) ctx; drawable = (xcb_drawable_t) (uintptr_t) buffer; xcb_dri2_create_drawable (dri2_dpy->conn, drawable); attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT; buffers_cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, drawable, 1, 1, attachments); geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable); buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, buffers_cookie, NULL); buffers = xcb_dri2_get_buffers_buffers (buffers_reply); if (buffers == NULL) { return NULL; } geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn, geometry_cookie, &error); if (geometry_reply == NULL || error != NULL) { _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); free(error); free(buffers_reply); return NULL; } switch (geometry_reply->depth) { case 16: format = __DRI_IMAGE_FORMAT_RGB565; break; case 24: format = __DRI_IMAGE_FORMAT_XRGB8888; break; case 32: format = __DRI_IMAGE_FORMAT_ARGB8888; break; default: _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr: unsupported pixmap depth"); free(buffers_reply); free(geometry_reply); return NULL; } dri2_img = malloc(sizeof *dri2_img); if (!dri2_img) { free(buffers_reply); free(geometry_reply); _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); return EGL_NO_IMAGE_KHR; } if (!_eglInitImage(&dri2_img->base, disp)) { free(buffers_reply); free(geometry_reply); free(dri2_img); return EGL_NO_IMAGE_KHR; } stride = buffers[0].pitch / buffers[0].cpp; dri2_img->dri_image = dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, buffers_reply->width, buffers_reply->height, format, buffers[0].name, stride, dri2_img); free(buffers_reply); free(geometry_reply); return &dri2_img->base; }
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; }