From a0051b9da28fb67cebae1fef322603ddb8f619f8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 19 Dec 2014 01:03:08 +0100 Subject: [PATCH] vo_opengl: add GLES 2 support Rather basic support. Almost nothing works, and even if it does, it's bound to be inefficient (due to texture upload). This was tested with the nVidia desktop binary drivers, which provide GLES 2 support only. However, nVidia is not known to be very strict about OpenGL, and the driver is very new too, so the vo_opengl code will have bugs too. --- video/out/gl_common.c | 17 ++++++++++------- video/out/gl_osd.c | 2 +- video/out/gl_video.c | 20 +++++++++++++++++--- video/out/gl_video_shaders.glsl | 19 +++++++++++++++---- video/out/gl_x11egl.c | 2 +- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/video/out/gl_common.c b/video/out/gl_common.c index aa5cd763ae..a8d08d1c4a 100644 --- a/video/out/gl_common.c +++ b/video/out/gl_common.c @@ -510,11 +510,9 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), if (gl->es) { gl->es = gl->version; - if (gl->version >= 300) { - gl->version = 300; // pretend it's desktop OpenGL 3.0 - } else { - mp_warn(log, "At least GLESv3 required.\n"); - gl->version = 0; + gl->version = 0; + if (gl->es < 200) { + mp_fatal(log, "At least GLESv2 required.\n"); return; } } @@ -532,7 +530,7 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), // and above. bool has_legacy = false; - if (gl->version >= MPGL_VER(3, 0)) { + if (gl->version >= 300) { gl->GetStringi = get_fn(fn_ctx, "glGetStringi"); gl->GetIntegerv = get_fn(fn_ctx, "glGetIntegerv"); @@ -550,7 +548,7 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), // This version doesn't have GL_ARB_compatibility yet, and always // includes legacy (except with CONTEXT_FORWARD_COMPATIBLE_BIT_ARB). - if (gl->version == MPGL_VER(3, 0) && !gl->es) + if (gl->version == 300) has_legacy = true; } else { const char *ext = (char*)gl->GetString(GL_EXTENSIONS); @@ -559,6 +557,9 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), has_legacy = true; } + if (gl->es) + has_legacy = false; + if (has_legacy) mp_verbose(log, "OpenGL legacy compat. found.\n"); mp_dbg(log, "Combined OpenGL extensions string:\n%s\n", gl->extensions); @@ -631,6 +632,8 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), gl->glsl_version = 0; if (gl->es) { + if (gl->es >= 200) + gl->glsl_version = 100; if (gl->es >= 300) gl->glsl_version = 300; } else { diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c index f0917c364e..2bac4ef357 100644 --- a/video/out/gl_osd.c +++ b/video/out/gl_osd.c @@ -66,7 +66,7 @@ struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd .scratch = talloc_zero_size(ctx, 1), }; - if (gl->es) { + if (gl->es >= 300) { ctx->fmt_table = osd_to_gles3_formats; } else if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG)) { ctx->fmt_table = osd_to_gl_legacy_formats; diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 8d4682bfe7..5f8925bcb6 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -244,6 +244,17 @@ static const struct fmt_entry gl_byte_formats_gles3[] = { {0, 0, 0, 0}, // 4 x 16 }; +static const struct fmt_entry gl_byte_formats_gles2[] = { + {0, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE}, // 1 x 8 + {0, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE}, // 2 x 8 + {0, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE}, // 3 x 8 + {0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}, // 4 x 8 + {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_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE}, // 1 x 8 {0, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE}, // 2 x 8 @@ -399,8 +410,10 @@ 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_byte_formats; - if (gl->es) { + if (gl->es >= 300) { fmts = gl_byte_formats_gles3; + } else if (gl->es) { + fmts = gl_byte_formats_gles2; } else if (!(gl->mpgl_caps & MPGL_CAP_TEX_RG)) { fmts = gl_byte_formats_legacy; } @@ -941,7 +954,7 @@ static void compile_shaders(struct gl_video *p) talloc_asprintf(tmp, "#version %d%s\n" "#define HAVE_RG %d\n" "%s%s", - gl->glsl_version, gl->es ? " es" : "", + gl->glsl_version, gl->es >= 300 ? " es" : "", rg, shader_prelude, PRELUDE_END); bool use_cms = p->opts.srgb || p->use_lut_3d; @@ -2102,7 +2115,8 @@ static void check_gl_features(struct gl_video *p) } } - // GLES doesn't provide filtered 16 bit integer textures + // GLES3 doesn't provide filtered 16 bit integer textures + // GLES2 doesn't even provide 3D textures if (p->use_lut_3d && gl->es) { p->use_lut_3d = false; disabled[n_disabled++] = "color management (GLES unsupported)"; diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl index 547d5cd621..937673b0c3 100644 --- a/video/out/gl_video_shaders.glsl +++ b/video/out/gl_video_shaders.glsl @@ -29,6 +29,12 @@ #ifdef GL_ES precision mediump float; +#define HAVE_3DTEX (__VERSION__ >= 300) +#define HAVE_ARRAYS (__VERSION__ >= 300) +#else +// Desktop GL +#define HAVE_3DTEX 1 +#define HAVE_ARRAYS 1 #endif // GLSL 1.20 compatibility layer @@ -88,7 +94,9 @@ vec3 bt2020_compand(vec3 v) uniform mat3 transform; uniform vec3 translation; +#if HAVE_3DTEX uniform sampler3D lut_3d; +#endif uniform mat3 cms_matrix; // transformation from file's gamut to bt.2020 in vec2 vertex_position; @@ -122,7 +130,7 @@ void main() { // and to BT.2020 for 3DLUT). Normal clamping here as perceptually // accurate colorimetry is probably not worth the performance trade-off // here. - color.rgb = clamp(cms_matrix * color.rgb, 0, 1); + color.rgb = clamp(cms_matrix * color.rgb, 0.0, 1.0); #endif #ifdef USE_OSD_3DLUT color.rgb = pow(color.rgb, vec3(1.0/2.4)); // linear -> 2.4 3DLUT space @@ -166,7 +174,9 @@ uniform vec2 chroma_center_offset; uniform vec2 chroma_div; uniform sampler2D lut_c; uniform sampler2D lut_l; +#if HAVE_3DTEX uniform sampler3D lut_3d; +#endif uniform sampler2D dither; uniform mat3 colormatrix; uniform vec3 colormatrix_c; @@ -230,16 +240,17 @@ vec4 sample_bicubic_fast(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord, float p return mix(aa, ab, parmx.b); } +#if HAVE_ARRAYS float[2] weights2(sampler2D lookup, float f) { vec2 c = texture(lookup, vec2(0.5, f)).RG; return float[2](c.r, c.g); } - float[6] weights6(sampler2D lookup, float f) { vec4 c1 = texture(lookup, vec2(0.25, f)); vec4 c2 = texture(lookup, vec2(0.75, f)); return float[6](c1.r, c1.g, c1.b, c2.r, c2.g, c2.b); } +#endif // For N=n*4 with n>1 (N==4 is covered by weights4()). #define WEIGHTS_N(NAME, N) \ @@ -391,7 +402,7 @@ void main() { // CONST_LUMA involves numbers outside the [0,1] range so we make sure // to clip here, after the (possible) USE_CONST_LUMA calculations are done, // instead of immediately after the colormatrix conversion. - color = clamp(color, 0, 1); + color = clamp(color, 0.0, 1.0); #endif // If we are scaling in linear light (SRGB or 3DLUT option enabled), we // expand our source colors before scaling. This shader currently just @@ -435,7 +446,7 @@ void main() { // the fact that they're not representable on the target device. // TODO: Desaturate colorimetrically; this happens automatically for // 3dlut targets but not for sRGB mode. Not sure if this is a requirement. - color = clamp(color, 0, 1); + color = clamp(color, 0.0, 1.0); #endif #ifdef USE_3DLUT // For the 3DLUT we are arbitrarily using 2.4 as input gamma to reduce diff --git a/video/out/gl_x11egl.c b/video/out/gl_x11egl.c index 8f2a5e4ffa..2bd4def4df 100644 --- a/video/out/gl_x11egl.c +++ b/video/out/gl_x11egl.c @@ -68,7 +68,7 @@ static bool create_context_egl(MPGLContext *ctx, EGLConfig config, EGLint context_attributes[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, - es ? 3 : MPGL_VER_GET_MAJOR(ctx->requested_gl_version), + es ? 2 : MPGL_VER_GET_MAJOR(ctx->requested_gl_version), EGL_NONE };