summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2020-05-03 14:05:33 +0200
committerNiklas Haas <git@haasn.xyz>2020-05-03 14:08:02 +0200
commit06948438dfd31e124fcb98f41fdaf600330da060 (patch)
tree2dd4232723f9a7b76545b5be043a0ea362d5c604
parentcae2ffb6eb52f56167aeabf40caa28ecb3ca498b (diff)
downloadmpv-oversample_mixless.tar.bz2
mpv-oversample_mixless.tar.xz
vo_gpu: optimize interpolation for the single-frame caseoversample_mixless
When interpolation is enabled with one of the "special" interpolation modes (oversample or linear), this avoids a double-sample and blend in the relatively common case of only drawing a single frame, at the cost of triggering one additional shader compilation when this case first arises.
-rw-r--r--video/out/gpu/video.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 41c021bd94..475619bb79 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -3192,13 +3192,24 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
mix = 1 - mix;
}
+ int first_frame = 0;
+ int num_frames = size;
+
// Blend the frames together
if (oversample || linear) {
- gl_sc_uniform_dynamic(p->sc);
- gl_sc_uniform_f(p->sc, "inter_coeff", mix);
- GLSL(color = mix(texture(texture0, texcoord0),
- texture(texture1, texcoord1),
- inter_coeff);)
+ const float single_frame_delta = 1e-4;
+ if (mix < single_frame_delta || mix > 1.0 - single_frame_delta) {
+ // Optimize for the common case in which we only have one tex
+ GLSL(color = texture(texture0, texcoord0);)
+ first_frame = mix < single_frame_delta ? 0 : 1;
+ num_frames = 1;
+ } else {
+ gl_sc_uniform_dynamic(p->sc);
+ gl_sc_uniform_f(p->sc, "inter_coeff", mix);
+ GLSL(color = mix(texture(texture0, texcoord0),
+ texture(texture1, texcoord1),
+ inter_coeff);)
+ }
} else {
gl_sc_uniform_dynamic(p->sc);
gl_sc_uniform_f(p->sc, "fcoord", mix);
@@ -3206,7 +3217,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
}
// Load all the required frames
- for (int i = 0; i < size; i++) {
+ for (int i = first_frame; i < num_frames; i++) {
struct image img =
image_wrap(p->surfaces[surface_wrap(surface_bse+i)].tex,
PLANE_RGB, p->components);
@@ -3214,7 +3225,7 @@ static void gl_video_interpolate_frame(struct gl_video *p, struct vo_frame *t,
// the textures are bound in-order and starting at 0, we just
// assert to make sure this is the case (which it should always be)
int id = pass_bind(p, img);
- assert(id == i);
+ assert(id == i - first_frame);
}
MP_TRACE(p, "inter frame dur: %f vsync: %f, mix: %f\n",