mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 12:02:23 +02:00
vo_opengl: add support for rectangle textures
This allows vo_opengl to use GL_TEXTURE_RECTANGLE textures, either by enabling it with the 'rectangle-textures' sub-option, or by having a hwdec backend force it. By default it's off. The _only_ reason we're adding this is because VDA can export rectangle textures only.
This commit is contained in:
parent
f30c2c99d1
commit
dc582f2505
@ -486,6 +486,11 @@ Available video output drivers are:
|
|||||||
Set the YUV chroma sample location. auto means use the bitstream
|
Set the YUV chroma sample location. auto means use the bitstream
|
||||||
flags (default: auto).
|
flags (default: auto).
|
||||||
|
|
||||||
|
``rectangle-textures``
|
||||||
|
Force use of rectangle textures (default: no). Normally this shouldn't
|
||||||
|
have any advantages over normal textures. Note that hardware decoding
|
||||||
|
overrides this flag.
|
||||||
|
|
||||||
``opengl-hq``
|
``opengl-hq``
|
||||||
Same as ``opengl``, but with default settings for high quality rendering.
|
Same as ``opengl``, but with default settings for high quality rendering.
|
||||||
|
|
||||||
|
@ -177,6 +177,9 @@ struct gl_hwdec {
|
|||||||
// internal representation in gl_video.c as the hardware texture.
|
// internal representation in gl_video.c as the hardware texture.
|
||||||
// It's used to build the rendering chain, and also as screenshot format.
|
// It's used to build the rendering chain, and also as screenshot format.
|
||||||
int converted_imgfmt;
|
int converted_imgfmt;
|
||||||
|
// Normally this is GL_TEXTURE_2D, but the hwdec driver can set it to
|
||||||
|
// GL_TEXTURE_RECTANGLE.
|
||||||
|
GLenum gl_texture_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gl_hwdec_driver {
|
struct gl_hwdec_driver {
|
||||||
|
@ -145,6 +145,8 @@ struct gl_video {
|
|||||||
|
|
||||||
int depth_g;
|
int depth_g;
|
||||||
|
|
||||||
|
GLenum gl_target; // texture target (GL_TEXTURE_2D, ...) for video and FBOs
|
||||||
|
|
||||||
GLuint vertex_buffer;
|
GLuint vertex_buffer;
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
|
|
||||||
@ -340,6 +342,7 @@ const struct m_sub_options gl_video_conf = {
|
|||||||
({"no", 0},
|
({"no", 0},
|
||||||
{"yes", 1}, {"", 1},
|
{"yes", 1}, {"", 1},
|
||||||
{"blend", 2})),
|
{"blend", 2})),
|
||||||
|
OPT_FLAG("rectangle-textures", use_rectangle, 0),
|
||||||
{0}
|
{0}
|
||||||
},
|
},
|
||||||
.size = sizeof(struct gl_video_opts),
|
.size = sizeof(struct gl_video_opts),
|
||||||
@ -419,17 +422,19 @@ static void write_quad(struct vertex *va,
|
|||||||
float x0, float y0, float x1, float y1,
|
float x0, float y0, float x1, float y1,
|
||||||
float tx0, float ty0, float tx1, float ty1,
|
float tx0, float ty0, float tx1, float ty1,
|
||||||
float texture_w, float texture_h,
|
float texture_w, float texture_h,
|
||||||
const uint8_t color[4], bool flip)
|
const uint8_t color[4], GLenum target, bool flip)
|
||||||
{
|
{
|
||||||
static const uint8_t white[4] = { 255, 255, 255, 255 };
|
static const uint8_t white[4] = { 255, 255, 255, 255 };
|
||||||
|
|
||||||
if (!color)
|
if (!color)
|
||||||
color = white;
|
color = white;
|
||||||
|
|
||||||
tx0 /= texture_w;
|
if (target == GL_TEXTURE_2D) {
|
||||||
ty0 /= texture_h;
|
tx0 /= texture_w;
|
||||||
tx1 /= texture_w;
|
ty0 /= texture_h;
|
||||||
ty1 /= texture_h;
|
tx1 /= texture_w;
|
||||||
|
ty1 /= texture_h;
|
||||||
|
}
|
||||||
|
|
||||||
if (flip) {
|
if (flip) {
|
||||||
float tmp = ty0;
|
float tmp = ty0;
|
||||||
@ -470,14 +475,14 @@ static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h,
|
|||||||
|
|
||||||
gl->GenFramebuffers(1, &fbo->fbo);
|
gl->GenFramebuffers(1, &fbo->fbo);
|
||||||
gl->GenTextures(1, &fbo->texture);
|
gl->GenTextures(1, &fbo->texture);
|
||||||
gl->BindTexture(GL_TEXTURE_2D, fbo->texture);
|
gl->BindTexture(p->gl_target, fbo->texture);
|
||||||
gl->TexImage2D(GL_TEXTURE_2D, 0, iformat,
|
gl->TexImage2D(p->gl_target, 0, iformat,
|
||||||
fbo->tex_w, fbo->tex_h, 0,
|
fbo->tex_w, fbo->tex_h, 0,
|
||||||
GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
default_tex_params(gl, GL_TEXTURE_2D, GL_LINEAR);
|
default_tex_params(gl, p->gl_target, GL_LINEAR);
|
||||||
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
|
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
|
||||||
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, fbo->texture, 0);
|
p->gl_target, fbo->texture, 0);
|
||||||
|
|
||||||
if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
MP_ERR(p, "Error: framebuffer completeness check failed!\n");
|
MP_ERR(p, "Error: framebuffer completeness check failed!\n");
|
||||||
@ -567,8 +572,20 @@ static void update_uniforms(struct gl_video *p, GLuint program)
|
|||||||
snprintf(textures_size_n, sizeof(textures_size_n), "textures_size[%d]", n);
|
snprintf(textures_size_n, sizeof(textures_size_n), "textures_size[%d]", n);
|
||||||
|
|
||||||
gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n);
|
gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n);
|
||||||
gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n),
|
if (p->gl_target == GL_TEXTURE_2D) {
|
||||||
p->image.planes[n].tex_w, p->image.planes[n].tex_h);
|
gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n),
|
||||||
|
p->image.planes[n].tex_w, p->image.planes[n].tex_h);
|
||||||
|
} else {
|
||||||
|
// Makes the pixel size calculation code think they are 1x1
|
||||||
|
gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n), 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loc = gl->GetUniformLocation(program, "chroma_div");
|
||||||
|
if (loc >= 0) {
|
||||||
|
int xs = p->image_desc.chroma_xs;
|
||||||
|
int ys = p->image_desc.chroma_ys;
|
||||||
|
gl->Uniform2f(loc, 1.0 / (1 << xs), 1.0 / (1 << ys));
|
||||||
}
|
}
|
||||||
|
|
||||||
loc = gl->GetUniformLocation(program, "chroma_center_offset");
|
loc = gl->GetUniformLocation(program, "chroma_center_offset");
|
||||||
@ -588,8 +605,9 @@ static void update_uniforms(struct gl_video *p, GLuint program)
|
|||||||
// move chroma center to luma center (in chroma coord. space)
|
// move chroma center to luma center (in chroma coord. space)
|
||||||
float o_x = ls_w < 1 ? ls_w * -cx / 2 : 0;
|
float o_x = ls_w < 1 ? ls_w * -cx / 2 : 0;
|
||||||
float o_y = ls_h < 1 ? ls_h * -cy / 2 : 0;
|
float o_y = ls_h < 1 ? ls_h * -cy / 2 : 0;
|
||||||
gl->Uniform2f(loc, o_x / FFMAX(p->image.planes[1].w, 1),
|
int c = p->gl_target == GL_TEXTURE_2D ? 1 : 0;
|
||||||
o_y / FFMAX(p->image.planes[1].h, 1));
|
gl->Uniform2f(loc, o_x / FFMAX(p->image.planes[1].w * c, 1),
|
||||||
|
o_y / FFMAX(p->image.planes[1].h * c, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"),
|
gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"),
|
||||||
@ -798,6 +816,13 @@ static void compile_shaders(struct gl_video *p)
|
|||||||
char *header = talloc_asprintf(tmp, "#version %d\n%s%s", gl->glsl_version,
|
char *header = talloc_asprintf(tmp, "#version %d\n%s%s", gl->glsl_version,
|
||||||
shader_prelude, PRELUDE_END);
|
shader_prelude, PRELUDE_END);
|
||||||
|
|
||||||
|
if (p->gl_target == GL_TEXTURE_RECTANGLE) {
|
||||||
|
shader_def(&header, "VIDEO_SAMPLER", "sampler2DRect");
|
||||||
|
shader_def_opt(&header, "USE_RECTANGLE", true);
|
||||||
|
} else {
|
||||||
|
shader_def(&header, "VIDEO_SAMPLER", "sampler2D");
|
||||||
|
}
|
||||||
|
|
||||||
// Need to pass alpha through the whole chain. (Not needed for OSD shaders.)
|
// Need to pass alpha through the whole chain. (Not needed for OSD shaders.)
|
||||||
if (p->opts.alpha_mode == 1)
|
if (p->opts.alpha_mode == 1)
|
||||||
shader_def_opt(&header, "USE_ALPHA", p->has_alpha);
|
shader_def_opt(&header, "USE_ALPHA", p->has_alpha);
|
||||||
@ -1218,7 +1243,7 @@ static void set_image_textures(struct gl_video *p, struct video_image *vimg,
|
|||||||
|
|
||||||
for (int n = 0; n < 4; n++) {
|
for (int n = 0; n < 4; n++) {
|
||||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||||
gl->BindTexture(GL_TEXTURE_2D, imgtex[n]);
|
gl->BindTexture(p->gl_target, imgtex[n]);
|
||||||
}
|
}
|
||||||
gl->ActiveTexture(GL_TEXTURE0);
|
gl->ActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
@ -1229,7 +1254,7 @@ static void unset_image_textures(struct gl_video *p)
|
|||||||
|
|
||||||
for (int n = 0; n < 4; n++) {
|
for (int n = 0; n < 4; n++) {
|
||||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||||
gl->BindTexture(GL_TEXTURE_2D, 0);
|
gl->BindTexture(p->gl_target, 0);
|
||||||
}
|
}
|
||||||
gl->ActiveTexture(GL_TEXTURE0);
|
gl->ActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
@ -1241,10 +1266,14 @@ static void init_video(struct gl_video *p, const struct mp_image_params *params)
|
|||||||
{
|
{
|
||||||
GL *gl = p->gl;
|
GL *gl = p->gl;
|
||||||
|
|
||||||
check_gl_features(p);
|
|
||||||
|
|
||||||
init_format(params->imgfmt, p);
|
init_format(params->imgfmt, p);
|
||||||
|
|
||||||
|
p->gl_target = p->opts.use_rectangle ? GL_TEXTURE_RECTANGLE : GL_TEXTURE_2D;
|
||||||
|
if (p->hwdec_active)
|
||||||
|
p->gl_target = p->hwdec->gl_texture_target;
|
||||||
|
|
||||||
|
check_gl_features(p);
|
||||||
|
|
||||||
p->image_w = params->w;
|
p->image_w = params->w;
|
||||||
p->image_h = params->h;
|
p->image_h = params->h;
|
||||||
p->image_dw = params->d_w;
|
p->image_dw = params->d_w;
|
||||||
@ -1295,13 +1324,13 @@ static void init_video(struct gl_video *p, const struct mp_image_params *params)
|
|||||||
|
|
||||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||||
gl->GenTextures(1, &plane->gl_texture);
|
gl->GenTextures(1, &plane->gl_texture);
|
||||||
gl->BindTexture(GL_TEXTURE_2D, plane->gl_texture);
|
gl->BindTexture(p->gl_target, plane->gl_texture);
|
||||||
|
|
||||||
gl->TexImage2D(GL_TEXTURE_2D, 0, plane->gl_internal_format,
|
gl->TexImage2D(p->gl_target, 0, plane->gl_internal_format,
|
||||||
plane->tex_w, plane->tex_h, 0,
|
plane->tex_w, plane->tex_h, 0,
|
||||||
plane->gl_format, plane->gl_type, NULL);
|
plane->gl_format, plane->gl_type, NULL);
|
||||||
|
|
||||||
default_tex_params(gl, GL_TEXTURE_2D, GL_LINEAR);
|
default_tex_params(gl, p->gl_target, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_VERBOSE(p, "Texture for plane %d: %dx%d\n",
|
MP_VERBOSE(p, "Texture for plane %d: %dx%d\n",
|
||||||
@ -1377,7 +1406,7 @@ static void render_to_fbo(struct gl_video *p, struct fbotex *fbo,
|
|||||||
write_quad(vb, -1, -1, 1, 1,
|
write_quad(vb, -1, -1, 1, 1,
|
||||||
x, y, x + w, y + h,
|
x, y, x + w, y + h,
|
||||||
tex_w, tex_h,
|
tex_w, tex_h,
|
||||||
NULL, false);
|
NULL, p->gl_target, false);
|
||||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||||
|
|
||||||
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
@ -1394,7 +1423,7 @@ static void handle_pass(struct gl_video *p, struct fbotex *chain,
|
|||||||
if (!program)
|
if (!program)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gl->BindTexture(GL_TEXTURE_2D, chain->texture);
|
gl->BindTexture(p->gl_target, chain->texture);
|
||||||
gl->UseProgram(program);
|
gl->UseProgram(program);
|
||||||
render_to_fbo(p, fbo, chain->vp_x, chain->vp_y,
|
render_to_fbo(p, fbo, chain->vp_x, chain->vp_y,
|
||||||
chain->vp_w, chain->vp_h,
|
chain->vp_w, chain->vp_h,
|
||||||
@ -1448,7 +1477,7 @@ void gl_video_render_frame(struct gl_video *p)
|
|||||||
|
|
||||||
handle_pass(p, &chain, &p->scale_sep_fbo, p->scale_sep_program);
|
handle_pass(p, &chain, &p->scale_sep_fbo, p->scale_sep_program);
|
||||||
|
|
||||||
gl->BindTexture(GL_TEXTURE_2D, chain.texture);
|
gl->BindTexture(p->gl_target, chain.texture);
|
||||||
gl->UseProgram(p->final_program);
|
gl->UseProgram(p->final_program);
|
||||||
|
|
||||||
struct mp_rect src = {p->src_rect.x0, chain.vp_y,
|
struct mp_rect src = {p->src_rect.x0, chain.vp_y,
|
||||||
@ -1468,7 +1497,7 @@ void gl_video_render_frame(struct gl_video *p)
|
|||||||
src.x0 / 2, src.y0,
|
src.x0 / 2, src.y0,
|
||||||
src.x0 / 2 + w / 2, src.y1,
|
src.x0 / 2 + w / 2, src.y1,
|
||||||
src_texw, src_texh,
|
src_texw, src_texh,
|
||||||
NULL, is_flipped);
|
NULL, p->gl_target, is_flipped);
|
||||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||||
|
|
||||||
glEnable3DRight(gl, p->opts.stereo_mode);
|
glEnable3DRight(gl, p->opts.stereo_mode);
|
||||||
@ -1479,7 +1508,7 @@ void gl_video_render_frame(struct gl_video *p)
|
|||||||
src.x0 / 2 + imgw / 2, src.y0,
|
src.x0 / 2 + imgw / 2, src.y0,
|
||||||
src.x0 / 2 + imgw / 2 + w / 2, src.y1,
|
src.x0 / 2 + imgw / 2 + w / 2, src.y1,
|
||||||
src_texw, src_texh,
|
src_texw, src_texh,
|
||||||
NULL, is_flipped);
|
NULL, p->gl_target, is_flipped);
|
||||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||||
|
|
||||||
glDisable3D(gl, p->opts.stereo_mode);
|
glDisable3D(gl, p->opts.stereo_mode);
|
||||||
@ -1490,7 +1519,7 @@ void gl_video_render_frame(struct gl_video *p)
|
|||||||
src.x0, src.y0,
|
src.x0, src.y0,
|
||||||
src.x1, src.y1,
|
src.x1, src.y1,
|
||||||
src_texw, src_texh,
|
src_texw, src_texh,
|
||||||
NULL, is_flipped);
|
NULL, p->gl_target, is_flipped);
|
||||||
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
draw_triangles(p, vb, VERTICES_PER_QUAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1644,8 +1673,8 @@ void gl_video_upload_image(struct gl_video *p, struct mp_image *mpi)
|
|||||||
plane_ptr = NULL; // PBO offset 0
|
plane_ptr = NULL; // PBO offset 0
|
||||||
}
|
}
|
||||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||||
gl->BindTexture(GL_TEXTURE_2D, plane->gl_texture);
|
gl->BindTexture(p->gl_target, plane->gl_texture);
|
||||||
glUploadTex(gl, GL_TEXTURE_2D, plane->gl_format, plane->gl_type,
|
glUploadTex(gl, p->gl_target, plane->gl_format, plane->gl_type,
|
||||||
plane_ptr, mpi->stride[n], 0, 0, plane->w, plane->h, 0);
|
plane_ptr, mpi->stride[n], 0, 0, plane->w, plane->h, 0);
|
||||||
}
|
}
|
||||||
gl->ActiveTexture(GL_TEXTURE0);
|
gl->ActiveTexture(GL_TEXTURE0);
|
||||||
@ -1674,7 +1703,7 @@ struct mp_image *gl_video_download_image(struct gl_video *p)
|
|||||||
for (int n = 0; n < p->plane_count; n++) {
|
for (int n = 0; n < p->plane_count; n++) {
|
||||||
struct texplane *plane = &vimg->planes[n];
|
struct texplane *plane = &vimg->planes[n];
|
||||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||||
glDownloadTex(gl, GL_TEXTURE_2D, plane->gl_format, plane->gl_type,
|
glDownloadTex(gl, p->gl_target, plane->gl_format, plane->gl_type,
|
||||||
image->planes[n], image->stride[n]);
|
image->planes[n], image->stride[n]);
|
||||||
}
|
}
|
||||||
mp_image_set_attributes(image, &p->image_params);
|
mp_image_set_attributes(image, &p->image_params);
|
||||||
@ -1711,7 +1740,7 @@ static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd,
|
|||||||
write_quad(&va[osd->num_vertices],
|
write_quad(&va[osd->num_vertices],
|
||||||
b->x, b->y, b->x + b->dw, b->y + b->dh,
|
b->x, b->y, b->x + b->dw, b->y + b->dh,
|
||||||
pos.x, pos.y, pos.x + b->w, pos.y + b->h,
|
pos.x, pos.y, pos.x + b->w, pos.y + b->h,
|
||||||
osd->w, osd->h, color, false);
|
osd->w, osd->h, color, GL_TEXTURE_2D, false);
|
||||||
osd->num_vertices += VERTICES_PER_QUAD;
|
osd->num_vertices += VERTICES_PER_QUAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2084,8 +2113,8 @@ struct gl_video *gl_video_init(GL *gl, struct mp_log *log)
|
|||||||
.gl = gl,
|
.gl = gl,
|
||||||
.log = log,
|
.log = log,
|
||||||
.opts = gl_video_opts_def,
|
.opts = gl_video_opts_def,
|
||||||
|
.gl_target = GL_TEXTURE_2D,
|
||||||
.gl_debug = true,
|
.gl_debug = true,
|
||||||
.colorspace = MP_CSP_DETAILS_DEFAULTS,
|
|
||||||
.scalers = {
|
.scalers = {
|
||||||
{ .index = 0, .name = "bilinear" },
|
{ .index = 0, .name = "bilinear" },
|
||||||
{ .index = 1, .name = "bilinear" },
|
{ .index = 1, .name = "bilinear" },
|
||||||
|
@ -46,6 +46,7 @@ struct gl_video_opts {
|
|||||||
int stereo_mode;
|
int stereo_mode;
|
||||||
int alpha_mode;
|
int alpha_mode;
|
||||||
int chroma_location;
|
int chroma_location;
|
||||||
|
int use_rectangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct m_sub_options gl_video_conf;
|
extern const struct m_sub_options gl_video_conf;
|
||||||
|
@ -112,12 +112,13 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#!section frag_video
|
#!section frag_video
|
||||||
uniform sampler2D texture0;
|
uniform VIDEO_SAMPLER texture0;
|
||||||
uniform sampler2D texture1;
|
uniform VIDEO_SAMPLER texture1;
|
||||||
uniform sampler2D texture2;
|
uniform VIDEO_SAMPLER texture2;
|
||||||
uniform sampler2D texture3;
|
uniform VIDEO_SAMPLER texture3;
|
||||||
uniform vec2 textures_size[4];
|
uniform vec2 textures_size[4];
|
||||||
uniform vec2 chroma_center_offset;
|
uniform vec2 chroma_center_offset;
|
||||||
|
uniform vec2 chroma_div;
|
||||||
uniform sampler1D lut_c_1d;
|
uniform sampler1D lut_c_1d;
|
||||||
uniform sampler1D lut_l_1d;
|
uniform sampler1D lut_l_1d;
|
||||||
uniform sampler2D lut_c_2d;
|
uniform sampler2D lut_c_2d;
|
||||||
@ -140,7 +141,7 @@ DECLARE_FRAGPARMS
|
|||||||
#define CONV_NV12 1
|
#define CONV_NV12 1
|
||||||
#define CONV_PLANAR 2
|
#define CONV_PLANAR 2
|
||||||
|
|
||||||
vec4 sample_bilinear(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
vec4 sample_bilinear(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) {
|
||||||
return texture(tex, texcoord);
|
return texture(tex, texcoord);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +162,7 @@ vec4 calcweights(float s) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sample_bicubic_fast(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
vec4 sample_bicubic_fast(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) {
|
||||||
vec2 pt = 1 / texsize;
|
vec2 pt = 1 / texsize;
|
||||||
vec2 fcoord = fract(texcoord * texsize + vec2(0.5, 0.5));
|
vec2 fcoord = fract(texcoord * texsize + vec2(0.5, 0.5));
|
||||||
vec4 parmx = calcweights(fcoord.x);
|
vec4 parmx = calcweights(fcoord.x);
|
||||||
@ -222,7 +223,7 @@ float[16] weights16(sampler2D lookup, float f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define CONVOLUTION_SEP_N(NAME, N) \
|
#define CONVOLUTION_SEP_N(NAME, N) \
|
||||||
vec4 NAME(sampler2D tex, vec2 texcoord, vec2 pt, float weights[N]) { \
|
vec4 NAME(VIDEO_SAMPLER tex, vec2 texcoord, vec2 pt, float weights[N]) {\
|
||||||
vec4 res = vec4(0); \
|
vec4 res = vec4(0); \
|
||||||
for (int n = 0; n < N; n++) { \
|
for (int n = 0; n < N; n++) { \
|
||||||
res += weights[n] * texture(tex, texcoord + pt * n); \
|
res += weights[n] * texture(tex, texcoord + pt * n); \
|
||||||
@ -240,7 +241,7 @@ CONVOLUTION_SEP_N(convolution_sep16, 16)
|
|||||||
// The dir parameter is (0, 1) or (1, 0), and we expect the shader compiler to
|
// The dir parameter is (0, 1) or (1, 0), and we expect the shader compiler to
|
||||||
// remove all the redundant multiplications and additions.
|
// remove all the redundant multiplications and additions.
|
||||||
#define SAMPLE_CONVOLUTION_SEP_N(NAME, N, SAMPLERT, CONV_FUNC, WEIGHTS_FUNC)\
|
#define SAMPLE_CONVOLUTION_SEP_N(NAME, N, SAMPLERT, CONV_FUNC, WEIGHTS_FUNC)\
|
||||||
vec4 NAME(vec2 dir, SAMPLERT lookup, sampler2D tex, vec2 texsize, \
|
vec4 NAME(vec2 dir, SAMPLERT lookup, VIDEO_SAMPLER tex, vec2 texsize, \
|
||||||
vec2 texcoord) { \
|
vec2 texcoord) { \
|
||||||
vec2 pt = (1 / texsize) * dir; \
|
vec2 pt = (1 / texsize) * dir; \
|
||||||
float fcoord = dot(fract(texcoord * texsize - 0.5), dir); \
|
float fcoord = dot(fract(texcoord * texsize - 0.5), dir); \
|
||||||
@ -258,7 +259,7 @@ SAMPLE_CONVOLUTION_SEP_N(sample_convolution_sep16, 16, sampler2D, convolution_se
|
|||||||
|
|
||||||
|
|
||||||
#define CONVOLUTION_N(NAME, N) \
|
#define CONVOLUTION_N(NAME, N) \
|
||||||
vec4 NAME(sampler2D tex, vec2 texcoord, vec2 pt, float taps_x[N], \
|
vec4 NAME(VIDEO_SAMPLER tex, vec2 texcoord, vec2 pt, float taps_x[N], \
|
||||||
float taps_y[N]) { \
|
float taps_y[N]) { \
|
||||||
vec4 res = vec4(0); \
|
vec4 res = vec4(0); \
|
||||||
for (int y = 0; y < N; y++) { \
|
for (int y = 0; y < N; y++) { \
|
||||||
@ -278,7 +279,7 @@ CONVOLUTION_N(convolution12, 12)
|
|||||||
CONVOLUTION_N(convolution16, 16)
|
CONVOLUTION_N(convolution16, 16)
|
||||||
|
|
||||||
#define SAMPLE_CONVOLUTION_N(NAME, N, SAMPLERT, CONV_FUNC, WEIGHTS_FUNC) \
|
#define SAMPLE_CONVOLUTION_N(NAME, N, SAMPLERT, CONV_FUNC, WEIGHTS_FUNC) \
|
||||||
vec4 NAME(SAMPLERT lookup, sampler2D tex, vec2 texsize, vec2 texcoord) {\
|
vec4 NAME(SAMPLERT lookup, VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) {\
|
||||||
vec2 pt = 1 / texsize; \
|
vec2 pt = 1 / texsize; \
|
||||||
vec2 fcoord = fract(texcoord * texsize - 0.5); \
|
vec2 fcoord = fract(texcoord * texsize - 0.5); \
|
||||||
vec2 base = texcoord - fcoord * pt; \
|
vec2 base = texcoord - fcoord * pt; \
|
||||||
@ -296,7 +297,7 @@ SAMPLE_CONVOLUTION_N(sample_convolution16, 16, sampler2D, convolution16, weights
|
|||||||
|
|
||||||
|
|
||||||
// Unsharp masking
|
// Unsharp masking
|
||||||
vec4 sample_sharpen3(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
vec4 sample_sharpen3(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) {
|
||||||
vec2 pt = 1 / texsize;
|
vec2 pt = 1 / texsize;
|
||||||
vec2 st = pt * 0.5;
|
vec2 st = pt * 0.5;
|
||||||
vec4 p = texture(tex, texcoord);
|
vec4 p = texture(tex, texcoord);
|
||||||
@ -307,7 +308,7 @@ vec4 sample_sharpen3(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
|||||||
return p + (p - 0.25 * sum) * filter_param1;
|
return p + (p - 0.25 * sum) * filter_param1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 sample_sharpen5(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
vec4 sample_sharpen5(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) {
|
||||||
vec2 pt = 1 / texsize;
|
vec2 pt = 1 / texsize;
|
||||||
vec2 st1 = pt * 1.2;
|
vec2 st1 = pt * 1.2;
|
||||||
vec4 p = texture(tex, texcoord);
|
vec4 p = texture(tex, texcoord);
|
||||||
@ -325,7 +326,14 @@ vec4 sample_sharpen5(sampler2D tex, vec2 texsize, vec2 texcoord) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 chr_texcoord = texcoord + chroma_center_offset;
|
vec2 chr_texcoord = texcoord;
|
||||||
|
#ifdef USE_RECTANGLE
|
||||||
|
chr_texcoord = chr_texcoord * chroma_div;
|
||||||
|
#else
|
||||||
|
// Texture coordinates are [0,1], and chroma plane coordinates are
|
||||||
|
// magically rescaled.
|
||||||
|
#endif
|
||||||
|
chr_texcoord = chr_texcoord + chroma_center_offset;
|
||||||
#ifndef USE_CONV
|
#ifndef USE_CONV
|
||||||
#define USE_CONV 0
|
#define USE_CONV 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -206,6 +206,7 @@ static void load_hwdec_driver(struct gl_priv *p,
|
|||||||
.log = mp_log_new(hwdec, p->vo->log, drv->api_name),
|
.log = mp_log_new(hwdec, p->vo->log, drv->api_name),
|
||||||
.mpgl = p->glctx,
|
.mpgl = p->glctx,
|
||||||
.info = talloc_zero(hwdec, struct mp_hwdec_info),
|
.info = talloc_zero(hwdec, struct mp_hwdec_info),
|
||||||
|
.gl_texture_target = GL_TEXTURE_2D,
|
||||||
};
|
};
|
||||||
mpgl_lock(p->glctx);
|
mpgl_lock(p->glctx);
|
||||||
if (hwdec->driver->create(hwdec) < 0) {
|
if (hwdec->driver->create(hwdec) < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user