dri3.c revision 42542f5f
142542f5fSchristos/* 242542f5fSchristos * Copyright (c) 2014 Intel Corporation 342542f5fSchristos * 442542f5fSchristos * Permission is hereby granted, free of charge, to any person obtaining a 542542f5fSchristos * copy of this software and associated documentation files (the "Software"), 642542f5fSchristos * to deal in the Software without restriction, including without limitation 742542f5fSchristos * the rights to use, copy, modify, merge, publish, distribute, sublicense, 842542f5fSchristos * and/or sell copies of the Software, and to permit persons to whom the 942542f5fSchristos * Software is furnished to do so, subject to the following conditions: 1042542f5fSchristos * 1142542f5fSchristos * The above copyright notice and this permission notice (including the next 1242542f5fSchristos * paragraph) shall be included in all copies or substantial portions of the 1342542f5fSchristos * Software. 1442542f5fSchristos * 1542542f5fSchristos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1642542f5fSchristos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1742542f5fSchristos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1842542f5fSchristos * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1942542f5fSchristos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2042542f5fSchristos * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2142542f5fSchristos * SOFTWARE. 2242542f5fSchristos * 2342542f5fSchristos */ 2442542f5fSchristos 2542542f5fSchristos#include <X11/Xlib.h> 2642542f5fSchristos#include <X11/Xlib-xcb.h> 2742542f5fSchristos#include <X11/xshmfence.h> 2842542f5fSchristos#include <xcb/xcb.h> 2942542f5fSchristos#include <xcb/dri3.h> 3042542f5fSchristos#include <xcb/sync.h> 3142542f5fSchristos#include <unistd.h> 3242542f5fSchristos 3342542f5fSchristos#include "dri3.h" 3442542f5fSchristos 3542542f5fSchristosPixmap dri3_create_pixmap(Display *dpy, 3642542f5fSchristos Drawable draw, 3742542f5fSchristos int width, int height, int depth, 3842542f5fSchristos int fd, int bpp, int stride, int size) 3942542f5fSchristos{ 4042542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 4142542f5fSchristos if (fd >= 0) { 4242542f5fSchristos xcb_pixmap_t pixmap = xcb_generate_id(c); 4342542f5fSchristos xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); 4442542f5fSchristos return pixmap; 4542542f5fSchristos } 4642542f5fSchristos return 0; 4742542f5fSchristos} 4842542f5fSchristos 4942542f5fSchristosint dri3_create_fd(Display *dpy, 5042542f5fSchristos Pixmap pixmap, 5142542f5fSchristos int *stride) 5242542f5fSchristos{ 5342542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 5442542f5fSchristos xcb_dri3_buffer_from_pixmap_cookie_t cookie; 5542542f5fSchristos xcb_dri3_buffer_from_pixmap_reply_t *reply; 5642542f5fSchristos 5742542f5fSchristos cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); 5842542f5fSchristos reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); 5942542f5fSchristos if (!reply) 6042542f5fSchristos return -1; 6142542f5fSchristos 6242542f5fSchristos if (reply->nfd != 1) 6342542f5fSchristos return -1; 6442542f5fSchristos 6542542f5fSchristos *stride = reply->stride; 6642542f5fSchristos return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; 6742542f5fSchristos} 6842542f5fSchristos 6942542f5fSchristosint dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) 7042542f5fSchristos{ 7142542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 7242542f5fSchristos struct dri3_fence f; 7342542f5fSchristos int fd; 7442542f5fSchristos 7542542f5fSchristos fd = xshmfence_alloc_shm(); 7642542f5fSchristos if (fd < 0) 7742542f5fSchristos return -1; 7842542f5fSchristos 7942542f5fSchristos f.addr = xshmfence_map_shm(fd); 8042542f5fSchristos if (f.addr == NULL) { 8142542f5fSchristos close(fd); 8242542f5fSchristos return -1; 8342542f5fSchristos } 8442542f5fSchristos 8542542f5fSchristos f.xid = xcb_generate_id(c); 8642542f5fSchristos xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); 8742542f5fSchristos 8842542f5fSchristos *fence = f; 8942542f5fSchristos return 0; 9042542f5fSchristos} 9142542f5fSchristos 9242542f5fSchristosvoid dri3_fence_sync(Display *dpy, struct dri3_fence *fence) 9342542f5fSchristos{ 9442542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 9542542f5fSchristos 9642542f5fSchristos xshmfence_reset(fence->addr); 9742542f5fSchristos 9842542f5fSchristos xcb_sync_trigger_fence(c, fence->xid); 9942542f5fSchristos xcb_flush(c); 10042542f5fSchristos 10142542f5fSchristos xshmfence_await(fence->addr); 10242542f5fSchristos} 10342542f5fSchristos 10442542f5fSchristosvoid dri3_fence_free(Display *dpy, struct dri3_fence *fence) 10542542f5fSchristos{ 10642542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 10742542f5fSchristos 10842542f5fSchristos xshmfence_unmap_shm(fence->addr); 10942542f5fSchristos xcb_sync_destroy_fence(c, fence->xid); 11042542f5fSchristos} 11142542f5fSchristos 11242542f5fSchristosint dri3_open__full(Display *dpy, Window root, unsigned provider) 11342542f5fSchristos{ 11442542f5fSchristos xcb_connection_t *c = XGetXCBConnection(dpy); 11542542f5fSchristos xcb_dri3_open_cookie_t cookie; 11642542f5fSchristos xcb_dri3_open_reply_t *reply; 11742542f5fSchristos 11842542f5fSchristos cookie = xcb_dri3_open(c, root, provider); 11942542f5fSchristos reply = xcb_dri3_open_reply(c, cookie, NULL); 12042542f5fSchristos 12142542f5fSchristos if (!reply) 12242542f5fSchristos return -1; 12342542f5fSchristos 12442542f5fSchristos if (reply->nfd != 1) 12542542f5fSchristos return -1; 12642542f5fSchristos 12742542f5fSchristos return xcb_dri3_open_reply_fds(c, reply)[0]; 12842542f5fSchristos} 12942542f5fSchristos 13042542f5fSchristosint dri3_open(Display *dpy) 13142542f5fSchristos{ 13242542f5fSchristos return dri3_open__full(dpy, RootWindow(dpy, DefaultScreen(dpy)), None); 13342542f5fSchristos} 134