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