summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/gl_common.c43
-rw-r--r--video/out/gl_common.h2
-rw-r--r--video/out/gl_osd.c10
-rw-r--r--video/out/gl_video.c39
-rw-r--r--video/out/gl_video_shaders.glsl4
-rw-r--r--video/out/gl_x11egl.c37
6 files changed, 111 insertions, 24 deletions
diff --git a/video/out/gl_common.c b/video/out/gl_common.c
index d9df1aa7ee..2af96cab5a 100644
--- a/video/out/gl_common.c
+++ b/video/out/gl_common.c
@@ -495,9 +495,20 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
int major = 0, minor = 0;
const char *version = gl->GetString(GL_VERSION);
+ if (strncmp(version, "OpenGL ES ", 10) == 0) {
+ version += 10;
+ gl->es = true;
+ }
sscanf(version, "%d.%d", &major, &minor);
gl->version = MPGL_VER(major, minor);
- mp_verbose(log, "Detected OpenGL %d.%d.\n", major, minor);
+ mp_verbose(log, "Detected OpenGL %d.%d (%s).\n", major, minor,
+ gl->es ? "GLES" : "desktop");
+
+ if (gl->es && gl->version < MPGL_VER(3, 0)) {
+ mp_warn(log, "At least GLESv3 required.\n");
+ gl->version = 0;
+ return;
+ }
mp_verbose(log, "GL_VENDOR='%s'\n", gl->GetString(GL_VENDOR));
mp_verbose(log, "GL_RENDERER='%s'\n", gl->GetString(GL_RENDERER));
@@ -607,16 +618,21 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
}
gl->glsl_version = 0;
- if (gl->version >= MPGL_VER(2, 0))
- gl->glsl_version = 110;
- if (gl->version >= MPGL_VER(2, 1))
- gl->glsl_version = 120;
- if (gl->version >= MPGL_VER(3, 0))
- gl->glsl_version = 130;
- // Specifically needed for OSX (normally we request 3.0 contexts only, but
- // OSX always creates 3.2 contexts when requesting a core context).
- if (gl->version >= MPGL_VER(3, 2))
- gl->glsl_version = 150;
+ if (gl->es) {
+ if (gl->version >= MPGL_VER(3, 0))
+ gl->glsl_version = 300;
+ } else {
+ if (gl->version >= MPGL_VER(2, 0))
+ gl->glsl_version = 110;
+ if (gl->version >= MPGL_VER(2, 1))
+ gl->glsl_version = 120;
+ if (gl->version >= MPGL_VER(3, 0))
+ gl->glsl_version = 130;
+ // Specifically needed for OSX (normally we request 3.0 contexts only, but
+ // OSX always creates 3.2 contexts when requesting a core context).
+ if (gl->version >= MPGL_VER(3, 2))
+ gl->glsl_version = 150;
+ }
if (!is_software_gl(gl))
gl->mpgl_caps |= MPGL_CAP_NO_SW;
@@ -678,14 +694,18 @@ int glFmt2bpp(GLenum format, GLenum type)
return 2;
case GL_RGB:
case GL_BGR:
+ case GL_RGB_INTEGER:
return 3 * component_size;
case GL_RGBA:
case GL_BGRA:
+ case GL_RGBA_INTEGER:
return 4 * component_size;
case GL_RED:
+ case GL_RED_INTEGER:
return component_size;
case GL_RG:
case GL_LUMINANCE_ALPHA:
+ case GL_RG_INTEGER:
return 2 * component_size;
}
abort(); // unknown
@@ -817,6 +837,7 @@ static const struct backend backends[] = {
#endif
#if HAVE_EGL_X11
{"x11egl", mpgl_set_backend_x11egl},
+ {"x11egles", mpgl_set_backend_x11egles},
#endif
{0}
};
diff --git a/video/out/gl_common.h b/video/out/gl_common.h
index 3f86d74036..7ec06fc248 100644
--- a/video/out/gl_common.h
+++ b/video/out/gl_common.h
@@ -156,6 +156,7 @@ void mpgl_set_backend_cocoa(MPGLContext *ctx);
void mpgl_set_backend_w32(MPGLContext *ctx);
void mpgl_set_backend_x11(MPGLContext *ctx);
void mpgl_set_backend_x11egl(MPGLContext *ctx);
+void mpgl_set_backend_x11egles(MPGLContext *ctx);
void mpgl_set_backend_wayland(MPGLContext *ctx);
void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
@@ -169,6 +170,7 @@ void mp_log_source(struct mp_log *log, int lev, const char *src);
//function pointers loaded from the OpenGL library
struct GL {
+ bool es; // false: desktop GL, true: GLES
int version; // MPGL_VER() mangled
int glsl_version; // e.g. 130 for GLSL 1.30
char *extensions; // Equivalent to GL_EXTENSIONS
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index 6b97ef77cf..2276dc9f71 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -42,6 +42,11 @@ static const struct osd_fmt_entry osd_to_gl3_formats[SUBBITMAP_COUNT] = {
[SUBBITMAP_RGBA] = {GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE},
};
+static const struct osd_fmt_entry osd_to_gles3_formats[SUBBITMAP_COUNT] = {
+ [SUBBITMAP_LIBASS] = {GL_R8, GL_RED, GL_UNSIGNED_BYTE},
+ [SUBBITMAP_RGBA] = {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE},
+};
+
static const struct osd_fmt_entry osd_to_gl_legacy_formats[SUBBITMAP_COUNT] = {
[SUBBITMAP_LIBASS] = {GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE},
[SUBBITMAP_RGBA] = {GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE},
@@ -61,8 +66,11 @@ struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd
.scratch = talloc_zero_size(ctx, 1),
};
- if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG))
+ if (gl->es) {
+ ctx->fmt_table = osd_to_gles3_formats;
+ } else if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG)) {
ctx->fmt_table = osd_to_gl_legacy_formats;
+ }
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct mpgl_osd_part *p = talloc_ptrtype(ctx, p);
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index b139fed07c..e7c2c46450 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -231,6 +231,19 @@ static const struct fmt_entry gl_byte_formats[] = {
{0, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT}, // 4 x 16
};
+static const struct fmt_entry gl_byte_formats_gles3[] = {
+ {0, GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // 1 x 8
+ {0, GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // 2 x 8
+ {0, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}, // 3 x 8
+ {0, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // 4 x 8
+ // There are no filterable texture formats that can be uploaded as
+ // GL_UNSIGNED_SHORT, so apparently we're out of luck.
+ {0, 0, 0, 0}, // 1 x 16
+ {0, 0, 0, 0}, // 2 x 16
+ {0, 0, 0, 0}, // 3 x 16
+ {0, 0, 0, 0}, // 4 x 16
+};
+
static const struct fmt_entry gl_byte_formats_legacy[] = {
{0, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE}, // 1 x 8
{0, GL_LUMINANCE_ALPHA,
@@ -389,8 +402,12 @@ static const struct fmt_entry *find_tex_format(GL *gl, int bytes_per_comp,
{
assert(bytes_per_comp == 1 || bytes_per_comp == 2);
assert(n_channels >= 1 && n_channels <= 4);
- const struct fmt_entry *fmts = (gl->mpgl_caps & MPGL_CAP_TEX_RG)
- ? gl_byte_formats : gl_byte_formats_legacy;
+ const struct fmt_entry *fmts = gl_byte_formats;
+ if (gl->es) {
+ fmts = gl_byte_formats_gles3;
+ } else if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG)) {
+ fmts = gl_byte_formats_legacy;
+ }
return &fmts[n_channels - 1 + (bytes_per_comp - 1) * 4];
}
@@ -905,6 +922,8 @@ static void compile_shaders(struct gl_video *p)
{
GL *gl = p->gl;
+ debug_check_gl(p, "before shaders");
+
delete_shaders(p);
void *tmp = talloc_new(NULL);
@@ -916,10 +935,11 @@ static void compile_shaders(struct gl_video *p)
int rg = !!(gl->mpgl_caps & MPGL_CAP_TEX_RG);
char *header =
- talloc_asprintf(tmp, "#version %d\n"
+ talloc_asprintf(tmp, "#version %d%s\n"
"#define HAVE_RG %d\n"
"%s%s",
- gl->glsl_version, rg, shader_prelude, PRELUDE_END);
+ gl->glsl_version, gl->es ? " es" : "",
+ rg, shader_prelude, PRELUDE_END);
bool use_cms = p->opts.srgb || p->use_lut_3d;
@@ -2086,6 +2106,12 @@ static void check_gl_features(struct gl_video *p)
}
}
+ // GLES doesn't provide filtered 16 bit integer textures
+ if (p->use_lut_3d && gl->es) {
+ p->use_lut_3d = false;
+ disabled[n_disabled++] = "color management (GLES unsupported)";
+ }
+
int use_cms = p->opts.srgb || p->use_lut_3d;
// srgb_compand() not available
@@ -2338,6 +2364,11 @@ supported:
return false;
for (int p = 0; p < desc.num_planes; p++) {
+ if (!plane_format[p]->format)
+ return false;
+ }
+
+ for (int p = 0; p < desc.num_planes; p++) {
struct texplane *plane = &init->image.planes[p];
const struct fmt_entry *format = plane_format[p];
assert(format);
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index 6c588073ac..7f77be0421 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -27,6 +27,10 @@
// inserted at the beginning of all shaders
#!section prelude
+#ifdef GL_ES
+precision mediump float;
+#endif
+
// GLSL 1.20 compatibility layer
// texture() should be assumed to always map to texture2D()
#if __VERSION__ >= 130
diff --git a/video/out/gl_x11egl.c b/video/out/gl_x11egl.c
index 9732774994..8f2a5e4ffa 100644
--- a/video/out/gl_x11egl.c
+++ b/video/out/gl_x11egl.c
@@ -34,7 +34,7 @@ struct priv {
EGLSurface egl_surface;
};
-static EGLConfig select_fb_config_egl(struct MPGLContext *ctx)
+static EGLConfig select_fb_config_egl(struct MPGLContext *ctx, bool es)
{
struct priv *p = ctx->priv;
@@ -44,7 +44,7 @@ static EGLConfig select_fb_config_egl(struct MPGLContext *ctx)
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 0,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ EGL_RENDERABLE_TYPE, es ? EGL_OPENGL_ES_BIT : EGL_OPENGL_BIT,
EGL_NONE
};
@@ -62,13 +62,13 @@ static EGLConfig select_fb_config_egl(struct MPGLContext *ctx)
}
static bool create_context_egl(MPGLContext *ctx, EGLConfig config,
- EGLNativeWindowType window)
+ EGLNativeWindowType window, bool es)
{
struct priv *p = ctx->priv;
EGLint context_attributes[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR,
- MPGL_VER_GET_MAJOR(ctx->requested_gl_version),
+ es ? 3 : MPGL_VER_GET_MAJOR(ctx->requested_gl_version),
EGL_NONE
};
@@ -93,7 +93,7 @@ static bool create_context_egl(MPGLContext *ctx, EGLConfig config,
return true;
}
-static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
+static bool config_window_x11_egl_(struct MPGLContext *ctx, int flags, bool es)
{
struct priv *p = ctx->priv;
struct vo *vo = ctx->vo;
@@ -103,12 +103,12 @@ static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
return true;
}
- eglBindAPI(EGL_OPENGL_API);
+ eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
p->egl_display = eglGetDisplay(vo->x11->display);
eglInitialize(p->egl_display, NULL, NULL);
- EGLConfig config = select_fb_config_egl(ctx);
+ EGLConfig config = select_fb_config_egl(ctx, es);
if (!config)
return false;
@@ -126,7 +126,7 @@ static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
XFree(vi);
- if (!create_context_egl(ctx, config, (EGLNativeWindowType)vo->x11->window))
+ if (!create_context_egl(ctx, config, (EGLNativeWindowType)vo->x11->window, es))
{
vo_x11_uninit(ctx->vo);
return false;
@@ -138,6 +138,16 @@ static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
return true;
}
+static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
+{
+ return config_window_x11_egl_(ctx, flags, false);
+}
+
+static bool config_window_x11_egles(struct MPGLContext *ctx, int flags)
+{
+ return config_window_x11_egl_(ctx, flags, true);
+}
+
static void releaseGlContext_egl(MPGLContext *ctx)
{
struct priv *p = ctx->priv;
@@ -165,3 +175,14 @@ void mpgl_set_backend_x11egl(MPGLContext *ctx)
ctx->vo_uninit = vo_x11_uninit;
ctx->vo_control = vo_x11_control;
}
+
+void mpgl_set_backend_x11egles(MPGLContext *ctx)
+{
+ ctx->priv = talloc_zero(ctx, struct priv);
+ ctx->config_window = config_window_x11_egles;
+ ctx->releaseGlContext = releaseGlContext_egl;
+ ctx->swapGlBuffers = swapGlBuffers_egl;
+ ctx->vo_init = vo_x11_init;
+ ctx->vo_uninit = vo_x11_uninit;
+ ctx->vo_control = vo_x11_control;
+}