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