egl: simplify client/platform extension handling
For GLVND reasons the client/platform extensions strings should be split. While in the non GLVND case they're one big string. Currently we handle this distinction at run-time for not obvious reason. Adding additional code and complexity. Swap those with a few well placed #if USE_LIBGLVND guards. As a side result this removes a minor memory leak due to the concatenation in the non GLVND case. Signed-off-by: Emil Velikov <emil.velikov@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4491>
This commit is contained in:
@@ -692,13 +692,11 @@ eglQueryString(EGLDisplay dpy, EGLint name)
|
|||||||
_EGLDisplay *disp;
|
_EGLDisplay *disp;
|
||||||
_EGLDriver *drv;
|
_EGLDriver *drv;
|
||||||
|
|
||||||
|
#if !USE_LIBGLVND
|
||||||
if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
|
if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
|
||||||
const char *ret = _eglGetClientExtensionString();
|
RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
|
||||||
if (ret != NULL)
|
|
||||||
RETURN_EGL_SUCCESS(NULL, ret);
|
|
||||||
else
|
|
||||||
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
disp = _eglLockDisplay(dpy);
|
disp = _eglLockDisplay(dpy);
|
||||||
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
|
||||||
|
@@ -62,16 +62,27 @@ struct _egl_global _eglGlobal =
|
|||||||
_eglFiniDisplay,
|
_eglFiniDisplay,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#if USE_LIBGLVND
|
||||||
.ClientOnlyExtensionString =
|
.ClientOnlyExtensionString =
|
||||||
|
#else
|
||||||
|
.ClientExtensionString =
|
||||||
|
#endif
|
||||||
"EGL_EXT_client_extensions"
|
"EGL_EXT_client_extensions"
|
||||||
" EGL_EXT_device_base"
|
" EGL_EXT_device_base"
|
||||||
" EGL_EXT_device_enumeration"
|
" EGL_EXT_device_enumeration"
|
||||||
" EGL_EXT_device_query"
|
" EGL_EXT_device_query"
|
||||||
" EGL_EXT_platform_base"
|
" EGL_EXT_platform_base"
|
||||||
" EGL_KHR_client_get_all_proc_addresses"
|
" EGL_KHR_client_get_all_proc_addresses"
|
||||||
" EGL_KHR_debug",
|
" EGL_KHR_debug"
|
||||||
|
|
||||||
|
#if USE_LIBGLVND
|
||||||
|
,
|
||||||
.PlatformExtensionString =
|
.PlatformExtensionString =
|
||||||
|
#else
|
||||||
|
" "
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"EGL_EXT_platform_device"
|
||||||
#ifdef HAVE_WAYLAND_PLATFORM
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
" EGL_EXT_platform_wayland"
|
" EGL_EXT_platform_wayland"
|
||||||
#endif
|
#endif
|
||||||
@@ -84,11 +95,8 @@ struct _egl_global _eglGlobal =
|
|||||||
#ifdef HAVE_SURFACELESS_PLATFORM
|
#ifdef HAVE_SURFACELESS_PLATFORM
|
||||||
" EGL_MESA_platform_surfaceless"
|
" EGL_MESA_platform_surfaceless"
|
||||||
#endif
|
#endif
|
||||||
" EGL_EXT_platform_device"
|
|
||||||
"",
|
"",
|
||||||
|
|
||||||
.ClientExtensionString = NULL,
|
|
||||||
|
|
||||||
.debugCallback = NULL,
|
.debugCallback = NULL,
|
||||||
.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR,
|
.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR,
|
||||||
};
|
};
|
||||||
@@ -123,40 +131,6 @@ _eglAddAtExitCall(void (*func)(void))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
|
||||||
_eglGetClientExtensionString(void)
|
|
||||||
{
|
|
||||||
const char *ret;
|
|
||||||
|
|
||||||
mtx_lock(_eglGlobal.Mutex);
|
|
||||||
|
|
||||||
if (_eglGlobal.ClientExtensionString == NULL) {
|
|
||||||
size_t clientLen = strlen(_eglGlobal.ClientOnlyExtensionString);
|
|
||||||
size_t platformLen = strlen(_eglGlobal.PlatformExtensionString);
|
|
||||||
|
|
||||||
_eglGlobal.ClientExtensionString = (char *) malloc(clientLen + platformLen + 1);
|
|
||||||
if (_eglGlobal.ClientExtensionString != NULL) {
|
|
||||||
char *ptr = _eglGlobal.ClientExtensionString;
|
|
||||||
|
|
||||||
memcpy(ptr, _eglGlobal.ClientOnlyExtensionString, clientLen);
|
|
||||||
ptr += clientLen;
|
|
||||||
|
|
||||||
if (platformLen > 0) {
|
|
||||||
// Note that if PlatformExtensionString is not empty, then it will
|
|
||||||
// already have a leading space.
|
|
||||||
assert(_eglGlobal.PlatformExtensionString[0] == ' ');
|
|
||||||
memcpy(ptr, _eglGlobal.PlatformExtensionString, platformLen);
|
|
||||||
ptr += platformLen;
|
|
||||||
}
|
|
||||||
*ptr = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = _eglGlobal.ClientExtensionString;
|
|
||||||
|
|
||||||
mtx_unlock(_eglGlobal.Mutex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGLBoolean
|
EGLBoolean
|
||||||
_eglPointerIsDereferencable(void *p)
|
_eglPointerIsDereferencable(void *p)
|
||||||
{
|
{
|
||||||
|
@@ -61,13 +61,15 @@ struct _egl_global
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Under libglvnd, the client extension string has to be split into two
|
* Under libglvnd, the client extension string has to be split into two
|
||||||
* strings, one for platform extensions, and one for everything else. So,
|
* strings, one for platform extensions, and one for everything else.
|
||||||
* define separate strings for them. _eglGetClientExtensionString will
|
* For a non-glvnd build create a concatenated one.
|
||||||
* concatenate them together for a non-libglvnd build.
|
|
||||||
*/
|
*/
|
||||||
|
#if USE_LIBGLVND
|
||||||
const char *ClientOnlyExtensionString;
|
const char *ClientOnlyExtensionString;
|
||||||
const char *PlatformExtensionString;
|
const char *PlatformExtensionString;
|
||||||
char *ClientExtensionString;
|
#else
|
||||||
|
const char *ClientExtensionString;
|
||||||
|
#endif
|
||||||
|
|
||||||
EGLDEBUGPROCKHR debugCallback;
|
EGLDEBUGPROCKHR debugCallback;
|
||||||
unsigned int debugTypesEnabled;
|
unsigned int debugTypesEnabled;
|
||||||
@@ -86,9 +88,6 @@ static inline unsigned int DebugBitFromType(EGLenum type)
|
|||||||
return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR));
|
return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char *
|
|
||||||
_eglGetClientExtensionString(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform validity checks on a generic pointer.
|
* Perform validity checks on a generic pointer.
|
||||||
*/
|
*/
|
||||||
|
@@ -24,15 +24,8 @@ __eglGLVNDQueryString(EGLDisplay dpy, EGLenum name)
|
|||||||
static const char *
|
static const char *
|
||||||
__eglGLVNDGetVendorString(int name)
|
__eglGLVNDGetVendorString(int name)
|
||||||
{
|
{
|
||||||
if (name == __EGL_VENDOR_STRING_PLATFORM_EXTENSIONS) {
|
if (name == __EGL_VENDOR_STRING_PLATFORM_EXTENSIONS)
|
||||||
const char *str = _eglGlobal.PlatformExtensionString;
|
return _eglGlobal.PlatformExtensionString;
|
||||||
// The platform extension string may have a leading space. If it does,
|
|
||||||
// then skip over it.
|
|
||||||
while (*str == ' ') {
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user