diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/out/gl_common.c | 43 | ||||
-rw-r--r-- | video/out/gl_common.h | 2 | ||||
-rw-r--r-- | video/out/gl_osd.c | 10 | ||||
-rw-r--r-- | video/out/gl_video.c | 39 | ||||
-rw-r--r-- | video/out/gl_video_shaders.glsl | 4 | ||||
-rw-r--r-- | video/out/gl_x11egl.c | 37 |
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; +} |