egldisplay.c revision 7e102996
13464ebd5Sriastradh/************************************************************************** 23464ebd5Sriastradh * 3af69d88dSmrg * Copyright 2008 VMware, Inc. 43464ebd5Sriastradh * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 53464ebd5Sriastradh * Copyright 2010-2011 LunarG, Inc. 63464ebd5Sriastradh * All Rights Reserved. 73464ebd5Sriastradh * 83464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 93464ebd5Sriastradh * copy of this software and associated documentation files (the 103464ebd5Sriastradh * "Software"), to deal in the Software without restriction, including 113464ebd5Sriastradh * without limitation the rights to use, copy, modify, merge, publish, 123464ebd5Sriastradh * distribute, sub license, and/or sell copies of the Software, and to 133464ebd5Sriastradh * permit persons to whom the Software is furnished to do so, subject to 143464ebd5Sriastradh * the following conditions: 153464ebd5Sriastradh * 163464ebd5Sriastradh * The above copyright notice and this permission notice (including the 173464ebd5Sriastradh * next paragraph) shall be included in all copies or substantial portions 183464ebd5Sriastradh * of the Software. 193464ebd5Sriastradh * 203464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 213464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 223464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 233464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 243464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 253464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 263464ebd5Sriastradh * DEALINGS IN THE SOFTWARE. 273464ebd5Sriastradh * 283464ebd5Sriastradh **************************************************************************/ 293464ebd5Sriastradh 303464ebd5Sriastradh 314a49301eSmrg/** 324a49301eSmrg * Functions related to EGLDisplay. 334a49301eSmrg */ 344a49301eSmrg 354a49301eSmrg#include <assert.h> 364a49301eSmrg#include <stdlib.h> 374a49301eSmrg#include <string.h> 3801e04c3fSmrg#include "c11/threads.h" 3901e04c3fSmrg#include "util/u_atomic.h" 4001e04c3fSmrg 414a49301eSmrg#include "eglcontext.h" 42af69d88dSmrg#include "eglcurrent.h" 434a49301eSmrg#include "eglsurface.h" 444a49301eSmrg#include "egldisplay.h" 454a49301eSmrg#include "egldriver.h" 464a49301eSmrg#include "eglglobals.h" 474a49301eSmrg#include "egllog.h" 4801e04c3fSmrg#include "eglimage.h" 4901e04c3fSmrg#include "eglsync.h" 504a49301eSmrg 51af69d88dSmrg/* Includes for _eglNativePlatformDetectNativeDisplay */ 52af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 53af69d88dSmrg#include <wayland-client.h> 54af69d88dSmrg#endif 55af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 56af69d88dSmrg#include <gbm.h> 57af69d88dSmrg#endif 58af69d88dSmrg 59af69d88dSmrg 60af69d88dSmrg/** 617e102996Smaya * Map build-system platform names to platform types. 62af69d88dSmrg */ 63af69d88dSmrgstatic const struct { 64af69d88dSmrg _EGLPlatformType platform; 65af69d88dSmrg const char *name; 66af69d88dSmrg} egl_platforms[_EGL_NUM_PLATFORMS] = { 67af69d88dSmrg { _EGL_PLATFORM_X11, "x11" }, 68af69d88dSmrg { _EGL_PLATFORM_WAYLAND, "wayland" }, 69af69d88dSmrg { _EGL_PLATFORM_DRM, "drm" }, 7001e04c3fSmrg { _EGL_PLATFORM_ANDROID, "android" }, 7101e04c3fSmrg { _EGL_PLATFORM_HAIKU, "haiku" }, 7201e04c3fSmrg { _EGL_PLATFORM_SURFACELESS, "surfaceless" }, 73af69d88dSmrg}; 74af69d88dSmrg 754a49301eSmrg 763464ebd5Sriastradh/** 773464ebd5Sriastradh * Return the native platform by parsing EGL_PLATFORM. 783464ebd5Sriastradh */ 793464ebd5Sriastradhstatic _EGLPlatformType 803464ebd5Sriastradh_eglGetNativePlatformFromEnv(void) 813464ebd5Sriastradh{ 823464ebd5Sriastradh _EGLPlatformType plat = _EGL_INVALID_PLATFORM; 833464ebd5Sriastradh const char *plat_name; 843464ebd5Sriastradh EGLint i; 853464ebd5Sriastradh 863464ebd5Sriastradh plat_name = getenv("EGL_PLATFORM"); 873464ebd5Sriastradh /* try deprecated env variable */ 883464ebd5Sriastradh if (!plat_name || !plat_name[0]) 893464ebd5Sriastradh plat_name = getenv("EGL_DISPLAY"); 903464ebd5Sriastradh if (!plat_name || !plat_name[0]) 913464ebd5Sriastradh return _EGL_INVALID_PLATFORM; 923464ebd5Sriastradh 933464ebd5Sriastradh for (i = 0; i < _EGL_NUM_PLATFORMS; i++) { 943464ebd5Sriastradh if (strcmp(egl_platforms[i].name, plat_name) == 0) { 953464ebd5Sriastradh plat = egl_platforms[i].platform; 963464ebd5Sriastradh break; 973464ebd5Sriastradh } 983464ebd5Sriastradh } 993464ebd5Sriastradh 1003464ebd5Sriastradh return plat; 1013464ebd5Sriastradh} 1023464ebd5Sriastradh 1033464ebd5Sriastradh 104af69d88dSmrg/** 105af69d88dSmrg * Try detecting native platform with the help of native display characteristcs. 106af69d88dSmrg */ 107af69d88dSmrgstatic _EGLPlatformType 108af69d88dSmrg_eglNativePlatformDetectNativeDisplay(void *nativeDisplay) 109af69d88dSmrg{ 110af69d88dSmrg if (nativeDisplay == EGL_DEFAULT_DISPLAY) 111af69d88dSmrg return _EGL_INVALID_PLATFORM; 112af69d88dSmrg 113af69d88dSmrg if (_eglPointerIsDereferencable(nativeDisplay)) { 114af69d88dSmrg void *first_pointer = *(void **) nativeDisplay; 115af69d88dSmrg 116af69d88dSmrg (void) first_pointer; /* silence unused var warning */ 117af69d88dSmrg 118af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 119af69d88dSmrg /* wl_display is a wl_proxy, which is a wl_object. 120af69d88dSmrg * wl_object's first element points to the interfacetype. */ 121af69d88dSmrg if (first_pointer == &wl_display_interface) 122af69d88dSmrg return _EGL_PLATFORM_WAYLAND; 123af69d88dSmrg#endif 124af69d88dSmrg 125af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 126af69d88dSmrg /* gbm has a pointer to its constructor as first element. */ 127af69d88dSmrg if (first_pointer == gbm_create_device) 128af69d88dSmrg return _EGL_PLATFORM_DRM; 129af69d88dSmrg#endif 130af69d88dSmrg 131af69d88dSmrg#ifdef HAVE_X11_PLATFORM 132af69d88dSmrg /* If not matched to any other platform, fallback to x11. */ 133af69d88dSmrg return _EGL_PLATFORM_X11; 134af69d88dSmrg#endif 13501e04c3fSmrg 13601e04c3fSmrg#ifdef HAVE_HAIKU_PLATFORM 13701e04c3fSmrg return _EGL_PLATFORM_HAIKU; 13801e04c3fSmrg#endif 139af69d88dSmrg } 140af69d88dSmrg 141af69d88dSmrg return _EGL_INVALID_PLATFORM; 142af69d88dSmrg} 143af69d88dSmrg 144af69d88dSmrg 1453464ebd5Sriastradh/** 1463464ebd5Sriastradh * Return the native platform. It is the platform of the EGL native types. 1473464ebd5Sriastradh */ 1483464ebd5Sriastradh_EGLPlatformType 149af69d88dSmrg_eglGetNativePlatform(void *nativeDisplay) 1503464ebd5Sriastradh{ 1513464ebd5Sriastradh static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM; 15201e04c3fSmrg _EGLPlatformType detected_platform = native_platform; 15301e04c3fSmrg 15401e04c3fSmrg if (detected_platform == _EGL_INVALID_PLATFORM) { 15501e04c3fSmrg const char *detection_method; 1563464ebd5Sriastradh 15701e04c3fSmrg detected_platform = _eglGetNativePlatformFromEnv(); 158af69d88dSmrg detection_method = "environment overwrite"; 15901e04c3fSmrg 16001e04c3fSmrg if (detected_platform == _EGL_INVALID_PLATFORM) { 16101e04c3fSmrg detected_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay); 162af69d88dSmrg detection_method = "autodetected"; 163af69d88dSmrg } 1643464ebd5Sriastradh 16501e04c3fSmrg if (detected_platform == _EGL_INVALID_PLATFORM) { 16601e04c3fSmrg detected_platform = _EGL_NATIVE_PLATFORM; 16701e04c3fSmrg detection_method = "build-time configuration"; 16801e04c3fSmrg } 16901e04c3fSmrg 170af69d88dSmrg _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)", 17101e04c3fSmrg egl_platforms[detected_platform].name, detection_method); 17201e04c3fSmrg 17301e04c3fSmrg p_atomic_cmpxchg(&native_platform, _EGL_INVALID_PLATFORM, 17401e04c3fSmrg detected_platform); 17501e04c3fSmrg } 176af69d88dSmrg 1773464ebd5Sriastradh return native_platform; 1783464ebd5Sriastradh} 1793464ebd5Sriastradh 1803464ebd5Sriastradh 1814a49301eSmrg/** 1824a49301eSmrg * Finish display management. 1834a49301eSmrg */ 1844a49301eSmrgvoid 1854a49301eSmrg_eglFiniDisplay(void) 1864a49301eSmrg{ 1877e102996Smaya _EGLDisplay *dispList, *disp; 1884a49301eSmrg 1894a49301eSmrg /* atexit function is called with global mutex locked */ 1907e102996Smaya dispList = _eglGlobal.DisplayList; 1917e102996Smaya while (dispList) { 192cdc920a0Smrg EGLint i; 193cdc920a0Smrg 1944a49301eSmrg /* pop list head */ 1957e102996Smaya disp = dispList; 1967e102996Smaya dispList = dispList->Next; 1974a49301eSmrg 198cdc920a0Smrg for (i = 0; i < _EGL_NUM_RESOURCES; i++) { 1997e102996Smaya if (disp->ResourceLists[i]) { 2007e102996Smaya _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", disp); 201cdc920a0Smrg break; 202cdc920a0Smrg } 203cdc920a0Smrg } 2044a49301eSmrg 2057e102996Smaya free(disp); 2064a49301eSmrg } 2074a49301eSmrg _eglGlobal.DisplayList = NULL; 2084a49301eSmrg} 2094a49301eSmrg 2104a49301eSmrg 2114a49301eSmrg/** 212cdc920a0Smrg * Find the display corresponding to the specified native display, or create a 213cdc920a0Smrg * new one. 2144a49301eSmrg */ 2154a49301eSmrg_EGLDisplay * 2163464ebd5Sriastradh_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy) 2174a49301eSmrg{ 2187e102996Smaya _EGLDisplay *disp; 2194a49301eSmrg 2203464ebd5Sriastradh if (plat == _EGL_INVALID_PLATFORM) 2213464ebd5Sriastradh return NULL; 2223464ebd5Sriastradh 22301e04c3fSmrg mtx_lock(_eglGlobal.Mutex); 2244a49301eSmrg 225cdc920a0Smrg /* search the display list first */ 2267e102996Smaya disp = _eglGlobal.DisplayList; 2277e102996Smaya while (disp) { 2287e102996Smaya if (disp->Platform == plat && disp->PlatformDisplay == plat_dpy) 229cdc920a0Smrg break; 2307e102996Smaya disp = disp->Next; 2314a49301eSmrg } 2324a49301eSmrg 233cdc920a0Smrg /* create a new display */ 2347e102996Smaya if (!disp) { 2357e102996Smaya disp = calloc(1, sizeof(_EGLDisplay)); 2367e102996Smaya if (disp) { 2377e102996Smaya mtx_init(&disp->Mutex, mtx_plain); 2387e102996Smaya disp->Platform = plat; 2397e102996Smaya disp->PlatformDisplay = plat_dpy; 240cdc920a0Smrg 241cdc920a0Smrg /* add to the display list */ 2427e102996Smaya disp->Next = _eglGlobal.DisplayList; 2437e102996Smaya _eglGlobal.DisplayList = disp; 244cdc920a0Smrg } 245cdc920a0Smrg } 246cdc920a0Smrg 24701e04c3fSmrg mtx_unlock(_eglGlobal.Mutex); 2484a49301eSmrg 2497e102996Smaya return disp; 2504a49301eSmrg} 2514a49301eSmrg 2524a49301eSmrg 2534a49301eSmrg/** 2544a49301eSmrg * Destroy the contexts and surfaces that are linked to the display. 2554a49301eSmrg */ 2564a49301eSmrgvoid 2574a49301eSmrg_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) 2584a49301eSmrg{ 259cdc920a0Smrg _EGLResource *list; 2604a49301eSmrg 261cdc920a0Smrg list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; 262cdc920a0Smrg while (list) { 263cdc920a0Smrg _EGLContext *ctx = (_EGLContext *) list; 264cdc920a0Smrg list = list->Next; 2654a49301eSmrg 2664a49301eSmrg _eglUnlinkContext(ctx); 2674a49301eSmrg drv->API.DestroyContext(drv, display, ctx); 2684a49301eSmrg } 269cdc920a0Smrg assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); 2704a49301eSmrg 271cdc920a0Smrg list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; 272cdc920a0Smrg while (list) { 273cdc920a0Smrg _EGLSurface *surf = (_EGLSurface *) list; 274cdc920a0Smrg list = list->Next; 2754a49301eSmrg 2764a49301eSmrg _eglUnlinkSurface(surf); 2774a49301eSmrg drv->API.DestroySurface(drv, display, surf); 2784a49301eSmrg } 279cdc920a0Smrg assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); 28001e04c3fSmrg 28101e04c3fSmrg list = display->ResourceLists[_EGL_RESOURCE_IMAGE]; 28201e04c3fSmrg while (list) { 28301e04c3fSmrg _EGLImage *image = (_EGLImage *) list; 28401e04c3fSmrg list = list->Next; 28501e04c3fSmrg 28601e04c3fSmrg _eglUnlinkImage(image); 28701e04c3fSmrg drv->API.DestroyImageKHR(drv, display, image); 28801e04c3fSmrg } 28901e04c3fSmrg assert(!display->ResourceLists[_EGL_RESOURCE_IMAGE]); 29001e04c3fSmrg 29101e04c3fSmrg list = display->ResourceLists[_EGL_RESOURCE_SYNC]; 29201e04c3fSmrg while (list) { 29301e04c3fSmrg _EGLSync *sync = (_EGLSync *) list; 29401e04c3fSmrg list = list->Next; 29501e04c3fSmrg 29601e04c3fSmrg _eglUnlinkSync(sync); 29701e04c3fSmrg drv->API.DestroySyncKHR(drv, display, sync); 29801e04c3fSmrg } 29901e04c3fSmrg assert(!display->ResourceLists[_EGL_RESOURCE_SYNC]); 3004a49301eSmrg} 3014a49301eSmrg 3024a49301eSmrg 3034a49301eSmrg/** 3044a49301eSmrg * Free all the data hanging of an _EGLDisplay object, but not 3054a49301eSmrg * the object itself. 3064a49301eSmrg */ 3074a49301eSmrgvoid 3084a49301eSmrg_eglCleanupDisplay(_EGLDisplay *disp) 3094a49301eSmrg{ 3104a49301eSmrg if (disp->Configs) { 3113464ebd5Sriastradh _eglDestroyArray(disp->Configs, free); 3124a49301eSmrg disp->Configs = NULL; 3134a49301eSmrg } 3144a49301eSmrg 3154a49301eSmrg /* XXX incomplete */ 3164a49301eSmrg} 3174a49301eSmrg 3184a49301eSmrg 3194a49301eSmrg/** 3204a49301eSmrg * Return EGL_TRUE if the given handle is a valid handle to a display. 3214a49301eSmrg */ 3224a49301eSmrgEGLBoolean 3234a49301eSmrg_eglCheckDisplayHandle(EGLDisplay dpy) 3244a49301eSmrg{ 3254a49301eSmrg _EGLDisplay *cur; 3264a49301eSmrg 32701e04c3fSmrg mtx_lock(_eglGlobal.Mutex); 3284a49301eSmrg cur = _eglGlobal.DisplayList; 3294a49301eSmrg while (cur) { 3304a49301eSmrg if (cur == (_EGLDisplay *) dpy) 3314a49301eSmrg break; 3324a49301eSmrg cur = cur->Next; 3334a49301eSmrg } 33401e04c3fSmrg mtx_unlock(_eglGlobal.Mutex); 3354a49301eSmrg return (cur != NULL); 3364a49301eSmrg} 3374a49301eSmrg 3384a49301eSmrg 3394a49301eSmrg/** 340cdc920a0Smrg * Return EGL_TRUE if the given resource is valid. That is, the display does 341cdc920a0Smrg * own the resource. 3424a49301eSmrg */ 3434a49301eSmrgEGLBoolean 3447e102996Smaya_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *disp) 3454a49301eSmrg{ 3467e102996Smaya _EGLResource *list = disp->ResourceLists[type]; 347cdc920a0Smrg 348cdc920a0Smrg if (!res) 349cdc920a0Smrg return EGL_FALSE; 350cdc920a0Smrg 351cdc920a0Smrg while (list) { 352cdc920a0Smrg if (res == (void *) list) { 3537e102996Smaya assert(list->Display == disp); 3544a49301eSmrg break; 3554a49301eSmrg } 356cdc920a0Smrg list = list->Next; 3574a49301eSmrg } 358cdc920a0Smrg 359cdc920a0Smrg return (list != NULL); 3604a49301eSmrg} 3614a49301eSmrg 3624a49301eSmrg 3634a49301eSmrg/** 364af69d88dSmrg * Initialize a display resource. The size of the subclass object is 365af69d88dSmrg * specified. 366af69d88dSmrg * 367af69d88dSmrg * This is supposed to be called from the initializers of subclasses, such as 368af69d88dSmrg * _eglInitContext or _eglInitSurface. 3694a49301eSmrg */ 370cdc920a0Smrgvoid 3717e102996Smaya_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *disp) 3724a49301eSmrg{ 3733464ebd5Sriastradh memset(res, 0, size); 3747e102996Smaya res->Display = disp; 3753464ebd5Sriastradh res->RefCount = 1; 3763464ebd5Sriastradh} 3773464ebd5Sriastradh 3783464ebd5Sriastradh 3793464ebd5Sriastradh/** 3803464ebd5Sriastradh * Increment reference count for the resource. 3813464ebd5Sriastradh */ 3823464ebd5Sriastradhvoid 3833464ebd5Sriastradh_eglGetResource(_EGLResource *res) 3843464ebd5Sriastradh{ 3853464ebd5Sriastradh assert(res && res->RefCount > 0); 3863464ebd5Sriastradh /* hopefully a resource is always manipulated with its display locked */ 3873464ebd5Sriastradh res->RefCount++; 3883464ebd5Sriastradh} 3893464ebd5Sriastradh 3903464ebd5Sriastradh 3913464ebd5Sriastradh/** 3923464ebd5Sriastradh * Decrement reference count for the resource. 3933464ebd5Sriastradh */ 3943464ebd5SriastradhEGLBoolean 3953464ebd5Sriastradh_eglPutResource(_EGLResource *res) 3963464ebd5Sriastradh{ 3973464ebd5Sriastradh assert(res && res->RefCount > 0); 3983464ebd5Sriastradh res->RefCount--; 3993464ebd5Sriastradh return (!res->RefCount); 4003464ebd5Sriastradh} 4013464ebd5Sriastradh 4023464ebd5Sriastradh 4033464ebd5Sriastradh/** 4043464ebd5Sriastradh * Link a resource to its display. 4053464ebd5Sriastradh */ 4063464ebd5Sriastradhvoid 4073464ebd5Sriastradh_eglLinkResource(_EGLResource *res, _EGLResourceType type) 4083464ebd5Sriastradh{ 4093464ebd5Sriastradh assert(res->Display); 4103464ebd5Sriastradh 411cdc920a0Smrg res->IsLinked = EGL_TRUE; 4123464ebd5Sriastradh res->Next = res->Display->ResourceLists[type]; 4133464ebd5Sriastradh res->Display->ResourceLists[type] = res; 4143464ebd5Sriastradh _eglGetResource(res); 4154a49301eSmrg} 4164a49301eSmrg 4174a49301eSmrg 418cdc920a0Smrg/** 419cdc920a0Smrg * Unlink a linked resource from its display. 420cdc920a0Smrg */ 421cdc920a0Smrgvoid 422cdc920a0Smrg_eglUnlinkResource(_EGLResource *res, _EGLResourceType type) 423cdc920a0Smrg{ 424cdc920a0Smrg _EGLResource *prev; 425cdc920a0Smrg 426cdc920a0Smrg prev = res->Display->ResourceLists[type]; 427cdc920a0Smrg if (prev != res) { 428cdc920a0Smrg while (prev) { 429cdc920a0Smrg if (prev->Next == res) 430cdc920a0Smrg break; 431cdc920a0Smrg prev = prev->Next; 432cdc920a0Smrg } 433cdc920a0Smrg assert(prev); 434cdc920a0Smrg prev->Next = res->Next; 435cdc920a0Smrg } 436cdc920a0Smrg else { 437cdc920a0Smrg res->Display->ResourceLists[type] = res->Next; 438cdc920a0Smrg } 439cdc920a0Smrg 440cdc920a0Smrg res->Next = NULL; 441cdc920a0Smrg res->IsLinked = EGL_FALSE; 4423464ebd5Sriastradh _eglPutResource(res); 4433464ebd5Sriastradh 4443464ebd5Sriastradh /* We always unlink before destroy. The driver still owns a reference */ 4453464ebd5Sriastradh assert(res->RefCount); 446cdc920a0Smrg} 447af69d88dSmrg 448af69d88dSmrg#ifdef HAVE_X11_PLATFORM 449af69d88dSmrgstatic EGLBoolean 45001e04c3fSmrg_eglParseX11DisplayAttribList(_EGLDisplay *display, 45101e04c3fSmrg const EGLAttrib *attrib_list) 452af69d88dSmrg{ 453af69d88dSmrg int i; 454af69d88dSmrg 455af69d88dSmrg if (attrib_list == NULL) { 456af69d88dSmrg return EGL_TRUE; 457af69d88dSmrg } 458af69d88dSmrg 459af69d88dSmrg for (i = 0; attrib_list[i] != EGL_NONE; i += 2) { 46001e04c3fSmrg EGLAttrib attrib = attrib_list[i]; 46101e04c3fSmrg EGLAttrib value = attrib_list[i + 1]; 462af69d88dSmrg 463af69d88dSmrg /* EGL_EXT_platform_x11 recognizes exactly one attribute, 464af69d88dSmrg * EGL_PLATFORM_X11_SCREEN_EXT, which is optional. 465af69d88dSmrg */ 46601e04c3fSmrg if (attrib != EGL_PLATFORM_X11_SCREEN_EXT) 46701e04c3fSmrg return _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 46801e04c3fSmrg 46901e04c3fSmrg display->Options.Platform = (void *)(uintptr_t)value; 470af69d88dSmrg } 471af69d88dSmrg 472af69d88dSmrg return EGL_TRUE; 473af69d88dSmrg} 474af69d88dSmrg 475af69d88dSmrg_EGLDisplay* 476af69d88dSmrg_eglGetX11Display(Display *native_display, 47701e04c3fSmrg const EGLAttrib *attrib_list) 478af69d88dSmrg{ 47901e04c3fSmrg _EGLDisplay *display = _eglFindDisplay(_EGL_PLATFORM_X11, 48001e04c3fSmrg native_display); 48101e04c3fSmrg 48201e04c3fSmrg if (!display) { 48301e04c3fSmrg _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay"); 484af69d88dSmrg return NULL; 485af69d88dSmrg } 486af69d88dSmrg 48701e04c3fSmrg if (!_eglParseX11DisplayAttribList(display, attrib_list)) { 48801e04c3fSmrg return NULL; 48901e04c3fSmrg } 49001e04c3fSmrg 49101e04c3fSmrg return display; 492af69d88dSmrg} 493af69d88dSmrg#endif /* HAVE_X11_PLATFORM */ 494af69d88dSmrg 495af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 496af69d88dSmrg_EGLDisplay* 497af69d88dSmrg_eglGetGbmDisplay(struct gbm_device *native_display, 49801e04c3fSmrg const EGLAttrib *attrib_list) 499af69d88dSmrg{ 500af69d88dSmrg /* EGL_MESA_platform_gbm recognizes no attributes. */ 501af69d88dSmrg if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { 502af69d88dSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 503af69d88dSmrg return NULL; 504af69d88dSmrg } 505af69d88dSmrg 506af69d88dSmrg return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display); 507af69d88dSmrg} 508af69d88dSmrg#endif /* HAVE_DRM_PLATFORM */ 509af69d88dSmrg 510af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 511af69d88dSmrg_EGLDisplay* 512af69d88dSmrg_eglGetWaylandDisplay(struct wl_display *native_display, 51301e04c3fSmrg const EGLAttrib *attrib_list) 514af69d88dSmrg{ 515af69d88dSmrg /* EGL_EXT_platform_wayland recognizes no attributes. */ 516af69d88dSmrg if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { 517af69d88dSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 518af69d88dSmrg return NULL; 519af69d88dSmrg } 520af69d88dSmrg 521af69d88dSmrg return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display); 522af69d88dSmrg} 523af69d88dSmrg#endif /* HAVE_WAYLAND_PLATFORM */ 52401e04c3fSmrg 52501e04c3fSmrg#ifdef HAVE_SURFACELESS_PLATFORM 52601e04c3fSmrg_EGLDisplay* 52701e04c3fSmrg_eglGetSurfacelessDisplay(void *native_display, 52801e04c3fSmrg const EGLAttrib *attrib_list) 52901e04c3fSmrg{ 53001e04c3fSmrg /* This platform has no native display. */ 53101e04c3fSmrg if (native_display != NULL) { 53201e04c3fSmrg _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay"); 53301e04c3fSmrg return NULL; 53401e04c3fSmrg } 53501e04c3fSmrg 53601e04c3fSmrg /* This platform recognizes no display attributes. */ 53701e04c3fSmrg if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { 53801e04c3fSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 53901e04c3fSmrg return NULL; 54001e04c3fSmrg } 54101e04c3fSmrg 54201e04c3fSmrg return _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display); 54301e04c3fSmrg} 54401e04c3fSmrg#endif /* HAVE_SURFACELESS_PLATFORM */ 545