mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 16:33:02 +00:00
vo_opengl: simplify option handling
Instead of copying the options around... just don't. video.c now has full control over when options are updated. (It still gets notified from outside, but it decides when the updated options are copied: when m_config_cache_update() is called.) So there's no need for tricky stuff, and it can be simplified a bit. Also change lcms.c. We could do it like video.c, and get the options from the global config store. But it seems simpler to just provide a pointer to an option struct, which is arbitrarily mutated from the outside (from the perspective of lcms.c).
This commit is contained in:
parent
e5cefa346d
commit
9ab0f60d44
@ -26,7 +26,6 @@
|
||||
#include "common/common.h"
|
||||
#include "misc/bstr.h"
|
||||
#include "common/msg.h"
|
||||
#include "options/m_config.h"
|
||||
#include "options/m_option.h"
|
||||
#include "options/path.h"
|
||||
#include "video/csputils.h"
|
||||
@ -43,10 +42,11 @@
|
||||
struct gl_lcms {
|
||||
void *icc_data;
|
||||
size_t icc_size;
|
||||
char *current_profile;
|
||||
bool using_memory_profile;
|
||||
bool changed;
|
||||
enum mp_csp_prim prev_prim;
|
||||
enum mp_csp_trc prev_trc;
|
||||
enum mp_csp_prim current_prim;
|
||||
enum mp_csp_trc current_trc;
|
||||
|
||||
struct mp_log *log;
|
||||
struct mpv_global *global;
|
||||
@ -108,6 +108,8 @@ static void load_profile(struct gl_lcms *p)
|
||||
p->icc_data = NULL;
|
||||
p->icc_size = 0;
|
||||
p->using_memory_profile = false;
|
||||
talloc_free(p->current_profile);
|
||||
p->current_profile = NULL;
|
||||
|
||||
if (!p->opts->profile || !p->opts->profile[0])
|
||||
return;
|
||||
@ -124,35 +126,32 @@ static void load_profile(struct gl_lcms *p)
|
||||
|
||||
p->icc_data = iccdata.start;
|
||||
p->icc_size = iccdata.len;
|
||||
p->current_profile = talloc_strdup(p, p->opts->profile);
|
||||
}
|
||||
|
||||
struct gl_lcms *gl_lcms_init(void *talloc_ctx, struct mp_log *log,
|
||||
struct mpv_global *global)
|
||||
struct mpv_global *global,
|
||||
struct mp_icc_opts *opts)
|
||||
{
|
||||
struct gl_lcms *p = talloc_ptrtype(talloc_ctx, p);
|
||||
*p = (struct gl_lcms) {
|
||||
.global = global,
|
||||
.log = log,
|
||||
.changed = true,
|
||||
.opts = m_sub_options_copy(p, &mp_icc_conf, mp_icc_conf.defaults),
|
||||
.opts = opts,
|
||||
};
|
||||
gl_lcms_update_options(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void gl_lcms_set_options(struct gl_lcms *p, struct mp_icc_opts *opts)
|
||||
void gl_lcms_update_options(struct gl_lcms *p)
|
||||
{
|
||||
struct mp_icc_opts *old_opts = p->opts;
|
||||
p->opts = m_sub_options_copy(p, &mp_icc_conf, opts);
|
||||
|
||||
if ((p->using_memory_profile && !p->opts->profile_auto) ||
|
||||
!bstr_equals(bstr0(p->opts->profile), bstr0(old_opts->profile)))
|
||||
!bstr_equals(bstr0(p->opts->profile), bstr0(p->current_profile)))
|
||||
{
|
||||
load_profile(p);
|
||||
}
|
||||
|
||||
p->changed = true; // probably
|
||||
|
||||
talloc_free(old_opts);
|
||||
}
|
||||
|
||||
// Warning: profile.start must point to a ta allocation, and the function
|
||||
@ -185,16 +184,12 @@ bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return and _reset_ whether the profile or config has changed since the last
|
||||
// call. If it has changed, gl_lcms_get_lut3d() should be called.
|
||||
// Return whether the profile or config has changed since the last time it was
|
||||
// retrieved. If it has changed, gl_lcms_get_lut3d() should be called.
|
||||
bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim,
|
||||
enum mp_csp_trc trc)
|
||||
{
|
||||
bool change = p->changed || p->prev_prim != prim || p->prev_trc != trc;
|
||||
p->changed = false;
|
||||
p->prev_prim = prim;
|
||||
p->prev_trc = trc;
|
||||
return change;
|
||||
return p->changed || p->current_prim != prim || p->current_trc != trc;
|
||||
}
|
||||
|
||||
// Whether a profile is set. (gl_lcms_get_lut3d() is expected to return a lut,
|
||||
@ -316,6 +311,10 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
|
||||
int s_r, s_g, s_b;
|
||||
bool result = false;
|
||||
|
||||
p->changed = false;
|
||||
p->current_prim = prim;
|
||||
p->current_trc = trc;
|
||||
|
||||
if (!parse_3dlut_size(p->opts->size_str, &s_r, &s_g, &s_b))
|
||||
return false;
|
||||
|
||||
@ -451,14 +450,14 @@ const struct m_sub_options mp_icc_conf = {
|
||||
.defaults = &(const struct mp_icc_opts) {0},
|
||||
};
|
||||
|
||||
|
||||
struct gl_lcms *gl_lcms_init(void *talloc_ctx, struct mp_log *log,
|
||||
struct mpv_global *global)
|
||||
struct mpv_global *global,
|
||||
struct mp_icc_opts *opts)
|
||||
{
|
||||
return (struct gl_lcms *) talloc_new(talloc_ctx);
|
||||
}
|
||||
|
||||
void gl_lcms_set_options(struct gl_lcms *p, struct mp_icc_opts *opts) { }
|
||||
void gl_lcms_update_options(struct gl_lcms *p) { }
|
||||
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile) {return false;}
|
||||
|
||||
bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim,
|
||||
|
@ -26,8 +26,9 @@ struct mpv_global;
|
||||
struct gl_lcms;
|
||||
|
||||
struct gl_lcms *gl_lcms_init(void *talloc_ctx, struct mp_log *log,
|
||||
struct mpv_global *global);
|
||||
void gl_lcms_set_options(struct gl_lcms *p, struct mp_icc_opts *opts);
|
||||
struct mpv_global *global,
|
||||
struct mp_icc_opts *opts);
|
||||
void gl_lcms_update_options(struct gl_lcms *p);
|
||||
bool gl_lcms_set_memory_profile(struct gl_lcms *p, bstr profile);
|
||||
bool gl_lcms_has_profile(struct gl_lcms *p);
|
||||
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **,
|
||||
|
@ -169,7 +169,6 @@ struct gl_video {
|
||||
struct mpv_global *global;
|
||||
struct mp_log *log;
|
||||
struct gl_video_opts opts;
|
||||
struct gl_video_opts *opts_alloc;
|
||||
struct m_config_cache *opts_cache;
|
||||
struct gl_lcms *cms;
|
||||
bool gl_debug;
|
||||
@ -513,7 +512,6 @@ static void check_gl_features(struct gl_video *p);
|
||||
static bool init_format(struct gl_video *p, int fmt, bool test_only);
|
||||
static void init_image_desc(struct gl_video *p, int fmt);
|
||||
static bool gl_video_upload_image(struct gl_video *p, struct mp_image *mpi);
|
||||
static void set_options(struct gl_video *p, struct gl_video_opts *src);
|
||||
static const char *handle_scaler_opt(const char *name, bool tscale);
|
||||
static void reinit_from_options(struct gl_video *p);
|
||||
static void get_scale_factors(struct gl_video *p, bool transpose_rot, double xy[2]);
|
||||
@ -3026,7 +3024,7 @@ static void check_gl_features(struct gl_video *p)
|
||||
p->dumb_mode = true;
|
||||
p->use_lut_3d = false;
|
||||
// Most things don't work, so whitelist all options that still work.
|
||||
struct gl_video_opts new_opts = {
|
||||
p->opts = (struct gl_video_opts){
|
||||
.gamma = p->opts.gamma,
|
||||
.gamma_auto = p->opts.gamma_auto,
|
||||
.pbo = p->opts.pbo,
|
||||
@ -3040,8 +3038,7 @@ static void check_gl_features(struct gl_video *p)
|
||||
.tone_mapping_param = p->opts.tone_mapping_param,
|
||||
};
|
||||
for (int n = 0; n < SCALER_COUNT; n++)
|
||||
new_opts.scaler[n] = gl_video_opts_def.scaler[n];
|
||||
set_options(p, &new_opts);
|
||||
p->opts.scaler[n] = gl_video_opts_def.scaler[n];
|
||||
return;
|
||||
}
|
||||
p->dumb_mode = false;
|
||||
@ -3062,7 +3059,7 @@ static void check_gl_features(struct gl_video *p)
|
||||
if (reason) {
|
||||
MP_WARN(p, "Disabling scaler #%d %s %s.\n", n,
|
||||
p->opts.scaler[n].kernel.name, reason);
|
||||
// p->opts is a copy of p->opts_alloc => we can just mess with it.
|
||||
// p->opts is a copy => we can just mess with it.
|
||||
p->opts.scaler[n].kernel.name = "bilinear";
|
||||
if (n == SCALER_TSCALE)
|
||||
p->opts.interpolation = 0;
|
||||
@ -3414,13 +3411,13 @@ struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct mpv_global *g)
|
||||
.gl = gl,
|
||||
.global = g,
|
||||
.log = log,
|
||||
.cms = gl_lcms_init(p, log, g),
|
||||
.texture_16bit_depth = 16,
|
||||
.sc = gl_sc_create(gl, log),
|
||||
.opts_cache = m_config_cache_alloc(p, g, &gl_video_conf),
|
||||
};
|
||||
set_options(p, p->opts_cache->opts);
|
||||
gl_lcms_set_options(p->cms, p->opts.icc_opts);
|
||||
struct gl_video_opts *opts = p->opts_cache->opts;
|
||||
p->cms = gl_lcms_init(p, log, g, opts->icc_opts),
|
||||
p->opts = *opts;
|
||||
for (int n = 0; n < SCALER_COUNT; n++)
|
||||
p->scaler[n] = (struct scaler){.index = n};
|
||||
gl_video_set_debug(p, true);
|
||||
@ -3448,28 +3445,23 @@ static const char *handle_scaler_opt(const char *name, bool tscale)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void set_options(struct gl_video *p, struct gl_video_opts *src)
|
||||
{
|
||||
talloc_free(p->opts_alloc);
|
||||
p->opts_alloc = m_sub_options_copy(p, &gl_video_conf, src);
|
||||
p->opts = *p->opts_alloc;
|
||||
}
|
||||
|
||||
void gl_video_update_options(struct gl_video *p)
|
||||
{
|
||||
if (m_config_cache_update(p->opts_cache)) {
|
||||
set_options(p, p->opts_cache->opts);
|
||||
gl_lcms_update_options(p->cms);
|
||||
reinit_from_options(p);
|
||||
}
|
||||
}
|
||||
|
||||
static void reinit_from_options(struct gl_video *p)
|
||||
{
|
||||
p->use_lut_3d = false;
|
||||
|
||||
gl_lcms_set_options(p->cms, p->opts.icc_opts);
|
||||
p->use_lut_3d = gl_lcms_has_profile(p->cms);
|
||||
|
||||
// Copy the option fields, so that check_gl_features() can mutate them.
|
||||
// This works only for the fields themselves of course, not for any memory
|
||||
// referenced by them.
|
||||
p->opts = *(struct gl_video_opts *)p->opts_cache->opts;
|
||||
|
||||
check_gl_features(p);
|
||||
uninit_rendering(p);
|
||||
gl_video_setup_hooks(p);
|
||||
|
Loading…
Reference in New Issue
Block a user