1/* 2 * Copyright (c) 2014 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 */ 24 25#include <X11/Xlib.h> 26#include <X11/Xlib-xcb.h> 27#include <X11/xshmfence.h> 28#include <xcb/xcb.h> 29#include <xcb/dri3.h> 30#include <xcb/sync.h> 31#include <unistd.h> 32 33#include "dri3.h" 34 35Pixmap dri3_create_pixmap(Display *dpy, 36 Drawable draw, 37 int width, int height, int depth, 38 int fd, int bpp, int stride, int size) 39{ 40 xcb_connection_t *c = XGetXCBConnection(dpy); 41 if (fd >= 0) { 42 xcb_pixmap_t pixmap = xcb_generate_id(c); 43 xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); 44 return pixmap; 45 } 46 return 0; 47} 48 49int dri3_create_fd(Display *dpy, 50 Pixmap pixmap, 51 int *stride) 52{ 53 xcb_connection_t *c = XGetXCBConnection(dpy); 54 xcb_dri3_buffer_from_pixmap_cookie_t cookie; 55 xcb_dri3_buffer_from_pixmap_reply_t *reply; 56 57 cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); 58 reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); 59 if (!reply) 60 return -1; 61 62 if (reply->nfd != 1) 63 return -1; 64 65 *stride = reply->stride; 66 return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; 67} 68 69int dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) 70{ 71 xcb_connection_t *c = XGetXCBConnection(dpy); 72 struct dri3_fence f; 73 int fd; 74 75 fd = xshmfence_alloc_shm(); 76 if (fd < 0) 77 return -1; 78 79 f.addr = xshmfence_map_shm(fd); 80 if (f.addr == NULL) { 81 close(fd); 82 return -1; 83 } 84 85 f.xid = xcb_generate_id(c); 86 xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); 87 88 *fence = f; 89 return 0; 90} 91 92void dri3_fence_sync(Display *dpy, struct dri3_fence *fence) 93{ 94 xcb_connection_t *c = XGetXCBConnection(dpy); 95 96 xshmfence_reset(fence->addr); 97 98 xcb_sync_trigger_fence(c, fence->xid); 99 xcb_flush(c); 100 101 xshmfence_await(fence->addr); 102} 103 104void dri3_fence_free(Display *dpy, struct dri3_fence *fence) 105{ 106 xcb_connection_t *c = XGetXCBConnection(dpy); 107 108 xshmfence_unmap_shm(fence->addr); 109 xcb_sync_destroy_fence(c, fence->xid); 110} 111 112int dri3_open__full(Display *dpy, Window root, unsigned provider) 113{ 114 xcb_connection_t *c = XGetXCBConnection(dpy); 115 xcb_dri3_open_cookie_t cookie; 116 xcb_dri3_open_reply_t *reply; 117 118 cookie = xcb_dri3_open(c, root, provider); 119 reply = xcb_dri3_open_reply(c, cookie, NULL); 120 121 if (!reply) 122 return -1; 123 124 if (reply->nfd != 1) 125 return -1; 126 127 return xcb_dri3_open_reply_fds(c, reply)[0]; 128} 129 130int dri3_open(Display *dpy) 131{ 132 return dri3_open__full(dpy, RootWindow(dpy, DefaultScreen(dpy)), None); 133} 134