/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include #include #include #include #include #include #include #include "dri3.h" Pixmap dri3_create_pixmap(Display *dpy, Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size) { xcb_connection_t *c = XGetXCBConnection(dpy); if (fd >= 0) { xcb_pixmap_t pixmap = xcb_generate_id(c); xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); return pixmap; } return 0; } int dri3_create_fd(Display *dpy, Pixmap pixmap, int *stride) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_buffer_from_pixmap_cookie_t cookie; xcb_dri3_buffer_from_pixmap_reply_t *reply; cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; *stride = reply->stride; return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; } int dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); struct dri3_fence f; int fd; fd = xshmfence_alloc_shm(); if (fd < 0) return -1; f.addr = xshmfence_map_shm(fd); if (f.addr == NULL) { close(fd); return -1; } f.xid = xcb_generate_id(c); xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); *fence = f; return 0; } void dri3_fence_sync(Display *dpy, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); xshmfence_reset(fence->addr); xcb_sync_trigger_fence(c, fence->xid); xcb_flush(c); xshmfence_await(fence->addr); } void dri3_fence_free(Display *dpy, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); xshmfence_unmap_shm(fence->addr); xcb_sync_destroy_fence(c, fence->xid); } static void dri3_query_version(xcb_connection_t *c, int *major, int *minor) { xcb_dri3_query_version_reply_t *reply; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), NULL); if (reply != NULL) { *major = reply->major_version; *minor = reply->minor_version; free(reply); } } static int dri3_exists(xcb_connection_t *c) { const xcb_query_extension_reply_t *ext; int major, minor; major = minor = -1; ext = xcb_get_extension_data(c, &xcb_dri3_id); if (ext != NULL && ext->present) dri3_query_version(c, &major, &minor); return major >= 0; } int dri3_open__full(Display *dpy, Window root, unsigned provider) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_open_cookie_t cookie; xcb_dri3_open_reply_t *reply; if (!dri3_exists(c)) return -1; cookie = xcb_dri3_open(c, root, provider); reply = xcb_dri3_open_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; return xcb_dri3_open_reply_fds(c, reply)[0]; } int dri3_open(Display *dpy) { return dri3_open__full(dpy, RootWindow(dpy, DefaultScreen(dpy)), None); }