xref: /aosp_15_r20/external/libva/va/wayland/va_wayland_drm.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
1*54e60f84SAndroid Build Coastguard Worker /*
2*54e60f84SAndroid Build Coastguard Worker  * va_wayland_drm.c - Wayland/DRM helpers
3*54e60f84SAndroid Build Coastguard Worker  *
4*54e60f84SAndroid Build Coastguard Worker  * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
5*54e60f84SAndroid Build Coastguard Worker  * Copyright (c) 2023 Emil Velikov
6*54e60f84SAndroid Build Coastguard Worker  *
7*54e60f84SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*54e60f84SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
9*54e60f84SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
10*54e60f84SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
11*54e60f84SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
12*54e60f84SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
13*54e60f84SAndroid Build Coastguard Worker  * the following conditions:
14*54e60f84SAndroid Build Coastguard Worker  *
15*54e60f84SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
16*54e60f84SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
17*54e60f84SAndroid Build Coastguard Worker  * of the Software.
18*54e60f84SAndroid Build Coastguard Worker  *
19*54e60f84SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*54e60f84SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*54e60f84SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*54e60f84SAndroid Build Coastguard Worker  * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
23*54e60f84SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*54e60f84SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*54e60f84SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*54e60f84SAndroid Build Coastguard Worker  */
27*54e60f84SAndroid Build Coastguard Worker 
28*54e60f84SAndroid Build Coastguard Worker #include "sysdeps.h"
29*54e60f84SAndroid Build Coastguard Worker #include <unistd.h>
30*54e60f84SAndroid Build Coastguard Worker #include <errno.h>
31*54e60f84SAndroid Build Coastguard Worker #include <fcntl.h>
32*54e60f84SAndroid Build Coastguard Worker #include <dlfcn.h>
33*54e60f84SAndroid Build Coastguard Worker #include <sys/stat.h>
34*54e60f84SAndroid Build Coastguard Worker #include <xf86drm.h>
35*54e60f84SAndroid Build Coastguard Worker #include "va_drmcommon.h"
36*54e60f84SAndroid Build Coastguard Worker #include "drm/va_drm_utils.h"
37*54e60f84SAndroid Build Coastguard Worker #include "va_wayland_drm.h"
38*54e60f84SAndroid Build Coastguard Worker #include "va_wayland_private.h"
39*54e60f84SAndroid Build Coastguard Worker #include "wayland-drm-client-protocol.h"
40*54e60f84SAndroid Build Coastguard Worker 
41*54e60f84SAndroid Build Coastguard Worker typedef struct va_wayland_drm_context {
42*54e60f84SAndroid Build Coastguard Worker     struct va_wayland_context   base;
43*54e60f84SAndroid Build Coastguard Worker     struct wl_event_queue      *queue;
44*54e60f84SAndroid Build Coastguard Worker     struct wl_drm              *drm;
45*54e60f84SAndroid Build Coastguard Worker     uint32_t                    drm_name;
46*54e60f84SAndroid Build Coastguard Worker     struct wl_registry         *registry;
47*54e60f84SAndroid Build Coastguard Worker     unsigned int                is_authenticated        : 1;
48*54e60f84SAndroid Build Coastguard Worker } VADisplayContextWaylandDRM;
49*54e60f84SAndroid Build Coastguard Worker 
50*54e60f84SAndroid Build Coastguard Worker static void
drm_handle_device(void * data,struct wl_drm * drm,const char * device)51*54e60f84SAndroid Build Coastguard Worker drm_handle_device(void *data, struct wl_drm *drm, const char *device)
52*54e60f84SAndroid Build Coastguard Worker {
53*54e60f84SAndroid Build Coastguard Worker     VADisplayContextP const pDisplayContext = data;
54*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
55*54e60f84SAndroid Build Coastguard Worker     VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
56*54e60f84SAndroid Build Coastguard Worker     struct drm_state * const drm_state = ctx->drm_state;
57*54e60f84SAndroid Build Coastguard Worker     drm_magic_t magic;
58*54e60f84SAndroid Build Coastguard Worker     struct stat st;
59*54e60f84SAndroid Build Coastguard Worker     int fd = -1;
60*54e60f84SAndroid Build Coastguard Worker 
61*54e60f84SAndroid Build Coastguard Worker     fd = open(device, O_RDWR);
62*54e60f84SAndroid Build Coastguard Worker     if (fd < 0) {
63*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("failed to open %s: %s (errno %d)",
64*54e60f84SAndroid Build Coastguard Worker                          device, strerror(errno), errno);
65*54e60f84SAndroid Build Coastguard Worker         return;
66*54e60f84SAndroid Build Coastguard Worker     }
67*54e60f84SAndroid Build Coastguard Worker 
68*54e60f84SAndroid Build Coastguard Worker     if (fstat(fd, &st) < 0) {
69*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("failed to identify %s: %s (errno %d)",
70*54e60f84SAndroid Build Coastguard Worker                          device, strerror(errno), errno);
71*54e60f84SAndroid Build Coastguard Worker         close(fd);
72*54e60f84SAndroid Build Coastguard Worker         return;
73*54e60f84SAndroid Build Coastguard Worker     }
74*54e60f84SAndroid Build Coastguard Worker 
75*54e60f84SAndroid Build Coastguard Worker     if (!S_ISCHR(st.st_mode)) {
76*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("%s is not a device", device);
77*54e60f84SAndroid Build Coastguard Worker         close(fd);
78*54e60f84SAndroid Build Coastguard Worker         return;
79*54e60f84SAndroid Build Coastguard Worker     }
80*54e60f84SAndroid Build Coastguard Worker 
81*54e60f84SAndroid Build Coastguard Worker     drm_state->fd = fd;
82*54e60f84SAndroid Build Coastguard Worker 
83*54e60f84SAndroid Build Coastguard Worker     int type = drmGetNodeTypeFromFd(fd);
84*54e60f84SAndroid Build Coastguard Worker     if (type != DRM_NODE_RENDER) {
85*54e60f84SAndroid Build Coastguard Worker         drmGetMagic(drm_state->fd, &magic);
86*54e60f84SAndroid Build Coastguard Worker         wl_drm_authenticate(wl_drm_ctx->drm, magic);
87*54e60f84SAndroid Build Coastguard Worker     } else {
88*54e60f84SAndroid Build Coastguard Worker         wl_drm_ctx->is_authenticated = 1;
89*54e60f84SAndroid Build Coastguard Worker         drm_state->auth_type         = VA_DRM_AUTH_CUSTOM;
90*54e60f84SAndroid Build Coastguard Worker     }
91*54e60f84SAndroid Build Coastguard Worker }
92*54e60f84SAndroid Build Coastguard Worker 
93*54e60f84SAndroid Build Coastguard Worker static void
drm_handle_format(void * data,struct wl_drm * drm,uint32_t format)94*54e60f84SAndroid Build Coastguard Worker drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
95*54e60f84SAndroid Build Coastguard Worker {
96*54e60f84SAndroid Build Coastguard Worker }
97*54e60f84SAndroid Build Coastguard Worker 
98*54e60f84SAndroid Build Coastguard Worker static void
drm_handle_authenticated(void * data,struct wl_drm * drm)99*54e60f84SAndroid Build Coastguard Worker drm_handle_authenticated(void *data, struct wl_drm *drm)
100*54e60f84SAndroid Build Coastguard Worker {
101*54e60f84SAndroid Build Coastguard Worker     VADisplayContextP const pDisplayContext = data;
102*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
103*54e60f84SAndroid Build Coastguard Worker     VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
104*54e60f84SAndroid Build Coastguard Worker     struct drm_state * const drm_state = ctx->drm_state;
105*54e60f84SAndroid Build Coastguard Worker 
106*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->is_authenticated = 1;
107*54e60f84SAndroid Build Coastguard Worker     drm_state->auth_type         = VA_DRM_AUTH_CUSTOM;
108*54e60f84SAndroid Build Coastguard Worker }
109*54e60f84SAndroid Build Coastguard Worker 
110*54e60f84SAndroid Build Coastguard Worker static void
drm_handle_capabilities(void * data,struct wl_drm * wl_drm,uint32_t value)111*54e60f84SAndroid Build Coastguard Worker drm_handle_capabilities(void *data, struct wl_drm *wl_drm, uint32_t value)
112*54e60f84SAndroid Build Coastguard Worker {
113*54e60f84SAndroid Build Coastguard Worker     VADisplayContextP const pDisplayContext = data;
114*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
115*54e60f84SAndroid Build Coastguard Worker     struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
116*54e60f84SAndroid Build Coastguard Worker 
117*54e60f84SAndroid Build Coastguard Worker     vtable->has_prime_sharing = !!(value & WL_DRM_CAPABILITY_PRIME);
118*54e60f84SAndroid Build Coastguard Worker }
119*54e60f84SAndroid Build Coastguard Worker 
120*54e60f84SAndroid Build Coastguard Worker static const struct wl_drm_listener drm_listener = {
121*54e60f84SAndroid Build Coastguard Worker     drm_handle_device,
122*54e60f84SAndroid Build Coastguard Worker     drm_handle_format,
123*54e60f84SAndroid Build Coastguard Worker     drm_handle_authenticated,
124*54e60f84SAndroid Build Coastguard Worker     drm_handle_capabilities,
125*54e60f84SAndroid Build Coastguard Worker };
126*54e60f84SAndroid Build Coastguard Worker 
127*54e60f84SAndroid Build Coastguard Worker static VAStatus
va_DisplayContextGetDriverNames(VADisplayContextP pDisplayContext,char ** drivers,unsigned * num_drivers)128*54e60f84SAndroid Build Coastguard Worker va_DisplayContextGetDriverNames(
129*54e60f84SAndroid Build Coastguard Worker     VADisplayContextP pDisplayContext,
130*54e60f84SAndroid Build Coastguard Worker     char            **drivers,
131*54e60f84SAndroid Build Coastguard Worker     unsigned         *num_drivers
132*54e60f84SAndroid Build Coastguard Worker )
133*54e60f84SAndroid Build Coastguard Worker {
134*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
135*54e60f84SAndroid Build Coastguard Worker 
136*54e60f84SAndroid Build Coastguard Worker     return VA_DRM_GetDriverNames(ctx, drivers, num_drivers);
137*54e60f84SAndroid Build Coastguard Worker }
138*54e60f84SAndroid Build Coastguard Worker 
139*54e60f84SAndroid Build Coastguard Worker void
va_wayland_drm_destroy(VADisplayContextP pDisplayContext)140*54e60f84SAndroid Build Coastguard Worker va_wayland_drm_destroy(VADisplayContextP pDisplayContext)
141*54e60f84SAndroid Build Coastguard Worker {
142*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
143*54e60f84SAndroid Build Coastguard Worker     struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
144*54e60f84SAndroid Build Coastguard Worker     struct drm_state * const drm_state = ctx->drm_state;
145*54e60f84SAndroid Build Coastguard Worker     struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
146*54e60f84SAndroid Build Coastguard Worker 
147*54e60f84SAndroid Build Coastguard Worker     vtable->has_prime_sharing = 0;
148*54e60f84SAndroid Build Coastguard Worker     vtable->wl_interface = NULL;
149*54e60f84SAndroid Build Coastguard Worker 
150*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->is_authenticated = 0;
151*54e60f84SAndroid Build Coastguard Worker 
152*54e60f84SAndroid Build Coastguard Worker     if (drm_state) {
153*54e60f84SAndroid Build Coastguard Worker         if (drm_state->fd >= 0) {
154*54e60f84SAndroid Build Coastguard Worker             close(drm_state->fd);
155*54e60f84SAndroid Build Coastguard Worker             drm_state->fd = -1;
156*54e60f84SAndroid Build Coastguard Worker         }
157*54e60f84SAndroid Build Coastguard Worker         free(ctx->drm_state);
158*54e60f84SAndroid Build Coastguard Worker         ctx->drm_state = NULL;
159*54e60f84SAndroid Build Coastguard Worker     }
160*54e60f84SAndroid Build Coastguard Worker }
161*54e60f84SAndroid Build Coastguard Worker 
162*54e60f84SAndroid Build Coastguard Worker static void
registry_handle_global(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)163*54e60f84SAndroid Build Coastguard Worker registry_handle_global(
164*54e60f84SAndroid Build Coastguard Worker     void               *data,
165*54e60f84SAndroid Build Coastguard Worker     struct wl_registry *registry,
166*54e60f84SAndroid Build Coastguard Worker     uint32_t            name,
167*54e60f84SAndroid Build Coastguard Worker     const char         *interface,
168*54e60f84SAndroid Build Coastguard Worker     uint32_t            version
169*54e60f84SAndroid Build Coastguard Worker )
170*54e60f84SAndroid Build Coastguard Worker {
171*54e60f84SAndroid Build Coastguard Worker     VADisplayContextP const pDisplayContext = data;
172*54e60f84SAndroid Build Coastguard Worker     struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
173*54e60f84SAndroid Build Coastguard Worker 
174*54e60f84SAndroid Build Coastguard Worker     if (strcmp(interface, "wl_drm") == 0) {
175*54e60f84SAndroid Build Coastguard Worker         /* bind to at most version 2, but also support version 1 if
176*54e60f84SAndroid Build Coastguard Worker          * compositor does not have v2
177*54e60f84SAndroid Build Coastguard Worker          */
178*54e60f84SAndroid Build Coastguard Worker         wl_drm_ctx->drm_name = name;
179*54e60f84SAndroid Build Coastguard Worker         wl_drm_ctx->drm =
180*54e60f84SAndroid Build Coastguard Worker             wl_registry_bind(wl_drm_ctx->registry, name, &wl_drm_interface,
181*54e60f84SAndroid Build Coastguard Worker                              (version < 2) ? version : 2);
182*54e60f84SAndroid Build Coastguard Worker 
183*54e60f84SAndroid Build Coastguard Worker         if (wl_drm_ctx->drm
184*54e60f84SAndroid Build Coastguard Worker             && wl_drm_add_listener(wl_drm_ctx->drm, &drm_listener, pDisplayContext) != 0) {
185*54e60f84SAndroid Build Coastguard Worker             va_wayland_error("could not add listener to wl_drm");
186*54e60f84SAndroid Build Coastguard Worker             wl_drm_destroy(wl_drm_ctx->drm);
187*54e60f84SAndroid Build Coastguard Worker             wl_drm_ctx->drm = NULL;
188*54e60f84SAndroid Build Coastguard Worker         }
189*54e60f84SAndroid Build Coastguard Worker     }
190*54e60f84SAndroid Build Coastguard Worker }
191*54e60f84SAndroid Build Coastguard Worker 
192*54e60f84SAndroid Build Coastguard Worker static void
registry_handle_global_remove(void * data,struct wl_registry * registry,uint32_t name)193*54e60f84SAndroid Build Coastguard Worker registry_handle_global_remove(
194*54e60f84SAndroid Build Coastguard Worker     void               *data,
195*54e60f84SAndroid Build Coastguard Worker     struct wl_registry *registry,
196*54e60f84SAndroid Build Coastguard Worker     uint32_t            name
197*54e60f84SAndroid Build Coastguard Worker )
198*54e60f84SAndroid Build Coastguard Worker {
199*54e60f84SAndroid Build Coastguard Worker     struct va_wayland_drm_context *wl_drm_ctx = data;
200*54e60f84SAndroid Build Coastguard Worker 
201*54e60f84SAndroid Build Coastguard Worker     if (wl_drm_ctx->drm && name == wl_drm_ctx->drm_name) {
202*54e60f84SAndroid Build Coastguard Worker         wl_drm_destroy(wl_drm_ctx->drm);
203*54e60f84SAndroid Build Coastguard Worker         wl_drm_ctx->drm = NULL;
204*54e60f84SAndroid Build Coastguard Worker     }
205*54e60f84SAndroid Build Coastguard Worker }
206*54e60f84SAndroid Build Coastguard Worker 
207*54e60f84SAndroid Build Coastguard Worker static const struct wl_registry_listener registry_listener = {
208*54e60f84SAndroid Build Coastguard Worker     registry_handle_global,
209*54e60f84SAndroid Build Coastguard Worker     registry_handle_global_remove
210*54e60f84SAndroid Build Coastguard Worker };
211*54e60f84SAndroid Build Coastguard Worker 
212*54e60f84SAndroid Build Coastguard Worker static bool
wayland_roundtrip_queue(struct wl_display * display,struct wl_event_queue * queue)213*54e60f84SAndroid Build Coastguard Worker wayland_roundtrip_queue(struct wl_display *display,
214*54e60f84SAndroid Build Coastguard Worker                         struct wl_event_queue *queue)
215*54e60f84SAndroid Build Coastguard Worker {
216*54e60f84SAndroid Build Coastguard Worker     if (wl_display_roundtrip_queue(display, queue) < 0) {
217*54e60f84SAndroid Build Coastguard Worker         int err = wl_display_get_error(display);
218*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("Wayland roundtrip error: %s (errno %d)", strerror(err), err);
219*54e60f84SAndroid Build Coastguard Worker         return false;
220*54e60f84SAndroid Build Coastguard Worker     } else {
221*54e60f84SAndroid Build Coastguard Worker         return true;
222*54e60f84SAndroid Build Coastguard Worker     }
223*54e60f84SAndroid Build Coastguard Worker }
224*54e60f84SAndroid Build Coastguard Worker 
225*54e60f84SAndroid Build Coastguard Worker bool
va_wayland_drm_create(VADisplayContextP pDisplayContext)226*54e60f84SAndroid Build Coastguard Worker va_wayland_drm_create(VADisplayContextP pDisplayContext)
227*54e60f84SAndroid Build Coastguard Worker {
228*54e60f84SAndroid Build Coastguard Worker     bool result = false;
229*54e60f84SAndroid Build Coastguard Worker     VADriverContextP const ctx = pDisplayContext->pDriverContext;
230*54e60f84SAndroid Build Coastguard Worker     struct va_wayland_drm_context *wl_drm_ctx;
231*54e60f84SAndroid Build Coastguard Worker     struct drm_state *drm_state;
232*54e60f84SAndroid Build Coastguard Worker     struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
233*54e60f84SAndroid Build Coastguard Worker     struct wl_display *wrapped_display = NULL;
234*54e60f84SAndroid Build Coastguard Worker 
235*54e60f84SAndroid Build Coastguard Worker     vtable->wl_interface = NULL;
236*54e60f84SAndroid Build Coastguard Worker 
237*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx = malloc(sizeof(*wl_drm_ctx));
238*54e60f84SAndroid Build Coastguard Worker     if (!wl_drm_ctx) {
239*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not allocate wl_drm_ctx");
240*54e60f84SAndroid Build Coastguard Worker         goto end;
241*54e60f84SAndroid Build Coastguard Worker     }
242*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->base.destroy            = va_wayland_drm_destroy;
243*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->queue                   = NULL;
244*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->drm                     = NULL;
245*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->registry                = NULL;
246*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->is_authenticated        = 0;
247*54e60f84SAndroid Build Coastguard Worker     pDisplayContext->opaque             = wl_drm_ctx;
248*54e60f84SAndroid Build Coastguard Worker     pDisplayContext->vaGetDriverNames    = va_DisplayContextGetDriverNames;
249*54e60f84SAndroid Build Coastguard Worker 
250*54e60f84SAndroid Build Coastguard Worker     drm_state = calloc(1, sizeof(struct drm_state));
251*54e60f84SAndroid Build Coastguard Worker     if (!drm_state) {
252*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not allocate drm_state");
253*54e60f84SAndroid Build Coastguard Worker         goto end;
254*54e60f84SAndroid Build Coastguard Worker     }
255*54e60f84SAndroid Build Coastguard Worker     drm_state->fd        = -1;
256*54e60f84SAndroid Build Coastguard Worker     drm_state->auth_type = 0;
257*54e60f84SAndroid Build Coastguard Worker     ctx->drm_state       = drm_state;
258*54e60f84SAndroid Build Coastguard Worker     vtable->has_prime_sharing = 0;
259*54e60f84SAndroid Build Coastguard Worker 
260*54e60f84SAndroid Build Coastguard Worker     /* Use wrapped wl_display with private event queue to prevent
261*54e60f84SAndroid Build Coastguard Worker      * thread safety issues with applications that e.g. run an event pump
262*54e60f84SAndroid Build Coastguard Worker      * parallel to libva initialization.
263*54e60f84SAndroid Build Coastguard Worker      * Using the default queue, events might get lost and crashes occur
264*54e60f84SAndroid Build Coastguard Worker      * because wl_display_roundtrip is not thread-safe with respect to the
265*54e60f84SAndroid Build Coastguard Worker      * same queue.
266*54e60f84SAndroid Build Coastguard Worker      */
267*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->queue = wl_display_create_queue(ctx->native_dpy);
268*54e60f84SAndroid Build Coastguard Worker     if (!wl_drm_ctx->queue) {
269*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not create Wayland event queue");
270*54e60f84SAndroid Build Coastguard Worker         goto end;
271*54e60f84SAndroid Build Coastguard Worker     }
272*54e60f84SAndroid Build Coastguard Worker 
273*54e60f84SAndroid Build Coastguard Worker     wrapped_display = wl_proxy_create_wrapper(ctx->native_dpy);
274*54e60f84SAndroid Build Coastguard Worker     if (!wrapped_display) {
275*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not create Wayland proxy wrapper");
276*54e60f84SAndroid Build Coastguard Worker         goto end;
277*54e60f84SAndroid Build Coastguard Worker     }
278*54e60f84SAndroid Build Coastguard Worker 
279*54e60f84SAndroid Build Coastguard Worker     /* All created objects will inherit this queue */
280*54e60f84SAndroid Build Coastguard Worker     wl_proxy_set_queue((struct wl_proxy *) wrapped_display, wl_drm_ctx->queue);
281*54e60f84SAndroid Build Coastguard Worker     wl_drm_ctx->registry = wl_display_get_registry(wrapped_display);
282*54e60f84SAndroid Build Coastguard Worker     if (!wl_drm_ctx->registry) {
283*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not create wl_registry");
284*54e60f84SAndroid Build Coastguard Worker         goto end;
285*54e60f84SAndroid Build Coastguard Worker     }
286*54e60f84SAndroid Build Coastguard Worker     if (wl_registry_add_listener(wl_drm_ctx->registry, &registry_listener, pDisplayContext) != 0) {
287*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("could not add listener to wl_registry");
288*54e60f84SAndroid Build Coastguard Worker         goto end;
289*54e60f84SAndroid Build Coastguard Worker     }
290*54e60f84SAndroid Build Coastguard Worker     if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
291*54e60f84SAndroid Build Coastguard Worker         goto end;
292*54e60f84SAndroid Build Coastguard Worker 
293*54e60f84SAndroid Build Coastguard Worker     /* registry_handle_global should have been called by the
294*54e60f84SAndroid Build Coastguard Worker      * wl_display_roundtrip_queue above
295*54e60f84SAndroid Build Coastguard Worker      */
296*54e60f84SAndroid Build Coastguard Worker 
297*54e60f84SAndroid Build Coastguard Worker     /* Do not print an error, the compositor might just not support wl_drm */
298*54e60f84SAndroid Build Coastguard Worker     if (!wl_drm_ctx->drm)
299*54e60f84SAndroid Build Coastguard Worker         goto end;
300*54e60f84SAndroid Build Coastguard Worker     if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
301*54e60f84SAndroid Build Coastguard Worker         goto end;
302*54e60f84SAndroid Build Coastguard Worker     if (drm_state->fd < 0) {
303*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("did not get DRM device");
304*54e60f84SAndroid Build Coastguard Worker         goto end;
305*54e60f84SAndroid Build Coastguard Worker     }
306*54e60f84SAndroid Build Coastguard Worker 
307*54e60f84SAndroid Build Coastguard Worker     if (!wayland_roundtrip_queue(ctx->native_dpy, wl_drm_ctx->queue))
308*54e60f84SAndroid Build Coastguard Worker         goto end;
309*54e60f84SAndroid Build Coastguard Worker 
310*54e60f84SAndroid Build Coastguard Worker     if (!wl_drm_ctx->is_authenticated) {
311*54e60f84SAndroid Build Coastguard Worker         va_wayland_error("Wayland compositor did not respond to DRM authentication");
312*54e60f84SAndroid Build Coastguard Worker         goto end;
313*54e60f84SAndroid Build Coastguard Worker     }
314*54e60f84SAndroid Build Coastguard Worker 
315*54e60f84SAndroid Build Coastguard Worker     vtable->wl_interface = &wl_drm_interface;
316*54e60f84SAndroid Build Coastguard Worker     result = true;
317*54e60f84SAndroid Build Coastguard Worker 
318*54e60f84SAndroid Build Coastguard Worker end:
319*54e60f84SAndroid Build Coastguard Worker     if (wrapped_display) {
320*54e60f84SAndroid Build Coastguard Worker         wl_proxy_wrapper_destroy(wrapped_display);
321*54e60f84SAndroid Build Coastguard Worker         wrapped_display = NULL;
322*54e60f84SAndroid Build Coastguard Worker     }
323*54e60f84SAndroid Build Coastguard Worker 
324*54e60f84SAndroid Build Coastguard Worker     if (wl_drm_ctx) {
325*54e60f84SAndroid Build Coastguard Worker         if (wl_drm_ctx->drm) {
326*54e60f84SAndroid Build Coastguard Worker             wl_drm_destroy(wl_drm_ctx->drm);
327*54e60f84SAndroid Build Coastguard Worker             wl_drm_ctx->drm = NULL;
328*54e60f84SAndroid Build Coastguard Worker         }
329*54e60f84SAndroid Build Coastguard Worker 
330*54e60f84SAndroid Build Coastguard Worker         if (wl_drm_ctx->registry) {
331*54e60f84SAndroid Build Coastguard Worker             wl_registry_destroy(wl_drm_ctx->registry);
332*54e60f84SAndroid Build Coastguard Worker             wl_drm_ctx->registry = NULL;
333*54e60f84SAndroid Build Coastguard Worker         }
334*54e60f84SAndroid Build Coastguard Worker 
335*54e60f84SAndroid Build Coastguard Worker         if (wl_drm_ctx->queue) {
336*54e60f84SAndroid Build Coastguard Worker             wl_event_queue_destroy(wl_drm_ctx->queue);
337*54e60f84SAndroid Build Coastguard Worker             wl_drm_ctx->queue = NULL;
338*54e60f84SAndroid Build Coastguard Worker         }
339*54e60f84SAndroid Build Coastguard Worker     }
340*54e60f84SAndroid Build Coastguard Worker 
341*54e60f84SAndroid Build Coastguard Worker     return result;
342*54e60f84SAndroid Build Coastguard Worker }
343