player: use XDG_CACHE_HOME by default

This adds cache as a possible path for mpv to internally pick
(~/.cache/mpv for non-darwin unix-like systems, the usual config
directory for everyone else). For gpu shader cache and icc cache,
controlling whether or not to write such files is done with the new
--gpu-shader-cache and --icc-cache options respectively. Additionally,
--cache-on-disk no longer requires explicitly setting the --cache-dir
option. The old options, --cache-dir, --gpu-shader-cache-dir, and
--icc-cache-dir simply set an override for the directory to save cache
files. If unset, then the cache is saved in XDG_CACHE_HOME.
This commit is contained in:
Dudemanguy 2023-05-02 19:42:23 -05:00
parent 7c4c9bc86f
commit 4502522a7a
15 changed files with 87 additions and 25 deletions

View File

@ -64,6 +64,13 @@ Interface changes
- `--save-position-on-quit` and its associated commands now store state files in
the XDG_STATE_HOME directory by default. This only has an effect on linux/bsd
systems.
- mpv now implictly saves cache files in XDG_CACHE_HOME by default. This only has
an effect if the user enables options that would lead to cache being stored and
only makes a difference on linux/bsd systems.
- `--cache-on-disk` no longer requires explictly setting the `--cache-dir` option
- add `--icc-cache` and `--gpu-shader-cache` options to control whether or not to
save cache files for these features; explictly setting `--icc-cache-dir` and
`--gpu-shader-cache` is no longer required
--- mpv 0.35.0 ---
- add the `--vo=gpu-next` video output driver, as well as the options
`--allow-delayed-peak-detect`, `--builtin-scalers`,

View File

@ -461,6 +461,8 @@ Name Meaning
``~~desktop/`` the path to the desktop (win32, macOS)
``~~exe_dir/`` win32 only: the path to the directory containing the exe (for
config file purposes; ``$MPV_HOME`` overrides it)
``~~cache/`` the path to application cache data (``~/.cache/mpv/``)
On some platforms, this will be the same as ``~~home/``.
``~~state/`` the path to application state data (``~/.local/state/mpv/``)
On some platforms, this will be the same as ``~~home/``.
``~~old_home/`` do not use

View File

@ -4771,8 +4771,6 @@ Cache
This makes sense only with ``--cache``. If the normal cache is disabled,
this option is ignored.
You need to set ``--cache-dir`` to use this.
The cache file is append-only. Even if the player appears to prune data, the
file space freed by it is not reused. The cache file is deleted when
playback is closed.
@ -4795,7 +4793,8 @@ Cache
continue to use the cache file that was opened first.
``--cache-dir=<path>``
Directory where to create temporary files (default: none).
Directory where to create temporary files. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.
Currently, this is used for ``--cache-on-disk`` only.
@ -6634,15 +6633,20 @@ them.
Applications using libmpv with the render API need to provide the ICC
profile via ``MPV_RENDER_PARAM_ICC_PROFILE``.
``--icc-cache-dir=<dirname>``
Store and load the 3D LUTs created from the ICC profile in this directory.
This can be used to speed up loading, since LittleCMS 2 can take a while to
create a 3D LUT. Note that these files contain uncompressed LUTs. Their
size depends on the ``--icc-3dlut-size``, and can be very big.
``--icc-cache``
Store and load 3D LUTs created from the ICC profile on disk in the
cache directory. This can be used to speed up loading, since LittleCMS
2 can take a while to create a 3D LUT. Note that these files contain
uncompressed LUTs. Their size depends on the ``--icc-3dlut-size``, and
can be very big.
NOTE: This is not cleaned automatically, so old, unused cache files may
stick around indefinitely.
``--icc-cache-dir``
The directory where icc cache is stored. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.
``--icc-intent=<value>``
Specifies the ICC intent used for the color transformation (when using
``--icc-profile``).
@ -6775,9 +6779,9 @@ them.
This option might be silently removed in the future.
``--gpu-shader-cache-dir=<dirname>``
Store and load compiled GLSL shaders in this directory. Normally, shader
compilation is very fast, so this is usually not needed. It mostly matters
``--gpu-shader-cache``
Store and load compiled GLSL shaders in the cache directory. Normally, shader
compilation is very fast, so this is not usually needed. It mostly matters
for GPU APIs that require internally recompiling shaders to other languages,
for example anything based on ANGLE or Vulkan. Enabling this can improve
startup performance on these platforms.
@ -6785,6 +6789,10 @@ them.
NOTE: This is not cleaned automatically, so old, unused cache files may
stick around indefinitely.
``--gpu-shader-cache-dir``
The directory where gpu shader cache is stored. Cache is stored in the system's
cache directory (usually ``~/.cache/mpv``) if this is unset.
Miscellaneous
-------------

View File

@ -10,6 +10,7 @@ struct mpv_global {
struct mp_client_api *client_api;
char *configdir;
struct stats_base *stats;
bool no_cachedir;
bool no_statedir;
};

View File

@ -100,10 +100,12 @@ struct demux_cache *demux_cache_create(struct mpv_global *global,
cache->fd = -1;
char *cache_dir = cache->opts->cache_dir;
if (!(cache_dir && cache_dir[0])) {
MP_ERR(cache, "No cache data directory supplied.\n");
goto fail;
if (cache_dir && cache_dir[0]) {
cache_dir = mp_get_user_path(NULL, global, cache_dir);
} else {
cache_dir = mp_find_user_file(NULL, global, "cache", "");
}
mp_mkdirp(cache_dir);
cache->filename = mp_path_join(cache, cache_dir, "mpv-cache-XXXXXX.dat");
cache->fd = mp_mkostemps(cache->filename, 4, O_CLOEXEC);

View File

@ -74,7 +74,7 @@ static const char *mp_get_platform_path(void *talloc_ctx,
{
assert(talloc_ctx);
bool config_dir = strcmp(type, "state") != 0;
bool config_dir = strcmp(type, "cache") != 0 && strcmp(type, "state") != 0;
if (global->configdir && config_dir) {
for (int n = 0; n < MP_ARRAY_SIZE(config_dirs); n++) {
if (strcmp(config_dirs[n], type) == 0)
@ -84,6 +84,8 @@ static const char *mp_get_platform_path(void *talloc_ctx,
// Return the native config path if the platform doesn't support the
// type we are trying to fetch.
if (strcmp(type, "cache") == 0 && global->no_cachedir)
type = "home";
if (strcmp(type, "state") == 0 && global->no_statedir)
type = "home";
@ -102,7 +104,10 @@ void mp_init_paths(struct mpv_global *global, struct MPOpts *opts)
// Check if the platform has unique directories that differ from
// the standard config directory.
void *tmp = talloc_new(NULL);
const char *cache = mp_get_platform_path(tmp, global, "cache");
const char *state = mp_get_platform_path(tmp, global, "state");
if (!cache)
global->no_cachedir = true;
if (!state)
global->no_statedir = true;
talloc_free(tmp);

View File

@ -27,11 +27,13 @@ static pthread_once_t path_init_once = PTHREAD_ONCE_INIT;
static char mpv_home[512];
static char old_home[512];
static char mpv_cache[512];
static char mpv_state[512];
static void path_init(void)
{
char *home = getenv("HOME");
char *xdg_cache = getenv("XDG_CACHE_HOME");
char *xdg_config = getenv("XDG_CONFIG_HOME");
char *xdg_state = getenv("XDG_STATE_HOME");
@ -45,6 +47,12 @@ static void path_init(void)
if (home && home[0])
snprintf(old_home, sizeof(old_home), "%s/.mpv", home);
if (xdg_cache && xdg_cache[0]) {
snprintf(mpv_cache, sizeof(mpv_cache), "%s/mpv", xdg_cache);
} else if (home && home[0]) {
snprintf(mpv_cache, sizeof(mpv_cache), "%s/.cache/mpv", home);
}
if (xdg_state && xdg_state[0]) {
snprintf(mpv_state, sizeof(mpv_state), "%s/mpv", xdg_state);
} else if (home && home[0]) {
@ -55,6 +63,7 @@ static void path_init(void)
// config dir only. Also do not use any other XDG directories.
if (mp_path_exists(old_home) && !mp_path_exists(mpv_home)) {
snprintf(mpv_home, sizeof(mpv_home), "%s", old_home);
snprintf(mpv_cache, sizeof(mpv_cache), "%s", old_home);
snprintf(mpv_state, sizeof(mpv_state), "%s", old_home);
old_home[0] = '\0';
}
@ -67,6 +76,8 @@ const char *mp_get_platform_path_unix(void *talloc_ctx, const char *type)
return mpv_home;
if (strcmp(type, "old_home") == 0)
return old_home;
if (strcmp(type, "cache") == 0)
return mpv_cache;
if (strcmp(type, "state") == 0)
return mpv_state;
if (strcmp(type, "global") == 0)

View File

@ -15,6 +15,7 @@
// implemented on every platform. Unlike some other type values that are
// platform specific (like "osxbundle"), the value of "home" is returned
// instead if these types are not explicitly defined.
// "cache" the native mpv-specific user cache dir
// "state" the native mpv-specific user state dir
//
// It is allowed to return a static string, so the caller must set talloc_ctx

View File

@ -332,7 +332,7 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
cmsContext cms = NULL;
char *cache_file = NULL;
if (p->opts->cache_dir && p->opts->cache_dir[0]) {
if (p->opts->cache) {
// Gamma is included in the header to help uniquely identify it,
// because we may change the parameter in the future or make it
// customizable, same for the primaries.
@ -352,7 +352,13 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d,
av_sha_final(sha, hash);
av_free(sha);
char *cache_dir = mp_get_user_path(tmp, p->global, p->opts->cache_dir);
char *cache_dir = p->opts->cache_dir;
if (cache_dir && cache_dir[0]) {
cache_dir = mp_get_user_path(NULL, p->global, cache_dir);
} else {
cache_dir = mp_find_user_file(NULL, p->global, "cache", "");
}
cache_file = talloc_strdup(tmp, "");
for (int i = 0; i < sizeof(hash); i++)
cache_file = talloc_asprintf_append(cache_file, "%02X", hash[i]);
@ -494,13 +500,13 @@ const struct m_sub_options mp_icc_conf = {
{"use-embedded-icc-profile", OPT_BOOL(use_embedded)},
{"icc-profile", OPT_STRING(profile), .flags = M_OPT_FILE},
{"icc-profile-auto", OPT_BOOL(profile_auto)},
{"icc-cache", OPT_BOOL(cache)},
{"icc-cache-dir", OPT_STRING(cache_dir), .flags = M_OPT_FILE},
{"icc-intent", OPT_INT(intent)},
{"icc-force-contrast", OPT_CHOICE(contrast, {"no", 0}, {"inf", -1}),
M_RANGE(0, 1000000)},
{"icc-3dlut-size", OPT_STRING_VALIDATE(size_str, validate_3dlut_size_opt)},
{"3dlut-size", OPT_REPLACED("icc-3dlut-size")},
{"icc-cache", OPT_REMOVED("see icc-cache-dir")},
{"icc-contrast", OPT_REMOVED("see icc-force-contrast")},
{0}
},

View File

@ -13,6 +13,7 @@ struct mp_icc_opts {
bool use_embedded;
char *profile;
bool profile_auto;
bool cache;
char *cache_dir;
char *size_str;
int intent;

View File

@ -557,9 +557,14 @@ static void update_uniform(struct gl_shader_cache *sc, struct sc_entry *e,
}
}
void gl_sc_set_cache_dir(struct gl_shader_cache *sc, const char *dir)
void gl_sc_set_cache_dir(struct gl_shader_cache *sc, char *dir)
{
talloc_free(sc->cache_dir);
if (dir && dir[0]) {
dir = mp_get_user_path(NULL, sc->global, dir);
} else {
dir = mp_find_user_file(NULL, sc->global, "cache", "");
}
sc->cache_dir = talloc_strdup(sc, dir);
}

View File

@ -63,4 +63,4 @@ struct mp_pass_perf gl_sc_dispatch_compute(struct gl_shader_cache *sc,
// The application can call this on errors, to reset the current shader. This
// is normally done implicitly by gl_sc_dispatch_*
void gl_sc_reset(struct gl_shader_cache *sc);
void gl_sc_set_cache_dir(struct gl_shader_cache *sc, const char *dir);
void gl_sc_set_cache_dir(struct gl_shader_cache *sc, char *dir);

View File

@ -465,6 +465,7 @@ const struct m_sub_options gl_video_conf = {
{"gpu-tex-pad-x", OPT_INT(tex_pad_x), M_RANGE(0, 4096)},
{"gpu-tex-pad-y", OPT_INT(tex_pad_y), M_RANGE(0, 4096)},
{"", OPT_SUBSTRUCT(icc_opts, mp_icc_conf)},
{"gpu-shader-cache", OPT_BOOL(shader_cache)},
{"gpu-shader-cache-dir", OPT_STRING(shader_cache_dir), .flags = M_OPT_FILE},
{"gpu-hwdec-interop",
OPT_STRING_VALIDATE(hwdec_interop, ra_hwdec_validate_opt)},
@ -4099,7 +4100,8 @@ static void reinit_from_options(struct gl_video *p)
check_gl_features(p);
uninit_rendering(p);
gl_sc_set_cache_dir(p->sc, p->opts.shader_cache_dir);
if (p->opts.shader_cache)
gl_sc_set_cache_dir(p->sc, p->opts.shader_cache_dir);
p->ra->use_pbo = p->opts.pbo;
gl_video_setup_hooks(p);
reinit_osd(p);

View File

@ -171,6 +171,7 @@ struct gl_video_opts {
float unsharp;
int tex_pad_x, tex_pad_y;
struct mp_icc_opts *icc_opts;
bool shader_cache;
int early_flush;
char *shader_cache_dir;
char *hwdec_interop;

View File

@ -1348,10 +1348,15 @@ static void wait_events(struct vo *vo, int64_t until_time_us)
static char *get_cache_file(struct priv *p)
{
struct gl_video_opts *opts = p->opts_cache->opts;
if (!opts->shader_cache_dir || !opts->shader_cache_dir[0])
if (!opts->shader_cache)
return NULL;
char *dir = mp_get_user_path(NULL, p->global, opts->shader_cache_dir);
char *dir = opts->shader_cache_dir;
if (dir && dir[0]) {
dir = mp_get_user_path(NULL, p->global, dir);
} else {
dir = mp_find_user_file(NULL, p->global, "cache", "");
}
char *file = mp_path_join(NULL, dir, "libplacebo.cache");
mp_mkdirp(dir);
talloc_free(dir);
@ -1575,7 +1580,7 @@ static const struct pl_hook *load_hook(struct priv *p, const char *path)
static stream_t *icc_open_cache(struct priv *p, uint64_t sig, int flags)
{
const struct gl_video_opts *opts = p->opts_cache->opts;
if (!opts->icc_opts->cache_dir || !opts->icc_opts->cache_dir[0])
if (!opts->icc_opts->cache)
return NULL;
char cache_name[16+1];
@ -1585,7 +1590,12 @@ static stream_t *icc_open_cache(struct priv *p, uint64_t sig, int flags)
}
cache_name[16] = '\0';
char *cache_dir = mp_get_user_path(NULL, p->global, opts->icc_opts->cache_dir);
char *cache_dir = opts->icc_opts->cache_dir;
if (cache_dir && cache_dir[0]) {
cache_dir = mp_get_user_path(NULL, p->global, cache_dir);
} else {
cache_dir = mp_find_user_file(NULL, p->global, "cache", "");
}
char *path = mp_path_join(NULL, cache_dir, cache_name);
stream_t *stream = NULL;