xref: /aosp_15_r20/external/mesa3d/src/egl/main/egldisplay.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker  *
3*61046927SAndroid Build Coastguard Worker  * Copyright 2008 VMware, Inc.
4*61046927SAndroid Build Coastguard Worker  * Copyright 2009-2010 Chia-I Wu <[email protected]>
5*61046927SAndroid Build Coastguard Worker  * Copyright 2010-2011 LunarG, Inc.
6*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
7*61046927SAndroid Build Coastguard Worker  *
8*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
9*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
10*61046927SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
11*61046927SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
12*61046927SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
13*61046927SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
14*61046927SAndroid Build Coastguard Worker  * the following conditions:
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
17*61046927SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
18*61046927SAndroid Build Coastguard Worker  * of the Software.
19*61046927SAndroid Build Coastguard Worker  *
20*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
27*61046927SAndroid Build Coastguard Worker  *
28*61046927SAndroid Build Coastguard Worker  **************************************************************************/
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker /**
31*61046927SAndroid Build Coastguard Worker  * Functions related to EGLDisplay.
32*61046927SAndroid Build Coastguard Worker  */
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker #include <assert.h>
35*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
36*61046927SAndroid Build Coastguard Worker #include <string.h>
37*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
38*61046927SAndroid Build Coastguard Worker #include <io.h>
39*61046927SAndroid Build Coastguard Worker #else
40*61046927SAndroid Build Coastguard Worker #include <unistd.h>
41*61046927SAndroid Build Coastguard Worker #endif
42*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
43*61046927SAndroid Build Coastguard Worker #include "c11/threads.h"
44*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
45*61046927SAndroid Build Coastguard Worker #include "util/os_file.h"
46*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker #include "eglcontext.h"
49*61046927SAndroid Build Coastguard Worker #include "eglcurrent.h"
50*61046927SAndroid Build Coastguard Worker #include "egldevice.h"
51*61046927SAndroid Build Coastguard Worker #include "egldisplay.h"
52*61046927SAndroid Build Coastguard Worker #include "egldriver.h"
53*61046927SAndroid Build Coastguard Worker #include "eglglobals.h"
54*61046927SAndroid Build Coastguard Worker #include "eglimage.h"
55*61046927SAndroid Build Coastguard Worker #include "egllog.h"
56*61046927SAndroid Build Coastguard Worker #include "eglsurface.h"
57*61046927SAndroid Build Coastguard Worker #include "eglsync.h"
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker /* Includes for _eglNativePlatformDetectNativeDisplay */
60*61046927SAndroid Build Coastguard Worker #ifdef HAVE_WAYLAND_PLATFORM
61*61046927SAndroid Build Coastguard Worker #include <wayland-client.h>
62*61046927SAndroid Build Coastguard Worker #endif
63*61046927SAndroid Build Coastguard Worker #ifdef HAVE_DRM_PLATFORM
64*61046927SAndroid Build Coastguard Worker #include <gbm.h>
65*61046927SAndroid Build Coastguard Worker #endif
66*61046927SAndroid Build Coastguard Worker #ifdef HAVE_WINDOWS_PLATFORM
67*61046927SAndroid Build Coastguard Worker #include <windows.h>
68*61046927SAndroid Build Coastguard Worker #endif
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker /**
71*61046927SAndroid Build Coastguard Worker  * Map build-system platform names to platform types.
72*61046927SAndroid Build Coastguard Worker  */
73*61046927SAndroid Build Coastguard Worker static const struct {
74*61046927SAndroid Build Coastguard Worker    _EGLPlatformType platform;
75*61046927SAndroid Build Coastguard Worker    const char *name;
76*61046927SAndroid Build Coastguard Worker } egl_platforms[] = {
77*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_X11, "x11"},
78*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_XCB, "xcb"},
79*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_WAYLAND, "wayland"},
80*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_DRM, "drm"},
81*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_ANDROID, "android"},
82*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_HAIKU, "haiku"},
83*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_SURFACELESS, "surfaceless"},
84*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_DEVICE, "device"},
85*61046927SAndroid Build Coastguard Worker    {_EGL_PLATFORM_WINDOWS, "windows"},
86*61046927SAndroid Build Coastguard Worker };
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker /**
89*61046927SAndroid Build Coastguard Worker  * Return the native platform by parsing EGL_PLATFORM.
90*61046927SAndroid Build Coastguard Worker  */
91*61046927SAndroid Build Coastguard Worker static _EGLPlatformType
_eglGetNativePlatformFromEnv(void)92*61046927SAndroid Build Coastguard Worker _eglGetNativePlatformFromEnv(void)
93*61046927SAndroid Build Coastguard Worker {
94*61046927SAndroid Build Coastguard Worker    _EGLPlatformType plat = _EGL_INVALID_PLATFORM;
95*61046927SAndroid Build Coastguard Worker    const char *plat_name;
96*61046927SAndroid Build Coastguard Worker    EGLint i;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    static_assert(ARRAY_SIZE(egl_platforms) == _EGL_NUM_PLATFORMS,
99*61046927SAndroid Build Coastguard Worker                  "Missing platform");
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    plat_name = getenv("EGL_PLATFORM");
102*61046927SAndroid Build Coastguard Worker    /* try deprecated env variable */
103*61046927SAndroid Build Coastguard Worker    if (!plat_name || !plat_name[0])
104*61046927SAndroid Build Coastguard Worker       plat_name = getenv("EGL_DISPLAY");
105*61046927SAndroid Build Coastguard Worker    if (!plat_name || !plat_name[0])
106*61046927SAndroid Build Coastguard Worker       return _EGL_INVALID_PLATFORM;
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker    for (i = 0; i < ARRAY_SIZE(egl_platforms); i++) {
109*61046927SAndroid Build Coastguard Worker       if (strcmp(egl_platforms[i].name, plat_name) == 0) {
110*61046927SAndroid Build Coastguard Worker          plat = egl_platforms[i].platform;
111*61046927SAndroid Build Coastguard Worker          break;
112*61046927SAndroid Build Coastguard Worker       }
113*61046927SAndroid Build Coastguard Worker    }
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker    if (plat == _EGL_INVALID_PLATFORM)
116*61046927SAndroid Build Coastguard Worker       _eglLog(_EGL_WARNING, "invalid EGL_PLATFORM given");
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    return plat;
119*61046927SAndroid Build Coastguard Worker }
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker /**
122*61046927SAndroid Build Coastguard Worker  * Try detecting native platform with the help of native display characteristics.
123*61046927SAndroid Build Coastguard Worker  */
124*61046927SAndroid Build Coastguard Worker static _EGLPlatformType
_eglNativePlatformDetectNativeDisplay(void * nativeDisplay)125*61046927SAndroid Build Coastguard Worker _eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
126*61046927SAndroid Build Coastguard Worker {
127*61046927SAndroid Build Coastguard Worker    if (nativeDisplay == EGL_DEFAULT_DISPLAY)
128*61046927SAndroid Build Coastguard Worker       return _EGL_INVALID_PLATFORM;
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker #ifdef HAVE_WINDOWS_PLATFORM
131*61046927SAndroid Build Coastguard Worker    if (GetObjectType(nativeDisplay) == OBJ_DC)
132*61046927SAndroid Build Coastguard Worker       return _EGL_PLATFORM_WINDOWS;
133*61046927SAndroid Build Coastguard Worker #endif
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker #if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
136*61046927SAndroid Build Coastguard Worker    if (_eglPointerIsDereferenceable(nativeDisplay)) {
137*61046927SAndroid Build Coastguard Worker       void *first_pointer = *(void **)nativeDisplay;
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker #ifdef HAVE_WAYLAND_PLATFORM
140*61046927SAndroid Build Coastguard Worker       /* wl_display is a wl_proxy, which is a wl_object.
141*61046927SAndroid Build Coastguard Worker        * wl_object's first element points to the interfacetype. */
142*61046927SAndroid Build Coastguard Worker       if (first_pointer == &wl_display_interface)
143*61046927SAndroid Build Coastguard Worker          return _EGL_PLATFORM_WAYLAND;
144*61046927SAndroid Build Coastguard Worker #endif
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker #ifdef HAVE_DRM_PLATFORM
147*61046927SAndroid Build Coastguard Worker       /* gbm has a pointer to its constructor as first element. */
148*61046927SAndroid Build Coastguard Worker       if (first_pointer == gbm_create_device)
149*61046927SAndroid Build Coastguard Worker          return _EGL_PLATFORM_DRM;
150*61046927SAndroid Build Coastguard Worker #endif
151*61046927SAndroid Build Coastguard Worker    }
152*61046927SAndroid Build Coastguard Worker #endif
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker    return _EGL_INVALID_PLATFORM;
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker /**
158*61046927SAndroid Build Coastguard Worker  * Return the native platform.  It is the platform of the EGL native types.
159*61046927SAndroid Build Coastguard Worker  */
160*61046927SAndroid Build Coastguard Worker _EGLPlatformType
_eglGetNativePlatform(void * nativeDisplay)161*61046927SAndroid Build Coastguard Worker _eglGetNativePlatform(void *nativeDisplay)
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker    _EGLPlatformType detected_platform = _eglGetNativePlatformFromEnv();
164*61046927SAndroid Build Coastguard Worker    const char *detection_method = "environment";
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker    if (detected_platform == _EGL_INVALID_PLATFORM) {
167*61046927SAndroid Build Coastguard Worker       detected_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
168*61046927SAndroid Build Coastguard Worker       detection_method = "autodetected";
169*61046927SAndroid Build Coastguard Worker    }
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker    if (detected_platform == _EGL_INVALID_PLATFORM) {
172*61046927SAndroid Build Coastguard Worker       detected_platform = _EGL_NATIVE_PLATFORM;
173*61046927SAndroid Build Coastguard Worker       detection_method = "build-time configuration";
174*61046927SAndroid Build Coastguard Worker    }
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
177*61046927SAndroid Build Coastguard Worker            egl_platforms[detected_platform].name, detection_method);
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker    return detected_platform;
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker /**
183*61046927SAndroid Build Coastguard Worker  * Finish display management.
184*61046927SAndroid Build Coastguard Worker  */
185*61046927SAndroid Build Coastguard Worker void
_eglFiniDisplay(void)186*61046927SAndroid Build Coastguard Worker _eglFiniDisplay(void)
187*61046927SAndroid Build Coastguard Worker {
188*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dispList, *disp;
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    /* atexit function is called with global mutex locked */
191*61046927SAndroid Build Coastguard Worker    dispList = _eglGlobal.DisplayList;
192*61046927SAndroid Build Coastguard Worker    while (dispList) {
193*61046927SAndroid Build Coastguard Worker       EGLint i;
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker       /* pop list head */
196*61046927SAndroid Build Coastguard Worker       disp = dispList;
197*61046927SAndroid Build Coastguard Worker       dispList = dispList->Next;
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker       for (i = 0; i < _EGL_NUM_RESOURCES; i++) {
200*61046927SAndroid Build Coastguard Worker          if (disp->ResourceLists[i]) {
201*61046927SAndroid Build Coastguard Worker             _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", disp);
202*61046927SAndroid Build Coastguard Worker             break;
203*61046927SAndroid Build Coastguard Worker          }
204*61046927SAndroid Build Coastguard Worker       }
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       /* The fcntl() code in _eglGetDeviceDisplay() ensures that valid fd >= 3,
207*61046927SAndroid Build Coastguard Worker        * and invalid one is 0.
208*61046927SAndroid Build Coastguard Worker        */
209*61046927SAndroid Build Coastguard Worker       if (disp->Options.fd)
210*61046927SAndroid Build Coastguard Worker          close(disp->Options.fd);
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker       free(disp->Options.Attribs);
213*61046927SAndroid Build Coastguard Worker       free(disp);
214*61046927SAndroid Build Coastguard Worker    }
215*61046927SAndroid Build Coastguard Worker    _eglGlobal.DisplayList = NULL;
216*61046927SAndroid Build Coastguard Worker }
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker static EGLBoolean
_eglSameAttribs(const EGLAttrib * a,const EGLAttrib * b)219*61046927SAndroid Build Coastguard Worker _eglSameAttribs(const EGLAttrib *a, const EGLAttrib *b)
220*61046927SAndroid Build Coastguard Worker {
221*61046927SAndroid Build Coastguard Worker    size_t na = _eglNumAttribs(a);
222*61046927SAndroid Build Coastguard Worker    size_t nb = _eglNumAttribs(b);
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker    /* different numbers of attributes must be different */
225*61046927SAndroid Build Coastguard Worker    if (na != nb)
226*61046927SAndroid Build Coastguard Worker       return EGL_FALSE;
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker    /* both lists NULL are the same */
229*61046927SAndroid Build Coastguard Worker    if (!a && !b)
230*61046927SAndroid Build Coastguard Worker       return EGL_TRUE;
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    /* otherwise, compare the lists */
233*61046927SAndroid Build Coastguard Worker    return memcmp(a, b, na * sizeof(a[0])) == 0 ? EGL_TRUE : EGL_FALSE;
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker /**
237*61046927SAndroid Build Coastguard Worker  * Find the display corresponding to the specified native display, or create a
238*61046927SAndroid Build Coastguard Worker  * new one. EGL 1.5 says:
239*61046927SAndroid Build Coastguard Worker  *
240*61046927SAndroid Build Coastguard Worker  *     Multiple calls made to eglGetPlatformDisplay with the same parameters
241*61046927SAndroid Build Coastguard Worker  *     will return the same EGLDisplay handle.
242*61046927SAndroid Build Coastguard Worker  *
243*61046927SAndroid Build Coastguard Worker  * We read this extremely strictly, and treat a call with NULL attribs as
244*61046927SAndroid Build Coastguard Worker  * different from a call with attribs only equal to { EGL_NONE }. Similarly
245*61046927SAndroid Build Coastguard Worker  * we do not sort the attribute list, so even if all attribute _values_ are
246*61046927SAndroid Build Coastguard Worker  * identical, different attribute orders will be considered different
247*61046927SAndroid Build Coastguard Worker  * parameters.
248*61046927SAndroid Build Coastguard Worker  */
249*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglFindDisplay(_EGLPlatformType plat,void * plat_dpy,const EGLAttrib * attrib_list)250*61046927SAndroid Build Coastguard Worker _eglFindDisplay(_EGLPlatformType plat, void *plat_dpy,
251*61046927SAndroid Build Coastguard Worker                 const EGLAttrib *attrib_list)
252*61046927SAndroid Build Coastguard Worker {
253*61046927SAndroid Build Coastguard Worker    _EGLDisplay *disp;
254*61046927SAndroid Build Coastguard Worker    size_t num_attribs;
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker    if (plat == _EGL_INVALID_PLATFORM)
257*61046927SAndroid Build Coastguard Worker       return NULL;
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(_eglGlobal.Mutex);
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker    /* search the display list first */
262*61046927SAndroid Build Coastguard Worker    for (disp = _eglGlobal.DisplayList; disp; disp = disp->Next) {
263*61046927SAndroid Build Coastguard Worker       if (disp->Platform == plat && disp->PlatformDisplay == plat_dpy &&
264*61046927SAndroid Build Coastguard Worker           _eglSameAttribs(disp->Options.Attribs, attrib_list))
265*61046927SAndroid Build Coastguard Worker          goto out;
266*61046927SAndroid Build Coastguard Worker    }
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    /* create a new display */
269*61046927SAndroid Build Coastguard Worker    assert(!disp);
270*61046927SAndroid Build Coastguard Worker    disp = calloc(1, sizeof(_EGLDisplay));
271*61046927SAndroid Build Coastguard Worker    if (!disp)
272*61046927SAndroid Build Coastguard Worker       goto out;
273*61046927SAndroid Build Coastguard Worker 
274*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&disp->Mutex, mtx_plain);
275*61046927SAndroid Build Coastguard Worker    u_rwlock_init(&disp->TerminateLock);
276*61046927SAndroid Build Coastguard Worker    disp->Platform = plat;
277*61046927SAndroid Build Coastguard Worker    disp->PlatformDisplay = plat_dpy;
278*61046927SAndroid Build Coastguard Worker    num_attribs = _eglNumAttribs(attrib_list);
279*61046927SAndroid Build Coastguard Worker    if (num_attribs) {
280*61046927SAndroid Build Coastguard Worker       disp->Options.Attribs = calloc(num_attribs, sizeof(EGLAttrib));
281*61046927SAndroid Build Coastguard Worker       if (!disp->Options.Attribs) {
282*61046927SAndroid Build Coastguard Worker          free(disp);
283*61046927SAndroid Build Coastguard Worker          disp = NULL;
284*61046927SAndroid Build Coastguard Worker          goto out;
285*61046927SAndroid Build Coastguard Worker       }
286*61046927SAndroid Build Coastguard Worker       memcpy(disp->Options.Attribs, attrib_list,
287*61046927SAndroid Build Coastguard Worker              num_attribs * sizeof(EGLAttrib));
288*61046927SAndroid Build Coastguard Worker    }
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker    /* add to the display list */
291*61046927SAndroid Build Coastguard Worker    disp->Next = _eglGlobal.DisplayList;
292*61046927SAndroid Build Coastguard Worker    _eglGlobal.DisplayList = disp;
293*61046927SAndroid Build Coastguard Worker 
294*61046927SAndroid Build Coastguard Worker out:
295*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(_eglGlobal.Mutex);
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker    return disp;
298*61046927SAndroid Build Coastguard Worker }
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker /**
301*61046927SAndroid Build Coastguard Worker  * Destroy the contexts and surfaces that are linked to the display.
302*61046927SAndroid Build Coastguard Worker  */
303*61046927SAndroid Build Coastguard Worker void
_eglReleaseDisplayResources(_EGLDisplay * display)304*61046927SAndroid Build Coastguard Worker _eglReleaseDisplayResources(_EGLDisplay *display)
305*61046927SAndroid Build Coastguard Worker {
306*61046927SAndroid Build Coastguard Worker    _EGLResource *list;
307*61046927SAndroid Build Coastguard Worker    const _EGLDriver *drv = display->Driver;
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker    simple_mtx_assert_locked(&display->Mutex);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    list = display->ResourceLists[_EGL_RESOURCE_CONTEXT];
312*61046927SAndroid Build Coastguard Worker    while (list) {
313*61046927SAndroid Build Coastguard Worker       _EGLContext *ctx = (_EGLContext *)list;
314*61046927SAndroid Build Coastguard Worker       list = list->Next;
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker       _eglUnlinkContext(ctx);
317*61046927SAndroid Build Coastguard Worker       drv->DestroyContext(display, ctx);
318*61046927SAndroid Build Coastguard Worker    }
319*61046927SAndroid Build Coastguard Worker    assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]);
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    list = display->ResourceLists[_EGL_RESOURCE_SURFACE];
322*61046927SAndroid Build Coastguard Worker    while (list) {
323*61046927SAndroid Build Coastguard Worker       _EGLSurface *surf = (_EGLSurface *)list;
324*61046927SAndroid Build Coastguard Worker       list = list->Next;
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker       _eglUnlinkSurface(surf);
327*61046927SAndroid Build Coastguard Worker       drv->DestroySurface(display, surf);
328*61046927SAndroid Build Coastguard Worker    }
329*61046927SAndroid Build Coastguard Worker    assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]);
330*61046927SAndroid Build Coastguard Worker 
331*61046927SAndroid Build Coastguard Worker    list = display->ResourceLists[_EGL_RESOURCE_IMAGE];
332*61046927SAndroid Build Coastguard Worker    while (list) {
333*61046927SAndroid Build Coastguard Worker       _EGLImage *image = (_EGLImage *)list;
334*61046927SAndroid Build Coastguard Worker       list = list->Next;
335*61046927SAndroid Build Coastguard Worker 
336*61046927SAndroid Build Coastguard Worker       _eglUnlinkImage(image);
337*61046927SAndroid Build Coastguard Worker       drv->DestroyImageKHR(display, image);
338*61046927SAndroid Build Coastguard Worker    }
339*61046927SAndroid Build Coastguard Worker    assert(!display->ResourceLists[_EGL_RESOURCE_IMAGE]);
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker    list = display->ResourceLists[_EGL_RESOURCE_SYNC];
342*61046927SAndroid Build Coastguard Worker    while (list) {
343*61046927SAndroid Build Coastguard Worker       _EGLSync *sync = (_EGLSync *)list;
344*61046927SAndroid Build Coastguard Worker       list = list->Next;
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker       _eglUnlinkSync(sync);
347*61046927SAndroid Build Coastguard Worker       drv->DestroySyncKHR(display, sync);
348*61046927SAndroid Build Coastguard Worker    }
349*61046927SAndroid Build Coastguard Worker    assert(!display->ResourceLists[_EGL_RESOURCE_SYNC]);
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker /**
353*61046927SAndroid Build Coastguard Worker  * Free all the data hanging of an _EGLDisplay object, but not
354*61046927SAndroid Build Coastguard Worker  * the object itself.
355*61046927SAndroid Build Coastguard Worker  */
356*61046927SAndroid Build Coastguard Worker void
_eglCleanupDisplay(_EGLDisplay * disp)357*61046927SAndroid Build Coastguard Worker _eglCleanupDisplay(_EGLDisplay *disp)
358*61046927SAndroid Build Coastguard Worker {
359*61046927SAndroid Build Coastguard Worker    if (disp->Configs) {
360*61046927SAndroid Build Coastguard Worker       _eglDestroyArray(disp->Configs, free);
361*61046927SAndroid Build Coastguard Worker       disp->Configs = NULL;
362*61046927SAndroid Build Coastguard Worker    }
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker    /* XXX incomplete */
365*61046927SAndroid Build Coastguard Worker }
366*61046927SAndroid Build Coastguard Worker 
367*61046927SAndroid Build Coastguard Worker /**
368*61046927SAndroid Build Coastguard Worker  * Return EGL_TRUE if the given resource is valid.  That is, the display does
369*61046927SAndroid Build Coastguard Worker  * own the resource.
370*61046927SAndroid Build Coastguard Worker  */
371*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglCheckResource(void * res,_EGLResourceType type,_EGLDisplay * disp)372*61046927SAndroid Build Coastguard Worker _eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *disp)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker    _EGLResource *list = disp->ResourceLists[type];
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    simple_mtx_assert_locked(&disp->Mutex);
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker    if (!res)
379*61046927SAndroid Build Coastguard Worker       return EGL_FALSE;
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker    while (list) {
382*61046927SAndroid Build Coastguard Worker       if (res == (void *)list) {
383*61046927SAndroid Build Coastguard Worker          assert(list->Display == disp);
384*61046927SAndroid Build Coastguard Worker          break;
385*61046927SAndroid Build Coastguard Worker       }
386*61046927SAndroid Build Coastguard Worker       list = list->Next;
387*61046927SAndroid Build Coastguard Worker    }
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker    return (list != NULL);
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker /**
393*61046927SAndroid Build Coastguard Worker  * Initialize a display resource.  The size of the subclass object is
394*61046927SAndroid Build Coastguard Worker  * specified.
395*61046927SAndroid Build Coastguard Worker  *
396*61046927SAndroid Build Coastguard Worker  * This is supposed to be called from the initializers of subclasses, such as
397*61046927SAndroid Build Coastguard Worker  * _eglInitContext or _eglInitSurface.
398*61046927SAndroid Build Coastguard Worker  */
399*61046927SAndroid Build Coastguard Worker void
_eglInitResource(_EGLResource * res,EGLint size,_EGLDisplay * disp)400*61046927SAndroid Build Coastguard Worker _eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *disp)
401*61046927SAndroid Build Coastguard Worker {
402*61046927SAndroid Build Coastguard Worker    memset(res, 0, size);
403*61046927SAndroid Build Coastguard Worker    res->Display = disp;
404*61046927SAndroid Build Coastguard Worker    res->RefCount = 1;
405*61046927SAndroid Build Coastguard Worker }
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker /**
408*61046927SAndroid Build Coastguard Worker  * Increment reference count for the resource.
409*61046927SAndroid Build Coastguard Worker  */
410*61046927SAndroid Build Coastguard Worker void
_eglGetResource(_EGLResource * res)411*61046927SAndroid Build Coastguard Worker _eglGetResource(_EGLResource *res)
412*61046927SAndroid Build Coastguard Worker {
413*61046927SAndroid Build Coastguard Worker    assert(res && res->RefCount > 0);
414*61046927SAndroid Build Coastguard Worker    p_atomic_inc(&res->RefCount);
415*61046927SAndroid Build Coastguard Worker }
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker /**
418*61046927SAndroid Build Coastguard Worker  * Decrement reference count for the resource.
419*61046927SAndroid Build Coastguard Worker  */
420*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglPutResource(_EGLResource * res)421*61046927SAndroid Build Coastguard Worker _eglPutResource(_EGLResource *res)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker    assert(res && res->RefCount > 0);
424*61046927SAndroid Build Coastguard Worker    return p_atomic_dec_zero(&res->RefCount);
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker 
427*61046927SAndroid Build Coastguard Worker /**
428*61046927SAndroid Build Coastguard Worker  * Link a resource to its display.
429*61046927SAndroid Build Coastguard Worker  */
430*61046927SAndroid Build Coastguard Worker void
_eglLinkResource(_EGLResource * res,_EGLResourceType type)431*61046927SAndroid Build Coastguard Worker _eglLinkResource(_EGLResource *res, _EGLResourceType type)
432*61046927SAndroid Build Coastguard Worker {
433*61046927SAndroid Build Coastguard Worker    assert(res->Display);
434*61046927SAndroid Build Coastguard Worker    simple_mtx_assert_locked(&res->Display->Mutex);
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker    res->IsLinked = EGL_TRUE;
437*61046927SAndroid Build Coastguard Worker    res->Next = res->Display->ResourceLists[type];
438*61046927SAndroid Build Coastguard Worker    res->Display->ResourceLists[type] = res;
439*61046927SAndroid Build Coastguard Worker    _eglGetResource(res);
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker /**
443*61046927SAndroid Build Coastguard Worker  * Unlink a linked resource from its display.
444*61046927SAndroid Build Coastguard Worker  */
445*61046927SAndroid Build Coastguard Worker void
_eglUnlinkResource(_EGLResource * res,_EGLResourceType type)446*61046927SAndroid Build Coastguard Worker _eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
447*61046927SAndroid Build Coastguard Worker {
448*61046927SAndroid Build Coastguard Worker    _EGLResource *prev;
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker    simple_mtx_assert_locked(&res->Display->Mutex);
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    prev = res->Display->ResourceLists[type];
453*61046927SAndroid Build Coastguard Worker    if (prev != res) {
454*61046927SAndroid Build Coastguard Worker       while (prev) {
455*61046927SAndroid Build Coastguard Worker          if (prev->Next == res)
456*61046927SAndroid Build Coastguard Worker             break;
457*61046927SAndroid Build Coastguard Worker          prev = prev->Next;
458*61046927SAndroid Build Coastguard Worker       }
459*61046927SAndroid Build Coastguard Worker       assert(prev);
460*61046927SAndroid Build Coastguard Worker       prev->Next = res->Next;
461*61046927SAndroid Build Coastguard Worker    } else {
462*61046927SAndroid Build Coastguard Worker       res->Display->ResourceLists[type] = res->Next;
463*61046927SAndroid Build Coastguard Worker    }
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker    res->Next = NULL;
466*61046927SAndroid Build Coastguard Worker    res->IsLinked = EGL_FALSE;
467*61046927SAndroid Build Coastguard Worker    _eglPutResource(res);
468*61046927SAndroid Build Coastguard Worker 
469*61046927SAndroid Build Coastguard Worker    /* We always unlink before destroy.  The driver still owns a reference */
470*61046927SAndroid Build Coastguard Worker    assert(res->RefCount);
471*61046927SAndroid Build Coastguard Worker }
472*61046927SAndroid Build Coastguard Worker 
473*61046927SAndroid Build Coastguard Worker #ifdef HAVE_X11_PLATFORM
474*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetX11Display(Display * native_display,const EGLAttrib * attrib_list)475*61046927SAndroid Build Coastguard Worker _eglGetX11Display(Display *native_display, const EGLAttrib *attrib_list)
476*61046927SAndroid Build Coastguard Worker {
477*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dpy;
478*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev = NULL;
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker    /* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
481*61046927SAndroid Build Coastguard Worker     * which is optional.
482*61046927SAndroid Build Coastguard Worker     */
483*61046927SAndroid Build Coastguard Worker    if (attrib_list != NULL) {
484*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
485*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
486*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
487*61046927SAndroid Build Coastguard Worker 
488*61046927SAndroid Build Coastguard Worker          switch (attrib) {
489*61046927SAndroid Build Coastguard Worker          case EGL_DEVICE_EXT:
490*61046927SAndroid Build Coastguard Worker             dev = _eglLookupDevice((void *)value);
491*61046927SAndroid Build Coastguard Worker             if (!dev) {
492*61046927SAndroid Build Coastguard Worker                _eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
493*61046927SAndroid Build Coastguard Worker                return NULL;
494*61046927SAndroid Build Coastguard Worker             }
495*61046927SAndroid Build Coastguard Worker             break;
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker          /* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
498*61046927SAndroid Build Coastguard Worker           * which is optional.
499*61046927SAndroid Build Coastguard Worker           */
500*61046927SAndroid Build Coastguard Worker          case EGL_PLATFORM_X11_SCREEN_EXT:
501*61046927SAndroid Build Coastguard Worker             break;
502*61046927SAndroid Build Coastguard Worker 
503*61046927SAndroid Build Coastguard Worker          default:
504*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
505*61046927SAndroid Build Coastguard Worker             return NULL;
506*61046927SAndroid Build Coastguard Worker          }
507*61046927SAndroid Build Coastguard Worker       }
508*61046927SAndroid Build Coastguard Worker    }
509*61046927SAndroid Build Coastguard Worker 
510*61046927SAndroid Build Coastguard Worker    dpy = _eglFindDisplay(_EGL_PLATFORM_X11, native_display, attrib_list);
511*61046927SAndroid Build Coastguard Worker    if (dpy) {
512*61046927SAndroid Build Coastguard Worker       dpy->Device = dev;
513*61046927SAndroid Build Coastguard Worker    }
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker    return dpy;
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker #endif /* HAVE_X11_PLATFORM */
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker #ifdef HAVE_XCB_PLATFORM
520*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetXcbDisplay(xcb_connection_t * native_display,const EGLAttrib * attrib_list)521*61046927SAndroid Build Coastguard Worker _eglGetXcbDisplay(xcb_connection_t *native_display,
522*61046927SAndroid Build Coastguard Worker                   const EGLAttrib *attrib_list)
523*61046927SAndroid Build Coastguard Worker {
524*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dpy;
525*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev = NULL;
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker    /* EGL_EXT_platform_xcb recognizes exactly one attribute,
528*61046927SAndroid Build Coastguard Worker     * EGL_PLATFORM_XCB_SCREEN_EXT, which is optional.
529*61046927SAndroid Build Coastguard Worker     */
530*61046927SAndroid Build Coastguard Worker    if (attrib_list != NULL) {
531*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
532*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
533*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker          switch (attrib) {
536*61046927SAndroid Build Coastguard Worker          case EGL_DEVICE_EXT:
537*61046927SAndroid Build Coastguard Worker             dev = _eglLookupDevice((void *)value);
538*61046927SAndroid Build Coastguard Worker             if (!dev) {
539*61046927SAndroid Build Coastguard Worker                _eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
540*61046927SAndroid Build Coastguard Worker                return NULL;
541*61046927SAndroid Build Coastguard Worker             }
542*61046927SAndroid Build Coastguard Worker             break;
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker          case EGL_PLATFORM_XCB_SCREEN_EXT:
545*61046927SAndroid Build Coastguard Worker             break;
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker          default:
548*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
549*61046927SAndroid Build Coastguard Worker             return NULL;
550*61046927SAndroid Build Coastguard Worker          }
551*61046927SAndroid Build Coastguard Worker       }
552*61046927SAndroid Build Coastguard Worker    }
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker    dpy = _eglFindDisplay(_EGL_PLATFORM_XCB, native_display, attrib_list);
555*61046927SAndroid Build Coastguard Worker    if (dpy) {
556*61046927SAndroid Build Coastguard Worker       dpy->Device = dev;
557*61046927SAndroid Build Coastguard Worker    }
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    return dpy;
560*61046927SAndroid Build Coastguard Worker }
561*61046927SAndroid Build Coastguard Worker #endif /* HAVE_XCB_PLATFORM */
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker #ifdef HAVE_DRM_PLATFORM
564*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetGbmDisplay(struct gbm_device * native_display,const EGLAttrib * attrib_list)565*61046927SAndroid Build Coastguard Worker _eglGetGbmDisplay(struct gbm_device *native_display,
566*61046927SAndroid Build Coastguard Worker                   const EGLAttrib *attrib_list)
567*61046927SAndroid Build Coastguard Worker {
568*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dpy;
569*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev = NULL;
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker    /* This platform recognizes only EXT_explicit_device */
572*61046927SAndroid Build Coastguard Worker    if (attrib_list) {
573*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
574*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
575*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
576*61046927SAndroid Build Coastguard Worker 
577*61046927SAndroid Build Coastguard Worker          switch (attrib) {
578*61046927SAndroid Build Coastguard Worker          case EGL_DEVICE_EXT:
579*61046927SAndroid Build Coastguard Worker             dev = _eglLookupDevice((void *)value);
580*61046927SAndroid Build Coastguard Worker             if (!dev) {
581*61046927SAndroid Build Coastguard Worker                _eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
582*61046927SAndroid Build Coastguard Worker                return NULL;
583*61046927SAndroid Build Coastguard Worker             }
584*61046927SAndroid Build Coastguard Worker             break;
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker          default:
587*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
588*61046927SAndroid Build Coastguard Worker             return NULL;
589*61046927SAndroid Build Coastguard Worker          }
590*61046927SAndroid Build Coastguard Worker       }
591*61046927SAndroid Build Coastguard Worker    }
592*61046927SAndroid Build Coastguard Worker 
593*61046927SAndroid Build Coastguard Worker    dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, native_display, attrib_list);
594*61046927SAndroid Build Coastguard Worker    if (dpy) {
595*61046927SAndroid Build Coastguard Worker       dpy->Device = dev;
596*61046927SAndroid Build Coastguard Worker    }
597*61046927SAndroid Build Coastguard Worker 
598*61046927SAndroid Build Coastguard Worker    return dpy;
599*61046927SAndroid Build Coastguard Worker }
600*61046927SAndroid Build Coastguard Worker #endif /* HAVE_DRM_PLATFORM */
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker #ifdef HAVE_WAYLAND_PLATFORM
603*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetWaylandDisplay(struct wl_display * native_display,const EGLAttrib * attrib_list)604*61046927SAndroid Build Coastguard Worker _eglGetWaylandDisplay(struct wl_display *native_display,
605*61046927SAndroid Build Coastguard Worker                       const EGLAttrib *attrib_list)
606*61046927SAndroid Build Coastguard Worker {
607*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dpy;
608*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev = NULL;
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker    /* This platform recognizes only EXT_explicit_device */
611*61046927SAndroid Build Coastguard Worker    if (attrib_list) {
612*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
613*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
614*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker          switch (attrib) {
617*61046927SAndroid Build Coastguard Worker          case EGL_DEVICE_EXT:
618*61046927SAndroid Build Coastguard Worker             dev = _eglLookupDevice((void *)value);
619*61046927SAndroid Build Coastguard Worker             if (!dev) {
620*61046927SAndroid Build Coastguard Worker                _eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
621*61046927SAndroid Build Coastguard Worker                return NULL;
622*61046927SAndroid Build Coastguard Worker             }
623*61046927SAndroid Build Coastguard Worker             break;
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker          default:
626*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
627*61046927SAndroid Build Coastguard Worker             return NULL;
628*61046927SAndroid Build Coastguard Worker          }
629*61046927SAndroid Build Coastguard Worker       }
630*61046927SAndroid Build Coastguard Worker    }
631*61046927SAndroid Build Coastguard Worker 
632*61046927SAndroid Build Coastguard Worker    dpy = _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display, attrib_list);
633*61046927SAndroid Build Coastguard Worker    if (dpy) {
634*61046927SAndroid Build Coastguard Worker       dpy->Device = dev;
635*61046927SAndroid Build Coastguard Worker    }
636*61046927SAndroid Build Coastguard Worker 
637*61046927SAndroid Build Coastguard Worker    return dpy;
638*61046927SAndroid Build Coastguard Worker }
639*61046927SAndroid Build Coastguard Worker #endif /* HAVE_WAYLAND_PLATFORM */
640*61046927SAndroid Build Coastguard Worker 
641*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetSurfacelessDisplay(void * native_display,const EGLAttrib * attrib_list)642*61046927SAndroid Build Coastguard Worker _eglGetSurfacelessDisplay(void *native_display, const EGLAttrib *attrib_list)
643*61046927SAndroid Build Coastguard Worker {
644*61046927SAndroid Build Coastguard Worker    _EGLDisplay *dpy;
645*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev = NULL;
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker    /* Any native display must be an EGLDeviceEXT we know about */
648*61046927SAndroid Build Coastguard Worker    if (native_display != NULL) {
649*61046927SAndroid Build Coastguard Worker       _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
650*61046927SAndroid Build Coastguard Worker       return NULL;
651*61046927SAndroid Build Coastguard Worker    }
652*61046927SAndroid Build Coastguard Worker 
653*61046927SAndroid Build Coastguard Worker    /* This platform recognizes only EXT_explicit_device */
654*61046927SAndroid Build Coastguard Worker    if (attrib_list) {
655*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
656*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
657*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker          switch (attrib) {
660*61046927SAndroid Build Coastguard Worker          case EGL_DEVICE_EXT:
661*61046927SAndroid Build Coastguard Worker             dev = _eglLookupDevice((void *)value);
662*61046927SAndroid Build Coastguard Worker             if (!dev) {
663*61046927SAndroid Build Coastguard Worker                _eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
664*61046927SAndroid Build Coastguard Worker                return NULL;
665*61046927SAndroid Build Coastguard Worker             }
666*61046927SAndroid Build Coastguard Worker             break;
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker          default:
669*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
670*61046927SAndroid Build Coastguard Worker             return NULL;
671*61046927SAndroid Build Coastguard Worker          }
672*61046927SAndroid Build Coastguard Worker       }
673*61046927SAndroid Build Coastguard Worker    }
674*61046927SAndroid Build Coastguard Worker 
675*61046927SAndroid Build Coastguard Worker    dpy = _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, NULL, attrib_list);
676*61046927SAndroid Build Coastguard Worker    if (dpy) {
677*61046927SAndroid Build Coastguard Worker       dpy->Device = dev;
678*61046927SAndroid Build Coastguard Worker    }
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker    return dpy;
681*61046927SAndroid Build Coastguard Worker }
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker #ifdef HAVE_ANDROID_PLATFORM
684*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetAndroidDisplay(void * native_display,const EGLAttrib * attrib_list)685*61046927SAndroid Build Coastguard Worker _eglGetAndroidDisplay(void *native_display, const EGLAttrib *attrib_list)
686*61046927SAndroid Build Coastguard Worker {
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker    /* This platform recognizes no display attributes. */
689*61046927SAndroid Build Coastguard Worker    if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
690*61046927SAndroid Build Coastguard Worker       _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
691*61046927SAndroid Build Coastguard Worker       return NULL;
692*61046927SAndroid Build Coastguard Worker    }
693*61046927SAndroid Build Coastguard Worker 
694*61046927SAndroid Build Coastguard Worker    return _eglFindDisplay(_EGL_PLATFORM_ANDROID, native_display, attrib_list);
695*61046927SAndroid Build Coastguard Worker }
696*61046927SAndroid Build Coastguard Worker #endif /* HAVE_ANDROID_PLATFORM */
697*61046927SAndroid Build Coastguard Worker 
698*61046927SAndroid Build Coastguard Worker _EGLDisplay *
_eglGetDeviceDisplay(void * native_display,const EGLAttrib * attrib_list)699*61046927SAndroid Build Coastguard Worker _eglGetDeviceDisplay(void *native_display, const EGLAttrib *attrib_list)
700*61046927SAndroid Build Coastguard Worker {
701*61046927SAndroid Build Coastguard Worker    _EGLDevice *dev;
702*61046927SAndroid Build Coastguard Worker    _EGLDisplay *display;
703*61046927SAndroid Build Coastguard Worker    int fd = -1;
704*61046927SAndroid Build Coastguard Worker 
705*61046927SAndroid Build Coastguard Worker    dev = _eglLookupDevice(native_display);
706*61046927SAndroid Build Coastguard Worker    if (!dev) {
707*61046927SAndroid Build Coastguard Worker       _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
708*61046927SAndroid Build Coastguard Worker       return NULL;
709*61046927SAndroid Build Coastguard Worker    }
710*61046927SAndroid Build Coastguard Worker 
711*61046927SAndroid Build Coastguard Worker    if (attrib_list) {
712*61046927SAndroid Build Coastguard Worker       for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
713*61046927SAndroid Build Coastguard Worker          EGLAttrib attrib = attrib_list[i];
714*61046927SAndroid Build Coastguard Worker          EGLAttrib value = attrib_list[i + 1];
715*61046927SAndroid Build Coastguard Worker 
716*61046927SAndroid Build Coastguard Worker          /* EGL_EXT_platform_device does not recognize any attributes,
717*61046927SAndroid Build Coastguard Worker           * EGL_EXT_device_drm adds the optional EGL_DRM_MASTER_FD_EXT.
718*61046927SAndroid Build Coastguard Worker           */
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker          if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM) ||
721*61046927SAndroid Build Coastguard Worker              attrib != EGL_DRM_MASTER_FD_EXT) {
722*61046927SAndroid Build Coastguard Worker             _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
723*61046927SAndroid Build Coastguard Worker             return NULL;
724*61046927SAndroid Build Coastguard Worker          }
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker          fd = (int)value;
727*61046927SAndroid Build Coastguard Worker       }
728*61046927SAndroid Build Coastguard Worker    }
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker    display = _eglFindDisplay(_EGL_PLATFORM_DEVICE, native_display, attrib_list);
731*61046927SAndroid Build Coastguard Worker    if (!display) {
732*61046927SAndroid Build Coastguard Worker       _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
733*61046927SAndroid Build Coastguard Worker       return NULL;
734*61046927SAndroid Build Coastguard Worker    }
735*61046927SAndroid Build Coastguard Worker 
736*61046927SAndroid Build Coastguard Worker    /* If the fd is explicitly provided and we did not dup() it yet, do so.
737*61046927SAndroid Build Coastguard Worker     * The spec mandates that we do so, since we'll need it past the
738*61046927SAndroid Build Coastguard Worker     * eglGetPlatformDisplay call.
739*61046927SAndroid Build Coastguard Worker     *
740*61046927SAndroid Build Coastguard Worker     * The new fd is guaranteed to be 3 or greater.
741*61046927SAndroid Build Coastguard Worker     */
742*61046927SAndroid Build Coastguard Worker    if (fd != -1 && display->Options.fd == 0) {
743*61046927SAndroid Build Coastguard Worker       display->Options.fd = os_dupfd_cloexec(fd);
744*61046927SAndroid Build Coastguard Worker       if (display->Options.fd == -1) {
745*61046927SAndroid Build Coastguard Worker          /* Do not (really) need to teardown the display */
746*61046927SAndroid Build Coastguard Worker          _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
747*61046927SAndroid Build Coastguard Worker          return NULL;
748*61046927SAndroid Build Coastguard Worker       }
749*61046927SAndroid Build Coastguard Worker    }
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker    return display;
752*61046927SAndroid Build Coastguard Worker }
753