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. Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> --- src/waffle/egl/wegl_config.c | 37 ++++++------------------- src/waffle/egl/wegl_display.c | 63 ++++++++++++++++++++++++++----------------- src/waffle/egl/wegl_display.h | 2 ++ 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/src/waffle/egl/wegl_config.c b/src/waffle/egl/wegl_config.c index a79bc53..ef35b45 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)); @@ -57,6 +55,14 @@ check_context_attrs(struct wegl_display *dpy, switch (attrs->context_api) { case WAFFLE_CONTEXT_OPENGL: + if (!dpy->supports_opengl) { + wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, + "EGL 1.4 of later and eglQueryString(EGL_CLIENT_APIS) " + "== 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 " @@ -77,32 +83,11 @@ 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)) { - wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, - "failed to open the OpenGL ES2 library"); - return false; - } - return true; - case WAFFLE_CONTEXT_OPENGL_ES3: if (!dpy->KHR_create_context) { wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, @@ -111,12 +96,6 @@ check_context_attrs(struct wegl_display *dpy, 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 b3d0d88..c9368fc 100644 --- a/src/waffle/egl/wegl_display.c +++ b/src/waffle/egl/wegl_display.c @@ -24,6 +24,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assert.h> +#include <string.h> #include "wcore_error.h" #include "wcore_platform.h" @@ -34,22 +35,46 @@ #include "wegl_platform.h" static bool -get_extensions(struct wegl_display *dpy) +parse_version_extensions(struct wegl_display *dpy, EGLint major, EGLint minor) { struct wegl_platform *plat = wegl_platform(dpy->wcore.platform); - const char *extensions = plat->eglQueryString(dpy->egl, EGL_EXTENSIONS); + const char *apis = plat->eglQueryString(dpy->egl, EGL_CLIENT_APIS); + const char *extensions; - if (!extensions) { - wegl_emit_error(plat, "eglQueryString(EGL_EXTENSIONS)"); + // Our minimum requirement - EGL 1.2 ... + if (major != 1 || minor < 2) { + wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM, + "EGL 1.2 or later is required"); 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); + // ... plus working eglQueryString(EGL_CLIENT_APIS) and "OpenGL_ES" in the + // APIs string. + if (!apis || !strstr(apis, "OpenGL_ES")) { + wegl_emit_error(plat, "eglQueryString(EGL_CLIENT_APIS)"); + return false; + } + + // Optional bits, if we're running EGL 1.4 ... + if (major == 1 && minor >= 4) { + extensions = plat->eglQueryString(dpy->egl, EGL_EXTENSIONS); + + // Should never fail. + if (!extensions) { + wegl_emit_error(plat, "eglQueryString(EGL_EXTENSIONS)"); + return false; + } - dpy->KHR_create_context = waffle_is_extension_in_string(extensions, "EGL_KHR_create_context"); + // 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); + + dpy->KHR_create_context = waffle_is_extension_in_string(extensions, "EGL_KHR_create_context"); + + // ... and OpenGL is in the APIs string, then we should be fine. + dpy->supports_opengl = waffle_is_extension_in_string(apis, "OpenGL"); + } return true; } @@ -81,7 +106,7 @@ wegl_display_init(struct wegl_display *dpy, goto fail; } - ok = get_extensions(dpy); + ok = parse_version_extensions(dpy, major, minor); if (!ok) goto fail; @@ -112,30 +137,18 @@ 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->supports_opengl; 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 true; case WAFFLE_CONTEXT_OPENGL_ES3: - if (!dpy->KHR_create_context) - return false; - - waffle_dl = WAFFLE_DL_OPENGL_ES3; - break; + return 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 43b83ef..9401334 100644 --- a/src/waffle/egl/wegl_display.h +++ b/src/waffle/egl/wegl_display.h @@ -37,6 +37,8 @@ struct wcore_display; struct wegl_display { struct wcore_display wcore; EGLDisplay egl; + + bool supports_opengl; bool KHR_create_context; }; -- 2.8.0 _______________________________________________ waffle mailing list waffle@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/waffle