mirror of
https://github.com/mpv-player/mpv
synced 2024-12-29 02:22:19 +00:00
vo_opengl: EGL: better desktop-GL context creation
Stops Mesa from restricting us to OpenGL 3.0. It also tries to create GLES 3 contexts for drivers which do not just return a higher context when requesting GLES 2. I don't know whether this code is a good or bad idea. A not-so-good aspect is that we don't check for EGL 1.5 (or 1.4 extensions) for some of the more advanced context attributes. But EGL implementations should be able to tolerate it and return an error, and then we'd use the fallback.
This commit is contained in:
parent
c48bd0ef18
commit
d2e8bc4499
@ -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
|
||||
};
|
||||
EGLContext *ctx = NULL;
|
||||
|
||||
if (!es) {
|
||||
context_attributes[2] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
|
||||
context_attributes[3] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user