summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-07-29 20:14:48 +0200
committerwm4 <wm4@nowhere>2017-07-29 20:14:48 +0200
commit8494fdadaeb25b3c1a42c71559be5bd74d1d4638 (patch)
treeda93683844c45e1fec754c68dc19c99d167562f2
parent0f9fcf0ed4ecb54eaadbddd3cbbc14d39ab93227 (diff)
downloadmpv-8494fdadaeb25b3c1a42c71559be5bd74d1d4638.tar.bz2
mpv-8494fdadaeb25b3c1a42c71559be5bd74d1d4638.tar.xz
vo_opengl: manage dither texture via ra
Also add some more helpers. Fix the broken math.h include statement. utils.c uses ra_gl.h internals, which it shouldn't, and which will be removed again as soon as this code gets converted to ra fully.
-rw-r--r--video/out/opengl/ra.c12
-rw-r--r--video/out/opengl/ra.h6
-rw-r--r--video/out/opengl/ra_gl.c11
-rw-r--r--video/out/opengl/utils.c12
-rw-r--r--video/out/opengl/utils.h6
-rw-r--r--video/out/opengl/video.c53
6 files changed, 66 insertions, 34 deletions
diff --git a/video/out/opengl/ra.c b/video/out/opengl/ra.c
index df27f723c2..57734afd81 100644
--- a/video/out/opengl/ra.c
+++ b/video/out/opengl/ra.c
@@ -4,6 +4,18 @@
#include "ra.h"
+struct ra_tex *ra_tex_create(struct ra *ra, const struct ra_tex_params *params)
+{
+ return ra->fns->tex_create(ra, params);
+}
+
+void ra_tex_free(struct ra *ra, struct ra_tex **tex)
+{
+ if (*tex)
+ ra->fns->tex_destroy(ra, *tex);
+ *tex = NULL;
+}
+
// Return whether this is a tightly packed format with no external padding and
// with the same bit size/depth in all components.
static bool ra_format_is_regular(const struct ra_format *fmt)
diff --git a/video/out/opengl/ra.h b/video/out/opengl/ra.h
index 211f87077b..11b458b616 100644
--- a/video/out/opengl/ra.h
+++ b/video/out/opengl/ra.h
@@ -71,6 +71,9 @@ struct ra_tex_params {
// if true, repeat texture coordinates
bool non_normalized; // hack for GL_TEXTURE_RECTANGLE OSX idiocy
// always set to false, except in OSX code
+ // If non-NULL, the texture will be created with these contents, and is
+ // considered immutable afterwards (no upload, mapping, or rendering to it).
+ void *initial_data;
};
struct ra_tex {
@@ -137,6 +140,9 @@ struct ra_fns {
bool (*poll_mapped_buffer)(struct ra *ra, struct ra_mapped_buffer *buf);
};
+struct ra_tex *ra_tex_create(struct ra *ra, const struct ra_tex_params *params);
+void ra_tex_free(struct ra *ra, struct ra_tex **tex);
+
const struct ra_format *ra_find_unorm_format(struct ra *ra,
int bytes_per_component,
int n_components);
diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c
index 01f1fcd6e5..faf8812df7 100644
--- a/video/out/opengl/ra_gl.c
+++ b/video/out/opengl/ra_gl.c
@@ -144,24 +144,29 @@ static struct ra_tex *gl_tex_create(struct ra *ra,
if (params->dimensions > 2)
gl->TexParameteri(tex_gl->target, GL_TEXTURE_WRAP_R, wrap);
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
switch (params->dimensions) {
case 1:
gl->TexImage1D(tex_gl->target, 0, tex_gl->internal_format, params->w,
- 0, tex_gl->format, tex_gl->type, NULL);
+ 0, tex_gl->format, tex_gl->type, params->initial_data);
break;
case 2:
gl->TexImage2D(tex_gl->target, 0, tex_gl->internal_format, params->w,
- params->h, 0, tex_gl->format, tex_gl->type, NULL);
+ params->h, 0, tex_gl->format, tex_gl->type,
+ params->initial_data);
break;
case 3:
gl->TexImage3D(tex_gl->target, 0, tex_gl->internal_format, params->w,
params->h, params->d, 0, tex_gl->format, tex_gl->type,
- NULL);
+ params->initial_data);
break;
}
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
gl->BindTexture(tex_gl->target, 0);
+ tex->params.initial_data = NULL;
+
return tex;
}
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index 8c52b61cba..024b8d4bbe 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -33,6 +33,7 @@
#include "options/path.h"
#include "stream/stream.h"
#include "formats.h"
+#include "ra_gl.h"
#include "utils.h"
// GLU has this as gluErrorString (we don't use GLU, as it is legacy-OpenGL)
@@ -746,6 +747,17 @@ void gl_sc_uniform_tex_ui(struct gl_shader_cache *sc, char *name, GLuint texture
u->tex_handle = texture;
}
+void gl_sc_uniform_texture(struct gl_shader_cache *sc, char *name,
+ struct ra_tex *tex)
+{
+ struct ra_tex_gl *tex_gl = tex->priv;
+ if (tex->params.format->ctype == RA_CTYPE_UINT) {
+ gl_sc_uniform_tex_ui(sc, name, tex_gl->texture);
+ } else {
+ gl_sc_uniform_tex(sc, name, tex_gl->target, tex_gl->texture);
+ }
+}
+
static const char *mp_image2D_type(GLenum access)
{
switch (access) {
diff --git a/video/out/opengl/utils.h b/video/out/opengl/utils.h
index 7e5f8f5931..2a15d85b71 100644
--- a/video/out/opengl/utils.h
+++ b/video/out/opengl/utils.h
@@ -19,8 +19,10 @@
#ifndef MP_GL_UTILS_
#define MP_GL_UTILS_
+#include <math.h>
+
#include "common.h"
-#include "math.h"
+#include "ra.h"
struct mp_log;
@@ -145,6 +147,8 @@ void gl_sc_paddf(struct gl_shader_cache *sc, const char *textf, ...)
PRINTF_ATTRIBUTE(2, 3);
void gl_sc_uniform_tex(struct gl_shader_cache *sc, char *name, GLenum target,
GLuint texture);
+void gl_sc_uniform_texture(struct gl_shader_cache *sc, char *name,
+ struct ra_tex *tex);
void gl_sc_uniform_tex_ui(struct gl_shader_cache *sc, char *name, GLuint texture);
void gl_sc_uniform_image2D(struct gl_shader_cache *sc, char *name, GLuint texture,
GLuint iformat, GLenum access);
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 2cf0d11783..2cbf99bad8 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -205,8 +205,7 @@ struct gl_video {
bool use_lut_3d;
int lut_3d_size[3];
- GLuint dither_texture;
- int dither_size;
+ struct ra_tex *dither_texture;
struct mp_image_params real_image_params; // configured format
struct mp_image_params image_params; // texture format (mind hwdec case)
@@ -531,13 +530,10 @@ static void reinit_osd(struct gl_video *p)
static void uninit_rendering(struct gl_video *p)
{
- GL *gl = p->gl;
-
for (int n = 0; n < SCALER_COUNT; n++)
uninit_scaler(p, &p->scaler[n]);
- gl->DeleteTextures(1, &p->dither_texture);
- p->dither_texture = 0;
+ ra_tex_free(p->ra, &p->dither_texture);
for (int n = 0; n < 4; n++) {
fbotex_uninit(&p->merge_fbo[n]);
@@ -2582,8 +2578,6 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
static void pass_dither(struct gl_video *p)
{
- GL *gl = p->gl;
-
// Assume 8 bits per component if unknown.
int dst_depth = p->fb_depth;
if (p->opts.dither_depth > 0)
@@ -2597,7 +2591,7 @@ static void pass_dither(struct gl_video *p)
int tex_size = 0;
void *tex_data = NULL;
- const struct gl_format *fmt = NULL;
+ const struct ra_format *fmt = NULL;
void *temp = NULL;
if (p->opts.dither_algo == DITHER_FRUIT) {
@@ -2612,13 +2606,13 @@ static void pass_dither(struct gl_video *p)
}
// Prefer R16 texture since they provide higher precision.
- fmt = gl_find_unorm_format(gl, 2, 1);
+ fmt = ra_find_unorm_format(p->ra, 2, 1);
if (!fmt)
- fmt = gl_find_float16_format(gl, 1);
+ fmt = ra_find_float16_format(p->ra, 1);
if (fmt) {
tex_size = size;
tex_data = p->last_dither_matrix;
- if (fmt->type == GL_UNSIGNED_SHORT) {
+ if (fmt->ctype == RA_CTYPE_UNORM) {
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;
@@ -2634,24 +2628,23 @@ static void pass_dither(struct gl_video *p)
temp = talloc_array(NULL, char, 8 * 8);
mp_make_ordered_dither_matrix(temp, 8);
- fmt = gl_find_unorm_format(gl, 1, 1);
+ fmt = ra_find_unorm_format(p->ra, 1, 1);
tex_size = 8;
tex_data = temp;
}
- p->dither_size = tex_size;
-
- 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, 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);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
- gl->BindTexture(GL_TEXTURE_2D, 0);
+ struct ra_tex_params params = {
+ .dimensions = 2,
+ .w = tex_size,
+ .h = tex_size,
+ .d = 1,
+ .format = fmt,
+ .render_src = true,
+ .src_linear = true,
+ .src_repeat = true,
+ .initial_data = tex_data,
+ };
+ p->dither_texture = ra_tex_create(p->ra, &params);
debug_check_gl(p, "dither setup");
@@ -2665,10 +2658,11 @@ static void pass_dither(struct gl_video *p)
// dither matrix. The precision of the source implicitly decides how many
// dither patterns can be visible.
int dither_quantization = (1 << dst_depth) - 1;
+ int dither_size = p->dither_texture->params.w;
- gl_sc_uniform_tex(p->sc, "dither", GL_TEXTURE_2D, p->dither_texture);
+ gl_sc_uniform_texture(p->sc, "dither", p->dither_texture);
- GLSLF("vec2 dither_pos = gl_FragCoord.xy * 1.0/%d.0;\n", p->dither_size);
+ GLSLF("vec2 dither_pos = gl_FragCoord.xy * 1.0/%d.0;\n", dither_size);
if (p->opts.temporal_dither) {
int phase = (p->frames_rendered / p->opts.temporal_dither_period) % 8u;
@@ -2684,8 +2678,7 @@ static void pass_dither(struct gl_video *p)
GLSL(float dither_value = texture(dither, dither_pos).r;)
GLSLF("color = floor(color * %d.0 + dither_value + 0.5 / %d.0) * 1.0/%d.0;\n",
- dither_quantization, p->dither_size * p->dither_size,
- dither_quantization);
+ dither_quantization, dither_size * dither_size, dither_quantization);
}
// Draws the OSD, in scene-referred colors.. If cms is true, subtitles are