summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/video.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-07-29 20:12:43 +0200
committerwm4 <wm4@nowhere>2017-07-29 20:12:43 +0200
commit0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227 (patch)
tree391346a8333d9d3dcf692c853310839a4556b164 /video/out/opengl/video.c
parent6fcc09ff3d0db649ff7a8d9fdcb49c0d0b700905 (diff)
downloadmpv-0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227.tar.bz2
mpv-0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227.tar.xz
vo_opengl: do not use GL format conversion on texture upload
The dither texture data is created as a float array, but uploaded to a texture with GL_R16 as internal format. We relied on GL to do the conversion from float to uint16_t. Not all GL variants even support this: GLES does not provide this conversion (one of the reasons why this code has a float16 code path). Also, ra is not going to do this. So just convert on the fly. Still keep the float16 texture format fallback, because not all GLES implementations provide GL_R16. There is some possibility that we'll need to provide some kind of upload conversion anyway for float->float16. We still rely on GL doing this implicitly, and all GL variants support it, but with RA there might be the need for explicit conversion. Even then, it might be best to reduce the number of conversion cases. I'll worry about this later.
Diffstat (limited to 'video/out/opengl/video.c')
-rw-r--r--video/out/opengl/video.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index ac8c9462ee..2cf0d11783 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -2597,10 +2597,8 @@ static void pass_dither(struct gl_video *p)
int tex_size = 0;
void *tex_data = NULL;
- GLint tex_iformat = 0;
- GLint tex_format = 0;
- GLenum tex_type = 0;
- unsigned char temp[256];
+ const struct gl_format *fmt = NULL;
+ void *temp = NULL;
if (p->opts.dither_algo == DITHER_FRUIT) {
int sizeb = p->opts.dither_size;
@@ -2614,15 +2612,18 @@ static void pass_dither(struct gl_video *p)
}
// Prefer R16 texture since they provide higher precision.
- const struct gl_format *fmt = gl_find_unorm_format(gl, 2, 1);
- if (!fmt || gl->es)
+ fmt = gl_find_unorm_format(gl, 2, 1);
+ if (!fmt)
fmt = gl_find_float16_format(gl, 1);
if (fmt) {
tex_size = size;
- tex_iformat = fmt->internal_format;
- tex_format = fmt->format;
- tex_type = GL_FLOAT;
tex_data = p->last_dither_matrix;
+ if (fmt->type == GL_UNSIGNED_SHORT) {
+ uint16_t *t = temp = talloc_array(NULL, uint16_t, size * size);
+ for (int n = 0; n < size * size; n++)
+ t[n] = p->last_dither_matrix[n] * UINT16_MAX;
+ tex_data = t;
+ }
} else {
MP_VERBOSE(p, "GL too old. Falling back to ordered dither.\n");
p->opts.dither_algo = DITHER_ORDERED;
@@ -2630,14 +2631,11 @@ static void pass_dither(struct gl_video *p)
}
if (p->opts.dither_algo == DITHER_ORDERED) {
- assert(sizeof(temp) >= 8 * 8);
+ temp = talloc_array(NULL, char, 8 * 8);
mp_make_ordered_dither_matrix(temp, 8);
- const struct gl_format *fmt = gl_find_unorm_format(gl, 1, 1);
+ fmt = gl_find_unorm_format(gl, 1, 1);
tex_size = 8;
- tex_iformat = fmt->internal_format;
- tex_format = fmt->format;
- tex_type = fmt->type;
tex_data = temp;
}
@@ -2646,8 +2644,8 @@ static void pass_dither(struct gl_video *p)
gl->GenTextures(1, &p->dither_texture);
gl->BindTexture(GL_TEXTURE_2D, p->dither_texture);
gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- gl->TexImage2D(GL_TEXTURE_2D, 0, tex_iformat, tex_size, tex_size, 0,
- tex_format, tex_type, tex_data);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, fmt->internal_format, tex_size, tex_size,
+ 0, fmt->format, fmt->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);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -2656,6 +2654,8 @@ static void pass_dither(struct gl_video *p)
gl->BindTexture(GL_TEXTURE_2D, 0);
debug_check_gl(p, "dither setup");
+
+ talloc_free(temp);
}
GLSLF("// dithering\n");