[waffle] [PATCHv3 07/13] wegl: untangle dl_can_open() and support_api()
Emil Velikov
emil.l.velikov at gmail.com
Sat May 14 18:18:16 UTC 2016
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.velikov at 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
More information about the waffle
mailing list