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:
wm4 2013-12-01 23:39:13 +01:00
parent f30c2c99d1
commit dc582f2505
6 changed files with 91 additions and 44 deletions

View File

@ -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.

View File

@ -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 {

View File

@ -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" },

View File

@ -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;

View File

@ -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

View File

@ -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) {