summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/opengl/egl_helpers.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/video/out/opengl/egl_helpers.c b/video/out/opengl/egl_helpers.c
index e96ae93b06..a5ffd5cf95 100644
--- a/video/out/opengl/egl_helpers.c
+++ b/video/out/opengl/egl_helpers.c
@@ -23,23 +23,43 @@
// EGL 1.5
#ifndef EGL_CONTEXT_OPENGL_PROFILE_MASK
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_OPENGL_ES3_BIT 0x00000040
#endif
static bool create_context(EGLDisplay display, struct mp_log *log, int msgl,
- int vo_flags,
+ int vo_flags, bool es3,
EGLContext *out_context, EGLConfig *out_config)
{
bool es = vo_flags & VOFLAG_GLES;
- mp_msg(log, MSGL_V, "Trying to create %s context.\n", es ? "GLES" : "GL");
- if (!eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) {
+ EGLenum api = EGL_OPENGL_API;
+ EGLint rend = EGL_OPENGL_BIT;
+ const char *name = "Desktop OpenGL";
+ if (es) {
+ api = EGL_OPENGL_ES_API;
+ rend = EGL_OPENGL_ES2_BIT;
+ name = "GLES 2.0";
+ }
+ if (es3) {
+ api = EGL_OPENGL_ES_API;
+ rend = EGL_OPENGL_ES3_BIT;
+ name = "GLES 3.x";
+ }
+
+ mp_msg(log, MSGL_V, "Trying to create %s context.\n", name);
+
+ if (!eglBindAPI(api)) {
mp_msg(log, MSGL_V, "Could not bind API!\n");
return false;
}
+
EGLint attributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 1,
@@ -47,7 +67,7 @@ static bool create_context(EGLDisplay display, struct mp_log *log, int msgl,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, (vo_flags & VOFLAG_ALPHA ) ? 1 : 0,
EGL_DEPTH_SIZE, 0,
- EGL_RENDERABLE_TYPE, es ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT,
+ EGL_RENDERABLE_TYPE, rend,
EGL_NONE
};
@@ -61,21 +81,40 @@ static bool create_context(EGLDisplay display, struct mp_log *log, int msgl,
return false;
}
- EGLint context_attributes[] = {
- // aka EGL_CONTEXT_MAJOR_VERSION_KHR
- EGL_CONTEXT_CLIENT_VERSION, es ? 2 : 3,
- EGL_NONE, EGL_NONE,
- EGL_NONE
- };
-
- if (!es) {
- context_attributes[2] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
- context_attributes[3] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
+ EGLContext *ctx = NULL;
+
+ if (es) {
+ EGLint attrs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, es3 ? 3 : 2,
+ EGL_NONE
+ };
+
+ ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, attrs);
+ } else {
+ for (int n = 0; mpgl_preferred_gl_versions[n]; n++) {
+ int ver = mpgl_preferred_gl_versions[n];
+
+ EGLint attrs[] = {
+ EGL_CONTEXT_MAJOR_VERSION, MPGL_VER_GET_MAJOR(ver),
+ EGL_CONTEXT_MINOR_VERSION, MPGL_VER_GET_MINOR(ver),
+ EGL_CONTEXT_OPENGL_PROFILE_MASK,
+ ver >= 320 ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT : 0,
+ EGL_NONE
+ };
+
+ ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, attrs);
+ if (ctx)
+ break;
+ }
+
+ if (!ctx) {
+ // Fallback for EGL 1.4 without EGL_KHR_create_context.
+ EGLint attrs[] = { EGL_NONE };
+
+ ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, attrs);
+ }
}
- EGLContext *ctx = eglCreateContext(display, config,
- EGL_NO_CONTEXT, context_attributes);
-
if (!ctx) {
mp_msg(log, msgl, "Could not create EGL context!\n");
return false;
@@ -99,13 +138,20 @@ bool mpegl_create_context(EGLDisplay display, struct mp_log *log, int vo_flags,
int msgl = vo_flags & VOFLAG_PROBING ? MSGL_V : MSGL_FATAL;
if (!(vo_flags & VOFLAG_GLES)) {
- if (create_context(display, log, msgl, clean_flags,
+ // Desktop OpenGL
+ if (create_context(display, log, msgl, clean_flags, false,
out_context, out_config))
return true;
}
if (!(vo_flags & VOFLAG_NO_GLES)) {
- if (create_context(display, log, msgl, clean_flags | VOFLAG_GLES,
+ // ES 3.x
+ if (create_context(display, log, msgl, clean_flags | VOFLAG_GLES, true,
+ out_context, out_config))
+ return true;
+
+ // ES 2.0
+ if (create_context(display, log, msgl, clean_flags | VOFLAG_GLES, false,
out_context, out_config))
return true;
}