[vlc-commits] opengl: add support for dithering

Niklas Haas git at videolan.org
Thu Jan 4 12:09:57 CET 2018


vlc | branch: master | Niklas Haas <vlc at haasn.xyz> | Thu Jan  4 09:10:38 2018 +0100| [7c11bcf2722be9be73c1a1eaa0db4b5d6a66546d] | committer: Thomas Guillem

opengl: add support for dithering

This uses libplacebo's high quality blue noise algorithm. The lut_size
is chosen as 4 because the method of embedding (literal LUT) is not that
great. Larger texture sizes would require OpenGL/RA support, which is
not currently in the scope of VLC+libplacebo. (Alternatively, we could
try and use a uniform float array instead of a constant array - but it
doesn't seem to matter much)

In theory, we could also try making VLC forwards-compatible with GLSL 130+ and
then enabling the fixed-function ordered dither where available.

Note by Thomas Guillem:
Dithering is disabled by default since it can have an impact on performances
depending on OSses / GL extensions / GPU.

Modified-by: Thomas Guillem <thomas at gllm.fr>
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7c11bcf2722be9be73c1a1eaa0db4b5d6a66546d
---

 modules/video_output/opengl/fragment_shaders.c | 30 ++++++++++++++++++++++++++
 modules/video_output/opengl/vout_helper.h      | 26 +++++++++++++++++++++-
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 74fb3b5b1a..f959d9a69c 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -621,7 +621,37 @@ opengl_fragment_shader_init_impl(opengl_tex_converter_t *tc, GLenum tex_target,
                 pl_color_space_from_video_format(&tc->fmt),
                 dst_space, NULL, false);
 
+        struct pl_shader_obj *dither_state = NULL;
+        int method = var_InheritInteger(tc->gl, "dither-algo");
+        if (method >= 0) {
+
+            unsigned out_bits = 0;
+            int override = var_InheritInteger(tc->gl, "dither-depth");
+            if (override > 0)
+                out_bits = override;
+            else
+            {
+                GLint fb_depth = 0;
+#if !defined(USE_OPENGL_ES2)
+                /* fetch framebuffer depth (we are already bound to the default one). */
+                if (tc->vt->GetFramebufferAttachmentParameteriv != NULL)
+                    tc->vt->GetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK_LEFT,
+                                                                GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
+                                                                &fb_depth);
+#endif
+                if (fb_depth <= 0)
+                    fb_depth = 8;
+                out_bits = fb_depth;
+            }
+
+            pl_shader_dither(sh, out_bits, &dither_state, &(struct pl_dither_params) {
+                .method   = method,
+                .lut_size = 4, // avoid too large values, since this gets embedded
+            });
+        }
+
         const struct pl_shader_res *res = tc->pl_sh_res = pl_shader_finalize(sh);
+        pl_shader_obj_destroy(&dither_state);
 
         FREENULL(tc->uloc.pl_vars);
         tc->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
diff --git a/modules/video_output/opengl/vout_helper.h b/modules/video_output/opengl/vout_helper.h
index 6df2f9b19b..03ba2eb05a 100644
--- a/modules/video_output/opengl/vout_helper.h
+++ b/modules/video_output/opengl/vout_helper.h
@@ -178,6 +178,26 @@ static const char * const tone_text[] = {
 #define TONEMAP_WARN_TEXT N_("Highlight clipped pixels")
 #define TONEMAP_WARN_LONGTEXT N_("Debugging tool to indicate which pixels were clipped as part of the tone mapping process.")
 
+#define DITHER_TEXT N_("Dithering algorithm")
+#define DITHER_LONGTEXT N_("The algorithm to use when dithering to a lower bit depth (degrades performance on some platforms).")
+
+static const int dither_values[] = {
+    -1, // no dithering
+    PL_DITHER_BLUE_NOISE,
+    PL_DITHER_WHITE_NOISE,
+    PL_DITHER_ORDERED_LUT,
+};
+
+static const char * const dither_text[] = {
+    "Disabled",
+    "Blue noise",
+    "White noise",
+    "Bayer matrix (ordered dither)",
+};
+
+#define DEPTH_TEXT N_("Dither depth override (0 = framebuffer depth)")
+#define DEPTH_LONGTEXT N_("Overrides the detected framebuffer depth. Useful to dither to lower bit depths than otherwise required.")
+
 #define add_glopts_placebo() \
     set_section(N_("Colorspace conversion"), NULL) \
     add_integer("rendering-intent", pl_color_map_default_params.intent, \
@@ -195,7 +215,11 @@ static const char * const tone_text[] = {
               TONEMAP_PARAM_TEXT, TONEMAP_PARAM_LONGTEXT, true) \
     add_float("tone-mapping-desat", pl_color_map_default_params.tone_mapping_desaturate, \
               TONEMAP_DESAT_TEXT, TONEMAP_DESAT_LONGTEXT, false) \
-    add_bool("tone-mapping-warn", false, TONEMAP_WARN_TEXT, TONEMAP_WARN_LONGTEXT, false)
+    add_bool("tone-mapping-warn", false, TONEMAP_WARN_TEXT, TONEMAP_WARN_LONGTEXT, false) \
+    set_section(N_("Dithering"), NULL) \
+    add_integer("dither-algo", -1, DITHER_TEXT, DITHER_LONGTEXT, false) \
+            change_integer_list(dither_values, dither_text) \
+    add_integer_with_range("dither-depth", 0, 0, 16, DEPTH_TEXT, DEPTH_LONGTEXT, false)
 #else
 #define add_glopts_placebo()
 #endif



More information about the vlc-commits mailing list