Files
sync_replay_project/apps/desktop/lib/src/shaders/shader_presets.dart
T
foxyzandClaude Opus 5.5 ea607c1a52
ci / core (push) Successful in 27s
ci / server (push) Successful in 1m4s
ci / updater-windows (push) Successful in 5m50s
Stabilisation quick fixes: orderly close, visible version and update band, chat pop-ups on, Windows shaders and hwdec, render logs
- Close: hide the window, dispose every player, thumbnail job and the
  sound engine, leave, then close normally; Linux runner _exit (the
  NVIDIA EGL exit handler crashed 10/10 closes, 0/41 now); Windows tears
  down inside the message loop, then TerminateProcess; watchdogs.
- Version under the Settings tab; an update band instead of a dot,
  never over a video; checks at start and every 4 hours.
- Chat pop-ups default to All again.
- Shader read-back compared as a list (old mpv joins with ','), so
  Windows stops turning shaders off; Windows hwdec auto-copy.
- Render diagnostics (`mpv: render` lines); RAM-only demuxer cache pin
  silences the file-cache warning; a volume readout test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 18:01:44 +03:00

96 lines
3.3 KiB
Dart

import 'dart:io';
// Anime4K v4.0.1 presets, file for file as in Anime4K's mpv templates
// (md/Template/GLSL_Mac_Linux_{High,Low}-end/input.conf): HQ = the
// high-end GPU set, Fast = the low-end set.
/// Anime4K release the shipped files come from (assets/shaders/anime4k).
const anime4kVersion = '4.0.1';
enum ShaderPreset {
off('Off'),
a('Mode A'),
b('Mode B'),
c('Mode C'),
aa('Mode A+A'),
bb('Mode B+B'),
ca('Mode C+A'),
custom('Custom shaders');
final String label;
const ShaderPreset(this.label);
/// The six Anime4K modes, in Ctrl+1..Ctrl+6 order.
static const modes = [a, b, c, aa, bb, ca];
bool get isAnime4k => modes.contains(this);
}
enum ShaderQuality {
hq('HQ'),
fast('Fast');
final String label;
const ShaderQuality(this.label);
}
/// "Mode A (HQ)", "Off", "Custom shaders".
String shaderLabel(ShaderPreset preset, ShaderQuality quality) =>
preset.isAnime4k ? '${preset.label} (${quality.label})' : preset.label;
const _clamp = 'Anime4K_Clamp_Highlights.glsl';
const _down = [
'Anime4K_AutoDownscalePre_x2.glsl',
'Anime4K_AutoDownscalePre_x4.glsl',
];
/// Anime4K file names of [preset] in mpv order; empty for off/custom.
List<String> anime4kFiles(ShaderPreset preset, ShaderQuality quality) {
final hq = quality == ShaderQuality.hq;
// Big/small network sizes: HQ uses VL then M, Fast uses M then S.
final big = hq ? 'VL' : 'M';
final small = hq ? 'M' : 'S';
String restore(String size) => 'Anime4K_Restore_CNN_$size.glsl';
String soft(String size) => 'Anime4K_Restore_CNN_Soft_$size.glsl';
String up(String size) => 'Anime4K_Upscale_CNN_x2_$size.glsl';
String denoise(String size) => 'Anime4K_Upscale_Denoise_CNN_x2_$size.glsl';
return switch (preset) {
ShaderPreset.off || ShaderPreset.custom => const [],
ShaderPreset.a => [_clamp, restore(big), up(big), ..._down, up(small)],
ShaderPreset.b => [_clamp, soft(big), up(big), ..._down, up(small)],
ShaderPreset.c => [_clamp, denoise(big), ..._down, up(small)],
ShaderPreset.aa => [
_clamp, restore(big), up(big), restore(small), ..._down, up(small)
],
ShaderPreset.bb => [
_clamp, soft(big), up(big), ..._down, soft(small), up(small)
],
ShaderPreset.ca => [
_clamp, denoise(big), ..._down, restore(small), up(small)
],
};
}
/// Every file some preset needs: exactly what assets/shaders/anime4k holds.
List<String> get anime4kAllFiles => {
for (final p in ShaderPreset.modes)
for (final q in ShaderQuality.values) ...anime4kFiles(p, q),
}.toList()
..sort();
/// mpv's path-list separator: ';' on Windows, ':' elsewhere.
String shaderListSeparator({bool? windows}) =>
(windows ?? Platform.isWindows) ? ';' : ':';
/// The `glsl-shaders` value for [paths].
String joinShaderPaths(List<String> paths, {bool? windows}) =>
paths.join(shaderListSeparator(windows: windows));
/// Whether mpv's read-back [got] of `glsl-shaders` is the list [paths].
/// Recent mpv prints a path list joined with [shaderListSeparator]; older
/// mpv (0.37 and before, the bundled Windows libmpv among them) joins it
/// with ','. Matched against each joined form rather than split: a path
/// may itself hold ':' (a Windows drive letter) or ','.
bool shaderListMatches(List<String> paths, String? got) =>
got != null && const [',', ';', ':'].any((sep) => paths.join(sep) == got);