mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
0f9fcf0ed4
commit
8494fdadae
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¶ms);
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue