From 68898f5aa43eaa28621c3d64505466ee91f9f98c Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 3 Mar 2026 10:10:04 +0000 Subject: [PATCH] video/out: add OpenGL 2.0 support Add support for OpenGL 2.0 for legacy systems like macOS 10.6. Changes: - Lower minimum OpenGL version from 2.1 to 2.0 - Update GLSL version: GL 2.0 uses GLSL 110, GL 2.1+ uses GLSL 120 - Update format flags comments to reflect GL 2.0-2.x range - Update error messages to mention GL 2.0 instead of 2.1 - Load GL 2.0 core functions (same as 2.1) - Note: F_GL2 flag already correctly matches GL 2.0-2.x range - Note: F_GL2F flag covers GL 2.x with extensions (texture_rg, etc.) This allows mpv to run on systems with OpenGL 2.0 drivers, such as older macOS versions and legacy graphics hardware. --- video/out/gpu/video.c | 2 +- video/out/hwdec/hwdec_cuda_gl.c | 4 ++-- video/out/opengl/common.c | 13 +++++++------ video/out/opengl/context.c | 1 + video/out/opengl/formats.c | 4 ++-- video/out/opengl/formats.h | 4 ++-- video/out/opengl/ra_gl.c | 4 ++-- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index f9649501f7..50addcc0d6 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -3060,7 +3060,7 @@ static float chroma_realign(int size, int pixel) return size / (float)chroma_upsize(size, pixel); } -// Minimal rendering code path, for GLES or OpenGL 2.1 without proper FBOs. +// Minimal rendering code path, for GLES or OpenGL 2.0 without proper FBOs. static void pass_render_frame_dumb(struct gl_video *p) { struct image img[4]; diff --git a/video/out/hwdec/hwdec_cuda_gl.c b/video/out/hwdec/hwdec_cuda_gl.c index 4c2535232f..ce590cc724 100644 --- a/video/out/hwdec/hwdec_cuda_gl.c +++ b/video/out/hwdec/hwdec_cuda_gl.c @@ -110,8 +110,8 @@ static bool cuda_gl_check(const struct ra_hwdec *hw) { return false; // This is not an OpenGL RA. GL *gl = ra_gl_get(hw->ra_ctx->ra); - if (gl->version < 210 && gl->es < 300) { - MP_VERBOSE(hw, "need OpenGL >= 2.1 or OpenGL-ES >= 3.0\n"); + if (gl->version < 200 && gl->es < 300) { + MP_VERBOSE(hw, "need OpenGL >= 2.0 or OpenGL-ES >= 3.0\n"); return false; } diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index a5de79c901..f51f4ddf29 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -89,10 +89,10 @@ struct gl_functions { // Note: to keep the number of sections low, some functions are in multiple // sections (if there are tricky combinations of GL/ES versions) static const struct gl_functions gl_functions[] = { - // GL 2.1+ desktop and GLES 2.0+ (anything we support) - // Probably all of these are in GL 2.0 too, but we require GLSL 120. + // GL 2.0+ desktop and GLES 2.0+ (anything we support) + // All these functions are in GL 2.0 core. { - .ver_core = 210, + .ver_core = 200, .ver_es_core = 200, .functions = (const struct gl_function[]) { DEF_FN(ActiveTexture), @@ -150,9 +150,9 @@ static const struct gl_functions gl_functions[] = { {0} }, }, - // GL 2.1+ desktop only (and GLSL 120 shaders) + // GL 2.0+ desktop only (these are not in GLES 2.0) { - .ver_core = 210, + .ver_core = 200, .provides = MPGL_CAP_ROW_LENGTH | MPGL_CAP_1D_TEX, .functions = (const struct gl_function[]) { DEF_FN(DrawBuffer), @@ -649,7 +649,8 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), if (gl->es >= 300) gl->glsl_version = gl->es; } else { - gl->glsl_version = 120; + // GL 2.0 supports GLSL 110, GL 2.1+ supports GLSL 120 + gl->glsl_version = gl->version >= 210 ? 120 : 110; int glsl_major = 0, glsl_minor = 0; if (shader && sscanf(shader, "%d.%d", &glsl_major, &glsl_minor) == 2) gl->glsl_version = glsl_major * 100 + glsl_minor; diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c index 31675dc4f2..810df30dda 100644 --- a/video/out/opengl/context.c +++ b/video/out/opengl/context.c @@ -34,6 +34,7 @@ const int mpgl_min_required_gl_versions[] = { 440, 320, 210, + 200, 0 }; diff --git a/video/out/opengl/formats.c b/video/out/opengl/formats.c index dd0e89d54d..7ea1e84048 100644 --- a/video/out/opengl/formats.c +++ b/video/out/opengl/formats.c @@ -104,7 +104,7 @@ const struct gl_format gl_formats[] = { // Return an or-ed combination of all F_ flags that apply. int gl_format_feature_flags(GL *gl) { - return (gl->version == 210 ? F_GL2 : 0) + return (gl->version >= 200 && gl->version < 300 ? F_GL2 : 0) | (gl->version >= 300 ? F_GL3 : 0) | (gl->es == 200 ? F_ES2 : 0) | (gl->es >= 300 ? F_ES3 : 0) @@ -112,7 +112,7 @@ int gl_format_feature_flags(GL *gl) | (gl->mpgl_caps & MPGL_CAP_EXT16 ? F_EXT16 : 0) | ((gl->es >= 300 && (gl->mpgl_caps & MPGL_CAP_EXT_CR_HFLOAT)) ? F_EXTF16 : 0) - | ((gl->version == 210 && + | ((gl->version >= 200 && gl->version < 300 && (gl->mpgl_caps & MPGL_CAP_ARB_FLOAT) && (gl->mpgl_caps & MPGL_CAP_TEX_RG) && (gl->mpgl_caps & MPGL_CAP_FB)) ? F_GL2F : 0) diff --git a/video/out/opengl/formats.h b/video/out/opengl/formats.h index f727a3b6ef..93bd341e8c 100644 --- a/video/out/opengl/formats.h +++ b/video/out/opengl/formats.h @@ -16,14 +16,14 @@ enum { // Version flags. If at least 1 flag matches, the format entry is considered // supported on the current GL context. - F_GL2 = 1 << 0, // GL2.1-only + F_GL2 = 1 << 0, // GL 2.0-2.x (without extensions) F_GL3 = 1 << 1, // GL3.0 or later F_ES2 = 1 << 2, // ES2-only F_ES3 = 1 << 3, // ES3.0 or later F_ES32 = 1 << 4, // ES3.2 or later F_EXT16 = 1 << 5, // ES with GL_EXT_texture_norm16 F_EXTF16 = 1 << 6, // GL_EXT_color_buffer_half_float - F_GL2F = 1 << 7, // GL2.1-only with texture_rg + texture_float + FBOs + F_GL2F = 1 << 7, // GL 2.0-2.x with texture_rg + texture_float + FBOs F_APPL = 1 << 8, // GL_APPLE_rgb_422 // Feature flags. They are additional and signal presence of features. diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c index 8662bd4f5a..c61a04361e 100644 --- a/video/out/opengl/ra_gl.c +++ b/video/out/opengl/ra_gl.c @@ -80,8 +80,8 @@ static void probe_real_size(GL *gl, struct ra_format *fmt) static int ra_init_gl(struct ra *ra, GL *gl) { - if (gl->version < 210 && gl->es < 200) { - MP_ERR(ra, "At least OpenGL 2.1 or OpenGL ES 2.0 required.\n"); + if (gl->version < 200 && gl->es < 200) { + MP_ERR(ra, "At least OpenGL 2.0 or OpenGL ES 2.0 required.\n"); return -1; }