mirror of https://github.com/mpv-player/mpv
vo_opengl: GLES 3 support
Tested with MESA on software emulation. Seems to work well, although the default FBO format in opengl-hq disables most interesting features. I have no idea how well it will work on real hardware (or if it does at all). Unfortunately, some features, including playback of 10 bit video, are not supported. Not sure what to do about this. GLES 2 or 1 do not work.
This commit is contained in:
parent
07975877be
commit
10befa26d9
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
@ -2337,6 +2363,11 @@ supported:
|
|||
if (desc.num_planes == 4 && (init->plane_bits % 8) != 0)
|
||||
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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue