egldisplay.c revision 848b8605
1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2008 VMware, Inc.
4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5848b8605Smrg * Copyright 2010-2011 LunarG, Inc.
6848b8605Smrg * All Rights Reserved.
7848b8605Smrg *
8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9848b8605Smrg * copy of this software and associated documentation files (the
10848b8605Smrg * "Software"), to deal in the Software without restriction, including
11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
14848b8605Smrg * the following conditions:
15848b8605Smrg *
16848b8605Smrg * The above copyright notice and this permission notice (including the
17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
18848b8605Smrg * of the Software.
19848b8605Smrg *
20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26848b8605Smrg * DEALINGS IN THE SOFTWARE.
27848b8605Smrg *
28848b8605Smrg **************************************************************************/
29848b8605Smrg
30848b8605Smrg
31848b8605Smrg/**
32848b8605Smrg * Functions related to EGLDisplay.
33848b8605Smrg */
34848b8605Smrg
35848b8605Smrg#include <assert.h>
36848b8605Smrg#include <stdlib.h>
37848b8605Smrg#include <string.h>
38848b8605Smrg#include "eglcontext.h"
39848b8605Smrg#include "eglcurrent.h"
40848b8605Smrg#include "eglsurface.h"
41848b8605Smrg#include "egldisplay.h"
42848b8605Smrg#include "egldriver.h"
43848b8605Smrg#include "eglglobals.h"
44848b8605Smrg#include "eglmutex.h"
45848b8605Smrg#include "egllog.h"
46848b8605Smrg
47848b8605Smrg/* Includes for _eglNativePlatformDetectNativeDisplay */
48848b8605Smrg#ifdef HAVE_MINCORE
49848b8605Smrg#include <unistd.h>
50848b8605Smrg#include <sys/mman.h>
51848b8605Smrg#endif
52848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
53848b8605Smrg#include <wayland-client.h>
54848b8605Smrg#endif
55848b8605Smrg#ifdef HAVE_DRM_PLATFORM
56848b8605Smrg#include <gbm.h>
57848b8605Smrg#endif
58848b8605Smrg#ifdef HAVE_FBDEV_PLATFORM
59848b8605Smrg#include <stdint.h>
60848b8605Smrg#include <sys/types.h>
61848b8605Smrg#include <sys/stat.h>
62848b8605Smrg#endif
63848b8605Smrg
64848b8605Smrg
65848b8605Smrg/**
66848b8605Smrg * Map --with-egl-platforms names to platform types.
67848b8605Smrg */
68848b8605Smrgstatic const struct {
69848b8605Smrg   _EGLPlatformType platform;
70848b8605Smrg   const char *name;
71848b8605Smrg} egl_platforms[_EGL_NUM_PLATFORMS] = {
72848b8605Smrg   { _EGL_PLATFORM_WINDOWS, "gdi" },
73848b8605Smrg   { _EGL_PLATFORM_X11, "x11" },
74848b8605Smrg   { _EGL_PLATFORM_WAYLAND, "wayland" },
75848b8605Smrg   { _EGL_PLATFORM_DRM, "drm" },
76848b8605Smrg   { _EGL_PLATFORM_FBDEV, "fbdev" },
77848b8605Smrg   { _EGL_PLATFORM_NULL, "null" },
78848b8605Smrg   { _EGL_PLATFORM_ANDROID, "android" }
79848b8605Smrg};
80848b8605Smrg
81848b8605Smrg
82848b8605Smrg/**
83848b8605Smrg * Return the native platform by parsing EGL_PLATFORM.
84848b8605Smrg */
85848b8605Smrgstatic _EGLPlatformType
86848b8605Smrg_eglGetNativePlatformFromEnv(void)
87848b8605Smrg{
88848b8605Smrg   _EGLPlatformType plat = _EGL_INVALID_PLATFORM;
89848b8605Smrg   const char *plat_name;
90848b8605Smrg   EGLint i;
91848b8605Smrg
92848b8605Smrg   plat_name = getenv("EGL_PLATFORM");
93848b8605Smrg   /* try deprecated env variable */
94848b8605Smrg   if (!plat_name || !plat_name[0])
95848b8605Smrg      plat_name = getenv("EGL_DISPLAY");
96848b8605Smrg   if (!plat_name || !plat_name[0])
97848b8605Smrg      return _EGL_INVALID_PLATFORM;
98848b8605Smrg
99848b8605Smrg   for (i = 0; i < _EGL_NUM_PLATFORMS; i++) {
100848b8605Smrg      if (strcmp(egl_platforms[i].name, plat_name) == 0) {
101848b8605Smrg         plat = egl_platforms[i].platform;
102848b8605Smrg         break;
103848b8605Smrg      }
104848b8605Smrg   }
105848b8605Smrg
106848b8605Smrg   return plat;
107848b8605Smrg}
108848b8605Smrg
109848b8605Smrg
110848b8605Smrg/**
111848b8605Smrg * Perform validity checks on a generic pointer.
112848b8605Smrg */
113848b8605Smrgstatic EGLBoolean
114848b8605Smrg_eglPointerIsDereferencable(void *p)
115848b8605Smrg{
116848b8605Smrg#ifdef HAVE_MINCORE
117848b8605Smrg   uintptr_t addr = (uintptr_t) p;
118848b8605Smrg   unsigned char valid = 0;
119848b8605Smrg   const long page_size = getpagesize();
120848b8605Smrg
121848b8605Smrg   if (p == NULL)
122848b8605Smrg      return EGL_FALSE;
123848b8605Smrg
124848b8605Smrg   /* align addr to page_size */
125848b8605Smrg   addr &= ~(page_size - 1);
126848b8605Smrg
127848b8605Smrg   if (mincore((void *) addr, page_size, &valid) < 0) {
128848b8605Smrg      _eglLog(_EGL_DEBUG, "mincore failed: %m");
129848b8605Smrg      return EGL_FALSE;
130848b8605Smrg   }
131848b8605Smrg
132848b8605Smrg   return (valid & 0x01) == 0x01;
133848b8605Smrg#else
134848b8605Smrg   return p != NULL;
135848b8605Smrg#endif
136848b8605Smrg}
137848b8605Smrg
138848b8605Smrg
139848b8605Smrg/**
140848b8605Smrg * Try detecting native platform with the help of native display characteristcs.
141848b8605Smrg */
142848b8605Smrgstatic _EGLPlatformType
143848b8605Smrg_eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
144848b8605Smrg{
145848b8605Smrg#ifdef HAVE_FBDEV_PLATFORM
146848b8605Smrg   struct stat buf;
147848b8605Smrg#endif
148848b8605Smrg
149848b8605Smrg   if (nativeDisplay == EGL_DEFAULT_DISPLAY)
150848b8605Smrg      return _EGL_INVALID_PLATFORM;
151848b8605Smrg
152848b8605Smrg#ifdef HAVE_FBDEV_PLATFORM
153848b8605Smrg   /* fbdev is the only platform that can be a file descriptor. */
154848b8605Smrg   if (fstat((intptr_t) nativeDisplay, &buf) == 0 && S_ISCHR(buf.st_mode))
155848b8605Smrg      return _EGL_PLATFORM_FBDEV;
156848b8605Smrg#endif
157848b8605Smrg
158848b8605Smrg   if (_eglPointerIsDereferencable(nativeDisplay)) {
159848b8605Smrg      void *first_pointer = *(void **) nativeDisplay;
160848b8605Smrg
161848b8605Smrg      (void) first_pointer; /* silence unused var warning */
162848b8605Smrg
163848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
164848b8605Smrg      /* wl_display is a wl_proxy, which is a wl_object.
165848b8605Smrg       * wl_object's first element points to the interfacetype. */
166848b8605Smrg      if (first_pointer == &wl_display_interface)
167848b8605Smrg         return _EGL_PLATFORM_WAYLAND;
168848b8605Smrg#endif
169848b8605Smrg
170848b8605Smrg#ifdef HAVE_DRM_PLATFORM
171848b8605Smrg      /* gbm has a pointer to its constructor as first element. */
172848b8605Smrg      if (first_pointer == gbm_create_device)
173848b8605Smrg         return _EGL_PLATFORM_DRM;
174848b8605Smrg#endif
175848b8605Smrg
176848b8605Smrg#ifdef HAVE_X11_PLATFORM
177848b8605Smrg      /* If not matched to any other platform, fallback to x11. */
178848b8605Smrg      return _EGL_PLATFORM_X11;
179848b8605Smrg#endif
180848b8605Smrg   }
181848b8605Smrg
182848b8605Smrg   return _EGL_INVALID_PLATFORM;
183848b8605Smrg}
184848b8605Smrg
185848b8605Smrg
186848b8605Smrg/**
187848b8605Smrg * Return the native platform.  It is the platform of the EGL native types.
188848b8605Smrg */
189848b8605Smrg_EGLPlatformType
190848b8605Smrg_eglGetNativePlatform(void *nativeDisplay)
191848b8605Smrg{
192848b8605Smrg   static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
193848b8605Smrg   char *detection_method = NULL;
194848b8605Smrg
195848b8605Smrg   if (native_platform == _EGL_INVALID_PLATFORM) {
196848b8605Smrg      native_platform = _eglGetNativePlatformFromEnv();
197848b8605Smrg      detection_method = "environment overwrite";
198848b8605Smrg      if (native_platform == _EGL_INVALID_PLATFORM) {
199848b8605Smrg         native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
200848b8605Smrg         detection_method = "autodetected";
201848b8605Smrg         if (native_platform == _EGL_INVALID_PLATFORM) {
202848b8605Smrg            native_platform = _EGL_NATIVE_PLATFORM;
203848b8605Smrg            detection_method = "build-time configuration";
204848b8605Smrg         }
205848b8605Smrg      }
206848b8605Smrg   }
207848b8605Smrg
208848b8605Smrg   if (detection_method != NULL)
209848b8605Smrg      _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
210848b8605Smrg              egl_platforms[native_platform].name, detection_method);
211848b8605Smrg
212848b8605Smrg   return native_platform;
213848b8605Smrg}
214848b8605Smrg
215848b8605Smrg
216848b8605Smrg/**
217848b8605Smrg * Finish display management.
218848b8605Smrg */
219848b8605Smrgvoid
220848b8605Smrg_eglFiniDisplay(void)
221848b8605Smrg{
222848b8605Smrg   _EGLDisplay *dpyList, *dpy;
223848b8605Smrg
224848b8605Smrg   /* atexit function is called with global mutex locked */
225848b8605Smrg   dpyList = _eglGlobal.DisplayList;
226848b8605Smrg   while (dpyList) {
227848b8605Smrg      EGLint i;
228848b8605Smrg
229848b8605Smrg      /* pop list head */
230848b8605Smrg      dpy = dpyList;
231848b8605Smrg      dpyList = dpyList->Next;
232848b8605Smrg
233848b8605Smrg      for (i = 0; i < _EGL_NUM_RESOURCES; i++) {
234848b8605Smrg         if (dpy->ResourceLists[i]) {
235848b8605Smrg            _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy);
236848b8605Smrg            break;
237848b8605Smrg         }
238848b8605Smrg      }
239848b8605Smrg
240848b8605Smrg      free(dpy);
241848b8605Smrg   }
242848b8605Smrg   _eglGlobal.DisplayList = NULL;
243848b8605Smrg}
244848b8605Smrg
245848b8605Smrg
246848b8605Smrg/**
247848b8605Smrg * Find the display corresponding to the specified native display, or create a
248848b8605Smrg * new one.
249848b8605Smrg */
250848b8605Smrg_EGLDisplay *
251848b8605Smrg_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)
252848b8605Smrg{
253848b8605Smrg   _EGLDisplay *dpy;
254848b8605Smrg
255848b8605Smrg   if (plat == _EGL_INVALID_PLATFORM)
256848b8605Smrg      return NULL;
257848b8605Smrg
258848b8605Smrg   _eglLockMutex(_eglGlobal.Mutex);
259848b8605Smrg
260848b8605Smrg   /* search the display list first */
261848b8605Smrg   dpy = _eglGlobal.DisplayList;
262848b8605Smrg   while (dpy) {
263848b8605Smrg      if (dpy->Platform == plat && dpy->PlatformDisplay == plat_dpy)
264848b8605Smrg         break;
265848b8605Smrg      dpy = dpy->Next;
266848b8605Smrg   }
267848b8605Smrg
268848b8605Smrg   /* create a new display */
269848b8605Smrg   if (!dpy) {
270848b8605Smrg      dpy = calloc(1, sizeof(_EGLDisplay));
271848b8605Smrg      if (dpy) {
272848b8605Smrg         _eglInitMutex(&dpy->Mutex);
273848b8605Smrg         dpy->Platform = plat;
274848b8605Smrg         dpy->PlatformDisplay = plat_dpy;
275848b8605Smrg
276848b8605Smrg         /* add to the display list */
277848b8605Smrg         dpy->Next = _eglGlobal.DisplayList;
278848b8605Smrg         _eglGlobal.DisplayList = dpy;
279848b8605Smrg      }
280848b8605Smrg   }
281848b8605Smrg
282848b8605Smrg   _eglUnlockMutex(_eglGlobal.Mutex);
283848b8605Smrg
284848b8605Smrg   return dpy;
285848b8605Smrg}
286848b8605Smrg
287848b8605Smrg
288848b8605Smrg/**
289848b8605Smrg * Destroy the contexts and surfaces that are linked to the display.
290848b8605Smrg */
291848b8605Smrgvoid
292848b8605Smrg_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
293848b8605Smrg{
294848b8605Smrg   _EGLResource *list;
295848b8605Smrg
296848b8605Smrg   list = display->ResourceLists[_EGL_RESOURCE_CONTEXT];
297848b8605Smrg   while (list) {
298848b8605Smrg      _EGLContext *ctx = (_EGLContext *) list;
299848b8605Smrg      list = list->Next;
300848b8605Smrg
301848b8605Smrg      _eglUnlinkContext(ctx);
302848b8605Smrg      drv->API.DestroyContext(drv, display, ctx);
303848b8605Smrg   }
304848b8605Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]);
305848b8605Smrg
306848b8605Smrg   list = display->ResourceLists[_EGL_RESOURCE_SURFACE];
307848b8605Smrg   while (list) {
308848b8605Smrg      _EGLSurface *surf = (_EGLSurface *) list;
309848b8605Smrg      list = list->Next;
310848b8605Smrg
311848b8605Smrg      _eglUnlinkSurface(surf);
312848b8605Smrg      drv->API.DestroySurface(drv, display, surf);
313848b8605Smrg   }
314848b8605Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]);
315848b8605Smrg}
316848b8605Smrg
317848b8605Smrg
318848b8605Smrg/**
319848b8605Smrg * Free all the data hanging of an _EGLDisplay object, but not
320848b8605Smrg * the object itself.
321848b8605Smrg */
322848b8605Smrgvoid
323848b8605Smrg_eglCleanupDisplay(_EGLDisplay *disp)
324848b8605Smrg{
325848b8605Smrg   if (disp->Configs) {
326848b8605Smrg      _eglDestroyArray(disp->Configs, free);
327848b8605Smrg      disp->Configs = NULL;
328848b8605Smrg   }
329848b8605Smrg
330848b8605Smrg   /* XXX incomplete */
331848b8605Smrg}
332848b8605Smrg
333848b8605Smrg
334848b8605Smrg/**
335848b8605Smrg * Return EGL_TRUE if the given handle is a valid handle to a display.
336848b8605Smrg */
337848b8605SmrgEGLBoolean
338848b8605Smrg_eglCheckDisplayHandle(EGLDisplay dpy)
339848b8605Smrg{
340848b8605Smrg   _EGLDisplay *cur;
341848b8605Smrg
342848b8605Smrg   _eglLockMutex(_eglGlobal.Mutex);
343848b8605Smrg   cur = _eglGlobal.DisplayList;
344848b8605Smrg   while (cur) {
345848b8605Smrg      if (cur == (_EGLDisplay *) dpy)
346848b8605Smrg         break;
347848b8605Smrg      cur = cur->Next;
348848b8605Smrg   }
349848b8605Smrg   _eglUnlockMutex(_eglGlobal.Mutex);
350848b8605Smrg   return (cur != NULL);
351848b8605Smrg}
352848b8605Smrg
353848b8605Smrg
354848b8605Smrg/**
355848b8605Smrg * Return EGL_TRUE if the given resource is valid.  That is, the display does
356848b8605Smrg * own the resource.
357848b8605Smrg */
358848b8605SmrgEGLBoolean
359848b8605Smrg_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy)
360848b8605Smrg{
361848b8605Smrg   _EGLResource *list = dpy->ResourceLists[type];
362848b8605Smrg
363848b8605Smrg   if (!res)
364848b8605Smrg      return EGL_FALSE;
365848b8605Smrg
366848b8605Smrg   while (list) {
367848b8605Smrg      if (res == (void *) list) {
368848b8605Smrg         assert(list->Display == dpy);
369848b8605Smrg         break;
370848b8605Smrg      }
371848b8605Smrg      list = list->Next;
372848b8605Smrg   }
373848b8605Smrg
374848b8605Smrg   return (list != NULL);
375848b8605Smrg}
376848b8605Smrg
377848b8605Smrg
378848b8605Smrg/**
379848b8605Smrg * Initialize a display resource.  The size of the subclass object is
380848b8605Smrg * specified.
381848b8605Smrg *
382848b8605Smrg * This is supposed to be called from the initializers of subclasses, such as
383848b8605Smrg * _eglInitContext or _eglInitSurface.
384848b8605Smrg */
385848b8605Smrgvoid
386848b8605Smrg_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy)
387848b8605Smrg{
388848b8605Smrg   memset(res, 0, size);
389848b8605Smrg   res->Display = dpy;
390848b8605Smrg   res->RefCount = 1;
391848b8605Smrg}
392848b8605Smrg
393848b8605Smrg
394848b8605Smrg/**
395848b8605Smrg * Increment reference count for the resource.
396848b8605Smrg */
397848b8605Smrgvoid
398848b8605Smrg_eglGetResource(_EGLResource *res)
399848b8605Smrg{
400848b8605Smrg   assert(res && res->RefCount > 0);
401848b8605Smrg   /* hopefully a resource is always manipulated with its display locked */
402848b8605Smrg   res->RefCount++;
403848b8605Smrg}
404848b8605Smrg
405848b8605Smrg
406848b8605Smrg/**
407848b8605Smrg * Decrement reference count for the resource.
408848b8605Smrg */
409848b8605SmrgEGLBoolean
410848b8605Smrg_eglPutResource(_EGLResource *res)
411848b8605Smrg{
412848b8605Smrg   assert(res && res->RefCount > 0);
413848b8605Smrg   res->RefCount--;
414848b8605Smrg   return (!res->RefCount);
415848b8605Smrg}
416848b8605Smrg
417848b8605Smrg
418848b8605Smrg/**
419848b8605Smrg * Link a resource to its display.
420848b8605Smrg */
421848b8605Smrgvoid
422848b8605Smrg_eglLinkResource(_EGLResource *res, _EGLResourceType type)
423848b8605Smrg{
424848b8605Smrg   assert(res->Display);
425848b8605Smrg
426848b8605Smrg   res->IsLinked = EGL_TRUE;
427848b8605Smrg   res->Next = res->Display->ResourceLists[type];
428848b8605Smrg   res->Display->ResourceLists[type] = res;
429848b8605Smrg   _eglGetResource(res);
430848b8605Smrg}
431848b8605Smrg
432848b8605Smrg
433848b8605Smrg/**
434848b8605Smrg * Unlink a linked resource from its display.
435848b8605Smrg */
436848b8605Smrgvoid
437848b8605Smrg_eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
438848b8605Smrg{
439848b8605Smrg   _EGLResource *prev;
440848b8605Smrg
441848b8605Smrg   prev = res->Display->ResourceLists[type];
442848b8605Smrg   if (prev != res) {
443848b8605Smrg      while (prev) {
444848b8605Smrg         if (prev->Next == res)
445848b8605Smrg            break;
446848b8605Smrg         prev = prev->Next;
447848b8605Smrg      }
448848b8605Smrg      assert(prev);
449848b8605Smrg      prev->Next = res->Next;
450848b8605Smrg   }
451848b8605Smrg   else {
452848b8605Smrg      res->Display->ResourceLists[type] = res->Next;
453848b8605Smrg   }
454848b8605Smrg
455848b8605Smrg   res->Next = NULL;
456848b8605Smrg   res->IsLinked = EGL_FALSE;
457848b8605Smrg   _eglPutResource(res);
458848b8605Smrg
459848b8605Smrg   /* We always unlink before destroy.  The driver still owns a reference */
460848b8605Smrg   assert(res->RefCount);
461848b8605Smrg}
462848b8605Smrg
463848b8605Smrg#ifdef HAVE_X11_PLATFORM
464848b8605Smrgstatic EGLBoolean
465848b8605Smrg_eglParseX11DisplayAttribList(const EGLint *attrib_list)
466848b8605Smrg{
467848b8605Smrg   int i;
468848b8605Smrg
469848b8605Smrg   if (attrib_list == NULL) {
470848b8605Smrg      return EGL_TRUE;
471848b8605Smrg   }
472848b8605Smrg
473848b8605Smrg   for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
474848b8605Smrg      EGLint attrib = attrib_list[i];
475848b8605Smrg      EGLint value = attrib_list[i + 1];
476848b8605Smrg
477848b8605Smrg      /* EGL_EXT_platform_x11 recognizes exactly one attribute,
478848b8605Smrg       * EGL_PLATFORM_X11_SCREEN_EXT, which is optional.
479848b8605Smrg       *
480848b8605Smrg       * Mesa supports connecting to only the default screen, so we reject
481848b8605Smrg       * screen != 0.
482848b8605Smrg       */
483848b8605Smrg      if (attrib != EGL_PLATFORM_X11_SCREEN_EXT || value != 0) {
484848b8605Smrg         _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
485848b8605Smrg         return EGL_FALSE;
486848b8605Smrg      }
487848b8605Smrg   }
488848b8605Smrg
489848b8605Smrg   return EGL_TRUE;
490848b8605Smrg}
491848b8605Smrg
492848b8605Smrg_EGLDisplay*
493848b8605Smrg_eglGetX11Display(Display *native_display,
494848b8605Smrg                  const EGLint *attrib_list)
495848b8605Smrg{
496848b8605Smrg   if (!_eglParseX11DisplayAttribList(attrib_list)) {
497848b8605Smrg      return NULL;
498848b8605Smrg   }
499848b8605Smrg
500848b8605Smrg   return _eglFindDisplay(_EGL_PLATFORM_X11, native_display);
501848b8605Smrg}
502848b8605Smrg#endif /* HAVE_X11_PLATFORM */
503848b8605Smrg
504848b8605Smrg#ifdef HAVE_DRM_PLATFORM
505848b8605Smrg_EGLDisplay*
506848b8605Smrg_eglGetGbmDisplay(struct gbm_device *native_display,
507848b8605Smrg                  const EGLint *attrib_list)
508848b8605Smrg{
509848b8605Smrg   /* EGL_MESA_platform_gbm recognizes no attributes. */
510848b8605Smrg   if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
511848b8605Smrg      _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
512848b8605Smrg      return NULL;
513848b8605Smrg   }
514848b8605Smrg
515848b8605Smrg   return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display);
516848b8605Smrg}
517848b8605Smrg#endif /* HAVE_DRM_PLATFORM */
518848b8605Smrg
519848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
520848b8605Smrg_EGLDisplay*
521848b8605Smrg_eglGetWaylandDisplay(struct wl_display *native_display,
522848b8605Smrg                      const EGLint *attrib_list)
523848b8605Smrg{
524848b8605Smrg   /* EGL_EXT_platform_wayland recognizes no attributes. */
525848b8605Smrg   if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
526848b8605Smrg      _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
527848b8605Smrg      return NULL;
528848b8605Smrg   }
529848b8605Smrg
530848b8605Smrg   return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display);
531848b8605Smrg}
532848b8605Smrg#endif /* HAVE_WAYLAND_PLATFORM */
533