vo_gpu_next: move gpu-next opts to specific sub option

This matches the general workflow in the codebase. We keep a cache of
these new options and update them if needed.

Fixes #13481 and fixes #11518.
This commit is contained in:
Dudemanguy 2024-02-14 12:36:05 -06:00
parent 073858fcdd
commit 85e84f6d92
3 changed files with 68 additions and 55 deletions

View File

@ -75,6 +75,7 @@ extern const struct m_sub_options input_config;
extern const struct m_sub_options encode_config;
extern const struct m_sub_options ra_ctx_conf;
extern const struct m_sub_options gl_video_conf;
extern const struct m_sub_options gl_next_conf;
extern const struct m_sub_options ao_alsa_conf;
extern const struct m_sub_options demux_conf;
@ -867,6 +868,7 @@ static const m_option_t mp_opts[] = {
{"", OPT_SUBSTRUCT(ra_ctx_opts, ra_ctx_conf)},
{"", OPT_SUBSTRUCT(gl_video_opts, gl_video_conf)},
{"", OPT_SUBSTRUCT(gl_next_opts, gl_next_conf)},
{"", OPT_SUBSTRUCT(spirv_opts, spirv_conf)},
#if HAVE_GL

View File

@ -366,6 +366,7 @@ typedef struct MPOpts {
struct ra_ctx_opts *ra_ctx_opts;
struct gl_video_opts *gl_video_opts;
struct gl_next_opts *gl_next_opts;
struct angle_opts *angle_opts;
struct opengl_opts *opengl_opts;
struct vulkan_opts *vulkan_opts;

View File

@ -33,6 +33,7 @@
#include "config.h"
#include "common/common.h"
#include "options/m_config.h"
#include "options/options.h"
#include "options/path.h"
#include "osdep/io.h"
#include "osdep/threads.h"
@ -137,21 +138,18 @@ struct priv {
pl_options pars;
struct m_config_cache *opts_cache;
struct m_config_cache *next_opts_cache;
struct gl_next_opts *next_opts;
struct cache shader_cache, icc_cache;
struct mp_csp_equalizer_state *video_eq;
struct scaler_params scalers[SCALER_COUNT];
const struct pl_hook **hooks; // storage for `params.hooks`
enum pl_color_levels output_levels;
char **raw_opts;
struct pl_icc_params icc_params;
char *icc_path;
pl_icc_object icc_profile;
struct user_lut image_lut;
struct user_lut target_lut;
struct user_lut lut;
// Cached shaders, preserved across options updates
struct user_hook *user_hooks;
int num_user_hooks;
@ -159,17 +157,53 @@ struct priv {
// Performance data of last frame
struct frame_info perf_fresh;
struct frame_info perf_redraw;
bool delayed_peak;
bool inter_preserve;
bool target_hint;
float corner_rounding;
};
static void update_render_options(struct vo *vo);
static void update_lut(struct priv *p, struct user_lut *lut);
struct gl_next_opts {
bool delayed_peak;
float corner_rounding;
bool inter_preserve;
struct user_lut lut;
struct user_lut image_lut;
struct user_lut target_lut;
bool target_hint;
char **raw_opts;
};
const struct m_opt_choice_alternatives lut_types[] = {
{"auto", PL_LUT_UNKNOWN},
{"native", PL_LUT_NATIVE},
{"normalized", PL_LUT_NORMALIZED},
{"conversion", PL_LUT_CONVERSION},
{0}
};
#define OPT_BASE_STRUCT struct gl_next_opts
const struct m_sub_options gl_next_conf = {
.opts = (const struct m_option[]) {
{"allow-delayed-peak-detect", OPT_BOOL(delayed_peak)},
{"corner-rounding", OPT_FLOAT(corner_rounding), M_RANGE(0, 1)},
{"interpolation-preserve", OPT_BOOL(inter_preserve)},
{"lut", OPT_STRING(lut.opt), .flags = M_OPT_FILE},
{"lut-type", OPT_CHOICE_C(lut.type, lut_types)},
{"image-lut", OPT_STRING(image_lut.opt), .flags = M_OPT_FILE},
{"image-lut-type", OPT_CHOICE_C(image_lut.type, lut_types)},
{"target-lut", OPT_STRING(target_lut.opt), .flags = M_OPT_FILE},
{"target-colorspace-hint", OPT_BOOL(target_hint)},
// No `target-lut-type` because we don't support non-RGB targets
{"libplacebo-opts", OPT_KEYVALUELIST(raw_opts)},
{0},
},
.defaults = &(struct gl_next_opts) {
.inter_preserve = true,
},
.size = sizeof(struct gl_next_opts),
.change_flags = UPDATE_VIDEO,
};
static pl_buf get_dr_buf(struct priv *p, const uint8_t *ptr)
{
mp_mutex_lock(&p->dr_lock);
@ -671,9 +705,9 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
pl_icc_profile_compute_signature(&frame->profile);
// Update LUT attached to this frame
update_lut(p, &p->image_lut);
frame->lut = p->image_lut.lut;
frame->lut_type = p->image_lut.type;
update_lut(p, &p->next_opts->image_lut);
frame->lut = p->next_opts->image_lut.lut;
frame->lut_type = p->next_opts->image_lut.type;
return true;
}
@ -719,12 +753,14 @@ static void update_options(struct vo *vo)
{
struct priv *p = vo->priv;
pl_options pars = p->pars;
if (m_config_cache_update(p->opts_cache))
bool changed = m_config_cache_update(p->opts_cache);
changed = m_config_cache_update(p->next_opts_cache) || changed;
if (changed)
update_render_options(vo);
update_lut(p, &p->lut);
pars->params.lut = p->lut.lut;
pars->params.lut_type = p->lut.type;
update_lut(p, &p->next_opts->lut);
pars->params.lut = p->next_opts->lut.lut;
pars->params.lut_type = p->next_opts->lut.type;
// Update equalizer state
struct mp_csp_params cparams = MP_CSP_PARAMS_DEFAULTS;
@ -736,7 +772,7 @@ static void update_options(struct vo *vo)
pars->color_adjustment.gamma = cparams.gamma;
p->output_levels = cparams.levels_out;
for (char **kv = p->raw_opts; kv && kv[0]; kv += 2)
for (char **kv = p->next_opts->raw_opts; kv && kv[0]; kv += 2)
pl_options_set_str(pars, kv[0], kv[1]);
}
@ -768,9 +804,9 @@ static void apply_target_contrast(struct priv *p, struct pl_color_space *color)
static void apply_target_options(struct priv *p, struct pl_frame *target)
{
update_lut(p, &p->target_lut);
target->lut = p->target_lut.lut;
target->lut_type = p->target_lut.type;
update_lut(p, &p->next_opts->target_lut);
target->lut = p->next_opts->target_lut.lut;
target->lut_type = p->next_opts->target_lut.type;
// Colorspace overrides
const struct gl_video_opts *opts = p->opts_cache->opts;
@ -874,7 +910,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
params.info_callback = info_callback;
params.info_priv = vo;
params.skip_caching_single_frame = !cache_frame;
params.preserve_mixing_cache = p->inter_preserve && !frame->still;
params.preserve_mixing_cache = p->next_opts->inter_preserve && !frame->still;
if (frame->still)
params.frame_mixer = NULL;
@ -931,7 +967,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
p->last_id = id;
}
if (p->target_hint && frame->current) {
if (p->next_opts->target_hint && frame->current) {
struct pl_color_space hint = frame->current->params.color;
if (opts->target_prim)
hint.primaries = opts->target_prim;
@ -941,7 +977,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
hint.hdr.max_luma = opts->target_peak;
apply_target_contrast(p, &hint);
pl_swapchain_colorspace_hint(p->sw, &hint);
} else if (!p->target_hint) {
} else if (!p->next_opts->target_hint) {
pl_swapchain_colorspace_hint(p->sw, NULL);
}
@ -1742,6 +1778,8 @@ static int preinit(struct vo *vo)
{
struct priv *p = vo->priv;
p->opts_cache = m_config_cache_alloc(p, vo->global, &gl_video_conf);
p->next_opts_cache = m_config_cache_alloc(p, vo->global, &gl_next_conf);
p->next_opts = p->next_opts_cache->opts;
p->video_eq = mp_csp_equalizer_create(p, vo->global);
p->global = vo->global;
p->log = vo->log;
@ -2040,7 +2078,7 @@ static void update_render_options(struct vo *vo)
pars->params.disable_linear_scaling = !opts->linear_downscaling && !opts->linear_upscaling;
pars->params.disable_fbos = opts->dumb_mode == 1;
pars->params.blend_against_tiles = opts->alpha_mode == ALPHA_BLEND_TILES;
pars->params.corner_rounding = p->corner_rounding;
pars->params.corner_rounding = p->next_opts->corner_rounding;
pars->params.correct_subpixel_offsets = !opts->scaler_resizes_only;
// Map scaler options as best we can
@ -2074,7 +2112,7 @@ static void update_render_options(struct vo *vo)
pars->peak_detect_params.scene_threshold_low = opts->tone_map.scene_threshold_low;
pars->peak_detect_params.scene_threshold_high = opts->tone_map.scene_threshold_high;
pars->peak_detect_params.percentile = opts->tone_map.peak_percentile;
pars->peak_detect_params.allow_delayed = p->delayed_peak;
pars->peak_detect_params.allow_delayed = p->next_opts->delayed_peak;
const struct pl_tone_map_function * const tone_map_funs[] = {
[TONE_MAPPING_AUTO] = &pl_tone_map_auto,
@ -2153,16 +2191,6 @@ static void update_render_options(struct vo *vo)
pars->params.hooks = p->hooks;
}
#define OPT_BASE_STRUCT struct priv
const struct m_opt_choice_alternatives lut_types[] = {
{"auto", PL_LUT_UNKNOWN},
{"native", PL_LUT_NATIVE},
{"normalized", PL_LUT_NORMALIZED},
{"conversion", PL_LUT_CONVERSION},
{0}
};
const struct vo_driver video_out_gpu_next = {
.description = "Video output based on libplacebo",
.name = "gpu-next",
@ -2181,22 +2209,4 @@ const struct vo_driver video_out_gpu_next = {
.wakeup = wakeup,
.uninit = uninit,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.inter_preserve = true,
},
.options = (const struct m_option[]) {
{"allow-delayed-peak-detect", OPT_BOOL(delayed_peak)},
{"corner-rounding", OPT_FLOAT(corner_rounding), M_RANGE(0, 1)},
{"interpolation-preserve", OPT_BOOL(inter_preserve)},
{"lut", OPT_STRING(lut.opt), .flags = M_OPT_FILE},
{"lut-type", OPT_CHOICE_C(lut.type, lut_types)},
{"image-lut", OPT_STRING(image_lut.opt), .flags = M_OPT_FILE},
{"image-lut-type", OPT_CHOICE_C(image_lut.type, lut_types)},
{"target-lut", OPT_STRING(target_lut.opt), .flags = M_OPT_FILE},
{"target-colorspace-hint", OPT_BOOL(target_hint)},
// No `target-lut-type` because we don't support non-RGB targets
{"libplacebo-opts", OPT_KEYVALUELIST(raw_opts)},
{0}
},
};