mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Use eglGetPlatformDisplay when it's available.
Added a platform parameter to egl_init_context. If the caller provides a platform other than EGL_NONE, then it will try to use eglGetPlatformDisplay or eglGetPlatformDisplayEXT instead of eglGetDisplay. If neither eglGetPlatformDisplay or eglGetPlatformDisplayEXT is supported, then it will still fall back to calling eglGetDisplay. Updated the Wayland, X11, and DRM callers to use the correct platform enum. Those are the callers that don't just pass EGL_DEFAULT_DISPLAY as the native display handle. Calling eglGetDisplay with any value other than EGL_DEFAULT_DISPLAY is inherently unreliable, because it requires the EGL implementation to guess a platform type based on a (void *) pointer. Some implementations might not identify a particular platform, or worse, might guess wrong. Fixes https://github.com/libretro/RetroArch/issues/4790
This commit is contained in:
parent
f21bb4d0dc
commit
fcccc9dc0b
@ -208,12 +208,129 @@ void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height)
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_egl_version(int minMajorVersion, int minMinorVersion)
|
||||
{
|
||||
const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
|
||||
int major, minor;
|
||||
int count;
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
count = sscanf(str, "%d.%d", &major, &minor);
|
||||
if (count != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (major < minMajorVersion)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (major > minMajorVersion)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (minor >= minMinorVersion)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_egl_client_extension(const char *name)
|
||||
{
|
||||
const char *str;
|
||||
size_t nameLen;
|
||||
|
||||
str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (str == NULL)
|
||||
{
|
||||
// The EGL implementation doesn't support client extensions at all.
|
||||
return false;
|
||||
}
|
||||
|
||||
nameLen = strlen(name);
|
||||
while (*str != '\0')
|
||||
{
|
||||
// Use strspn and strcspn to find the start position and length of each
|
||||
// token in the extension string. Using strtok could also work, but
|
||||
// that would require allocating a copy of the string.
|
||||
size_t len = strcspn(str, " ");
|
||||
if (len == nameLen && strncmp(str, name, nameLen) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
str += len;
|
||||
str += strspn(str, " ");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static EGLDisplay get_egl_display(EGLenum platform, void *native)
|
||||
{
|
||||
if (platform != EGL_NONE)
|
||||
{
|
||||
// If the client library supports at least EGL 1.5, then we can call
|
||||
// eglGetPlatformDisplay. Otherwise, see if eglGetPlatformDisplayEXT
|
||||
// is available.
|
||||
if (check_egl_version(1, 5))
|
||||
{
|
||||
typedef EGLDisplay (EGLAPIENTRY * pfn_eglGetPlatformDisplay)
|
||||
(EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
|
||||
pfn_eglGetPlatformDisplay ptr_eglGetPlatformDisplay;
|
||||
|
||||
RARCH_LOG("[EGL] Found EGL client version >= 1.5, trying eglGetPlatformDisplay\n");
|
||||
ptr_eglGetPlatformDisplay = (pfn_eglGetPlatformDisplay)
|
||||
eglGetProcAddress("eglGetPlatformDisplay");
|
||||
if (ptr_eglGetPlatformDisplay != NULL)
|
||||
{
|
||||
EGLDisplay dpy = ptr_eglGetPlatformDisplay(platform, native, NULL);
|
||||
if (dpy != EGL_NO_DISPLAY)
|
||||
{
|
||||
return dpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (check_egl_client_extension("EGL_EXT_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT;
|
||||
|
||||
RARCH_LOG("[EGL] Found EGL_EXT_platform_base, trying eglGetPlatformDisplayEXT\n");
|
||||
ptr_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
if (ptr_eglGetPlatformDisplayEXT != NULL)
|
||||
{
|
||||
EGLDisplay dpy = ptr_eglGetPlatformDisplayEXT(platform, native, NULL);
|
||||
if (dpy != EGL_NO_DISPLAY)
|
||||
{
|
||||
return dpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Either the caller didn't provide a platform type, or the EGL
|
||||
// implementation doesn't support eglGetPlatformDisplay. In this case, try
|
||||
// eglGetDisplay and hope for the best.
|
||||
RARCH_LOG("[EGL] Falling back to eglGetDisplay\n");
|
||||
return eglGetDisplay((EGLNativeDisplayType) native);
|
||||
}
|
||||
|
||||
bool egl_init_context(egl_ctx_data_t *egl,
|
||||
EGLenum platform,
|
||||
void *display_data,
|
||||
EGLint *major, EGLint *minor,
|
||||
EGLint *n, const EGLint *attrib_ptr)
|
||||
{
|
||||
EGLDisplay dpy = (NativeDisplayType)eglGetDisplay((EGLNativeDisplayType)display_data);
|
||||
EGLDisplay dpy = get_egl_display(platform, display_data);
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
RARCH_ERR("[EGL]: Couldn't get EGL display.\n");
|
||||
|
@ -89,6 +89,7 @@ void egl_set_swap_interval(egl_ctx_data_t *egl, unsigned interval);
|
||||
void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height);
|
||||
|
||||
bool egl_init_context(egl_ctx_data_t *egl,
|
||||
EGLenum platform,
|
||||
void *display_data,
|
||||
EGLint *major,
|
||||
EGLint *minor,
|
||||
|
@ -143,7 +143,7 @@ static void *android_gfx_ctx_init(video_frame_info_t *video_info, void *video_dr
|
||||
#ifdef HAVE_EGL
|
||||
RARCH_LOG("Android EGL: GLES version = %d.\n", g_es3 ? 3 : 2);
|
||||
|
||||
if (!egl_init_context(&and->egl, EGL_DEFAULT_DISPLAY,
|
||||
if (!egl_init_context(&and->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor, &n, attribs))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -563,7 +563,8 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm)
|
||||
case GFX_CTX_OPENGL_ES_API:
|
||||
case GFX_CTX_OPENVG_API:
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&drm->egl, (EGLNativeDisplayType)g_gbm_dev, &major,
|
||||
if (!egl_init_context(&drm->egl, EGL_PLATFORM_GBM_KHR,
|
||||
(EGLNativeDisplayType)g_gbm_dev, &major,
|
||||
&minor, &n, attrib_ptr))
|
||||
goto error;
|
||||
|
||||
|
@ -135,7 +135,7 @@ static void *gfx_ctx_emscripten_init(video_frame_info_t *video_info, void *video
|
||||
return (void*)"emscripten";
|
||||
}
|
||||
|
||||
if (!egl_init_context(&emscripten->egl, EGL_DEFAULT_DISPLAY,
|
||||
if (!egl_init_context(&emscripten->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor, &n, attribute_list))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -116,7 +116,7 @@ static void *gfx_ctx_mali_fbdev_init(video_frame_info_t *video_info, void *video
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&mali->egl, EGL_DEFAULT_DISPLAY,
|
||||
if (!egl_init_context(&mali->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor, &n, attribs))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -83,7 +83,7 @@ static void *gfx_ctx_opendingux_init(video_frame_info_t *video_info, void *video
|
||||
#ifdef HAVE_EGL
|
||||
frontend_driver_install_signal_handler();
|
||||
|
||||
if (!egl_init_context(&viv->egl, EGL_DEFAULT_DISPLAY,
|
||||
if (!egl_init_context(&viv->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor,
|
||||
&n, attribs))
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ static void *gfx_ctx_qnx_init(video_frame_info_t *video_info, void *video_driver
|
||||
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&qnx->egl, EGL_DEFAULT_DISPLAY, &major, &minor,
|
||||
if (!egl_init_context(&qnx->egl, EGL_NONE, EGL_DEFAULT_DISPLAY, &major, &minor,
|
||||
&n, attribs))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -183,7 +183,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
|
||||
bcm_host_init();
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&vc->egl, EGL_DEFAULT_DISPLAY,
|
||||
if (!egl_init_context(&vc->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor, &n, attribute_list))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -90,7 +90,7 @@ static void *gfx_ctx_vivante_init(video_frame_info_t *video_info, void *video_dr
|
||||
system("setterm -cursor off");
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&viv->egl, EGL_DEFAULT_DISPLAY, &major, &minor,
|
||||
if (!egl_init_context(&viv->egl, EGL_NONE, EGL_DEFAULT_DISPLAY, &major, &minor,
|
||||
&n, attribs))
|
||||
{
|
||||
egl_report_error();
|
||||
|
@ -900,6 +900,7 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
|
||||
case GFX_CTX_OPENVG_API:
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&wl->egl,
|
||||
EGL_PLATFORM_WAYLAND_KHR,
|
||||
(EGLNativeDisplayType)wl->dpy,
|
||||
&major, &minor, &n, attrib_ptr))
|
||||
{
|
||||
|
@ -163,8 +163,8 @@ static void *gfx_ctx_xegl_init(video_frame_info_t *video_info, void *video_drive
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&xegl->egl, (EGLNativeDisplayType)g_x11_dpy,
|
||||
&major, &minor, &n, attrib_ptr))
|
||||
if (!egl_init_context(&xegl->egl, EGL_PLATFORM_X11_KHR,
|
||||
(EGLNativeDisplayType)g_x11_dpy, &major, &minor, &n, attrib_ptr))
|
||||
{
|
||||
egl_report_error();
|
||||
goto error;
|
||||
|
Loading…
x
Reference in New Issue
Block a user