egldisplay.c revision af69d88d
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> 384a49301eSmrg#include "eglcontext.h" 39af69d88dSmrg#include "eglcurrent.h" 404a49301eSmrg#include "eglsurface.h" 414a49301eSmrg#include "egldisplay.h" 424a49301eSmrg#include "egldriver.h" 434a49301eSmrg#include "eglglobals.h" 444a49301eSmrg#include "eglmutex.h" 454a49301eSmrg#include "egllog.h" 464a49301eSmrg 47af69d88dSmrg/* Includes for _eglNativePlatformDetectNativeDisplay */ 48af69d88dSmrg#ifdef HAVE_MINCORE 49af69d88dSmrg#include <unistd.h> 50af69d88dSmrg#include <sys/mman.h> 51af69d88dSmrg#endif 52af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 53af69d88dSmrg#include <wayland-client.h> 54af69d88dSmrg#endif 55af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 56af69d88dSmrg#include <gbm.h> 57af69d88dSmrg#endif 58af69d88dSmrg#ifdef HAVE_FBDEV_PLATFORM 59af69d88dSmrg#include <stdint.h> 60af69d88dSmrg#include <sys/types.h> 61af69d88dSmrg#include <sys/stat.h> 62af69d88dSmrg#endif 63af69d88dSmrg 64af69d88dSmrg 65af69d88dSmrg/** 66af69d88dSmrg * Map --with-egl-platforms names to platform types. 67af69d88dSmrg */ 68af69d88dSmrgstatic const struct { 69af69d88dSmrg _EGLPlatformType platform; 70af69d88dSmrg const char *name; 71af69d88dSmrg} egl_platforms[_EGL_NUM_PLATFORMS] = { 72af69d88dSmrg { _EGL_PLATFORM_WINDOWS, "gdi" }, 73af69d88dSmrg { _EGL_PLATFORM_X11, "x11" }, 74af69d88dSmrg { _EGL_PLATFORM_WAYLAND, "wayland" }, 75af69d88dSmrg { _EGL_PLATFORM_DRM, "drm" }, 76af69d88dSmrg { _EGL_PLATFORM_FBDEV, "fbdev" }, 77af69d88dSmrg { _EGL_PLATFORM_NULL, "null" }, 78af69d88dSmrg { _EGL_PLATFORM_ANDROID, "android" } 79af69d88dSmrg}; 80af69d88dSmrg 814a49301eSmrg 823464ebd5Sriastradh/** 833464ebd5Sriastradh * Return the native platform by parsing EGL_PLATFORM. 843464ebd5Sriastradh */ 853464ebd5Sriastradhstatic _EGLPlatformType 863464ebd5Sriastradh_eglGetNativePlatformFromEnv(void) 873464ebd5Sriastradh{ 883464ebd5Sriastradh _EGLPlatformType plat = _EGL_INVALID_PLATFORM; 893464ebd5Sriastradh const char *plat_name; 903464ebd5Sriastradh EGLint i; 913464ebd5Sriastradh 923464ebd5Sriastradh plat_name = getenv("EGL_PLATFORM"); 933464ebd5Sriastradh /* try deprecated env variable */ 943464ebd5Sriastradh if (!plat_name || !plat_name[0]) 953464ebd5Sriastradh plat_name = getenv("EGL_DISPLAY"); 963464ebd5Sriastradh if (!plat_name || !plat_name[0]) 973464ebd5Sriastradh return _EGL_INVALID_PLATFORM; 983464ebd5Sriastradh 993464ebd5Sriastradh for (i = 0; i < _EGL_NUM_PLATFORMS; i++) { 1003464ebd5Sriastradh if (strcmp(egl_platforms[i].name, plat_name) == 0) { 1013464ebd5Sriastradh plat = egl_platforms[i].platform; 1023464ebd5Sriastradh break; 1033464ebd5Sriastradh } 1043464ebd5Sriastradh } 1053464ebd5Sriastradh 1063464ebd5Sriastradh return plat; 1073464ebd5Sriastradh} 1083464ebd5Sriastradh 1093464ebd5Sriastradh 110af69d88dSmrg/** 111af69d88dSmrg * Perform validity checks on a generic pointer. 112af69d88dSmrg */ 113af69d88dSmrgstatic EGLBoolean 114af69d88dSmrg_eglPointerIsDereferencable(void *p) 115af69d88dSmrg{ 116af69d88dSmrg#ifdef HAVE_MINCORE 117af69d88dSmrg uintptr_t addr = (uintptr_t) p; 118af69d88dSmrg unsigned char valid = 0; 119af69d88dSmrg const long page_size = getpagesize(); 120af69d88dSmrg 121af69d88dSmrg if (p == NULL) 122af69d88dSmrg return EGL_FALSE; 123af69d88dSmrg 124af69d88dSmrg /* align addr to page_size */ 125af69d88dSmrg addr &= ~(page_size - 1); 126af69d88dSmrg 127af69d88dSmrg if (mincore((void *) addr, page_size, &valid) < 0) { 128af69d88dSmrg _eglLog(_EGL_DEBUG, "mincore failed: %m"); 129af69d88dSmrg return EGL_FALSE; 130af69d88dSmrg } 131af69d88dSmrg 132af69d88dSmrg return (valid & 0x01) == 0x01; 133af69d88dSmrg#else 134af69d88dSmrg return p != NULL; 135af69d88dSmrg#endif 136af69d88dSmrg} 137af69d88dSmrg 138af69d88dSmrg 139af69d88dSmrg/** 140af69d88dSmrg * Try detecting native platform with the help of native display characteristcs. 141af69d88dSmrg */ 142af69d88dSmrgstatic _EGLPlatformType 143af69d88dSmrg_eglNativePlatformDetectNativeDisplay(void *nativeDisplay) 144af69d88dSmrg{ 145af69d88dSmrg#ifdef HAVE_FBDEV_PLATFORM 146af69d88dSmrg struct stat buf; 147af69d88dSmrg#endif 148af69d88dSmrg 149af69d88dSmrg if (nativeDisplay == EGL_DEFAULT_DISPLAY) 150af69d88dSmrg return _EGL_INVALID_PLATFORM; 151af69d88dSmrg 152af69d88dSmrg#ifdef HAVE_FBDEV_PLATFORM 153af69d88dSmrg /* fbdev is the only platform that can be a file descriptor. */ 154af69d88dSmrg if (fstat((intptr_t) nativeDisplay, &buf) == 0 && S_ISCHR(buf.st_mode)) 155af69d88dSmrg return _EGL_PLATFORM_FBDEV; 156af69d88dSmrg#endif 157af69d88dSmrg 158af69d88dSmrg if (_eglPointerIsDereferencable(nativeDisplay)) { 159af69d88dSmrg void *first_pointer = *(void **) nativeDisplay; 160af69d88dSmrg 161af69d88dSmrg (void) first_pointer; /* silence unused var warning */ 162af69d88dSmrg 163af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 164af69d88dSmrg /* wl_display is a wl_proxy, which is a wl_object. 165af69d88dSmrg * wl_object's first element points to the interfacetype. */ 166af69d88dSmrg if (first_pointer == &wl_display_interface) 167af69d88dSmrg return _EGL_PLATFORM_WAYLAND; 168af69d88dSmrg#endif 169af69d88dSmrg 170af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 171af69d88dSmrg /* gbm has a pointer to its constructor as first element. */ 172af69d88dSmrg if (first_pointer == gbm_create_device) 173af69d88dSmrg return _EGL_PLATFORM_DRM; 174af69d88dSmrg#endif 175af69d88dSmrg 176af69d88dSmrg#ifdef HAVE_X11_PLATFORM 177af69d88dSmrg /* If not matched to any other platform, fallback to x11. */ 178af69d88dSmrg return _EGL_PLATFORM_X11; 179af69d88dSmrg#endif 180af69d88dSmrg } 181af69d88dSmrg 182af69d88dSmrg return _EGL_INVALID_PLATFORM; 183af69d88dSmrg} 184af69d88dSmrg 185af69d88dSmrg 1863464ebd5Sriastradh/** 1873464ebd5Sriastradh * Return the native platform. It is the platform of the EGL native types. 1883464ebd5Sriastradh */ 1893464ebd5Sriastradh_EGLPlatformType 190af69d88dSmrg_eglGetNativePlatform(void *nativeDisplay) 1913464ebd5Sriastradh{ 1923464ebd5Sriastradh static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM; 193af69d88dSmrg char *detection_method = NULL; 1943464ebd5Sriastradh 1953464ebd5Sriastradh if (native_platform == _EGL_INVALID_PLATFORM) { 1963464ebd5Sriastradh native_platform = _eglGetNativePlatformFromEnv(); 197af69d88dSmrg detection_method = "environment overwrite"; 198af69d88dSmrg if (native_platform == _EGL_INVALID_PLATFORM) { 199af69d88dSmrg native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay); 200af69d88dSmrg detection_method = "autodetected"; 201af69d88dSmrg if (native_platform == _EGL_INVALID_PLATFORM) { 202af69d88dSmrg native_platform = _EGL_NATIVE_PLATFORM; 203af69d88dSmrg detection_method = "build-time configuration"; 204af69d88dSmrg } 205af69d88dSmrg } 2063464ebd5Sriastradh } 2073464ebd5Sriastradh 208af69d88dSmrg if (detection_method != NULL) 209af69d88dSmrg _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)", 210af69d88dSmrg egl_platforms[native_platform].name, detection_method); 211af69d88dSmrg 2123464ebd5Sriastradh return native_platform; 2133464ebd5Sriastradh} 2143464ebd5Sriastradh 2153464ebd5Sriastradh 2164a49301eSmrg/** 2174a49301eSmrg * Finish display management. 2184a49301eSmrg */ 2194a49301eSmrgvoid 2204a49301eSmrg_eglFiniDisplay(void) 2214a49301eSmrg{ 2224a49301eSmrg _EGLDisplay *dpyList, *dpy; 2234a49301eSmrg 2244a49301eSmrg /* atexit function is called with global mutex locked */ 2254a49301eSmrg dpyList = _eglGlobal.DisplayList; 2264a49301eSmrg while (dpyList) { 227cdc920a0Smrg EGLint i; 228cdc920a0Smrg 2294a49301eSmrg /* pop list head */ 2304a49301eSmrg dpy = dpyList; 2314a49301eSmrg dpyList = dpyList->Next; 2324a49301eSmrg 233cdc920a0Smrg for (i = 0; i < _EGL_NUM_RESOURCES; i++) { 234cdc920a0Smrg if (dpy->ResourceLists[i]) { 235cdc920a0Smrg _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); 236cdc920a0Smrg break; 237cdc920a0Smrg } 238cdc920a0Smrg } 2394a49301eSmrg 2404a49301eSmrg free(dpy); 2414a49301eSmrg } 2424a49301eSmrg _eglGlobal.DisplayList = NULL; 2434a49301eSmrg} 2444a49301eSmrg 2454a49301eSmrg 2464a49301eSmrg/** 247cdc920a0Smrg * Find the display corresponding to the specified native display, or create a 248cdc920a0Smrg * new one. 2494a49301eSmrg */ 2504a49301eSmrg_EGLDisplay * 2513464ebd5Sriastradh_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy) 2524a49301eSmrg{ 2534a49301eSmrg _EGLDisplay *dpy; 2544a49301eSmrg 2553464ebd5Sriastradh if (plat == _EGL_INVALID_PLATFORM) 2563464ebd5Sriastradh return NULL; 2573464ebd5Sriastradh 2584a49301eSmrg _eglLockMutex(_eglGlobal.Mutex); 2594a49301eSmrg 260cdc920a0Smrg /* search the display list first */ 2614a49301eSmrg dpy = _eglGlobal.DisplayList; 2624a49301eSmrg while (dpy) { 2633464ebd5Sriastradh if (dpy->Platform == plat && dpy->PlatformDisplay == plat_dpy) 264cdc920a0Smrg break; 2654a49301eSmrg dpy = dpy->Next; 2664a49301eSmrg } 2674a49301eSmrg 268cdc920a0Smrg /* create a new display */ 269cdc920a0Smrg if (!dpy) { 270af69d88dSmrg dpy = calloc(1, sizeof(_EGLDisplay)); 271cdc920a0Smrg if (dpy) { 272cdc920a0Smrg _eglInitMutex(&dpy->Mutex); 2733464ebd5Sriastradh dpy->Platform = plat; 2743464ebd5Sriastradh dpy->PlatformDisplay = plat_dpy; 275cdc920a0Smrg 276cdc920a0Smrg /* add to the display list */ 277cdc920a0Smrg dpy->Next = _eglGlobal.DisplayList; 278cdc920a0Smrg _eglGlobal.DisplayList = dpy; 279cdc920a0Smrg } 280cdc920a0Smrg } 281cdc920a0Smrg 2824a49301eSmrg _eglUnlockMutex(_eglGlobal.Mutex); 2834a49301eSmrg 284cdc920a0Smrg return dpy; 2854a49301eSmrg} 2864a49301eSmrg 2874a49301eSmrg 2884a49301eSmrg/** 2894a49301eSmrg * Destroy the contexts and surfaces that are linked to the display. 2904a49301eSmrg */ 2914a49301eSmrgvoid 2924a49301eSmrg_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) 2934a49301eSmrg{ 294cdc920a0Smrg _EGLResource *list; 2954a49301eSmrg 296cdc920a0Smrg list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; 297cdc920a0Smrg while (list) { 298cdc920a0Smrg _EGLContext *ctx = (_EGLContext *) list; 299cdc920a0Smrg list = list->Next; 3004a49301eSmrg 3014a49301eSmrg _eglUnlinkContext(ctx); 3024a49301eSmrg drv->API.DestroyContext(drv, display, ctx); 3034a49301eSmrg } 304cdc920a0Smrg assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); 3054a49301eSmrg 306cdc920a0Smrg list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; 307cdc920a0Smrg while (list) { 308cdc920a0Smrg _EGLSurface *surf = (_EGLSurface *) list; 309cdc920a0Smrg list = list->Next; 3104a49301eSmrg 3114a49301eSmrg _eglUnlinkSurface(surf); 3124a49301eSmrg drv->API.DestroySurface(drv, display, surf); 3134a49301eSmrg } 314cdc920a0Smrg assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); 3154a49301eSmrg} 3164a49301eSmrg 3174a49301eSmrg 3184a49301eSmrg/** 3194a49301eSmrg * Free all the data hanging of an _EGLDisplay object, but not 3204a49301eSmrg * the object itself. 3214a49301eSmrg */ 3224a49301eSmrgvoid 3234a49301eSmrg_eglCleanupDisplay(_EGLDisplay *disp) 3244a49301eSmrg{ 3254a49301eSmrg if (disp->Configs) { 3263464ebd5Sriastradh _eglDestroyArray(disp->Configs, free); 3274a49301eSmrg disp->Configs = NULL; 3284a49301eSmrg } 3294a49301eSmrg 3304a49301eSmrg /* XXX incomplete */ 3314a49301eSmrg} 3324a49301eSmrg 3334a49301eSmrg 3344a49301eSmrg/** 3354a49301eSmrg * Return EGL_TRUE if the given handle is a valid handle to a display. 3364a49301eSmrg */ 3374a49301eSmrgEGLBoolean 3384a49301eSmrg_eglCheckDisplayHandle(EGLDisplay dpy) 3394a49301eSmrg{ 3404a49301eSmrg _EGLDisplay *cur; 3414a49301eSmrg 3424a49301eSmrg _eglLockMutex(_eglGlobal.Mutex); 3434a49301eSmrg cur = _eglGlobal.DisplayList; 3444a49301eSmrg while (cur) { 3454a49301eSmrg if (cur == (_EGLDisplay *) dpy) 3464a49301eSmrg break; 3474a49301eSmrg cur = cur->Next; 3484a49301eSmrg } 3494a49301eSmrg _eglUnlockMutex(_eglGlobal.Mutex); 3504a49301eSmrg return (cur != NULL); 3514a49301eSmrg} 3524a49301eSmrg 3534a49301eSmrg 3544a49301eSmrg/** 355cdc920a0Smrg * Return EGL_TRUE if the given resource is valid. That is, the display does 356cdc920a0Smrg * own the resource. 3574a49301eSmrg */ 3584a49301eSmrgEGLBoolean 359cdc920a0Smrg_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy) 3604a49301eSmrg{ 361cdc920a0Smrg _EGLResource *list = dpy->ResourceLists[type]; 362cdc920a0Smrg 363cdc920a0Smrg if (!res) 364cdc920a0Smrg return EGL_FALSE; 365cdc920a0Smrg 366cdc920a0Smrg while (list) { 367cdc920a0Smrg if (res == (void *) list) { 368cdc920a0Smrg assert(list->Display == dpy); 3694a49301eSmrg break; 3704a49301eSmrg } 371cdc920a0Smrg list = list->Next; 3724a49301eSmrg } 373cdc920a0Smrg 374cdc920a0Smrg return (list != NULL); 3754a49301eSmrg} 3764a49301eSmrg 3774a49301eSmrg 3784a49301eSmrg/** 379af69d88dSmrg * Initialize a display resource. The size of the subclass object is 380af69d88dSmrg * specified. 381af69d88dSmrg * 382af69d88dSmrg * This is supposed to be called from the initializers of subclasses, such as 383af69d88dSmrg * _eglInitContext or _eglInitSurface. 3844a49301eSmrg */ 385cdc920a0Smrgvoid 3863464ebd5Sriastradh_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy) 3874a49301eSmrg{ 3883464ebd5Sriastradh memset(res, 0, size); 389cdc920a0Smrg res->Display = dpy; 3903464ebd5Sriastradh res->RefCount = 1; 3913464ebd5Sriastradh} 3923464ebd5Sriastradh 3933464ebd5Sriastradh 3943464ebd5Sriastradh/** 3953464ebd5Sriastradh * Increment reference count for the resource. 3963464ebd5Sriastradh */ 3973464ebd5Sriastradhvoid 3983464ebd5Sriastradh_eglGetResource(_EGLResource *res) 3993464ebd5Sriastradh{ 4003464ebd5Sriastradh assert(res && res->RefCount > 0); 4013464ebd5Sriastradh /* hopefully a resource is always manipulated with its display locked */ 4023464ebd5Sriastradh res->RefCount++; 4033464ebd5Sriastradh} 4043464ebd5Sriastradh 4053464ebd5Sriastradh 4063464ebd5Sriastradh/** 4073464ebd5Sriastradh * Decrement reference count for the resource. 4083464ebd5Sriastradh */ 4093464ebd5SriastradhEGLBoolean 4103464ebd5Sriastradh_eglPutResource(_EGLResource *res) 4113464ebd5Sriastradh{ 4123464ebd5Sriastradh assert(res && res->RefCount > 0); 4133464ebd5Sriastradh res->RefCount--; 4143464ebd5Sriastradh return (!res->RefCount); 4153464ebd5Sriastradh} 4163464ebd5Sriastradh 4173464ebd5Sriastradh 4183464ebd5Sriastradh/** 4193464ebd5Sriastradh * Link a resource to its display. 4203464ebd5Sriastradh */ 4213464ebd5Sriastradhvoid 4223464ebd5Sriastradh_eglLinkResource(_EGLResource *res, _EGLResourceType type) 4233464ebd5Sriastradh{ 4243464ebd5Sriastradh assert(res->Display); 4253464ebd5Sriastradh 426cdc920a0Smrg res->IsLinked = EGL_TRUE; 4273464ebd5Sriastradh res->Next = res->Display->ResourceLists[type]; 4283464ebd5Sriastradh res->Display->ResourceLists[type] = res; 4293464ebd5Sriastradh _eglGetResource(res); 4304a49301eSmrg} 4314a49301eSmrg 4324a49301eSmrg 433cdc920a0Smrg/** 434cdc920a0Smrg * Unlink a linked resource from its display. 435cdc920a0Smrg */ 436cdc920a0Smrgvoid 437cdc920a0Smrg_eglUnlinkResource(_EGLResource *res, _EGLResourceType type) 438cdc920a0Smrg{ 439cdc920a0Smrg _EGLResource *prev; 440cdc920a0Smrg 441cdc920a0Smrg prev = res->Display->ResourceLists[type]; 442cdc920a0Smrg if (prev != res) { 443cdc920a0Smrg while (prev) { 444cdc920a0Smrg if (prev->Next == res) 445cdc920a0Smrg break; 446cdc920a0Smrg prev = prev->Next; 447cdc920a0Smrg } 448cdc920a0Smrg assert(prev); 449cdc920a0Smrg prev->Next = res->Next; 450cdc920a0Smrg } 451cdc920a0Smrg else { 452cdc920a0Smrg res->Display->ResourceLists[type] = res->Next; 453cdc920a0Smrg } 454cdc920a0Smrg 455cdc920a0Smrg res->Next = NULL; 456cdc920a0Smrg res->IsLinked = EGL_FALSE; 4573464ebd5Sriastradh _eglPutResource(res); 4583464ebd5Sriastradh 4593464ebd5Sriastradh /* We always unlink before destroy. The driver still owns a reference */ 4603464ebd5Sriastradh assert(res->RefCount); 461cdc920a0Smrg} 462af69d88dSmrg 463af69d88dSmrg#ifdef HAVE_X11_PLATFORM 464af69d88dSmrgstatic EGLBoolean 465af69d88dSmrg_eglParseX11DisplayAttribList(const EGLint *attrib_list) 466af69d88dSmrg{ 467af69d88dSmrg int i; 468af69d88dSmrg 469af69d88dSmrg if (attrib_list == NULL) { 470af69d88dSmrg return EGL_TRUE; 471af69d88dSmrg } 472af69d88dSmrg 473af69d88dSmrg for (i = 0; attrib_list[i] != EGL_NONE; i += 2) { 474af69d88dSmrg EGLint attrib = attrib_list[i]; 475af69d88dSmrg EGLint value = attrib_list[i + 1]; 476af69d88dSmrg 477af69d88dSmrg /* EGL_EXT_platform_x11 recognizes exactly one attribute, 478af69d88dSmrg * EGL_PLATFORM_X11_SCREEN_EXT, which is optional. 479af69d88dSmrg * 480af69d88dSmrg * Mesa supports connecting to only the default screen, so we reject 481af69d88dSmrg * screen != 0. 482af69d88dSmrg */ 483af69d88dSmrg if (attrib != EGL_PLATFORM_X11_SCREEN_EXT || value != 0) { 484af69d88dSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 485af69d88dSmrg return EGL_FALSE; 486af69d88dSmrg } 487af69d88dSmrg } 488af69d88dSmrg 489af69d88dSmrg return EGL_TRUE; 490af69d88dSmrg} 491af69d88dSmrg 492af69d88dSmrg_EGLDisplay* 493af69d88dSmrg_eglGetX11Display(Display *native_display, 494af69d88dSmrg const EGLint *attrib_list) 495af69d88dSmrg{ 496af69d88dSmrg if (!_eglParseX11DisplayAttribList(attrib_list)) { 497af69d88dSmrg return NULL; 498af69d88dSmrg } 499af69d88dSmrg 500af69d88dSmrg return _eglFindDisplay(_EGL_PLATFORM_X11, native_display); 501af69d88dSmrg} 502af69d88dSmrg#endif /* HAVE_X11_PLATFORM */ 503af69d88dSmrg 504af69d88dSmrg#ifdef HAVE_DRM_PLATFORM 505af69d88dSmrg_EGLDisplay* 506af69d88dSmrg_eglGetGbmDisplay(struct gbm_device *native_display, 507af69d88dSmrg const EGLint *attrib_list) 508af69d88dSmrg{ 509af69d88dSmrg /* EGL_MESA_platform_gbm recognizes no attributes. */ 510af69d88dSmrg if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { 511af69d88dSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 512af69d88dSmrg return NULL; 513af69d88dSmrg } 514af69d88dSmrg 515af69d88dSmrg return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display); 516af69d88dSmrg} 517af69d88dSmrg#endif /* HAVE_DRM_PLATFORM */ 518af69d88dSmrg 519af69d88dSmrg#ifdef HAVE_WAYLAND_PLATFORM 520af69d88dSmrg_EGLDisplay* 521af69d88dSmrg_eglGetWaylandDisplay(struct wl_display *native_display, 522af69d88dSmrg const EGLint *attrib_list) 523af69d88dSmrg{ 524af69d88dSmrg /* EGL_EXT_platform_wayland recognizes no attributes. */ 525af69d88dSmrg if (attrib_list != NULL && attrib_list[0] != EGL_NONE) { 526af69d88dSmrg _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); 527af69d88dSmrg return NULL; 528af69d88dSmrg } 529af69d88dSmrg 530af69d88dSmrg return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display); 531af69d88dSmrg} 532af69d88dSmrg#endif /* HAVE_WAYLAND_PLATFORM */ 533