X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglglobals.c;h=f39cbfe4489b07e74caa434246d66c5b14efca0b;hp=5182b18e226f0e9443abf8dcc5dfc569ab62e141;hb=a38e21d6683aeecb51aea4f933a77c6e7f1a6179;hpb=653a83445f94620673f747a4ace6847a2c7fdb4d diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 5182b18e226..f39cbfe4489 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,28 +1,105 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * Copyright 2009-2010 Chia-I Wu + * Copyright 2010-2011 LunarG, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + #include +#include +#include #include +#include "c11/threads.h" + #include "eglglobals.h" +#include "egldevice.h" #include "egldisplay.h" #include "egldriver.h" -#include "eglmutex.h" +#include "util/macros.h" + +#ifdef HAVE_MINCORE +#include +#include +#endif -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +static mtx_t _eglGlobalMutex = _MTX_INITIALIZER_NP; -static _EGL_DECLARE_MUTEX(_eglGlobalMutex); struct _egl_global _eglGlobal = { - &_eglGlobalMutex, /* Mutex */ - NULL, /* DisplayList */ - 1, /* FreeScreenHandle */ - 0, /* NumDrivers */ - { NULL }, /* Drivers */ - 2, /* NumAtExitCalls */ - { + .Mutex = &_eglGlobalMutex, + .DisplayList = NULL, + .DeviceList = &_eglSoftwareDevice, + .NumAtExitCalls = 3, + .AtExitCalls = { /* default AtExitCalls, called in reverse order */ - _eglUnloadDrivers, /* always called last */ - _eglFiniDisplay + _eglFiniDevice, /* always called last */ + _eglUnloadDrivers, + _eglFiniDisplay, }, + +#if USE_LIBGLVND + .ClientOnlyExtensionString = +#else + .ClientExtensionString = +#endif + "EGL_EXT_client_extensions" + " EGL_EXT_device_base" + " EGL_EXT_device_enumeration" + " EGL_EXT_device_query" + " EGL_EXT_platform_base" + " EGL_KHR_client_get_all_proc_addresses" + " EGL_KHR_debug" + +#if USE_LIBGLVND + , + .PlatformExtensionString = +#else + " " +#endif + + "EGL_EXT_platform_device" +#ifdef HAVE_WAYLAND_PLATFORM + " EGL_EXT_platform_wayland" + " EGL_KHR_platform_wayland" +#endif +#ifdef HAVE_X11_PLATFORM + " EGL_EXT_platform_x11" + " EGL_KHR_platform_x11" +#endif +#ifdef HAVE_DRM_PLATFORM + " EGL_MESA_platform_gbm" + " EGL_KHR_platform_gbm" +#endif + " EGL_MESA_platform_surfaceless" + "", + + .debugCallback = NULL, + .debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR, }; @@ -41,7 +118,7 @@ _eglAddAtExitCall(void (*func)(void)) if (func) { static EGLBoolean registered = EGL_FALSE; - _eglLockMutex(_eglGlobal.Mutex); + mtx_lock(_eglGlobal.Mutex); if (!registered) { atexit(_eglAtExit); @@ -51,6 +128,42 @@ _eglAddAtExitCall(void (*func)(void)) assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls)); _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func; - _eglUnlockMutex(_eglGlobal.Mutex); + mtx_unlock(_eglGlobal.Mutex); } } + +EGLBoolean +_eglPointerIsDereferencable(void *p) +{ + uintptr_t addr = (uintptr_t) p; + const long page_size = getpagesize(); +#ifdef HAVE_MINCORE + unsigned char valid = 0; + + if (p == NULL) + return EGL_FALSE; + + /* align addr to page_size */ + addr &= ~(page_size - 1); + + if (mincore((void *) addr, page_size, &valid) < 0) { + return EGL_FALSE; + } + + /* mincore() returns 0 on success, and -1 on failure. The last parameter + * is a vector of bytes with one entry for each page queried. mincore + * returns page residency information in the first bit of each byte in the + * vector. + * + * Residency doesn't actually matter when determining whether a pointer is + * dereferenceable, so the output vector can be ignored. What matters is + * whether mincore succeeds. See: + * + * http://man7.org/linux/man-pages/man2/mincore.2.html + */ + return EGL_TRUE; +#else + // Without mincore(), we just assume that the first page is unmapped. + return addr >= page_size; +#endif +}