summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/out/gl_video.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 25b1547327..1f140b040d 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -132,7 +132,7 @@ struct fbotex {
GLuint fbo;
GLuint texture;
int tex_w, tex_h; // size of .texture
- int vp_w, vp_h; // viewport of fbo / used part of the texture
+ int vp_x, vp_y, vp_w, vp_h; // viewport of fbo / used part of the texture
};
struct gl_video {
@@ -397,10 +397,12 @@ static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h,
assert(!fbo->fbo);
assert(!fbo->texture);
- tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h);
+ *fbo = (struct fbotex) {
+ .vp_w = w,
+ .vp_h = h,
+ };
- fbo->vp_w = w;
- fbo->vp_h = h;
+ tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h);
mp_msg(MSGT_VO, MSGL_V, "[gl] Create FBO: %dx%d\n", fbo->tex_w, fbo->tex_h);
@@ -505,7 +507,7 @@ static void update_uniforms(struct gl_video *p, GLuint program)
gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n);
gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n),
- p->image.planes[n].w, p->image.planes[n].h);
+ p->image.planes[n].tex_w, p->image.planes[n].tex_h);
}
gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"),
@@ -1055,7 +1057,7 @@ static void reinit_rendering(struct gl_video *p)
update_all_uniforms(p);
if (p->indirect_program && !p->indirect_fbo.fbo)
- fbotex_init(p, &p->indirect_fbo, p->texture_w, p->texture_h,
+ fbotex_init(p, &p->indirect_fbo, p->image_w, p->image_h,
p->opts.fbo_format);
recreate_osd(p);
@@ -1214,17 +1216,17 @@ static void change_dither_trafo(struct gl_video *p)
gl->UseProgram(0);
}
-static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, int w, int h,
- int tex_w, int tex_h)
+static void render_to_fbo(struct gl_video *p, struct fbotex *fbo,
+ int x, int y, int w, int h, int tex_w, int tex_h)
{
GL *gl = p->gl;
- gl->Viewport(0, 0, fbo->vp_w, fbo->vp_h);
+ gl->Viewport(fbo->vp_x, fbo->vp_y, fbo->vp_w, fbo->vp_h);
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo);
struct vertex vb[VERTICES_PER_QUAD];
write_quad(vb, -1, -1, 1, 1,
- 0, 0, w, h,
+ x, y, x + w, y + h,
tex_w, tex_h,
NULL, false);
draw_triangles(p, vb, VERTICES_PER_QUAD);
@@ -1244,7 +1246,8 @@ static void handle_pass(struct gl_video *p, struct fbotex **source,
gl->BindTexture(GL_TEXTURE_2D, (*source)->texture);
gl->UseProgram(program);
- render_to_fbo(p, fbo, (*source)->vp_w, (*source)->vp_h,
+ render_to_fbo(p, fbo, (*source)->vp_x, (*source)->vp_y,
+ (*source)->vp_w, (*source)->vp_h,
(*source)->tex_w, (*source)->tex_h);
*source = fbo;
}
@@ -1272,23 +1275,37 @@ void gl_video_render_frame(struct gl_video *p)
set_image_textures(p, vimg);
struct fbotex dummy = {
- .vp_w = p->image_w, .vp_h = p->image_h,
- .tex_w = p->texture_w, .tex_h = p->texture_h,
+ .vp_w = p->image_w,
+ .vp_h = p->image_h,
+ .tex_w = p->texture_w,
+ .tex_h = p->texture_h,
.texture = vimg->planes[0].gl_texture,
};
struct fbotex *source = &dummy;
handle_pass(p, &source, &p->indirect_fbo, p->indirect_program);
+
+ // Clip to visible height so that separate scaling scales the visible part
+ // only (and the target FBO texture can have a bounded size).
+ // Don't clamp width; too hard to get correct final scaling on l/r borders.
+ dummy = *source;
+ source = &dummy;
+ source->vp_y = p->src_rect.y0,
+ source->vp_h = p->src_rect.y1 - p->src_rect.y0,
+
handle_pass(p, &source, &p->scale_sep_fbo, p->scale_sep_program);
gl->BindTexture(GL_TEXTURE_2D, source->texture);
gl->UseProgram(p->final_program);
- float final_texw = p->image_w * source->tex_w / (float)source->vp_w;
- float final_texh = p->image_h * source->tex_h / (float)source->vp_h;
+ float final_texw = source->tex_w;
+ float final_texh = source->tex_h;
+
+ struct mp_rect src = {p->src_rect.x0, source->vp_y,
+ p->src_rect.x1, source->vp_y + source->vp_h};
if (p->opts.stereo_mode) {
- int w = p->src_rect.x1 - p->src_rect.x0;
+ int w = src.x1 - src.x0;
int imgw = p->image_w;
glEnable3DLeft(gl, p->opts.stereo_mode);
@@ -1296,8 +1313,8 @@ void gl_video_render_frame(struct gl_video *p)
write_quad(vb,
p->dst_rect.x0, p->dst_rect.y0,
p->dst_rect.x1, p->dst_rect.y1,
- p->src_rect.x0 / 2, p->src_rect.y0,
- p->src_rect.x0 / 2 + w / 2, p->src_rect.y1,
+ src.x0 / 2, src.y0,
+ src.x0 / 2 + w / 2, src.y1,
final_texw, final_texh,
NULL, is_flipped);
draw_triangles(p, vb, VERTICES_PER_QUAD);
@@ -1307,8 +1324,8 @@ void gl_video_render_frame(struct gl_video *p)
write_quad(vb,
p->dst_rect.x0, p->dst_rect.y0,
p->dst_rect.x1, p->dst_rect.y1,
- p->src_rect.x0 / 2 + imgw / 2, p->src_rect.y0,
- p->src_rect.x0 / 2 + imgw / 2 + w / 2, p->src_rect.y1,
+ src.x0 / 2 + imgw / 2, src.y0,
+ src.x0 / 2 + imgw / 2 + w / 2, src.y1,
final_texw, final_texh,
NULL, is_flipped);
draw_triangles(p, vb, VERTICES_PER_QUAD);
@@ -1318,8 +1335,8 @@ void gl_video_render_frame(struct gl_video *p)
write_quad(vb,
p->dst_rect.x0, p->dst_rect.y0,
p->dst_rect.x1, p->dst_rect.y1,
- p->src_rect.x0, p->src_rect.y0,
- p->src_rect.x1, p->src_rect.y1,
+ src.x0, src.y0,
+ src.x1, src.y1,
final_texw, final_texh,
NULL, is_flipped);
draw_triangles(p, vb, VERTICES_PER_QUAD);