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 <sys/types.h>
26*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
27*d83cc019SAndroid Build Coastguard Worker #include <cairo.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker
35*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
36*d83cc019SAndroid Build Coastguard Worker #include <drm_fourcc.h>
37*d83cc019SAndroid Build Coastguard Worker #include <xf86drm.h>
38*d83cc019SAndroid Build Coastguard Worker #include <xf86drmMode.h>
39*d83cc019SAndroid Build Coastguard Worker #include <i915_drm.h>
40*d83cc019SAndroid Build Coastguard Worker #include "../overlay.h"
41*d83cc019SAndroid Build Coastguard Worker //#include "rgb2yuv.h"
42*d83cc019SAndroid Build Coastguard Worker
43*d83cc019SAndroid Build Coastguard Worker #ifndef ALIGN
44*d83cc019SAndroid Build Coastguard Worker #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
45*d83cc019SAndroid Build Coastguard Worker #endif
46*d83cc019SAndroid Build Coastguard Worker
47*d83cc019SAndroid Build Coastguard Worker struct kms_image {
48*d83cc019SAndroid Build Coastguard Worker uint32_t handle, name;
49*d83cc019SAndroid Build Coastguard Worker uint32_t format;
50*d83cc019SAndroid Build Coastguard Worker uint32_t width, height, stride;
51*d83cc019SAndroid Build Coastguard Worker uint32_t size;
52*d83cc019SAndroid Build Coastguard Worker void *map;
53*d83cc019SAndroid Build Coastguard Worker };
54*d83cc019SAndroid Build Coastguard Worker
55*d83cc019SAndroid Build Coastguard Worker struct kms_overlay {
56*d83cc019SAndroid Build Coastguard Worker struct overlay base;
57*d83cc019SAndroid Build Coastguard Worker struct kms_image image;
58*d83cc019SAndroid Build Coastguard Worker int fd;
59*d83cc019SAndroid Build Coastguard Worker int crtc;
60*d83cc019SAndroid Build Coastguard Worker
61*d83cc019SAndroid Build Coastguard Worker int x, y;
62*d83cc019SAndroid Build Coastguard Worker int visible;
63*d83cc019SAndroid Build Coastguard Worker
64*d83cc019SAndroid Build Coastguard Worker void *mem;
65*d83cc019SAndroid Build Coastguard Worker int size;
66*d83cc019SAndroid Build Coastguard Worker };
67*d83cc019SAndroid Build Coastguard Worker
to_kms_overlay(struct overlay * o)68*d83cc019SAndroid Build Coastguard Worker static inline struct kms_overlay *to_kms_overlay(struct overlay *o)
69*d83cc019SAndroid Build Coastguard Worker {
70*d83cc019SAndroid Build Coastguard Worker return (struct kms_overlay *)o;
71*d83cc019SAndroid Build Coastguard Worker }
72*d83cc019SAndroid Build Coastguard Worker
kms_create_fb(int fd,struct kms_image * image)73*d83cc019SAndroid Build Coastguard Worker static int kms_create_fb(int fd, struct kms_image *image)
74*d83cc019SAndroid Build Coastguard Worker {
75*d83cc019SAndroid Build Coastguard Worker uint32_t offsets[4], pitches[4], handles[4];
76*d83cc019SAndroid Build Coastguard Worker
77*d83cc019SAndroid Build Coastguard Worker handles[0] = image->handle;
78*d83cc019SAndroid Build Coastguard Worker pitches[0] = image->stride;
79*d83cc019SAndroid Build Coastguard Worker offsets[0] = 0;
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker return drmModeAddFB2(fd,
82*d83cc019SAndroid Build Coastguard Worker image->width, image->height, image->format,
83*d83cc019SAndroid Build Coastguard Worker handles, pitches, offsets,
84*d83cc019SAndroid Build Coastguard Worker &image->name, 0) == 0;
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker
attach_to_crtc(int fd,int crtc,int x,int y,struct kms_image * image)87*d83cc019SAndroid Build Coastguard Worker static int attach_to_crtc(int fd, int crtc, int x, int y, struct kms_image *image)
88*d83cc019SAndroid Build Coastguard Worker {
89*d83cc019SAndroid Build Coastguard Worker struct drm_mode_set_plane s;
90*d83cc019SAndroid Build Coastguard Worker
91*d83cc019SAndroid Build Coastguard Worker s.crtc_id = crtc;
92*d83cc019SAndroid Build Coastguard Worker s.fb_id = image->name;
93*d83cc019SAndroid Build Coastguard Worker s.flags = 0;
94*d83cc019SAndroid Build Coastguard Worker s.crtc_x = x;
95*d83cc019SAndroid Build Coastguard Worker s.crtc_y = y;
96*d83cc019SAndroid Build Coastguard Worker s.crtc_w = image->width;
97*d83cc019SAndroid Build Coastguard Worker s.crtc_h = image->height;
98*d83cc019SAndroid Build Coastguard Worker s.src_x = 0;
99*d83cc019SAndroid Build Coastguard Worker s.src_y = 0;
100*d83cc019SAndroid Build Coastguard Worker s.src_w = image->width << 16;
101*d83cc019SAndroid Build Coastguard Worker s.src_h = image->height << 16;
102*d83cc019SAndroid Build Coastguard Worker
103*d83cc019SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_MODE_SETPLANE, &s) == 0;
104*d83cc019SAndroid Build Coastguard Worker }
105*d83cc019SAndroid Build Coastguard Worker
detach_from_crtc(int fd,int crtc)106*d83cc019SAndroid Build Coastguard Worker static int detach_from_crtc(int fd, int crtc)
107*d83cc019SAndroid Build Coastguard Worker {
108*d83cc019SAndroid Build Coastguard Worker struct drm_mode_set_plane s;
109*d83cc019SAndroid Build Coastguard Worker
110*d83cc019SAndroid Build Coastguard Worker memset(&s, 0, sizeof(s));
111*d83cc019SAndroid Build Coastguard Worker s.crtc_id = crtc;
112*d83cc019SAndroid Build Coastguard Worker return drmIoctl(fd, DRM_IOCTL_MODE_SETPLANE, &s) == 0;
113*d83cc019SAndroid Build Coastguard Worker }
114*d83cc019SAndroid Build Coastguard Worker
kms_overlay_show(struct overlay * overlay)115*d83cc019SAndroid Build Coastguard Worker static void kms_overlay_show(struct overlay *overlay)
116*d83cc019SAndroid Build Coastguard Worker {
117*d83cc019SAndroid Build Coastguard Worker struct kms_overlay *priv = to_kms_overlay(overlay);
118*d83cc019SAndroid Build Coastguard Worker
119*d83cc019SAndroid Build Coastguard Worker memcpy(priv->image.map, priv->mem, priv->size);
120*d83cc019SAndroid Build Coastguard Worker
121*d83cc019SAndroid Build Coastguard Worker if (!priv->visible) {
122*d83cc019SAndroid Build Coastguard Worker attach_to_crtc(priv->fd, priv->crtc, priv->x, priv->y, &priv->image);
123*d83cc019SAndroid Build Coastguard Worker priv->visible = true;
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker }
126*d83cc019SAndroid Build Coastguard Worker
kms_overlay_hide(struct overlay * overlay)127*d83cc019SAndroid Build Coastguard Worker static void kms_overlay_hide(struct overlay *overlay)
128*d83cc019SAndroid Build Coastguard Worker {
129*d83cc019SAndroid Build Coastguard Worker struct kms_overlay *priv = to_kms_overlay(overlay);
130*d83cc019SAndroid Build Coastguard Worker
131*d83cc019SAndroid Build Coastguard Worker if (priv->visible) {
132*d83cc019SAndroid Build Coastguard Worker detach_from_crtc(priv->fd, priv->crtc);
133*d83cc019SAndroid Build Coastguard Worker priv->visible = false;
134*d83cc019SAndroid Build Coastguard Worker }
135*d83cc019SAndroid Build Coastguard Worker }
136*d83cc019SAndroid Build Coastguard Worker
kms_overlay_destroy(void * data)137*d83cc019SAndroid Build Coastguard Worker static void kms_overlay_destroy(void *data)
138*d83cc019SAndroid Build Coastguard Worker {
139*d83cc019SAndroid Build Coastguard Worker struct kms_overlay *priv = data;
140*d83cc019SAndroid Build Coastguard Worker drmIoctl(priv->fd, DRM_IOCTL_MODE_RMFB, &priv->image.name);
141*d83cc019SAndroid Build Coastguard Worker munmap(priv->image.map, priv->image.size);
142*d83cc019SAndroid Build Coastguard Worker free(priv->mem);
143*d83cc019SAndroid Build Coastguard Worker close(priv->fd);
144*d83cc019SAndroid Build Coastguard Worker free(priv);
145*d83cc019SAndroid Build Coastguard Worker }
146*d83cc019SAndroid Build Coastguard Worker
is_i915_device(int fd)147*d83cc019SAndroid Build Coastguard Worker static int is_i915_device(int fd)
148*d83cc019SAndroid Build Coastguard Worker {
149*d83cc019SAndroid Build Coastguard Worker drm_version_t version;
150*d83cc019SAndroid Build Coastguard Worker char name[5] = "";
151*d83cc019SAndroid Build Coastguard Worker
152*d83cc019SAndroid Build Coastguard Worker memset(&version, 0, sizeof(version));
153*d83cc019SAndroid Build Coastguard Worker version.name_len = 4;
154*d83cc019SAndroid Build Coastguard Worker version.name = name;
155*d83cc019SAndroid Build Coastguard Worker
156*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_VERSION, &version))
157*d83cc019SAndroid Build Coastguard Worker return 0;
158*d83cc019SAndroid Build Coastguard Worker
159*d83cc019SAndroid Build Coastguard Worker return strcmp("i915", name) == 0;
160*d83cc019SAndroid Build Coastguard Worker }
161*d83cc019SAndroid Build Coastguard Worker
check_device(int fd)162*d83cc019SAndroid Build Coastguard Worker static int check_device(int fd)
163*d83cc019SAndroid Build Coastguard Worker {
164*d83cc019SAndroid Build Coastguard Worker int ret;
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker /* Confirm that this is a i915.ko device with GEM/KMS enabled */
167*d83cc019SAndroid Build Coastguard Worker ret = is_i915_device(fd);
168*d83cc019SAndroid Build Coastguard Worker if (ret) {
169*d83cc019SAndroid Build Coastguard Worker struct drm_i915_getparam gp;
170*d83cc019SAndroid Build Coastguard Worker gp.param = I915_PARAM_HAS_GEM;
171*d83cc019SAndroid Build Coastguard Worker gp.value = &ret;
172*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
173*d83cc019SAndroid Build Coastguard Worker ret = 0;
174*d83cc019SAndroid Build Coastguard Worker }
175*d83cc019SAndroid Build Coastguard Worker if (ret) {
176*d83cc019SAndroid Build Coastguard Worker struct drm_mode_card_res res;
177*d83cc019SAndroid Build Coastguard Worker
178*d83cc019SAndroid Build Coastguard Worker memset(&res, 0, sizeof(res));
179*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
180*d83cc019SAndroid Build Coastguard Worker ret = 0;
181*d83cc019SAndroid Build Coastguard Worker }
182*d83cc019SAndroid Build Coastguard Worker
183*d83cc019SAndroid Build Coastguard Worker return ret;
184*d83cc019SAndroid Build Coastguard Worker }
185*d83cc019SAndroid Build Coastguard Worker
i915_open(void)186*d83cc019SAndroid Build Coastguard Worker static int i915_open(void)
187*d83cc019SAndroid Build Coastguard Worker {
188*d83cc019SAndroid Build Coastguard Worker char buf[80];
189*d83cc019SAndroid Build Coastguard Worker int fd, n;
190*d83cc019SAndroid Build Coastguard Worker
191*d83cc019SAndroid Build Coastguard Worker for (n = 0; n < 16; n++) {
192*d83cc019SAndroid Build Coastguard Worker sprintf(buf, "/dev/dri/card%d", n);
193*d83cc019SAndroid Build Coastguard Worker fd = open(buf, O_RDWR);
194*d83cc019SAndroid Build Coastguard Worker if (fd == -1)
195*d83cc019SAndroid Build Coastguard Worker continue;
196*d83cc019SAndroid Build Coastguard Worker
197*d83cc019SAndroid Build Coastguard Worker if (!check_device(fd)) {
198*d83cc019SAndroid Build Coastguard Worker close(fd);
199*d83cc019SAndroid Build Coastguard Worker continue;
200*d83cc019SAndroid Build Coastguard Worker }
201*d83cc019SAndroid Build Coastguard Worker return fd;
202*d83cc019SAndroid Build Coastguard Worker }
203*d83cc019SAndroid Build Coastguard Worker
204*d83cc019SAndroid Build Coastguard Worker return -1;
205*d83cc019SAndroid Build Coastguard Worker }
206*d83cc019SAndroid Build Coastguard Worker
config_get_pipe(struct config * config)207*d83cc019SAndroid Build Coastguard Worker static int config_get_pipe(struct config *config)
208*d83cc019SAndroid Build Coastguard Worker {
209*d83cc019SAndroid Build Coastguard Worker const char *str;
210*d83cc019SAndroid Build Coastguard Worker
211*d83cc019SAndroid Build Coastguard Worker str = config_get_value(config, "kms", "pipe");
212*d83cc019SAndroid Build Coastguard Worker if (str == NULL)
213*d83cc019SAndroid Build Coastguard Worker return 0;
214*d83cc019SAndroid Build Coastguard Worker
215*d83cc019SAndroid Build Coastguard Worker return atoi(str);
216*d83cc019SAndroid Build Coastguard Worker }
217*d83cc019SAndroid Build Coastguard Worker
218*d83cc019SAndroid Build Coastguard Worker cairo_surface_t *
kms_overlay_create(struct config * config,int * width,int * height)219*d83cc019SAndroid Build Coastguard Worker kms_overlay_create(struct config *config, int *width, int *height)
220*d83cc019SAndroid Build Coastguard Worker {
221*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_create create;
222*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_mmap_gtt map;
223*d83cc019SAndroid Build Coastguard Worker struct kms_overlay *priv;
224*d83cc019SAndroid Build Coastguard Worker drmModeResPtr kmode;
225*d83cc019SAndroid Build Coastguard Worker int i, pipe;
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker priv = malloc(sizeof(*priv));
228*d83cc019SAndroid Build Coastguard Worker if (priv == NULL)
229*d83cc019SAndroid Build Coastguard Worker return NULL;
230*d83cc019SAndroid Build Coastguard Worker
231*d83cc019SAndroid Build Coastguard Worker priv->fd = i915_open();
232*d83cc019SAndroid Build Coastguard Worker if (priv->fd == -1)
233*d83cc019SAndroid Build Coastguard Worker goto err_priv;
234*d83cc019SAndroid Build Coastguard Worker
235*d83cc019SAndroid Build Coastguard Worker kmode = drmModeGetResources(priv->fd);
236*d83cc019SAndroid Build Coastguard Worker if (kmode == 0)
237*d83cc019SAndroid Build Coastguard Worker goto err_fd;
238*d83cc019SAndroid Build Coastguard Worker
239*d83cc019SAndroid Build Coastguard Worker pipe = config_get_pipe(config);
240*d83cc019SAndroid Build Coastguard Worker priv->crtc = 0;
241*d83cc019SAndroid Build Coastguard Worker
242*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < kmode->count_crtcs; i++) {
243*d83cc019SAndroid Build Coastguard Worker struct drm_i915_get_pipe_from_crtc_id get_pipe;
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker get_pipe.pipe = 0;
246*d83cc019SAndroid Build Coastguard Worker get_pipe.crtc_id = kmode->crtcs[i];
247*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(priv->fd,
248*d83cc019SAndroid Build Coastguard Worker DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
249*d83cc019SAndroid Build Coastguard Worker &get_pipe)) {
250*d83cc019SAndroid Build Coastguard Worker continue;
251*d83cc019SAndroid Build Coastguard Worker }
252*d83cc019SAndroid Build Coastguard Worker
253*d83cc019SAndroid Build Coastguard Worker if (get_pipe.pipe != pipe)
254*d83cc019SAndroid Build Coastguard Worker continue;
255*d83cc019SAndroid Build Coastguard Worker
256*d83cc019SAndroid Build Coastguard Worker priv->crtc = get_pipe.crtc_id;
257*d83cc019SAndroid Build Coastguard Worker }
258*d83cc019SAndroid Build Coastguard Worker
259*d83cc019SAndroid Build Coastguard Worker if (priv->crtc == 0)
260*d83cc019SAndroid Build Coastguard Worker goto err_fd;
261*d83cc019SAndroid Build Coastguard Worker
262*d83cc019SAndroid Build Coastguard Worker priv->image.format = DRM_FORMAT_XRGB8888;
263*d83cc019SAndroid Build Coastguard Worker priv->image.width = ALIGN(*width, 4);
264*d83cc019SAndroid Build Coastguard Worker priv->image.height = ALIGN(*height, 2);
265*d83cc019SAndroid Build Coastguard Worker priv->image.stride = ALIGN(4*priv->image.width, 64);
266*d83cc019SAndroid Build Coastguard Worker priv->image.size = ALIGN(priv->image.stride * priv->image.height, 4096);
267*d83cc019SAndroid Build Coastguard Worker
268*d83cc019SAndroid Build Coastguard Worker create.handle = 0;
269*d83cc019SAndroid Build Coastguard Worker create.size = ALIGN(priv->image.size, 4096);
270*d83cc019SAndroid Build Coastguard Worker drmIoctl(priv->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
271*d83cc019SAndroid Build Coastguard Worker if (create.handle == 0)
272*d83cc019SAndroid Build Coastguard Worker goto err_fd;
273*d83cc019SAndroid Build Coastguard Worker
274*d83cc019SAndroid Build Coastguard Worker priv->image.handle = create.handle;
275*d83cc019SAndroid Build Coastguard Worker
276*d83cc019SAndroid Build Coastguard Worker if (!kms_create_fb(priv->fd, &priv->image))
277*d83cc019SAndroid Build Coastguard Worker goto err_create;
278*d83cc019SAndroid Build Coastguard Worker
279*d83cc019SAndroid Build Coastguard Worker /* XXX set color keys */
280*d83cc019SAndroid Build Coastguard Worker
281*d83cc019SAndroid Build Coastguard Worker if (!attach_to_crtc(priv->fd, priv->crtc, 0, 0, &priv->image))
282*d83cc019SAndroid Build Coastguard Worker goto err_fb;
283*d83cc019SAndroid Build Coastguard Worker detach_from_crtc(priv->fd, priv->crtc);
284*d83cc019SAndroid Build Coastguard Worker
285*d83cc019SAndroid Build Coastguard Worker map.handle = create.handle;
286*d83cc019SAndroid Build Coastguard Worker if (drmIoctl(priv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &map))
287*d83cc019SAndroid Build Coastguard Worker goto err_fb;
288*d83cc019SAndroid Build Coastguard Worker
289*d83cc019SAndroid Build Coastguard Worker priv->image.map = mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, map.offset);
290*d83cc019SAndroid Build Coastguard Worker if (priv->image.map == (void *)-1)
291*d83cc019SAndroid Build Coastguard Worker goto err_fb;
292*d83cc019SAndroid Build Coastguard Worker
293*d83cc019SAndroid Build Coastguard Worker priv->mem = malloc(create.size);
294*d83cc019SAndroid Build Coastguard Worker if (priv->mem == NULL)
295*d83cc019SAndroid Build Coastguard Worker goto err_map;
296*d83cc019SAndroid Build Coastguard Worker
297*d83cc019SAndroid Build Coastguard Worker priv->base.surface =
298*d83cc019SAndroid Build Coastguard Worker cairo_image_surface_create_for_data(priv->mem,
299*d83cc019SAndroid Build Coastguard Worker CAIRO_FORMAT_RGB24,
300*d83cc019SAndroid Build Coastguard Worker priv->image.width,
301*d83cc019SAndroid Build Coastguard Worker priv->image.height,
302*d83cc019SAndroid Build Coastguard Worker priv->image.stride);
303*d83cc019SAndroid Build Coastguard Worker if (cairo_surface_status(priv->base.surface))
304*d83cc019SAndroid Build Coastguard Worker goto err_mem;
305*d83cc019SAndroid Build Coastguard Worker
306*d83cc019SAndroid Build Coastguard Worker priv->base.show = kms_overlay_show;
307*d83cc019SAndroid Build Coastguard Worker priv->base.hide = kms_overlay_hide;
308*d83cc019SAndroid Build Coastguard Worker
309*d83cc019SAndroid Build Coastguard Worker priv->visible = false;
310*d83cc019SAndroid Build Coastguard Worker priv->x = 0;
311*d83cc019SAndroid Build Coastguard Worker priv->y = 0;
312*d83cc019SAndroid Build Coastguard Worker
313*d83cc019SAndroid Build Coastguard Worker cairo_surface_set_user_data(priv->base.surface, &overlay_key, priv, kms_overlay_destroy);
314*d83cc019SAndroid Build Coastguard Worker
315*d83cc019SAndroid Build Coastguard Worker *width = priv->image.width;
316*d83cc019SAndroid Build Coastguard Worker *height = priv->image.height;
317*d83cc019SAndroid Build Coastguard Worker
318*d83cc019SAndroid Build Coastguard Worker drmIoctl(priv->fd, DRM_IOCTL_GEM_CLOSE, &create.handle);
319*d83cc019SAndroid Build Coastguard Worker return priv->base.surface;
320*d83cc019SAndroid Build Coastguard Worker
321*d83cc019SAndroid Build Coastguard Worker err_mem:
322*d83cc019SAndroid Build Coastguard Worker free(priv->mem);
323*d83cc019SAndroid Build Coastguard Worker err_map:
324*d83cc019SAndroid Build Coastguard Worker munmap(priv->image.map, create.size);
325*d83cc019SAndroid Build Coastguard Worker err_fb:
326*d83cc019SAndroid Build Coastguard Worker drmIoctl(priv->fd, DRM_IOCTL_MODE_RMFB, &priv->image.name);
327*d83cc019SAndroid Build Coastguard Worker err_create:
328*d83cc019SAndroid Build Coastguard Worker drmIoctl(priv->fd, DRM_IOCTL_GEM_CLOSE, &create.handle);
329*d83cc019SAndroid Build Coastguard Worker err_fd:
330*d83cc019SAndroid Build Coastguard Worker close(priv->fd);
331*d83cc019SAndroid Build Coastguard Worker err_priv:
332*d83cc019SAndroid Build Coastguard Worker free(priv);
333*d83cc019SAndroid Build Coastguard Worker return NULL;
334*d83cc019SAndroid Build Coastguard Worker }
335