summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/egl_helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/egl_helpers.c')
-rw-r--r--video/out/opengl/egl_helpers.c96
1 files changed, 96 insertions, 0 deletions
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;
+}