summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2021-11-19 13:48:55 +0100
committerNiklas Haas <github-daiK1o@haasn.dev>2021-11-19 14:51:48 +0100
commit75ee35cec94d63842275016de43f9242166fa8e4 (patch)
tree7721f13ea83a660d5bb8e8e106b0f5da6bcc3ad7
parentd1e9f4a159a88d9a51197c31b0823b5875d0f97b (diff)
downloadmpv-75ee35cec94d63842275016de43f9242166fa8e4.tar.bz2
mpv-75ee35cec94d63842275016de43f9242166fa8e4.tar.xz
vo_gpu_next: simplify and improve frame redrawing logic
This almost perfectly recreates the semantics of --vo=gpu, i.e.: - still frames are never interpolated - non-repeated frames bypass single frame cache The only difference is that libplacebo doesn't do a cache/blit on the full output image, but rather it re-runs the last rendering step. This has some advantages and some drawbacks. The most notable advantage is that it also allows re-using the image contents when the only thing that changes is the OSD (whereas `--vo=gpu` would force a full re-render for that). The most notable drawback is that it also implies going through the dithering and output LUT logic on redraws. All in all, I think this is a pretty good trade-off in favor of `--vo=gpu-next`. Fully fixes the last remaining performance difference in #9430.
-rw-r--r--video/out/vo_gpu_next.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index fbc9474a67..fca4165d03 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -107,6 +107,7 @@ struct priv {
struct pl_dither_params dither;
struct scaler_params scalers[SCALER_COUNT];
const struct pl_hook **hooks; // storage for `params.hooks`
+ const struct pl_filter_config *frame_mixer;
#ifdef PL_HAVE_LCMS
struct pl_icc_params icc;
@@ -706,19 +707,6 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
break;
}
- if (frame->still && mix.num_frames) {
- double best = fabs(mix.timestamps[0]);
- // Recreate nearest neighbour semantics on this frame mix
- while (mix.num_frames > 1 && fabs(mix.timestamps[1]) < best) {
- best = fabs(mix.timestamps[1]);
- mix.frames++;
- mix.signatures++;
- mix.timestamps++;
- mix.num_frames--;
- }
- mix.num_frames = 1;
- }
-
// Update source crop on all existing frames. We technically own the
// `pl_frame` struct so this is kosher. This could be avoided by
// instead flushing the queue on resizes, but doing it this way avoids
@@ -743,8 +731,12 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
}
}
+#if PL_API_VER >= 179
+ p->params.skip_caching_single_frame = !frame->display_synced || frame->num_vsyncs == 1;
+#endif
p->params.preserve_mixing_cache = p->inter_preserve && !frame->still;
p->params.allow_delayed_peak_detect = p->delayed_peak;
+ p->params.frame_mixer = frame->still ? NULL : p->frame_mixer;
// Render frame
if (!pl_render_image_mix(p->rr, &mix, &target, &p->params)) {
@@ -1229,7 +1221,7 @@ static void update_render_options(struct priv *p)
// Map scaler options as best we can
p->params.upscaler = map_scaler(p, SCALER_SCALE);
p->params.downscaler = map_scaler(p, SCALER_DSCALE);
- p->params.frame_mixer = opts->interpolation ? map_scaler(p, SCALER_TSCALE) : NULL;
+ p->frame_mixer = opts->interpolation ? map_scaler(p, SCALER_TSCALE) : NULL;
p->deband = pl_deband_default_params;
p->deband.iterations = opts->deband_opts->iterations;