Calling dl_can_open() to determine whether the API is supported is confusing and somewhat incorrect.
Instead, determine the supported APIs based on the string provided by eglQueryString(EGL_CLIENT_APIS) and cross that with the minimum EGL requirement (for eglBindAPI) for each one. Note: we're added a minimum requirement of EGL 1.2 as things will explode badly with versions prior to it. v2: Completely reword commit message, finish implementation. v3: Keep get_apis() and get_extensions() separate. Use mask for the API. Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> --- src/waffle/egl/wegl_config.c | 43 +++++++++++--------------------- src/waffle/egl/wegl_display.c | 58 ++++++++++++++++++++++++++++++++----------- src/waffle/egl/wegl_display.h | 6 +++++ 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/waffle/egl/wegl_config.c b/src/waffle/egl/wegl_config.c index 08e06fb..37fbe65 100644 --- a/src/waffle/egl/wegl_config.c +++ b/src/waffle/egl/wegl_config.c @@ -41,8 +41,6 @@ static bool check_context_attrs(struct wegl_display *dpy, const struct wcore_config_attrs *attrs) { - struct wcore_platform *plat = dpy->wcore.platform; - if (attrs->context_forward_compatible) { assert(attrs->context_api == WAFFLE_CONTEXT_OPENGL); assert(wcore_config_attrs_version_ge(attrs, 30)); @@ -76,6 +74,14 @@ check_context_attrs(struct wegl_display *dpy, switch (attrs->context_api) { case WAFFLE_CONTEXT_OPENGL: + if (!(dpy->api_mask & WEGL_OPENGL_API)) { + wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, + "EGL 1.4 and eglQueryString(EGL_CLIENT_APIS) " + "advertising \"OpenGL\" are required in order to " + "request an OpenGL context."); + return false; + } + if (!wcore_config_attrs_version_eq(attrs, 10) && !dpy->KHR_create_context) { wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, "KHR_EXT_create_context is required in order to " @@ -96,46 +102,25 @@ check_context_attrs(struct wegl_display *dpy, return false; } - if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL)) { - wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, - "failed to open the OpenGL library"); - return false; - } - return true; case WAFFLE_CONTEXT_OPENGL_ES1: - if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES1)) { - wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, - "failed to open the OpenGL ES1 library"); - return false; - } - - return true; - case WAFFLE_CONTEXT_OPENGL_ES2: - if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES2)) { + case WAFFLE_CONTEXT_OPENGL_ES3: + if (!(dpy->api_mask & WEGL_OPENGL_ES_API)) { wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, - "failed to open the OpenGL ES2 library"); + "eglQueryString(EGL_CLIENT_APIS) does not" + "advertise OpenGL_ES."); return false; } - - return true; - - case WAFFLE_CONTEXT_OPENGL_ES3: - if (!dpy->KHR_create_context) { + if (attrs->context_api == WAFFLE_CONTEXT_OPENGL_ES3 && + !dpy->KHR_create_context) { wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, "EGL_KHR_create_context is required to request " "an OpenGL ES3 context"); return false; } - if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES3)) { - wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, - "failed to open the OpenGL ES3 library"); - return false; - } - return true; default: diff --git a/src/waffle/egl/wegl_display.c b/src/waffle/egl/wegl_display.c index c7be0a5..d5f6deb 100644 --- a/src/waffle/egl/wegl_display.c +++ b/src/waffle/egl/wegl_display.c @@ -34,6 +34,41 @@ #include "wegl_platform.h" static bool +get_apis(struct wegl_display *dpy) +{ + struct wegl_platform *plat = wegl_platform(dpy->wcore.platform); + const char *apis = plat->eglQueryString(dpy->egl, EGL_CLIENT_APIS); + + // Our minimum requirement - EGL 1.2 ... + if (dpy->major_version != 1 || dpy->minor_version < 2) { + wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, + "EGL 1.2 or later is required"); + return false; + } + + // ... plus working eglQueryString(EGL_CLIENT_APIS). + if (!apis) { + wegl_emit_error(plat, "eglQueryString(EGL_CLIENT_APIS)"); + return false; + } + + // waffle_is_extension_in_string() resets the error state. That's ok, + // however, because if we've reached this point then no error should be + // pending emission. + assert(wcore_error_get_code() == 0); + + if (waffle_is_extension_in_string(apis, "OpenGL_ES")) + dpy->api_mask |= WEGL_OPENGL_ES_API; + + // Check for "OpenGL" if we're running EGL 1.4 or later. + if (dpy->major_version == 1 && dpy->minor_version >= 4) + if (waffle_is_extension_in_string(apis, "OpenGL")) + dpy->api_mask |= WEGL_OPENGL_API; + + return true; +} + +static bool get_extensions(struct wegl_display *dpy) { struct wegl_platform *plat = wegl_platform(dpy->wcore.platform); @@ -81,6 +116,10 @@ wegl_display_init(struct wegl_display *dpy, goto fail; } + ok = get_apis(dpy); + if (!ok) + goto fail; + ok = get_extensions(dpy); if (!ok) goto fail; @@ -112,30 +151,19 @@ wegl_display_supports_context_api(struct wcore_display *wc_dpy, int32_t waffle_context_api) { struct wegl_display *dpy = wegl_display(wc_dpy); - struct wcore_platform *wc_plat = dpy->wcore.platform; - int32_t waffle_dl; switch (waffle_context_api) { case WAFFLE_CONTEXT_OPENGL: - waffle_dl = WAFFLE_DL_OPENGL; - break; + return !!(dpy->api_mask & WEGL_OPENGL_API); case WAFFLE_CONTEXT_OPENGL_ES1: - waffle_dl = WAFFLE_DL_OPENGL_ES1; - break; case WAFFLE_CONTEXT_OPENGL_ES2: - waffle_dl = WAFFLE_DL_OPENGL_ES2; - break; + return !!(dpy->api_mask & WEGL_OPENGL_ES_API); case WAFFLE_CONTEXT_OPENGL_ES3: - if (!dpy->KHR_create_context) - return false; - - waffle_dl = WAFFLE_DL_OPENGL_ES3; - break; + return !!(dpy->api_mask & WEGL_OPENGL_ES_API) && + dpy->KHR_create_context; default: wcore_error_internal("waffle_context_api has bad value %#x", waffle_context_api); return false; } - - return wc_plat->vtbl->dl_can_open(wc_plat, waffle_dl); } diff --git a/src/waffle/egl/wegl_display.h b/src/waffle/egl/wegl_display.h index 0d03ec8..348399d 100644 --- a/src/waffle/egl/wegl_display.h +++ b/src/waffle/egl/wegl_display.h @@ -34,9 +34,15 @@ struct wcore_display; +enum wegl_supported_api { + WEGL_OPENGL_API = 1 << 0, + WEGL_OPENGL_ES_API = 1 << 1, +}; + struct wegl_display { struct wcore_display wcore; EGLDisplay egl; + enum wegl_supported_api api_mask; bool EXT_create_context_robustness; bool KHR_create_context; EGLint major_version; -- 2.8.0 _______________________________________________ waffle mailing list waffle@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/waffle