From 75ee35cec94d63842275016de43f9242166fa8e4 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Fri, 19 Nov 2021 13:48:55 +0100 Subject: 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. --- video/out/vo_gpu_next.c | 20 ++++++-------------- 1 file 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; -- cgit v1.2.3