summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-07-31 20:44:16 +0200
committerwm4 <wm4@nowhere>2013-07-31 20:53:00 +0200
commit0656411e97afd5710b02563ee0b28423443592e9 (patch)
tree36375cff0a58d33e4c0b0ab788e878db334b4e13
parent42f06fb915856722d2e263aa72d0acaf1e00271c (diff)
downloadmpv-0656411e97afd5710b02563ee0b28423443592e9.tar.bz2
mpv-0656411e97afd5710b02563ee0b28423443592e9.tar.xz
m_config: store file local backup options differently
File local options need to backup the global option value while a file is played. Instead of keeping a pointer in m_config_option for the backup value, put it into a separate list. This reduces per-option overhead for a rarely used obscure feature. (This implementation would have been a bit dumb in pre-mpv m_config, because there local options were the default, and _all_ options were backed up when starting playback of a file. This is not the case anymore, and normally only a very small number of options are backed up by default.)
-rw-r--r--core/m_config.c43
-rw-r--r--core/m_config.h4
2 files changed, 31 insertions, 16 deletions
diff --git a/core/m_config.c b/core/m_config.c
index 414d397049..7faca24497 100644
--- a/core/m_config.c
+++ b/core/m_config.c
@@ -47,6 +47,13 @@ struct m_profile {
char **opts;
};
+// In the file local case, this contains the old global value.
+struct m_opt_backup {
+ struct m_opt_backup *next;
+ struct m_config_option *co;
+ void *backup;
+};
+
static int parse_include(struct m_config *config, struct bstr param, bool set)
{
if (param.len == 0)
@@ -175,14 +182,14 @@ static void add_options(struct m_config *config,
static int config_destroy(void *p)
{
struct m_config *config = p;
+ if (config->file_local_mode)
+ m_config_leave_file_local(config);
for (struct m_config_option *copt = config->opts; copt; copt = copt->next) {
if (copt->alias_owner)
continue;
if (copt->opt->type->flags & M_OPT_TYPE_DYNAMIC) {
m_option_free(copt->opt, copt->data);
}
- if (copt->global_backup)
- m_option_free(copt->opt, copt->global_backup);
}
return 0;
}
@@ -246,18 +253,26 @@ int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc,
static void ensure_backup(struct m_config *config, struct m_config_option *co)
{
- while (co->alias_owner)
- co = co->alias_owner;
if (!config->file_local_mode)
return;
if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
return;
if (co->opt->flags & M_OPT_GLOBAL)
return;
- if (co->global_backup)
+ if (!co->data)
return;
- co->global_backup = talloc_zero_size(co, co->opt->type->size);
- m_option_copy(co->opt, co->global_backup, co->data);
+ for (struct m_opt_backup *cur = config->backup_opts; cur; cur = cur->next) {
+ if (cur->co->data == co->data) // comparing data ptr catches aliases
+ return;
+ }
+ struct m_opt_backup *bc = talloc_ptrtype(NULL, bc);
+ *bc = (struct m_opt_backup) {
+ .co = co,
+ .backup = talloc_zero_size(bc, co->opt->type->size),
+ };
+ m_option_copy(co->opt, bc->backup, co->data);
+ bc->next = config->backup_opts;
+ config->backup_opts = bc;
}
void m_config_enter_file_local(struct m_config *config)
@@ -274,13 +289,13 @@ void m_config_leave_file_local(struct m_config *config)
{
assert(config->file_local_mode);
config->file_local_mode = false;
- for (struct m_config_option *co = config->opts; co; co = co->next) {
- if (co->global_backup) {
- m_option_copy(co->opt, co->data, co->global_backup);
- m_option_free(co->opt, co->global_backup);
- talloc_free(co->global_backup);
- co->global_backup = NULL;
- }
+ while (config->backup_opts) {
+ struct m_opt_backup *bc = config->backup_opts;
+ config->backup_opts = bc->next;
+
+ m_option_copy(bc->co->opt, bc->co->data, bc->backup);
+ m_option_free(bc->co->opt, bc->backup);
+ talloc_free(bc);
}
}
diff --git a/core/m_config.h b/core/m_config.h
index c48a4f1281..1ee7ecf1c0 100644
--- a/core/m_config.h
+++ b/core/m_config.h
@@ -44,8 +44,6 @@ struct m_config_option {
const struct m_option *opt;
// Raw value of the option.
void *data;
- // Raw value of the backup of the global value (or NULL).
- void *global_backup;
// If this is a suboption, the option that contains this option.
struct m_config_option *parent;
// If this option aliases another, more important option. The alias_owner
@@ -70,6 +68,8 @@ typedef struct m_config {
// Depth when recursively including profiles.
int profile_depth;
+ struct m_opt_backup *backup_opts;
+
bool use_profiles;
int (*includefunc)(struct m_config *conf, char *filename);