options: slightly better option update mechanism

Extend the flag-based notification mechanism that was used via
M_OPT_TERM. Make the vo_opengl update mechanism use this (which, btw.,
also fixes compilation with OpenGL renderers forcibly disabled).

While this adds a 3rd mechanism and just seems to further the chaos, I'd
rather have a very simple mechanism now, than actually furthering the
mess by mixing old and new update mechanisms. In particular, we'll be
able to remove quite some property implementations, and replace them
with much simpler update handling. The new update mechanism can also
more easily refactored once we have a final mechanism that handles
everything in an uniform way.
This commit is contained in:
wm4 2016-09-19 19:51:26 +02:00
parent 32f235bcef
commit fe7db61035
8 changed files with 63 additions and 27 deletions

View File

@ -418,6 +418,9 @@ static void add_sub_options(struct m_config *config,
for (int n = 0; n < config->num_groups; n++)
assert(config->groups[n].group != subopts);
// You can only use UPDATE_ flags here.
assert(!(subopts->change_flags & ~(unsigned)UPDATE_OPTS_MASK));
void *new_optstruct = NULL;
if (config->optstruct) { // only if not noalloc
new_optstruct = talloc_zero_size(config, subopts->size);
@ -1255,16 +1258,23 @@ void m_config_notify_change_co(struct m_config *config,
if (co->shadow_offset >= 0)
m_option_copy(co->opt, shadow->data + co->shadow_offset, co->data);
pthread_mutex_unlock(&shadow->lock);
int group = co->group;
while (group >= 0) {
atomic_fetch_add(&config->groups[group].ts, 1);
group = config->groups[group].parent_group;
}
}
if (config->global && (co->opt->flags & M_OPT_TERM))
mp_msg_update_msglevels(config->global);
int changed = co->opt->flags & UPDATE_OPTS_MASK;
int group = co->group;
while (group >= 0) {
struct m_config_group *g = &config->groups[group];
atomic_fetch_add(&g->ts, 1);
if (g->group)
changed |= g->group->change_flags;
group = g->parent_group;
}
if (config->option_change_callback) {
config->option_change_callback(config->option_change_callback_ctx, co,
changed);
}
}
bool m_config_is_in_group(struct m_config *config,

View File

@ -77,10 +77,17 @@ typedef struct m_config {
int (*includefunc)(void *ctx, char *filename, int flags);
void *includefunc_ctx;
// Can intercept option write accesses.
int (*option_set_callback)(void *ctx, struct m_config_option *co,
void *data, int flags);
void *option_set_callback_cb;
// Notification after an option was successfully written to.
// Uses flags as set in UPDATE_OPTS_MASK.
void (*option_change_callback)(void *ctx, struct m_config_option *co,
int flags);
void *option_change_callback_ctx;
// For the command line parser
int recursion_depth;

View File

@ -191,6 +191,9 @@ struct m_sub_options {
const struct m_option *opts;
size_t size;
const void *defaults;
// Change flags passed to mp_option_change_callback() if any option that is
// directly or indirectly part of this group is changed.
int change_flags;
};
#define CONF_TYPE_FLAG (&m_option_type_flag)
@ -372,12 +375,20 @@ struct m_option {
// The option expects a file name (or a list of file names)
#define M_OPT_FILE (1 << 11)
// Logging-related option - used to update log/terminal settings eagerly
#define M_OPT_TERM (1 << 12)
// Do not add as property.
#define M_OPT_NOPROP (1 << 13)
// The following are also part of the M_OPT_* flags, and are used to update
// certain groups of options.
#define UPDATE_OPT_FIRST (1 << 14)
#define UPDATE_TERM (1 << 14) // terminal options
#define UPDATE_RENDERER (1 << 15) // mainly vo_opengl options
#define UPDATE_OPT_LAST (1 << 15)
// All bits between _FIRST and _LAST (inclusive)
#define UPDATE_OPTS_MASK \
(((UPDATE_OPT_LAST << 1) - 1) & ~(unsigned)(UPDATE_OPT_FIRST - 1))
// These are kept for compatibility with older code.
#define CONF_MIN M_OPT_MIN
#define CONF_MAX M_OPT_MAX

View File

@ -256,14 +256,14 @@ const m_option_t mp_opts[] = {
OPT_FLAG("quiet", quiet, 0),
OPT_FLAG_STORE("really-quiet", verbose,
CONF_GLOBAL | CONF_PRE_PARSE | M_OPT_NOPROP, -10),
OPT_FLAG("terminal", use_terminal, CONF_GLOBAL | CONF_PRE_PARSE | M_OPT_TERM),
OPT_GENERAL(char**, "msg-level", msg_levels, CONF_PRE_PARSE | M_OPT_TERM,
OPT_FLAG("terminal", use_terminal, CONF_GLOBAL | CONF_PRE_PARSE | UPDATE_TERM),
OPT_GENERAL(char**, "msg-level", msg_levels, CONF_PRE_PARSE | UPDATE_TERM,
.type = &m_option_type_msglevels),
OPT_STRING("dump-stats", dump_stats, CONF_GLOBAL | CONF_PRE_PARSE),
OPT_FLAG("msg-color", msg_color, CONF_PRE_PARSE | M_OPT_TERM),
OPT_STRING("log-file", log_file, CONF_PRE_PARSE | M_OPT_FILE),
OPT_FLAG("msg-module", msg_module, M_OPT_TERM),
OPT_FLAG("msg-time", msg_time, M_OPT_TERM),
OPT_STRING("dump-stats", dump_stats, UPDATE_TERM | CONF_PRE_PARSE),
OPT_FLAG("msg-color", msg_color, CONF_PRE_PARSE | UPDATE_TERM),
OPT_STRING("log-file", log_file, CONF_PRE_PARSE | M_OPT_FILE | UPDATE_TERM),
OPT_FLAG("msg-module", msg_module, UPDATE_TERM),
OPT_FLAG("msg-time", msg_time, UPDATE_TERM),
#ifdef _WIN32
OPT_CHOICE("priority", w32_priority, CONF_GLOBAL,
({"no", 0},

View File

@ -5626,17 +5626,20 @@ void mp_notify(struct MPContext *mpctx, int event, void *arg)
mp_client_broadcast_event(mpctx, event, arg);
}
extern const struct m_sub_options gl_video_conf;
void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags)
{
struct MPContext *mpctx = ctx;
if (flags & UPDATE_TERM)
mp_msg_update_msglevels(mpctx->global);
if (flags & UPDATE_RENDERER) {
if (mpctx->video_out)
vo_control(mpctx->video_out, VOCTRL_UPDATE_RENDER_OPTS, NULL);
}
}
void mp_notify_property(struct MPContext *mpctx, const char *property)
{
struct m_config_option *co =
m_config_get_co_raw(mpctx->mconfig, bstr0(property));
if (co) {
if (m_config_is_in_group(mpctx->mconfig, &gl_video_conf, co)) {
if (mpctx->video_out)
vo_control(mpctx->video_out, VOCTRL_UPDATE_RENDER_OPTS, NULL);
}
}
mp_client_property_change(mpctx, property);
}

View File

@ -37,6 +37,7 @@ int mp_property_do(const char* name, int action, void* val,
struct MPContext *mpctx);
int mp_on_set_option(void *ctx, struct m_config_option *co, void *data, int flags);
void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags);
void mp_notify(struct MPContext *mpctx, int event, void *arg);
void mp_notify_property(struct MPContext *mpctx, const char *property);

View File

@ -359,6 +359,9 @@ struct MPContext *mp_create(void)
mpctx->mconfig->option_set_callback = mp_on_set_option;
mpctx->mconfig->option_set_callback_cb = mpctx;
mpctx->mconfig->option_change_callback = mp_option_change_callback;
mpctx->mconfig->option_change_callback_ctx = mpctx;
return mpctx;
}

View File

@ -415,6 +415,7 @@ const struct m_sub_options gl_video_conf = {
},
.size = sizeof(struct gl_video_opts),
.defaults = &gl_video_opts_def,
.change_flags = UPDATE_RENDERER,
};
#define LEGACY_SCALER_OPTS(n) \