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