summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-30 13:36:11 +0200
committerwm4 <wm4@nowhere>2013-05-30 15:38:07 +0200
commite08bf272ee100911001530aa605b8cf6b381c47e (patch)
tree77efcd9f67f63d82f098082d639921ab38cf7232 /video
parent6bfbca9912c2d86d6b28dc5000bb878fb5fbe849 (diff)
downloadmpv-e08bf272ee100911001530aa605b8cf6b381c47e.tar.bz2
mpv-e08bf272ee100911001530aa605b8cf6b381c47e.tar.xz
gl_video: fix some dithering bugs
The internal texture format GL_RED is typically 8 bit, which is clearly not good enough for the new dither matrix. The idea was to use a float texture format, but this was somehow "forgotten". Use GL_R16, since 16 bit textures are more robust, and provide more precision for the same memory usage. Change how the offset for centering the dither matrix is applied. This is needed for making it possible to round up values to the target depth. Before this commit, this changed the output even if the input was exact and input and output depth were the same, which is not really what you want. Now it doesn't do that anymore.
Diffstat (limited to 'video')
-rw-r--r--video/out/gl_video.c21
-rw-r--r--video/out/gl_video_shaders.glsl5
2 files changed, 11 insertions, 15 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index cc2656c763..58c3bdf761 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -156,7 +156,7 @@ struct gl_video {
GLuint dither_texture;
float dither_quantization;
- float dither_multiply;
+ float dither_center;
int dither_size;
uint32_t image_w, image_h;
@@ -522,8 +522,8 @@ static void update_uniforms(struct gl_video *p, GLuint program)
gl->Uniform1i(gl->GetUniformLocation(program, "dither"), TEXUNIT_DITHER);
gl->Uniform1f(gl->GetUniformLocation(program, "dither_quantization"),
p->dither_quantization);
- gl->Uniform1f(gl->GetUniformLocation(program, "dither_multiply"),
- p->dither_multiply);
+ gl->Uniform1f(gl->GetUniformLocation(program, "dither_center"),
+ p->dither_center);
float sparam1 = p->opts.scaler_params[0];
gl->Uniform1f(gl->GetUniformLocation(program, "filter_param1"),
@@ -953,6 +953,7 @@ static void init_dither(struct gl_video *p)
int tex_size;
void *tex_data;
+ GLint tex_iformat;
GLenum tex_type;
unsigned char temp[256];
@@ -968,6 +969,7 @@ static void init_dither(struct gl_video *p)
}
tex_size = size;
+ tex_iformat = GL_R16;
tex_type = GL_FLOAT;
tex_data = p->last_dither_matrix;
} else {
@@ -975,6 +977,7 @@ static void init_dither(struct gl_video *p)
mp_make_ordered_dither_matrix(temp, 8);
tex_size = 8;
+ tex_iformat = GL_RED;
tex_type = GL_UNSIGNED_BYTE;
tex_data = temp;
}
@@ -984,7 +987,7 @@ static void init_dither(struct gl_video *p)
// dither matrix. The precision of the source implicitly decides how many
// dither patterns can be visible.
p->dither_quantization = (1 << dst_depth) - 1;
- p->dither_multiply = p->dither_quantization + 1.0 / (tex_size * tex_size);
+ p->dither_center = 0.5 / (tex_size * tex_size);
p->dither_size = tex_size;
gl->ActiveTexture(GL_TEXTURE0 + TEXUNIT_DITHER);
@@ -992,7 +995,7 @@ static void init_dither(struct gl_video *p)
gl->BindTexture(GL_TEXTURE_2D, p->dither_texture);
gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RED, tex_size, tex_size, 0, GL_RED,
+ gl->TexImage2D(GL_TEXTURE_2D, 0, tex_iformat, tex_size, tex_size, 0, GL_RED,
tex_type, tex_data);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -1589,14 +1592,6 @@ static void check_gl_features(struct gl_video *p)
}
}
- if (!have_float_tex && p->opts.dither_depth >= 0) {
- // only fruit dithering uses float textures
- if (p->opts.dither_algo == 0) {
- p->opts.dither_depth = -1;
- disabled[n_disabled++] = "dithering (float tex.)";
- }
- }
-
if (!have_srgb && p->opts.srgb) {
p->opts.srgb = false;
disabled[n_disabled++] = "sRGB";
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index c19a19fbee..5d77d0c38f 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -126,7 +126,7 @@ uniform vec3 inv_gamma;
uniform float input_gamma;
uniform float conv_gamma;
uniform float dither_quantization;
-uniform float dither_multiply;
+uniform float dither_center;
uniform float filter_param1;
uniform vec2 dither_size;
@@ -382,7 +382,8 @@ void main() {
dither_pos = dither_trafo * dither_pos;
#endif
float dither_value = texture(dither, dither_pos).r;
- color = floor(color * dither_multiply + dither_value ) / dither_quantization;
+ color = floor(color * dither_quantization + dither_value + dither_center) /
+ dither_quantization;
#endif
#ifdef USE_ALPHA
out_color = vec4(color, alpha);