Skip to content

Commit

Permalink
player: use XDG_CACHE_HOME by default
Browse files Browse the repository at this point in the history
This adds cache as a possible path for mpv to interally 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 id done with the new
--gpu-shader-cache and --icc-cache options respectively. Additionally,
--cache-on-disk no longer requires explictly setting the --cache-dir
option. The old options, --gpu-shader-cache-dir and --icc-cache-dir,
simply set an override for the directory to save the files. If unset,
then it is saved in XDG_CACHE_HOME.
  • Loading branch information
Dudemanguy committed May 9, 2023
1 parent d3b837d commit 5d261e8
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 25 deletions.
7 changes: 7 additions & 0 deletions DOCS/interface-changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand Down
2 changes: 2 additions & 0 deletions DOCS/man/mpv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 19 additions & 11 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.

Expand Down Expand Up @@ -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``).
Expand Down Expand Up @@ -6775,16 +6779,20 @@ 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.

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
-------------

Expand Down
1 change: 1 addition & 0 deletions common/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
8 changes: 5 additions & 3 deletions demux/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion options/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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";

Expand All @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions osdep/path-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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]) {
Expand All @@ -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';
}
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions osdep/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions video/out/gpu/lcms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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]);
Expand Down Expand Up @@ -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}
},
Expand Down
1 change: 1 addition & 0 deletions video/out/gpu/lcms.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion video/out/gpu/shader_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion video/out/gpu/shader_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
4 changes: 3 additions & 1 deletion video/out/gpu/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)},
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions video/out/gpu/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 14 additions & 4 deletions video/out/vo_gpu_next.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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];
Expand All @@ -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;
Expand Down

0 comments on commit 5d261e8

Please sign in to comment.