summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-09-13 15:38:51 +0200
committerwm4 <wm4@nowhere>2016-09-13 18:03:43 +0200
commit6dc9280b580835d37fa8a8664b6bc142254ce1a1 (patch)
treed778fa0999b0654f9e4263c5ece43aa44863c9e0
parent3905c46f9a0f86b7e5fc40e7408cda1f695d4b57 (diff)
downloadmpv-6dc9280b580835d37fa8a8664b6bc142254ce1a1.tar.bz2
mpv-6dc9280b580835d37fa8a8664b6bc142254ce1a1.tar.xz
vo_opengl: factor some EGL context creation code
Add a function to egl_helpers.c for creating an EGL context and make context_x11egl.c use it. This is meant to be generic, and should work with other windowing APIs as well. The other EGL-using code in mpv can be switched to it.
-rw-r--r--video/out/opengl/context.c2
-rw-r--r--video/out/opengl/context.h1
-rw-r--r--video/out/opengl/context_x11egl.c90
-rw-r--r--video/out/opengl/egl_helpers.c96
-rw-r--r--video/out/opengl/egl_helpers.h7
5 files changed, 122 insertions, 74 deletions
diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c
index 21e6d6799e..a8058fb18c 100644
--- a/video/out/opengl/context.c
+++ b/video/out/opengl/context.c
@@ -155,6 +155,8 @@ static MPGLContext *init_backend(struct vo *vo, const struct mpgl_driver *driver
.vo = vo,
.driver = driver,
};
+ if (probing)
+ vo_flags |= VOFLAG_PROBING;
bool old_probing = vo->probing;
vo->probing = probing; // hack; kill it once backends are separate
MP_VERBOSE(vo, "Initializing OpenGL backend '%s'\n", ctx->driver->name);
diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h
index 505c51168a..d0588ddbd9 100644
--- a/video/out/opengl/context.h
+++ b/video/out/opengl/context.h
@@ -33,6 +33,7 @@ enum {
VOFLAG_ALPHA = 1 << 3, // Hint to request alpha framebuffer
VOFLAG_SW = 1 << 4, // Hint to accept a software GL renderer
VOFLAG_ANGLE_DCOMP = 1 << 5, // Whether DirectComposition is allowed
+ VOFLAG_PROBING = 1 << 6, // The backend is being auto-probed.
};
extern const int mpgl_preferred_gl_versions[];
diff --git a/video/out/opengl/context_x11egl.c b/video/out/opengl/context_x11egl.c
index aea388b9a2..7a9e4d31fc 100644
--- a/video/out/opengl/context_x11egl.c
+++ b/video/out/opengl/context_x11egl.c
@@ -49,94 +49,24 @@ static void mpegl_uninit(MPGLContext *ctx)
vo_x11_uninit(ctx->vo);
}
-static EGLConfig select_fb_config_egl(struct MPGLContext *ctx, bool es)
-{
- struct priv *p = ctx->priv;
-
- EGLint attributes[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_DEPTH_SIZE, 0,
- EGL_RENDERABLE_TYPE, es ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT,
- EGL_NONE
- };
-
- EGLint config_count;
- EGLConfig config;
-
- eglChooseConfig(p->egl_display, attributes, &config, 1, &config_count);
-
- if (!config_count) {
- MP_FATAL(ctx->vo, "Could not find EGL configuration!\n");
- return NULL;
- }
-
- return config;
-}
-
-static bool create_context_egl(MPGLContext *ctx, EGLConfig config,
- EGLNativeWindowType window, bool es)
-{
- struct priv *p = ctx->priv;
-
- 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;
- }
-
- p->egl_surface = eglCreateWindowSurface(p->egl_display, config, window, NULL);
-
- if (p->egl_surface == EGL_NO_SURFACE) {
- MP_FATAL(ctx->vo, "Could not create EGL surface!\n");
- return false;
- }
-
- p->egl_context = eglCreateContext(p->egl_display, config,
- EGL_NO_CONTEXT, context_attributes);
-
- if (p->egl_context == EGL_NO_CONTEXT) {
- MP_FATAL(ctx->vo, "Could not create EGL context!\n");
- return false;
- }
-
- eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
- p->egl_context);
-
- return true;
-}
-
static int mpegl_init(struct MPGLContext *ctx, int flags)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
- bool es = flags & VOFLAG_GLES;
int msgl = vo->probing ? MSGL_V : MSGL_FATAL;
if (!vo_x11_init(vo))
goto uninit;
- if (!eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) {
- mp_msg(vo->log, msgl, "Could not bind API (%s).\n", es ? "GLES" : "GL");
- goto uninit;
- }
-
p->egl_display = eglGetDisplay(vo->x11->display);
if (!eglInitialize(p->egl_display, NULL, NULL)) {
mp_msg(vo->log, msgl, "Could not initialize EGL.\n");
goto uninit;
}
- EGLConfig config = select_fb_config_egl(ctx, es);
- if (!config)
+ EGLConfig config;
+ if (!mpegl_create_context(p->egl_display, vo->log, flags, &p->egl_context,
+ &config))
goto uninit;
int vID, n;
@@ -156,8 +86,20 @@ static int mpegl_init(struct MPGLContext *ctx, int flags)
XFree(vi);
- if (!create_context_egl(ctx, config, (EGLNativeWindowType)vo->x11->window, es))
+ p->egl_surface = eglCreateWindowSurface(p->egl_display, config,
+ (EGLNativeWindowType)vo->x11->window, NULL);
+
+ if (p->egl_surface == EGL_NO_SURFACE) {
+ MP_FATAL(ctx->vo, "Could not create EGL surface!\n");
goto uninit;
+ }
+
+ if (!eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
+ p->egl_context))
+ {
+ MP_FATAL(ctx->vo, "Could not make context current!\n");
+ goto uninit;
+ }
const char *egl_exts = eglQueryString(p->egl_display, EGL_EXTENSIONS);
diff --git a/video/out/opengl/egl_helpers.c b/video/out/opengl/egl_helpers.c
index 7e236f1da9..b06e6a79af 100644
--- a/video/out/opengl/egl_helpers.c
+++ b/video/out/opengl/egl_helpers.c
@@ -15,6 +15,102 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "common/common.h"
+
#include "egl_helpers.h"
#include "common.h"
+#include "context.h"
+
+// EGL 1.5
+#ifndef EGL_CONTEXT_OPENGL_PROFILE_MASK
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#endif
+
+static bool create_context(EGLDisplay display, struct mp_log *log, int msgl,
+ int vo_flags,
+ 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)) {
+ mp_msg(log, msgl, "Could not bind API!\n");
+ return false;
+ }
+
+ EGLint attributes[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ 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_NONE
+ };
+
+ EGLint config_count;
+ EGLConfig config;
+
+ eglChooseConfig(display, attributes, &config, 1, &config_count);
+
+ if (!config_count) {
+ mp_msg(log, msgl, "Could not find EGL configuration!\n");
+ 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 = eglCreateContext(display, config,
+ EGL_NO_CONTEXT, context_attributes);
+
+ if (!ctx) {
+ mp_msg(log, msgl, "Could not create EGL context!\n");
+ return false;
+ }
+
+ *out_context = ctx;
+ *out_config = config;
+ return true;
+}
+
+// Create a context and return it and the config it was created with. If it
+// returns false, the out_* pointers are set to NULL.
+// vo_flags is a combination of VOFLAG_* values.
+bool mpegl_create_context(EGLDisplay display, struct mp_log *log, int vo_flags,
+ EGLContext *out_context, EGLConfig *out_config)
+{
+ *out_context = NULL;
+ *out_config = NULL;
+
+ int clean_flags = vo_flags & ~(unsigned)(VOFLAG_GLES | VOFLAG_NO_GLES);
+ int msgl = vo_flags & VOFLAG_PROBING ? MSGL_V : MSGL_FATAL;
+
+ if (!(vo_flags & VOFLAG_GLES)) {
+ if (create_context(display, log, msgl, clean_flags,
+ out_context, out_config))
+ return true;
+ }
+
+ if (!(vo_flags & VOFLAG_NO_GLES)) {
+ if (create_context(display, log, msgl, clean_flags | VOFLAG_GLES,
+ out_context, out_config))
+ return true;
+ }
+
+ mp_msg(log, msgl, "Could not create a GL context.\n");
+ return false;
+}
diff --git a/video/out/opengl/egl_helpers.h b/video/out/opengl/egl_helpers.h
index 3806ef1d35..04197493f3 100644
--- a/video/out/opengl/egl_helpers.h
+++ b/video/out/opengl/egl_helpers.h
@@ -1,7 +1,14 @@
#ifndef MP_GL_EGL_HELPERS_H
#define MP_GL_EGL_HELPERS_H
+#include <stdbool.h>
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
+struct mp_log;
+
+bool mpegl_create_context(EGLDisplay display, struct mp_log *log, int vo_flags,
+ EGLContext *out_context, EGLConfig *out_config);
+
#endif