diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/out/opengl/common.c | 20 | ||||
-rw-r--r-- | video/out/opengl/common.h | 2 | ||||
-rw-r--r-- | video/out/opengl/egl_helpers.c | 41 |
3 files changed, 47 insertions, 16 deletions
diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index 8fcc94df70..ed0b0d4747 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -486,6 +486,26 @@ static const struct gl_functions gl_functions[] = { #undef DEF_FN #undef DEF_FN_NAME +void mpgl_check_version(GL *gl, void *(*get_fn)(void *ctx, const char *n), + void *fn_ctx) +{ + gl->GetString = get_fn(fn_ctx, "glGetString"); + if (!gl->GetString) { + gl->version = 0; + return; + } + const char *version_string = gl->GetString(GL_VERSION); + if (!version_string) { + gl->version = 0; + return; + } + int major = 0, minor = 0; + if (sscanf(version_string, "%d.%d", &major, &minor) < 2) { + gl->version = 0; + return; + } + gl->version = MPGL_VER(major, minor); +} // Fill the GL struct with function pointers and extensions from the current // GL context. Called by the backend. diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h index 38414fe18b..c3691cfaf8 100644 --- a/video/out/opengl/common.h +++ b/video/out/opengl/common.h @@ -70,6 +70,8 @@ enum { #define MPGL_VER_P(ver) MPGL_VER_GET_MAJOR(ver), MPGL_VER_GET_MINOR(ver) +void mpgl_check_version(GL *gl, void *(*get_fn)(void *ctx, const char *n), + void *fn_ctx); void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *), const char *ext2, struct mp_log *log); void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), diff --git a/video/out/opengl/egl_helpers.c b/video/out/opengl/egl_helpers.c index ad026ba253..bcd85bfb73 100644 --- a/video/out/opengl/egl_helpers.c +++ b/video/out/opengl/egl_helpers.c @@ -78,6 +78,20 @@ static void dump_egl_config(struct mp_log *log, int msgl, EGLDisplay display, } } +static void *mpegl_get_proc_address(void *ctx, const char *name) +{ + void *p = eglGetProcAddress(name); +#if defined(__GLIBC__) && HAVE_LIBDL + // Some crappy ARM/Linux things do not provide EGL 1.5, so above call does + // not necessarily return function pointers for core functions. Try to get + // them from a loaded GLES lib. As POSIX leaves RTLD_DEFAULT "reserved", + // use it only with glibc. + if (!p) + p = dlsym(RTLD_DEFAULT, name); +#endif + return p; +} + // es_version: 0 (core), 2 or 3 static bool create_context(struct ra_ctx *ctx, EGLDisplay display, int es_version, struct mpegl_cb cb, @@ -188,11 +202,20 @@ static bool create_context(struct ra_ctx *ctx, EGLDisplay display, break; } - if (!egl_ctx && ra_gl_ctx_test_version(ctx, 140, false)) { + if (!egl_ctx) { // Fallback for EGL 1.4 without EGL_KHR_create_context. EGLint attrs[] = { EGL_NONE }; - egl_ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, attrs); + + GL *gl = talloc_zero(ctx, struct GL); + mpgl_check_version(gl, mpegl_get_proc_address, NULL); + if (gl->version < 210 || + !ra_gl_ctx_test_version(ctx, gl->version, false)) + { + eglDestroyContext(display, egl_ctx); + egl_ctx = NULL; + } + talloc_free(gl); } } @@ -252,20 +275,6 @@ static int GLAPIENTRY swap_interval(int interval) return !eglSwapInterval(display, interval); } -static void *mpegl_get_proc_address(void *ctx, const char *name) -{ - void *p = eglGetProcAddress(name); -#if defined(__GLIBC__) && HAVE_LIBDL - // Some crappy ARM/Linux things do not provide EGL 1.5, so above call does - // not necessarily return function pointers for core functions. Try to get - // them from a loaded GLES lib. As POSIX leaves RTLD_DEFAULT "reserved", - // use it only with glibc. - if (!p) - p = dlsym(RTLD_DEFAULT, name); -#endif - return p; -} - // Load gl version and function pointers into *gl. // Expects a current EGL context set. void mpegl_load_functions(struct GL *gl, struct mp_log *log) |