xref: /aosp_15_r20/external/igt-gpu-tools/overlay/x11/x11-overlay.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include <X11/Xlib.h>
26*d83cc019SAndroid Build Coastguard Worker #include <X11/extensions/Xvlib.h>
27*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
28*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
29*d83cc019SAndroid Build Coastguard Worker #include <cairo.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
31*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
32*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
33*d83cc019SAndroid Build Coastguard Worker #include <string.h>
34*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
35*d83cc019SAndroid Build Coastguard Worker 
36*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
37*d83cc019SAndroid Build Coastguard Worker #include <xf86drm.h>
38*d83cc019SAndroid Build Coastguard Worker #include <i915_drm.h>
39*d83cc019SAndroid Build Coastguard Worker #include "../overlay.h"
40*d83cc019SAndroid Build Coastguard Worker #include "dri2.h"
41*d83cc019SAndroid Build Coastguard Worker #include "position.h"
42*d83cc019SAndroid Build Coastguard Worker #include "rgb2yuv.h"
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker #ifndef ALIGN
45*d83cc019SAndroid Build Coastguard Worker #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
46*d83cc019SAndroid Build Coastguard Worker #endif
47*d83cc019SAndroid Build Coastguard Worker 
48*d83cc019SAndroid Build Coastguard Worker #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
49*d83cc019SAndroid Build Coastguard Worker #define FOURCC_RGB565 ((16 << 24) + ('B' << 16) + ('G' << 8) + 'R')
50*d83cc019SAndroid Build Coastguard Worker #define FOURCC_RGB888 ((24 << 24) + ('B' << 16) + ('G' << 8) + 'R')
51*d83cc019SAndroid Build Coastguard Worker 
52*d83cc019SAndroid Build Coastguard Worker struct x11_overlay {
53*d83cc019SAndroid Build Coastguard Worker 	struct overlay base;
54*d83cc019SAndroid Build Coastguard Worker 	Display *dpy;
55*d83cc019SAndroid Build Coastguard Worker 	GC gc;
56*d83cc019SAndroid Build Coastguard Worker 	XvPortID port;
57*d83cc019SAndroid Build Coastguard Worker 	XvImage *image;
58*d83cc019SAndroid Build Coastguard Worker 	void *map, *mem;
59*d83cc019SAndroid Build Coastguard Worker 	int size;
60*d83cc019SAndroid Build Coastguard Worker 	unsigned name;
61*d83cc019SAndroid Build Coastguard Worker 	int x, y;
62*d83cc019SAndroid Build Coastguard Worker 	int visible;
63*d83cc019SAndroid Build Coastguard Worker };
to_x11_overlay(struct overlay * o)64*d83cc019SAndroid Build Coastguard Worker static inline struct x11_overlay *to_x11_overlay(struct overlay *o)
65*d83cc019SAndroid Build Coastguard Worker {
66*d83cc019SAndroid Build Coastguard Worker 	return (struct x11_overlay *)o;
67*d83cc019SAndroid Build Coastguard Worker }
68*d83cc019SAndroid Build Coastguard Worker 
noop(Display * dpy,XErrorEvent * event)69*d83cc019SAndroid Build Coastguard Worker static int noop(Display *dpy, XErrorEvent *event)
70*d83cc019SAndroid Build Coastguard Worker {
71*d83cc019SAndroid Build Coastguard Worker 	return 0;
72*d83cc019SAndroid Build Coastguard Worker }
73*d83cc019SAndroid Build Coastguard Worker 
x11_overlay_show(struct overlay * overlay)74*d83cc019SAndroid Build Coastguard Worker static void x11_overlay_show(struct overlay *overlay)
75*d83cc019SAndroid Build Coastguard Worker {
76*d83cc019SAndroid Build Coastguard Worker 	struct x11_overlay *priv = to_x11_overlay(overlay);
77*d83cc019SAndroid Build Coastguard Worker 
78*d83cc019SAndroid Build Coastguard Worker 	if (priv->image->id == FOURCC_XVMC)
79*d83cc019SAndroid Build Coastguard Worker 		rgb2yuv(priv->base.surface, priv->image, priv->map);
80*d83cc019SAndroid Build Coastguard Worker 	else
81*d83cc019SAndroid Build Coastguard Worker 		memcpy(priv->map, priv->mem, priv->size);
82*d83cc019SAndroid Build Coastguard Worker 
83*d83cc019SAndroid Build Coastguard Worker 	if (!priv->visible) {
84*d83cc019SAndroid Build Coastguard Worker 		XvPutImage(priv->dpy, priv->port, DefaultRootWindow(priv->dpy),
85*d83cc019SAndroid Build Coastguard Worker 			   priv->gc, priv->image,
86*d83cc019SAndroid Build Coastguard Worker 			   0, 0,
87*d83cc019SAndroid Build Coastguard Worker 			   priv->image->width, priv->image->height,
88*d83cc019SAndroid Build Coastguard Worker 			   priv->x, priv->y,
89*d83cc019SAndroid Build Coastguard Worker 			   priv->image->width, priv->image->height);
90*d83cc019SAndroid Build Coastguard Worker 		XFlush(priv->dpy);
91*d83cc019SAndroid Build Coastguard Worker 		priv->visible = true;
92*d83cc019SAndroid Build Coastguard Worker 	}
93*d83cc019SAndroid Build Coastguard Worker }
94*d83cc019SAndroid Build Coastguard Worker 
x11_overlay_hide(struct overlay * overlay)95*d83cc019SAndroid Build Coastguard Worker static void x11_overlay_hide(struct overlay *overlay)
96*d83cc019SAndroid Build Coastguard Worker {
97*d83cc019SAndroid Build Coastguard Worker 	struct x11_overlay *priv = to_x11_overlay(overlay);
98*d83cc019SAndroid Build Coastguard Worker 	if (priv->visible) {
99*d83cc019SAndroid Build Coastguard Worker 		XClearWindow(priv->dpy, DefaultRootWindow(priv->dpy));
100*d83cc019SAndroid Build Coastguard Worker 		XFlush(priv->dpy);
101*d83cc019SAndroid Build Coastguard Worker 		priv->visible = false;
102*d83cc019SAndroid Build Coastguard Worker 	}
103*d83cc019SAndroid Build Coastguard Worker }
104*d83cc019SAndroid Build Coastguard Worker 
x11_overlay_destroy(void * data)105*d83cc019SAndroid Build Coastguard Worker static void x11_overlay_destroy(void *data)
106*d83cc019SAndroid Build Coastguard Worker {
107*d83cc019SAndroid Build Coastguard Worker 	struct x11_overlay *priv = data;
108*d83cc019SAndroid Build Coastguard Worker 	munmap(priv->map, priv->size);
109*d83cc019SAndroid Build Coastguard Worker 	free(priv->mem);
110*d83cc019SAndroid Build Coastguard Worker 	XCloseDisplay(priv->dpy);
111*d83cc019SAndroid Build Coastguard Worker 	free(priv);
112*d83cc019SAndroid Build Coastguard Worker }
113*d83cc019SAndroid Build Coastguard Worker 
114*d83cc019SAndroid Build Coastguard Worker static int x_error_count;
115*d83cc019SAndroid Build Coastguard Worker 
check_error_handler(Display * display,XErrorEvent * event)116*d83cc019SAndroid Build Coastguard Worker static int check_error_handler(Display *display, XErrorEvent *event)
117*d83cc019SAndroid Build Coastguard Worker {
118*d83cc019SAndroid Build Coastguard Worker 	x_error_count++;
119*d83cc019SAndroid Build Coastguard Worker 	return False; /* ignored */
120*d83cc019SAndroid Build Coastguard Worker }
121*d83cc019SAndroid Build Coastguard Worker 
122*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *
x11_overlay_create(struct config * config,int * width,int * height)123*d83cc019SAndroid Build Coastguard Worker x11_overlay_create(struct config *config, int *width, int *height)
124*d83cc019SAndroid Build Coastguard Worker {
125*d83cc019SAndroid Build Coastguard Worker 	Display *dpy;
126*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_t *surface;
127*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_create create;
128*d83cc019SAndroid Build Coastguard Worker 	struct drm_gem_flink flink;
129*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_mmap_gtt map;
130*d83cc019SAndroid Build Coastguard Worker 	struct x11_overlay *priv;
131*d83cc019SAndroid Build Coastguard Worker 	unsigned int count, i, j;
132*d83cc019SAndroid Build Coastguard Worker 	int fd, x, y, w, h;
133*d83cc019SAndroid Build Coastguard Worker 	XvAdaptorInfo *info;
134*d83cc019SAndroid Build Coastguard Worker 	XvImage *image;
135*d83cc019SAndroid Build Coastguard Worker 	XvPortID port = -1;
136*d83cc019SAndroid Build Coastguard Worker 	void *ptr, *mem;
137*d83cc019SAndroid Build Coastguard Worker 
138*d83cc019SAndroid Build Coastguard Worker 	dpy = XOpenDisplay(NULL);
139*d83cc019SAndroid Build Coastguard Worker 	if (dpy == NULL)
140*d83cc019SAndroid Build Coastguard Worker 		return NULL;
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	XSetErrorHandler(check_error_handler);
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 	ScreenOfDisplay(dpy, DefaultScreen(dpy));
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	fd = dri2_open(dpy);
147*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
148*d83cc019SAndroid Build Coastguard Worker 		goto err_dpy;
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker 	if (XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &count, &info) != Success)
151*d83cc019SAndroid Build Coastguard Worker 		goto err_fd;
152*d83cc019SAndroid Build Coastguard Worker 
153*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
154*d83cc019SAndroid Build Coastguard Worker 		unsigned long visual = 0;
155*d83cc019SAndroid Build Coastguard Worker 
156*d83cc019SAndroid Build Coastguard Worker 		if (info[i].num_ports != 1)
157*d83cc019SAndroid Build Coastguard Worker 			continue;
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < info[j].num_formats; j++) {
160*d83cc019SAndroid Build Coastguard Worker 			if (info[i].formats[j].depth == 24) {
161*d83cc019SAndroid Build Coastguard Worker 				visual = info[i].formats[j].visual_id;
162*d83cc019SAndroid Build Coastguard Worker 				break;
163*d83cc019SAndroid Build Coastguard Worker 			}
164*d83cc019SAndroid Build Coastguard Worker 		}
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 		if (visual == 0)
167*d83cc019SAndroid Build Coastguard Worker 			continue;
168*d83cc019SAndroid Build Coastguard Worker 
169*d83cc019SAndroid Build Coastguard Worker 		port = info[i].base_id;
170*d83cc019SAndroid Build Coastguard Worker 	}
171*d83cc019SAndroid Build Coastguard Worker 	XvFreeAdaptorInfo(info);
172*d83cc019SAndroid Build Coastguard Worker 	if (port == -1)
173*d83cc019SAndroid Build Coastguard Worker 		goto err_fd;
174*d83cc019SAndroid Build Coastguard Worker 
175*d83cc019SAndroid Build Coastguard Worker 	if (x_error_count)
176*d83cc019SAndroid Build Coastguard Worker 		goto err_fd;
177*d83cc019SAndroid Build Coastguard Worker 
178*d83cc019SAndroid Build Coastguard Worker 	XSetErrorHandler(noop);
179*d83cc019SAndroid Build Coastguard Worker 
180*d83cc019SAndroid Build Coastguard Worker 	x11_position(dpy, *width, *height, config, &x, &y, &w, &h);
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	image = XvCreateImage(dpy, port, FOURCC_RGB565, NULL, w, h);
183*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL)
184*d83cc019SAndroid Build Coastguard Worker 		image = XvCreateImage(dpy, port, FOURCC_RGB888, NULL, w, h);
185*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL) {
186*d83cc019SAndroid Build Coastguard Worker 		image = XvCreateImage(dpy, port, FOURCC_XVMC, NULL, w, h);
187*d83cc019SAndroid Build Coastguard Worker 		if (image->pitches[0] == 4) {
188*d83cc019SAndroid Build Coastguard Worker 			image->pitches[0] = ALIGN(image->width, 1024);
189*d83cc019SAndroid Build Coastguard Worker 			image->pitches[1] = ALIGN(image->width/2, 1024);
190*d83cc019SAndroid Build Coastguard Worker 			image->pitches[2] = ALIGN(image->width/2, 1024);
191*d83cc019SAndroid Build Coastguard Worker 			image->offsets[0] = 0;
192*d83cc019SAndroid Build Coastguard Worker 			image->offsets[1] = image->pitches[0] * image->height;
193*d83cc019SAndroid Build Coastguard Worker 			image->offsets[2] = image->offsets[1] + image->pitches[1] * image->height/2;
194*d83cc019SAndroid Build Coastguard Worker 		}
195*d83cc019SAndroid Build Coastguard Worker 		rgb2yuv_init();
196*d83cc019SAndroid Build Coastguard Worker 	}
197*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL)
198*d83cc019SAndroid Build Coastguard Worker 		goto err_fd;
199*d83cc019SAndroid Build Coastguard Worker 
200*d83cc019SAndroid Build Coastguard Worker 	switch (image->id) {
201*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_RGB888:
202*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_RGB565:
203*d83cc019SAndroid Build Coastguard Worker 		create.size = image->pitches[0] * image->height;
204*d83cc019SAndroid Build Coastguard Worker 		break;
205*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_XVMC:
206*d83cc019SAndroid Build Coastguard Worker 		create.size = image->pitches[0] * image->height;
207*d83cc019SAndroid Build Coastguard Worker 		create.size += image->pitches[1] * image->height;
208*d83cc019SAndroid Build Coastguard Worker 		break;
209*d83cc019SAndroid Build Coastguard Worker 	}
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	create.handle = 0;
212*d83cc019SAndroid Build Coastguard Worker 	create.size = ALIGN(create.size, 4096);
213*d83cc019SAndroid Build Coastguard Worker 	drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
214*d83cc019SAndroid Build Coastguard Worker 	if (create.handle == 0)
215*d83cc019SAndroid Build Coastguard Worker 		goto err_image;
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker 	flink.handle = create.handle;
218*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &flink))
219*d83cc019SAndroid Build Coastguard Worker 		goto err_create;
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 	map.handle = create.handle;
222*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &map))
223*d83cc019SAndroid Build Coastguard Worker 		goto err_create;
224*d83cc019SAndroid Build Coastguard Worker 
225*d83cc019SAndroid Build Coastguard Worker 	ptr = mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset);
226*d83cc019SAndroid Build Coastguard Worker 	if (ptr == (void *)-1)
227*d83cc019SAndroid Build Coastguard Worker 		goto err_create;
228*d83cc019SAndroid Build Coastguard Worker 
229*d83cc019SAndroid Build Coastguard Worker 	mem = malloc(create.size);
230*d83cc019SAndroid Build Coastguard Worker 	if (mem == NULL)
231*d83cc019SAndroid Build Coastguard Worker 		goto err_map;
232*d83cc019SAndroid Build Coastguard Worker 
233*d83cc019SAndroid Build Coastguard Worker 	switch (image->id) {
234*d83cc019SAndroid Build Coastguard Worker 	default:
235*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_RGB888:
236*d83cc019SAndroid Build Coastguard Worker 		i = CAIRO_FORMAT_RGB24;
237*d83cc019SAndroid Build Coastguard Worker 		j = image->pitches[0];
238*d83cc019SAndroid Build Coastguard Worker 		break;
239*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_RGB565:
240*d83cc019SAndroid Build Coastguard Worker 		i = CAIRO_FORMAT_RGB16_565;
241*d83cc019SAndroid Build Coastguard Worker 		j = image->pitches[0];
242*d83cc019SAndroid Build Coastguard Worker 		break;
243*d83cc019SAndroid Build Coastguard Worker 	case FOURCC_XVMC:
244*d83cc019SAndroid Build Coastguard Worker 		i = CAIRO_FORMAT_RGB16_565;
245*d83cc019SAndroid Build Coastguard Worker 		j = cairo_format_stride_for_width(i, image->width);
246*d83cc019SAndroid Build Coastguard Worker 		break;
247*d83cc019SAndroid Build Coastguard Worker 	}
248*d83cc019SAndroid Build Coastguard Worker 
249*d83cc019SAndroid Build Coastguard Worker 	surface = cairo_image_surface_create_for_data(mem, i, image->width, image->height, j);
250*d83cc019SAndroid Build Coastguard Worker 	if (cairo_surface_status(surface))
251*d83cc019SAndroid Build Coastguard Worker 		goto err_mem;
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker 	priv = malloc(sizeof(*priv));
254*d83cc019SAndroid Build Coastguard Worker 	if (priv == NULL)
255*d83cc019SAndroid Build Coastguard Worker 		goto err_surface;
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker 	priv->base.surface = surface;
258*d83cc019SAndroid Build Coastguard Worker 	priv->base.show = x11_overlay_show;
259*d83cc019SAndroid Build Coastguard Worker 	priv->base.hide = x11_overlay_hide;
260*d83cc019SAndroid Build Coastguard Worker 
261*d83cc019SAndroid Build Coastguard Worker 	priv->dpy = dpy;
262*d83cc019SAndroid Build Coastguard Worker 	priv->gc = XCreateGC(dpy, DefaultRootWindow(dpy), 0, NULL);
263*d83cc019SAndroid Build Coastguard Worker 	priv->port = port;
264*d83cc019SAndroid Build Coastguard Worker 	priv->map = ptr;
265*d83cc019SAndroid Build Coastguard Worker 	priv->mem = mem;
266*d83cc019SAndroid Build Coastguard Worker 	priv->size = create.size;
267*d83cc019SAndroid Build Coastguard Worker 	priv->name = flink.name;
268*d83cc019SAndroid Build Coastguard Worker 	priv->visible = false;
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 	priv->x = x;
271*d83cc019SAndroid Build Coastguard Worker 	priv->y = y;
272*d83cc019SAndroid Build Coastguard Worker 
273*d83cc019SAndroid Build Coastguard Worker 	priv->image = image;
274*d83cc019SAndroid Build Coastguard Worker 	priv->image->data = (void *)&priv->name;
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_set_user_data(surface, &overlay_key, priv, x11_overlay_destroy);
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker 	XvSetPortAttribute(dpy, port, XInternAtom(dpy, "XV_ALWAYS_ON_TOP", True), 1);
279*d83cc019SAndroid Build Coastguard Worker 
280*d83cc019SAndroid Build Coastguard Worker 	close(fd);
281*d83cc019SAndroid Build Coastguard Worker 
282*d83cc019SAndroid Build Coastguard Worker 	*width = image->width;
283*d83cc019SAndroid Build Coastguard Worker 	*height = image->height;
284*d83cc019SAndroid Build Coastguard Worker 	return surface;
285*d83cc019SAndroid Build Coastguard Worker 
286*d83cc019SAndroid Build Coastguard Worker err_surface:
287*d83cc019SAndroid Build Coastguard Worker 	cairo_surface_destroy(surface);
288*d83cc019SAndroid Build Coastguard Worker err_mem:
289*d83cc019SAndroid Build Coastguard Worker 	free(mem);
290*d83cc019SAndroid Build Coastguard Worker err_map:
291*d83cc019SAndroid Build Coastguard Worker 	munmap(ptr, create.size);
292*d83cc019SAndroid Build Coastguard Worker err_create:
293*d83cc019SAndroid Build Coastguard Worker 	drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle);
294*d83cc019SAndroid Build Coastguard Worker err_image:
295*d83cc019SAndroid Build Coastguard Worker err_fd:
296*d83cc019SAndroid Build Coastguard Worker 	close(fd);
297*d83cc019SAndroid Build Coastguard Worker err_dpy:
298*d83cc019SAndroid Build Coastguard Worker 	XCloseDisplay(dpy);
299*d83cc019SAndroid Build Coastguard Worker 	return NULL;
300*d83cc019SAndroid Build Coastguard Worker }
301*d83cc019SAndroid Build Coastguard Worker 
x11_overlay_stop(void)302*d83cc019SAndroid Build Coastguard Worker void x11_overlay_stop(void)
303*d83cc019SAndroid Build Coastguard Worker {
304*d83cc019SAndroid Build Coastguard Worker 	Display *dpy;
305*d83cc019SAndroid Build Coastguard Worker 	unsigned int count, i, j;
306*d83cc019SAndroid Build Coastguard Worker 	XvAdaptorInfo *info;
307*d83cc019SAndroid Build Coastguard Worker 	XvImage *image;
308*d83cc019SAndroid Build Coastguard Worker 	XvPortID port = -1;
309*d83cc019SAndroid Build Coastguard Worker 	uint32_t name;
310*d83cc019SAndroid Build Coastguard Worker 
311*d83cc019SAndroid Build Coastguard Worker 	dpy = XOpenDisplay(NULL);
312*d83cc019SAndroid Build Coastguard Worker 	if (dpy == NULL)
313*d83cc019SAndroid Build Coastguard Worker 		return;
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	if (XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &count, &info) != Success)
316*d83cc019SAndroid Build Coastguard Worker 		goto close;
317*d83cc019SAndroid Build Coastguard Worker 
318*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
319*d83cc019SAndroid Build Coastguard Worker 		unsigned long visual = 0;
320*d83cc019SAndroid Build Coastguard Worker 
321*d83cc019SAndroid Build Coastguard Worker 		if (info[i].num_ports != 1)
322*d83cc019SAndroid Build Coastguard Worker 			continue;
323*d83cc019SAndroid Build Coastguard Worker 
324*d83cc019SAndroid Build Coastguard Worker 		for (j = 0; j < info[j].num_formats; j++) {
325*d83cc019SAndroid Build Coastguard Worker 			if (info[i].formats[j].depth == 24) {
326*d83cc019SAndroid Build Coastguard Worker 				visual = info[i].formats[j].visual_id;
327*d83cc019SAndroid Build Coastguard Worker 				break;
328*d83cc019SAndroid Build Coastguard Worker 			}
329*d83cc019SAndroid Build Coastguard Worker 		}
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 		if (visual == 0)
332*d83cc019SAndroid Build Coastguard Worker 			continue;
333*d83cc019SAndroid Build Coastguard Worker 
334*d83cc019SAndroid Build Coastguard Worker 		port = info[i].base_id;
335*d83cc019SAndroid Build Coastguard Worker 	}
336*d83cc019SAndroid Build Coastguard Worker 	XvFreeAdaptorInfo(info);
337*d83cc019SAndroid Build Coastguard Worker 	if (port == -1)
338*d83cc019SAndroid Build Coastguard Worker 		goto close;
339*d83cc019SAndroid Build Coastguard Worker 
340*d83cc019SAndroid Build Coastguard Worker 	XSetErrorHandler(noop);
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 	image = XvCreateImage(dpy, port, FOURCC_RGB565, NULL, 16, 16);
343*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL)
344*d83cc019SAndroid Build Coastguard Worker 		image = XvCreateImage(dpy, port, FOURCC_RGB888, NULL, 16, 16);
345*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL)
346*d83cc019SAndroid Build Coastguard Worker 		image = XvCreateImage(dpy, port, FOURCC_XVMC, NULL, 16, 16);
347*d83cc019SAndroid Build Coastguard Worker 	if (image == NULL)
348*d83cc019SAndroid Build Coastguard Worker 		goto close;
349*d83cc019SAndroid Build Coastguard Worker 
350*d83cc019SAndroid Build Coastguard Worker 	name = 0;
351*d83cc019SAndroid Build Coastguard Worker 	image->data = (void *)&name;
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	XvPutImage(dpy, port, DefaultRootWindow(dpy),
354*d83cc019SAndroid Build Coastguard Worker 		   XCreateGC(dpy, DefaultRootWindow(dpy), 0, NULL), image,
355*d83cc019SAndroid Build Coastguard Worker 		   0, 0,
356*d83cc019SAndroid Build Coastguard Worker 		   1, 1,
357*d83cc019SAndroid Build Coastguard Worker 		   0, 0,
358*d83cc019SAndroid Build Coastguard Worker 		   1, 1);
359*d83cc019SAndroid Build Coastguard Worker 	XSync(dpy, True);
360*d83cc019SAndroid Build Coastguard Worker 
361*d83cc019SAndroid Build Coastguard Worker close:
362*d83cc019SAndroid Build Coastguard Worker 	XCloseDisplay(dpy);
363*d83cc019SAndroid Build Coastguard Worker }
364