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>
38b8e80941Smrg#include "c11/threads.h"
39b8e80941Smrg#include "util/u_atomic.h"
40b8e80941Smrg
41848b8605Smrg#include "eglcontext.h"
42848b8605Smrg#include "eglcurrent.h"
43848b8605Smrg#include "eglsurface.h"
44848b8605Smrg#include "egldisplay.h"
45848b8605Smrg#include "egldriver.h"
46848b8605Smrg#include "eglglobals.h"
47848b8605Smrg#include "egllog.h"
48b8e80941Smrg#include "eglimage.h"
49b8e80941Smrg#include "eglsync.h"
50848b8605Smrg
51848b8605Smrg/* Includes for _eglNativePlatformDetectNativeDisplay */
52848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
53848b8605Smrg#include <wayland-client.h>
54848b8605Smrg#endif
55848b8605Smrg#ifdef HAVE_DRM_PLATFORM
56848b8605Smrg#include <gbm.h>
57848b8605Smrg#endif
58848b8605Smrg
59848b8605Smrg
60848b8605Smrg/**
61b8e80941Smrg * Map build-system platform names to platform types.
62848b8605Smrg */
63848b8605Smrgstatic const struct {
64848b8605Smrg   _EGLPlatformType platform;
65848b8605Smrg   const char *name;
66848b8605Smrg} egl_platforms[_EGL_NUM_PLATFORMS] = {
67848b8605Smrg   { _EGL_PLATFORM_X11, "x11" },
68848b8605Smrg   { _EGL_PLATFORM_WAYLAND, "wayland" },
69848b8605Smrg   { _EGL_PLATFORM_DRM, "drm" },
70b8e80941Smrg   { _EGL_PLATFORM_ANDROID, "android" },
71b8e80941Smrg   { _EGL_PLATFORM_HAIKU, "haiku" },
72b8e80941Smrg   { _EGL_PLATFORM_SURFACELESS, "surfaceless" },
73848b8605Smrg};
74848b8605Smrg
75848b8605Smrg
76848b8605Smrg/**
77848b8605Smrg * Return the native platform by parsing EGL_PLATFORM.
78848b8605Smrg */
79848b8605Smrgstatic _EGLPlatformType
80848b8605Smrg_eglGetNativePlatformFromEnv(void)
81848b8605Smrg{
82848b8605Smrg   _EGLPlatformType plat = _EGL_INVALID_PLATFORM;
83848b8605Smrg   const char *plat_name;
84848b8605Smrg   EGLint i;
85848b8605Smrg
86848b8605Smrg   plat_name = getenv("EGL_PLATFORM");
87848b8605Smrg   /* try deprecated env variable */
88848b8605Smrg   if (!plat_name || !plat_name[0])
89848b8605Smrg      plat_name = getenv("EGL_DISPLAY");
90848b8605Smrg   if (!plat_name || !plat_name[0])
91848b8605Smrg      return _EGL_INVALID_PLATFORM;
92848b8605Smrg
93848b8605Smrg   for (i = 0; i < _EGL_NUM_PLATFORMS; i++) {
94848b8605Smrg      if (strcmp(egl_platforms[i].name, plat_name) == 0) {
95848b8605Smrg         plat = egl_platforms[i].platform;
96848b8605Smrg         break;
97848b8605Smrg      }
98848b8605Smrg   }
99848b8605Smrg
100848b8605Smrg   return plat;
101848b8605Smrg}
102848b8605Smrg
103848b8605Smrg
104848b8605Smrg/**
105848b8605Smrg * Try detecting native platform with the help of native display characteristcs.
106848b8605Smrg */
107848b8605Smrgstatic _EGLPlatformType
108848b8605Smrg_eglNativePlatformDetectNativeDisplay(void *nativeDisplay)
109848b8605Smrg{
110848b8605Smrg   if (nativeDisplay == EGL_DEFAULT_DISPLAY)
111848b8605Smrg      return _EGL_INVALID_PLATFORM;
112848b8605Smrg
113848b8605Smrg   if (_eglPointerIsDereferencable(nativeDisplay)) {
114848b8605Smrg      void *first_pointer = *(void **) nativeDisplay;
115848b8605Smrg
116848b8605Smrg      (void) first_pointer; /* silence unused var warning */
117848b8605Smrg
118848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
119848b8605Smrg      /* wl_display is a wl_proxy, which is a wl_object.
120848b8605Smrg       * wl_object's first element points to the interfacetype. */
121848b8605Smrg      if (first_pointer == &wl_display_interface)
122848b8605Smrg         return _EGL_PLATFORM_WAYLAND;
123848b8605Smrg#endif
124848b8605Smrg
125848b8605Smrg#ifdef HAVE_DRM_PLATFORM
126848b8605Smrg      /* gbm has a pointer to its constructor as first element. */
127848b8605Smrg      if (first_pointer == gbm_create_device)
128848b8605Smrg         return _EGL_PLATFORM_DRM;
129848b8605Smrg#endif
130848b8605Smrg
131848b8605Smrg#ifdef HAVE_X11_PLATFORM
132848b8605Smrg      /* If not matched to any other platform, fallback to x11. */
133848b8605Smrg      return _EGL_PLATFORM_X11;
134848b8605Smrg#endif
135b8e80941Smrg
136b8e80941Smrg#ifdef HAVE_HAIKU_PLATFORM
137b8e80941Smrg      return _EGL_PLATFORM_HAIKU;
138b8e80941Smrg#endif
139848b8605Smrg   }
140848b8605Smrg
141848b8605Smrg   return _EGL_INVALID_PLATFORM;
142848b8605Smrg}
143848b8605Smrg
144848b8605Smrg
145848b8605Smrg/**
146848b8605Smrg * Return the native platform.  It is the platform of the EGL native types.
147848b8605Smrg */
148848b8605Smrg_EGLPlatformType
149848b8605Smrg_eglGetNativePlatform(void *nativeDisplay)
150848b8605Smrg{
151848b8605Smrg   static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
152b8e80941Smrg   _EGLPlatformType detected_platform = native_platform;
153b8e80941Smrg
154b8e80941Smrg   if (detected_platform == _EGL_INVALID_PLATFORM) {
155b8e80941Smrg      const char *detection_method;
156848b8605Smrg
157b8e80941Smrg      detected_platform = _eglGetNativePlatformFromEnv();
158848b8605Smrg      detection_method = "environment overwrite";
159b8e80941Smrg
160b8e80941Smrg      if (detected_platform == _EGL_INVALID_PLATFORM) {
161b8e80941Smrg         detected_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
162848b8605Smrg         detection_method = "autodetected";
163848b8605Smrg      }
164848b8605Smrg
165b8e80941Smrg      if (detected_platform == _EGL_INVALID_PLATFORM) {
166b8e80941Smrg         detected_platform = _EGL_NATIVE_PLATFORM;
167b8e80941Smrg         detection_method = "build-time configuration";
168b8e80941Smrg      }
169b8e80941Smrg
170848b8605Smrg      _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
171b8e80941Smrg              egl_platforms[detected_platform].name, detection_method);
172b8e80941Smrg
173b8e80941Smrg      p_atomic_cmpxchg(&native_platform, _EGL_INVALID_PLATFORM,
174b8e80941Smrg                       detected_platform);
175b8e80941Smrg   }
176848b8605Smrg
177848b8605Smrg   return native_platform;
178848b8605Smrg}
179848b8605Smrg
180848b8605Smrg
181848b8605Smrg/**
182848b8605Smrg * Finish display management.
183848b8605Smrg */
184848b8605Smrgvoid
185848b8605Smrg_eglFiniDisplay(void)
186848b8605Smrg{
187b8e80941Smrg   _EGLDisplay *dispList, *disp;
188848b8605Smrg
189848b8605Smrg   /* atexit function is called with global mutex locked */
190b8e80941Smrg   dispList = _eglGlobal.DisplayList;
191b8e80941Smrg   while (dispList) {
192848b8605Smrg      EGLint i;
193848b8605Smrg
194848b8605Smrg      /* pop list head */
195b8e80941Smrg      disp = dispList;
196b8e80941Smrg      dispList = dispList->Next;
197848b8605Smrg
198848b8605Smrg      for (i = 0; i < _EGL_NUM_RESOURCES; i++) {
199b8e80941Smrg         if (disp->ResourceLists[i]) {
200b8e80941Smrg            _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", disp);
201848b8605Smrg            break;
202848b8605Smrg         }
203848b8605Smrg      }
204848b8605Smrg
205b8e80941Smrg      free(disp);
206848b8605Smrg   }
207848b8605Smrg   _eglGlobal.DisplayList = NULL;
208848b8605Smrg}
209848b8605Smrg
210848b8605Smrg
211848b8605Smrg/**
212848b8605Smrg * Find the display corresponding to the specified native display, or create a
213848b8605Smrg * new one.
214848b8605Smrg */
215848b8605Smrg_EGLDisplay *
216848b8605Smrg_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)
217848b8605Smrg{
218b8e80941Smrg   _EGLDisplay *disp;
219848b8605Smrg
220848b8605Smrg   if (plat == _EGL_INVALID_PLATFORM)
221848b8605Smrg      return NULL;
222848b8605Smrg
223b8e80941Smrg   mtx_lock(_eglGlobal.Mutex);
224848b8605Smrg
225848b8605Smrg   /* search the display list first */
226b8e80941Smrg   disp = _eglGlobal.DisplayList;
227b8e80941Smrg   while (disp) {
228b8e80941Smrg      if (disp->Platform == plat && disp->PlatformDisplay == plat_dpy)
229848b8605Smrg         break;
230b8e80941Smrg      disp = disp->Next;
231848b8605Smrg   }
232848b8605Smrg
233848b8605Smrg   /* create a new display */
234b8e80941Smrg   if (!disp) {
235b8e80941Smrg      disp = calloc(1, sizeof(_EGLDisplay));
236b8e80941Smrg      if (disp) {
237b8e80941Smrg         mtx_init(&disp->Mutex, mtx_plain);
238b8e80941Smrg         disp->Platform = plat;
239b8e80941Smrg         disp->PlatformDisplay = plat_dpy;
240848b8605Smrg
241848b8605Smrg         /* add to the display list */
242b8e80941Smrg         disp->Next = _eglGlobal.DisplayList;
243b8e80941Smrg         _eglGlobal.DisplayList = disp;
244848b8605Smrg      }
245848b8605Smrg   }
246848b8605Smrg
247b8e80941Smrg   mtx_unlock(_eglGlobal.Mutex);
248848b8605Smrg
249b8e80941Smrg   return disp;
250848b8605Smrg}
251848b8605Smrg
252848b8605Smrg
253848b8605Smrg/**
254848b8605Smrg * Destroy the contexts and surfaces that are linked to the display.
255848b8605Smrg */
256848b8605Smrgvoid
257848b8605Smrg_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
258848b8605Smrg{
259848b8605Smrg   _EGLResource *list;
260848b8605Smrg
261848b8605Smrg   list = display->ResourceLists[_EGL_RESOURCE_CONTEXT];
262848b8605Smrg   while (list) {
263848b8605Smrg      _EGLContext *ctx = (_EGLContext *) list;
264848b8605Smrg      list = list->Next;
265848b8605Smrg
266848b8605Smrg      _eglUnlinkContext(ctx);
267848b8605Smrg      drv->API.DestroyContext(drv, display, ctx);
268848b8605Smrg   }
269848b8605Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]);
270848b8605Smrg
271848b8605Smrg   list = display->ResourceLists[_EGL_RESOURCE_SURFACE];
272848b8605Smrg   while (list) {
273848b8605Smrg      _EGLSurface *surf = (_EGLSurface *) list;
274848b8605Smrg      list = list->Next;
275848b8605Smrg
276848b8605Smrg      _eglUnlinkSurface(surf);
277848b8605Smrg      drv->API.DestroySurface(drv, display, surf);
278848b8605Smrg   }
279848b8605Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]);
280b8e80941Smrg
281b8e80941Smrg   list = display->ResourceLists[_EGL_RESOURCE_IMAGE];
282b8e80941Smrg   while (list) {
283b8e80941Smrg      _EGLImage *image = (_EGLImage *) list;
284b8e80941Smrg      list = list->Next;
285b8e80941Smrg
286b8e80941Smrg      _eglUnlinkImage(image);
287b8e80941Smrg      drv->API.DestroyImageKHR(drv, display, image);
288b8e80941Smrg   }
289b8e80941Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_IMAGE]);
290b8e80941Smrg
291b8e80941Smrg   list = display->ResourceLists[_EGL_RESOURCE_SYNC];
292b8e80941Smrg   while (list) {
293b8e80941Smrg      _EGLSync *sync = (_EGLSync *) list;
294b8e80941Smrg      list = list->Next;
295b8e80941Smrg
296b8e80941Smrg      _eglUnlinkSync(sync);
297b8e80941Smrg      drv->API.DestroySyncKHR(drv, display, sync);
298b8e80941Smrg   }
299b8e80941Smrg   assert(!display->ResourceLists[_EGL_RESOURCE_SYNC]);
300848b8605Smrg}
301848b8605Smrg
302848b8605Smrg
303848b8605Smrg/**
304848b8605Smrg * Free all the data hanging of an _EGLDisplay object, but not
305848b8605Smrg * the object itself.
306848b8605Smrg */
307848b8605Smrgvoid
308848b8605Smrg_eglCleanupDisplay(_EGLDisplay *disp)
309848b8605Smrg{
310848b8605Smrg   if (disp->Configs) {
311848b8605Smrg      _eglDestroyArray(disp->Configs, free);
312848b8605Smrg      disp->Configs = NULL;
313848b8605Smrg   }
314848b8605Smrg
315848b8605Smrg   /* XXX incomplete */
316848b8605Smrg}
317848b8605Smrg
318848b8605Smrg
319848b8605Smrg/**
320848b8605Smrg * Return EGL_TRUE if the given handle is a valid handle to a display.
321848b8605Smrg */
322848b8605SmrgEGLBoolean
323848b8605Smrg_eglCheckDisplayHandle(EGLDisplay dpy)
324848b8605Smrg{
325848b8605Smrg   _EGLDisplay *cur;
326848b8605Smrg
327b8e80941Smrg   mtx_lock(_eglGlobal.Mutex);
328848b8605Smrg   cur = _eglGlobal.DisplayList;
329848b8605Smrg   while (cur) {
330848b8605Smrg      if (cur == (_EGLDisplay *) dpy)
331848b8605Smrg         break;
332848b8605Smrg      cur = cur->Next;
333848b8605Smrg   }
334b8e80941Smrg   mtx_unlock(_eglGlobal.Mutex);
335848b8605Smrg   return (cur != NULL);
336848b8605Smrg}
337848b8605Smrg
338848b8605Smrg
339848b8605Smrg/**
340848b8605Smrg * Return EGL_TRUE if the given resource is valid.  That is, the display does
341848b8605Smrg * own the resource.
342848b8605Smrg */
343848b8605SmrgEGLBoolean
344b8e80941Smrg_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *disp)
345848b8605Smrg{
346b8e80941Smrg   _EGLResource *list = disp->ResourceLists[type];
347848b8605Smrg
348848b8605Smrg   if (!res)
349848b8605Smrg      return EGL_FALSE;
350848b8605Smrg
351848b8605Smrg   while (list) {
352848b8605Smrg      if (res == (void *) list) {
353b8e80941Smrg         assert(list->Display == disp);
354848b8605Smrg         break;
355848b8605Smrg      }
356848b8605Smrg      list = list->Next;
357848b8605Smrg   }
358848b8605Smrg
359848b8605Smrg   return (list != NULL);
360848b8605Smrg}
361848b8605Smrg
362848b8605Smrg
363848b8605Smrg/**
364848b8605Smrg * Initialize a display resource.  The size of the subclass object is
365848b8605Smrg * specified.
366848b8605Smrg *
367848b8605Smrg * This is supposed to be called from the initializers of subclasses, such as
368848b8605Smrg * _eglInitContext or _eglInitSurface.
369848b8605Smrg */
370848b8605Smrgvoid
371b8e80941Smrg_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *disp)
372848b8605Smrg{
373848b8605Smrg   memset(res, 0, size);
374b8e80941Smrg   res->Display = disp;
375848b8605Smrg   res->RefCount = 1;
376848b8605Smrg}
377848b8605Smrg
378848b8605Smrg
379848b8605Smrg/**
380848b8605Smrg * Increment reference count for the resource.
381848b8605Smrg */
382848b8605Smrgvoid
383848b8605Smrg_eglGetResource(_EGLResource *res)
384848b8605Smrg{
385848b8605Smrg   assert(res && res->RefCount > 0);
386848b8605Smrg   /* hopefully a resource is always manipulated with its display locked */
387848b8605Smrg   res->RefCount++;
388848b8605Smrg}
389848b8605Smrg
390848b8605Smrg
391848b8605Smrg/**
392848b8605Smrg * Decrement reference count for the resource.
393848b8605Smrg */
394848b8605SmrgEGLBoolean
395848b8605Smrg_eglPutResource(_EGLResource *res)
396848b8605Smrg{
397848b8605Smrg   assert(res && res->RefCount > 0);
398848b8605Smrg   res->RefCount--;
399848b8605Smrg   return (!res->RefCount);
400848b8605Smrg}
401848b8605Smrg
402848b8605Smrg
403848b8605Smrg/**
404848b8605Smrg * Link a resource to its display.
405848b8605Smrg */
406848b8605Smrgvoid
407848b8605Smrg_eglLinkResource(_EGLResource *res, _EGLResourceType type)
408848b8605Smrg{
409848b8605Smrg   assert(res->Display);
410848b8605Smrg
411848b8605Smrg   res->IsLinked = EGL_TRUE;
412848b8605Smrg   res->Next = res->Display->ResourceLists[type];
413848b8605Smrg   res->Display->ResourceLists[type] = res;
414848b8605Smrg   _eglGetResource(res);
415848b8605Smrg}
416848b8605Smrg
417848b8605Smrg
418848b8605Smrg/**
419848b8605Smrg * Unlink a linked resource from its display.
420848b8605Smrg */
421848b8605Smrgvoid
422848b8605Smrg_eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
423848b8605Smrg{
424848b8605Smrg   _EGLResource *prev;
425848b8605Smrg
426848b8605Smrg   prev = res->Display->ResourceLists[type];
427848b8605Smrg   if (prev != res) {
428848b8605Smrg      while (prev) {
429848b8605Smrg         if (prev->Next == res)
430848b8605Smrg            break;
431848b8605Smrg         prev = prev->Next;
432848b8605Smrg      }
433848b8605Smrg      assert(prev);
434848b8605Smrg      prev->Next = res->Next;
435848b8605Smrg   }
436848b8605Smrg   else {
437848b8605Smrg      res->Display->ResourceLists[type] = res->Next;
438848b8605Smrg   }
439848b8605Smrg
440848b8605Smrg   res->Next = NULL;
441848b8605Smrg   res->IsLinked = EGL_FALSE;
442848b8605Smrg   _eglPutResource(res);
443848b8605Smrg
444848b8605Smrg   /* We always unlink before destroy.  The driver still owns a reference */
445848b8605Smrg   assert(res->RefCount);
446848b8605Smrg}
447848b8605Smrg
448848b8605Smrg#ifdef HAVE_X11_PLATFORM
449848b8605Smrgstatic EGLBoolean
450b8e80941Smrg_eglParseX11DisplayAttribList(_EGLDisplay *display,
451b8e80941Smrg                              const EGLAttrib *attrib_list)
452848b8605Smrg{
453848b8605Smrg   int i;
454848b8605Smrg
455848b8605Smrg   if (attrib_list == NULL) {
456848b8605Smrg      return EGL_TRUE;
457848b8605Smrg   }
458848b8605Smrg
459848b8605Smrg   for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
460b8e80941Smrg      EGLAttrib attrib = attrib_list[i];
461b8e80941Smrg      EGLAttrib value = attrib_list[i + 1];
462848b8605Smrg
463848b8605Smrg      /* EGL_EXT_platform_x11 recognizes exactly one attribute,
464848b8605Smrg       * EGL_PLATFORM_X11_SCREEN_EXT, which is optional.
465848b8605Smrg       */
466b8e80941Smrg      if (attrib != EGL_PLATFORM_X11_SCREEN_EXT)
467b8e80941Smrg         return _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
468b8e80941Smrg
469b8e80941Smrg      display->Options.Platform = (void *)(uintptr_t)value;
470848b8605Smrg   }
471848b8605Smrg
472848b8605Smrg   return EGL_TRUE;
473848b8605Smrg}
474848b8605Smrg
475848b8605Smrg_EGLDisplay*
476848b8605Smrg_eglGetX11Display(Display *native_display,
477b8e80941Smrg                  const EGLAttrib *attrib_list)
478848b8605Smrg{
479b8e80941Smrg   _EGLDisplay *display = _eglFindDisplay(_EGL_PLATFORM_X11,
480b8e80941Smrg                                          native_display);
481b8e80941Smrg
482b8e80941Smrg   if (!display) {
483b8e80941Smrg      _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay");
484848b8605Smrg      return NULL;
485848b8605Smrg   }
486848b8605Smrg
487b8e80941Smrg   if (!_eglParseX11DisplayAttribList(display, attrib_list)) {
488b8e80941Smrg      return NULL;
489b8e80941Smrg   }
490b8e80941Smrg
491b8e80941Smrg   return display;
492848b8605Smrg}
493848b8605Smrg#endif /* HAVE_X11_PLATFORM */
494848b8605Smrg
495848b8605Smrg#ifdef HAVE_DRM_PLATFORM
496848b8605Smrg_EGLDisplay*
497848b8605Smrg_eglGetGbmDisplay(struct gbm_device *native_display,
498b8e80941Smrg                  const EGLAttrib *attrib_list)
499848b8605Smrg{
500848b8605Smrg   /* EGL_MESA_platform_gbm recognizes no attributes. */
501848b8605Smrg   if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
502848b8605Smrg      _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
503848b8605Smrg      return NULL;
504848b8605Smrg   }
505848b8605Smrg
506848b8605Smrg   return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display);
507848b8605Smrg}
508848b8605Smrg#endif /* HAVE_DRM_PLATFORM */
509848b8605Smrg
510848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
511848b8605Smrg_EGLDisplay*
512848b8605Smrg_eglGetWaylandDisplay(struct wl_display *native_display,
513b8e80941Smrg                      const EGLAttrib *attrib_list)
514848b8605Smrg{
515848b8605Smrg   /* EGL_EXT_platform_wayland recognizes no attributes. */
516848b8605Smrg   if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
517848b8605Smrg      _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
518848b8605Smrg      return NULL;
519848b8605Smrg   }
520848b8605Smrg
521848b8605Smrg   return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display);
522848b8605Smrg}
523848b8605Smrg#endif /* HAVE_WAYLAND_PLATFORM */
524b8e80941Smrg
525b8e80941Smrg#ifdef HAVE_SURFACELESS_PLATFORM
526b8e80941Smrg_EGLDisplay*
527b8e80941Smrg_eglGetSurfacelessDisplay(void *native_display,
528b8e80941Smrg                          const EGLAttrib *attrib_list)
529b8e80941Smrg{
530b8e80941Smrg   /* This platform has no native display. */
531b8e80941Smrg   if (native_display != NULL) {
532b8e80941Smrg      _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
533b8e80941Smrg      return NULL;
534b8e80941Smrg   }
535b8e80941Smrg
536b8e80941Smrg   /* This platform recognizes no display attributes. */
537b8e80941Smrg   if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
538b8e80941Smrg      _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
539b8e80941Smrg      return NULL;
540b8e80941Smrg   }
541b8e80941Smrg
542b8e80941Smrg   return _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display);
543b8e80941Smrg}
544b8e80941Smrg#endif /* HAVE_SURFACELESS_PLATFORM */
545