summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2026-07-02 17:52:27 -0400
committerAndrew Opalach <andrew@akon.city> 2026-07-02 17:52:27 -0400
commit34933b7e1d682e67702999270cd3ceec0e167316 (patch)
treea6777f793fe658ad0facb85876e41cb66dbec2c2
parentef3f687db0f53f026e808c4284e084255c9e9dd5 (diff)
downloadcamu-34933b7e1d682e67702999270cd3ceec0e167316.tar.gz
camu-34933b7e1d682e67702999270cd3ceec0e167316.tar.bz2
camu-34933b7e1d682e67702999270cd3ceec0e167316.zip
Update deps, build fixes, cleanup
Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--flake.lock52
-rw-r--r--flake.nix28
-rwxr-xr-xscripts/run_blit_mode.bat6
-rwxr-xr-xscripts/run_flip_mode.bat7
-rwxr-xr-xscripts/shaderc_deps.sh8
-rw-r--r--src/buffer/audio.c8
-rw-r--r--src/fruits/cmv/cmv.c22
-rw-r--r--src/libsink/desktop.c2
-rw-r--r--src/libsink/sink.c33
-rw-r--r--src/render/meson.build1
-rw-r--r--src/render/renderer_libplacebo.c30
-rw-r--r--src/screen/screen.c18
-rw-r--r--src/util/color_palette.c2
-rw-r--r--src/util/color_palette.h2
-rw-r--r--subprojects/ffmpeg8.wrap20
-rw-r--r--subprojects/harfbuzz.wrap4
-rw-r--r--subprojects/libass.wrap4
-rw-r--r--subprojects/libplacebo.wrap4
-rw-r--r--subprojects/packagefiles/ffmpeg/meson.build6
-rw-r--r--subprojects/packagefiles/ffmpeg/version_3.3.9.diff39
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.1.1.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.1.2.diff29
-rw-r--r--subprojects/packagefiles/shaderc/spirv_tools_build_version.diff21
-rw-r--r--subprojects/shaderc.wrap4
-rw-r--r--subprojects/stela.wrap4
25 files changed, 249 insertions, 134 deletions
diff --git a/flake.lock b/flake.lock
index a168825..649ed7d 100644
--- a/flake.lock
+++ b/flake.lock
@@ -41,11 +41,11 @@
]
},
"locked": {
- "lastModified": 1776009237,
- "narHash": "sha256-HdeQqwvp3VKcJaKxF1Mh/FUzVM2Up+neOLWbpNrB578=",
+ "lastModified": 1782749631,
+ "narHash": "sha256-slFTUgDy0KTPA4LBAmC/9SngDq8GCPdX+ZR0yQHHN1E=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "30ca31c87a9bfa2c1315330f977ff63356907453",
+ "rev": "5d72a29fc36ac21adae6ae35568fe5ee6700850f",
"type": "github"
},
"original": {
@@ -75,12 +75,15 @@
}
},
"nixos-hardware": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_2"
+ },
"locked": {
- "lastModified": 1775490113,
- "narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=",
+ "lastModified": 1782562157,
+ "narHash": "sha256-a7+T6QSeowynwZ1ZJJbP8T8ntAytvrui8kFGJmIZt2c=",
"owner": "NixOS",
"repo": "nixos-hardware",
- "rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7",
+ "rev": "a9cf7546a938c737b079e738de73934a13de9784",
"type": "github"
},
"original": {
@@ -93,14 +96,14 @@
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat",
- "nixpkgs": "nixpkgs_2"
+ "nixpkgs": "nixpkgs_3"
},
"locked": {
- "lastModified": 1774972752,
- "narHash": "sha256-DnLIpFxznohpLkIFs390uZ0gxwkVyhtknhKNu+lQJK8=",
+ "lastModified": 1781182279,
+ "narHash": "sha256-V5EQQbDnmdiXGQXrEF1PEL7QYsFqfH8N1E89Z5ONwFk=",
"owner": "nix-community",
"repo": "NixOS-WSL",
- "rev": "d97e078f4788cddb8d11c3c99f72a4bb9ddec221",
+ "rev": "5675822ba756e6e56f8f6a5a76e90e0da2ece94d",
"type": "github"
},
"original": {
@@ -127,11 +130,24 @@
},
"nixpkgs_2": {
"locked": {
- "lastModified": 1773734432,
- "narHash": "sha256-IF5ppUWh6gHGHYDbtVUyhwy/i7D261P7fWD1bPefOsw=",
+ "lastModified": 1767892417,
+ "narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
+ "rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
+ "type": "tarball",
+ "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
+ }
+ },
+ "nixpkgs_3": {
+ "locked": {
+ "lastModified": 1780243769,
+ "narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "cda48547b432e8d3b18b4180ba07473762ec8558",
+ "rev": "331800de5053fcebacf6813adb5db9c9dca22a0c",
"type": "github"
},
"original": {
@@ -141,13 +157,13 @@
"type": "github"
}
},
- "nixpkgs_3": {
+ "nixpkgs_4": {
"locked": {
- "lastModified": 1775710090,
- "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
+ "lastModified": 1782723713,
+ "narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "4c1018dae018162ec878d42fec712642d214fdfa",
+ "rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
"type": "github"
},
"original": {
@@ -163,7 +179,7 @@
"nixgl": "nixgl",
"nixos-hardware": "nixos-hardware",
"nixos-wsl": "nixos-wsl",
- "nixpkgs": "nixpkgs_3"
+ "nixpkgs": "nixpkgs_4"
}
},
"systems": {
diff --git a/flake.nix b/flake.nix
index a568246..19e5520 100644
--- a/flake.nix
+++ b/flake.nix
@@ -22,7 +22,7 @@
overlays = [
(self: super: {
libplacebo = super.libplacebo.overrideAttrs (oldAttrs: {
- patches = oldAttrs.patches ++ [
+ patches = [
./subprojects/packagefiles/libplacebo/cache_ref_rect.diff
./subprojects/packagefiles/libplacebo/fix_rotate.diff
./subprojects/packagefiles/libplacebo/glClientWaitSync_0_return.diff
@@ -110,7 +110,6 @@
'';
sha256 = "eHLMUqX7jDWoGsz5Coz8FU9b4MCtS+ZCJcPpYjPiDIQ=";
};
- nvidia-support = false;
sources = [ "file" "http" "cdio" ];
codecs = [ "ffmpeg" ];
window = "wayland";
@@ -123,6 +122,7 @@
"-Dtests=disabled"
"-Drelease-asserts=false"
];
+ nvidia-support = false;
fixupPhase = if nvidia-support then ''
wrapProgram $out/bin/cmv --set XDG_DATA_DIRS "${pkgs.mesa}/share:${pkgs.linuxPackages.nvidia_x11}/share" --set __EGL_VENDOR_LIBRARY_DIRS "${pkgs.mesa}/share/glvnd/egl_vendor.d:${pkgs.linuxPackages.nvidia_x11}/share/glvnd/egl_vendor.d"
'' else ''
@@ -162,7 +162,7 @@
alsa-lib
libpulseaudio
libplacebo
- xxHash
+ xxhash
lcms
libdovi
notcurses
@@ -216,7 +216,7 @@
};
# https://cryptoisland.blog/posts/2024/12/09/flake-based-recipe-for-offline-dev-shells-in-nixos/
shellWrapper = with pkgs; let
- shell = devShells.${system}.default;
+ shell = devShells.${stdenv.hostPlatform.system}.default;
in pkgs.writeScriptBin "camu-devshell" ''
export PATH=${pkgs.lib.makeBinPath shell.nativeBuildInputs}:$PATH
export PKG_CONFIG_PATH=${pkgs.lib.makeSearchPathOutput "dev" "lib/pkgconfig" shell.buildInputs}:$PKG_CONFIG_PATH
@@ -230,7 +230,7 @@
devShells = forAllDevSystems (pkgs: rec {
default = with pkgs; mkShell rec {
NIX_HARDENING_ENABLE = "";
- nativeBuildInputs = packages.${system}.default.nativeBuildInputs ++ [
+ nativeBuildInputs = packages.${stdenv.hostPlatform.system}.default.nativeBuildInputs ++ [
gdb
clang-analyzer
perf-tools
@@ -278,7 +278,7 @@
#lollypop
#xfce.parole
];
- buildInputs = packages.${system}.default.buildInputs ++ [
+ buildInputs = packages.${stdenv.hostPlatform.system}.default.buildInputs ++ [
# glfw3 build
xinput
libXinerama
@@ -301,7 +301,7 @@
# libva from Nix.
export LIBVA_DRIVERS_PATH="${pkgs.mesa}/lib/dri"
export NIX_BUILD_SHELL=$SHELL
- export NIX_SHELL="camu-${system}+dev"
+ export NIX_SHELL="camu-${stdenv.hostPlatform.system}+dev"
export PS1="(\$NIX_SHELL)"$PS1
echo -en '\033]2;'nix-shell: $NIX_SHELL'\007'
'';
@@ -309,17 +309,17 @@
buildtest = with pkgs; mkShell {
NIX_HARDENING_ENABLE = "";
- nativeBuildInputs = packages.${system}.default.nativeBuildInputs ++ [
+ nativeBuildInputs = packages.${stdenv.hostPlatform.system}.default.nativeBuildInputs ++ [
gdb
clang-analyzer
perf-tools
valgrind
];
- buildInputs = packages.${system}.default.buildInputs;
+ buildInputs = packages.${stdenv.hostPlatform.system}.default.buildInputs;
shellHook = ''
export SHELL="${pkgs.bashInteractive}/bin/bash"
export NIX_BUILD_SHELL=$SHELL
- export NIX_SHELL="camu-${system}"
+ export NIX_SHELL="camu-${stdenv.hostPlatform.system}"
export PS1="(\$NIX_SHELL)"$PS1
'';
};
@@ -375,7 +375,7 @@
glslang
];
buildInputs = with pkgsCross.ucrt64; [
- zlib.static
+ (zlib.override { shared = false; })
(bzip2.override { enableStatic = true; enableShared = false; })
(soxr.overrideAttrs (oldAttrs: {
cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ];
@@ -384,7 +384,7 @@
mesonFlags = oldAttrs.mesonFlags ++ [ "--default-library=static" ];
}))
(openssl.override { static = true; })
- xxHash
+ xxhash
(libiconv.override { enableStatic = true; enableShared = false; })
vulkan-headers
#(shaderc.overrideAttrs (oldAttrs: {
@@ -420,13 +420,13 @@
NIX_HARDENING_ENABLE = "";
nativeBuildInputs = mingw64.nativeBuildInputs;
buildInputs = with pkgsCross.mingw32; [
- (buildWithFlags zlib.static "-Os")
+ (buildWithFlags (zlib.override { shared = false; }) "-Os")
((buildWithFlags bzip2 "-Os").override { enableStatic = true; enableShared = false; })
((buildWithFlags soxr "-Os").overrideAttrs (oldAttrs: {
cmakeFlags = oldAttrs.cmakeFlags ++ [ "-DBUILD_STATIC_LIBS=ON" "-DBUILD_SHARED_LIBS=OFF" ];
}))
((buildWithFlags openssl "-Os").override { static = true; })
- (buildWithFlags xxHash "-Os")
+ (buildWithFlags xxhash "-Os")
((buildWithFlags libiconv "-Os").override { enableStatic = true; enableShared = false; })
vulkan-headers
];
diff --git a/scripts/run_blit_mode.bat b/scripts/run_blit_mode.bat
index 8467e5d..c314a2f 100755
--- a/scripts/run_blit_mode.bat
+++ b/scripts/run_blit_mode.bat
@@ -1,3 +1,5 @@
+@echo off
set SINK_DXGI_FLIP=0
-set /p code=<host_code
-.\sink-d-%code%.exe \ No newline at end of file
+set SINK_DIR=%~dp0
+set /p code=<%SINK_DIR%\host_code
+%SINK_DIR%\sink-d-%code%.exe %* \ No newline at end of file
diff --git a/scripts/run_flip_mode.bat b/scripts/run_flip_mode.bat
index e6e9f31..c9e2c3c 100755
--- a/scripts/run_flip_mode.bat
+++ b/scripts/run_flip_mode.bat
@@ -1,3 +1,6 @@
+@echo off
set SINK_DXGI_FLIP=1
-set /p code=<host_code
-.\sink-d-%code%.exe \ No newline at end of file
+set SINK_FORCE_LOCAL=1
+set SINK_DIR=%~dp0
+set /p code=<%SINK_DIR%\host_code
+%SINK_DIR%\sink-d-%code%.exe %* \ No newline at end of file
diff --git a/scripts/shaderc_deps.sh b/scripts/shaderc_deps.sh
index 89aaf38..c9c793f 100755
--- a/scripts/shaderc_deps.sh
+++ b/scripts/shaderc_deps.sh
@@ -2,17 +2,19 @@
# We need a better way to do this.
+# https://github.com/google/shaderc/blob/known-good/known_good.json
+
git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
cd spirv-tools
-git checkout fbe4f3ad913c44fe8700545f8ffe35d1382b7093
+git checkout c1cb30bb04e2bf911755a40df1242cc6e3d83e26
cd ../
git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers
cd spirv-headers
-git checkout 04f10f650d514df88b76d25e83db360142c7b174
+git checkout ad9184e76a66b1001c29db9b0a3e87f646c64de0
cd ../
git clone https://github.com/KhronosGroup/glslang.git glslang
cd glslang
-git checkout f0bd0257c308b9a26562c1a30c4748a0219cc951
+git checkout 5ed4003a18a10a9d1bd7e43aaf1664499abffa83
cd ../
diff --git a/src/buffer/audio.c b/src/buffer/audio.c
index 7c10dda..a815c66 100644
--- a/src/buffer/audio.c
+++ b/src/buffer/audio.c
@@ -145,8 +145,8 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32
}
}
- if (base_pts == -1.0) {
- // We want this push() to set the pts even if sample_count = 0.
+ if (base_pts == -1.0) { // This push() has to set buf->pts even if sample_count = 0.
+ al_assert(!buf->buffered);
atomic_store(f64)(&buf->pts, pts, AL_ATOMIC_RELEASE);
}
@@ -478,8 +478,8 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
}
out:
- // We aren't safe to increment buf->pts from a different thread.
- // For that we could accumulate the difference and atomic_add here instead.
+ // Updating buf->pts from the read() thread has to be done in a single step.
+ // atomic_add() at the points where base_pts is incremented would be incorrect.
atomic_store(f64)(&buf->pts, base_pts, AL_ATOMIC_RELEASE);
// To signal EOF, return less then req.
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 6fe0790..a525377 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -121,19 +121,12 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
camu_ff_common_init();
#endif
- char *home_env = getenv("HOME");
- if (home_env) {
- str color_palette;
- al_str_from(&color_palette, home_env);
- al_str_cat(&color_palette, &al_str_c("/.config/colors.json"));
- camu_color_palette_init(&color_palette);
- al_str_free(&color_palette);
- }
+ s32 ret = EXIT_SUCCESS;
nn_event_loop_init(&c.loop);
u8 type;
- str addr;
+ str addr = al_str_null();
if (local) {
#ifdef NAUNET_ON_WINDOWS
type = NNWT_SOCKET_TCP;
@@ -170,8 +163,6 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
prefs->language.audio = CAMU_LANG_JAPANESE;
prefs->language.subtitles = CAMU_LANG_ENGLISH;
- s32 ret = EXIT_SUCCESS;
-
#ifndef CAMU_SINK_ONLY
if (local) {
camu_server_init(&c.server, &c.loop);
@@ -186,6 +177,15 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
}
#endif
+ char *home_env = getenv("HOME");
+ if (home_env) {
+ str color_palette;
+ al_str_from(&color_palette, home_env);
+ al_str_cat(&color_palette, &al_str_c("/.config/colors.json"));
+ camu_colors_maybe_init(&color_palette);
+ al_str_free(&color_palette);
+ }
+
str window_name;
al_str_from(&window_name, "Sink (");
if (local) {
diff --git a/src/libsink/desktop.c b/src/libsink/desktop.c
index ccc34a3..e9ccedb 100644
--- a/src/libsink/desktop.c
+++ b/src/libsink/desktop.c
@@ -256,7 +256,7 @@ bool camu_desktop_connect(struct camu_desktop *c, str *name, struct nn_event_loo
bool camu_desktop_tick(struct camu_desktop *c)
{
bool force;
- if (camu_screen_tick(&c->scr, &force) && !c->should_quit) {
+ if (!c->should_quit && camu_screen_tick(&c->scr, &force)) {
if (!c->renderer->render(c->renderer, &c->scr, force)) {
log_error("render() failed, forcing exit.");
c->should_quit = 1;
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 6c061a5..783f242 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -65,7 +65,7 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
// Store connection number in the upper 16 bits so IDs don't conflict after a server restart.
// If the sink disconnects but the server didn't restart, this will invalidate IDs that _do_ map
// to the same resource. That could be wasteful. It's also currently (ab)used by reseek().
-#define LOCAL_ENTRY_ID(sink, id) (((u64)(sink)->connection_number) << 48 | (u64)(id))
+#define LOCAL_ENTRY_ID(sink, id) (((u64)(sink)->connection_number) << 48 | (u64)(id)) // id is a u32.
#define REMOTE_ENTRY_ID(id) ((u32)(id & 0x7fffffff))
#define CONNECTION_NUMBER(id) ((id >> 48) & 0xffff)
@@ -73,13 +73,8 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
#define ENTRY_IS_VALID(entry) ((entry) && (entry) != (struct camu_sink_entry *)0xb00b)
// printf format for entries.
-#ifdef AL_DEBUG
-#define ENTRY_FMT "#%u(%p)" // @TODO: Put static and ended here at least.
-#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0), ((entry) ? (entry) : 0x0)
-#else
-#define ENTRY_FMT "#%u"
-#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0)
-#endif
+#define ENTRY_FMT "#%u(%p)"
+#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0), (entry)
#define AUDIO_STATE(entry) ((entry)->audio.state)
#define VIDEO_STATE(entry) ((entry)->video.state)
@@ -100,6 +95,7 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
#define ENTRY_EVAL_ENDED(entry) \
((AUDIO_ENDED(entry) && (VIDEO_ENDED(entry) || VIDEO_EMPTY(entry) || VIDEO_IS_STATIC(entry))) || \
(AUDIO_EMPTY(entry) && VIDEO_ENDED(entry)))
+// This assert would fail if using ENTRY_ENDED() in end_entry_and_advance_queue() before setting entry->ended.
#define ENTRY_ENDED(entry) (al_assert(entry->ended == ENTRY_EVAL_ENDED(entry)), entry->ended)
// IGNORED = ENDED or EMPTY.
@@ -921,16 +917,18 @@ static void evaluate_and_set_buffer_params(struct camu_sink *sink, struct camu_s
camu_audio_buffer_set_latency(&entry->audio.buf, audio);
camu_audio_buffer_set_no_video(&entry->audio.buf, ignore_video);
camu_video_buffer_set_latency(&entry->video.buf, video);
- log_info("video_latency: %f (%u frames), audio_latency: %f.", video, frames, audio);
+ log_info("video_latency: %fs (%u frames), audio_latency: %fs.", video, frames, audio);
if (sink->local) {
camu_audio_buffer_set_ignore_desync(&entry->audio.buf, ignore_video);
// When the video buffer starts the clock, we have to consider the audio
- // buffer is treating the last period of silence sent during a paused clock
+ // buffer is treating the last period of silence sent while the clock was paused
// as part of the stream. This poses an issue for sync because it requires more
- // than a period-length offset to not skip data at the start. Combined with the
- // fact that the timing of a request for the next period doesn't have be uniform.
- // Could make a diagram of this. // @TODO
- camu_clock_offset(&entry->clock, MAX(audio, video));
+ // than a period-length offset to not skip audio data at the start of the stream.
+ // Combined with the fact that the timing of a request for the next period
+ // doesn't have to be uniform. Something that is expected behavior but becomes
+ // a consideration when thinking about "Has the clock started yet?".
+ // @TODO: Could make a diagram of this.
+ camu_clock_offset(&entry->clock, MAX(audio, video) * 1.25);
}
}
@@ -1053,10 +1051,11 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
case LIANA_CLIENT_REMOVE_BUFFERS: {
struct lia_reconnect_info *rec = (struct lia_reconnect_info *)opaque;
nn_mutex_lock(&sink->lock);
+
log_trace("remove_buffers("ENTRY_FMT", %s, %s), entry == current: %s, static: %s.",
- ENTRY_ARG(entry), BOOLSTR(rec->reconnect),
- BOOLSTR(rec->unconfigured), BOOLSTR(entry == sink->current),
- BOOLSTR(!VIDEO_EMPTY(entry) ? VIDEO_IS_STATIC(entry) : false));
+ ENTRY_ARG(entry), BOOLSTR(rec->reconnect), BOOLSTR(rec->unconfigured),
+ BOOLSTR(entry == sink->current),
+ BOOLSTR(!VIDEO_EMPTY(entry) && VIDEO_IS_STATIC(entry)));
if (entry == sink->current) {
if (rec->reconnect) {
diff --git a/src/render/meson.build b/src/render/meson.build
index 10cb98e..44d8255 100644
--- a/src/render/meson.build
+++ b/src/render/meson.build
@@ -179,6 +179,7 @@ if get_option('subtitles').enabled()
'chafa=disabled',
'icu=disabled',
'freetype=disabled',
+ 'gpu=disabled',
# This does not override yield, and yielding breaks the build if tests=enabled.
# https://github.com/mesonbuild/meson/issues/5214
'tests=disabled',
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 80a71a6..704aebe 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -15,7 +15,7 @@
#ifdef AL_DEBUG
// vkQueueSubmit2: VK_ERROR_VALIDATION_FAILED_EXT leads to an annoying deadlock.
-#define RENDERER_DEBUG 0
+#define RENDERER_DEBUG 1
#else
#define RENDERER_DEBUG 0
#endif
@@ -433,7 +433,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
enum {
RESULT_SUBMIT = 1,
- RESULT_SUBMIT_AND_WAIT = 1 << 1
+ RESULT_WAIT = 1 << 1
};
u8 result = 0;
@@ -447,8 +447,8 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
if (camu_video_buffer_read(video->buf, &mix, &weighted)) {
// If mix.frames is NULL, read() returned QUEUE_MORE.
if (mix.frames) {
- // weighted is only set when read() returns QUEUE_OK.
- result |= (1 | 1 << weighted);
+ // weighted can only be set when read() returns QUEUE_OK.
+ result |= (RESULT_SUBMIT | (RESULT_WAIT * weighted));
// Terrible hack. Lets us distinguish static video buffers with the same dimensions.
// Tied to a libplacebo patch to consider info_priv in the hash.
intptr_t hash = (intptr_t)video->buf;
@@ -493,9 +493,15 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
*/
#ifdef CRT_BACKGROUND
if (!lr->frame_cleared) {
- clear_color[0] = 0.03f;
- clear_color[1] = 0.03f;
- clear_color[2] = 0.03f;
+ if (lr->params.background != PL_CLEAR_SKIP) {
+ clear_color[0] = 0.025f;
+ clear_color[1] = 0.025f;
+ clear_color[2] = 0.025f;
+ } else {
+ clear_color[0] = 0.f;
+ clear_color[1] = 0.f;
+ clear_color[2] = 0.f;
+ }
pl_frame_clear_rgba(lr->gpu, &lr->target, clear_color);
lr->frame_cleared = true;
}
@@ -554,7 +560,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
log_trace("swap_buffers(), (interval: %f).", tick - lr->last_swap_tick);
lr->last_swap_tick = tick;
- if (result & RESULT_SUBMIT_AND_WAIT) {
+ if (result & RESULT_WAIT) {
pl_gpu_finish(lr->gpu);
}
@@ -564,6 +570,10 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
void renderer_lp_free(struct camu_renderer **renderer)
{
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)*renderer;
+#ifdef CAMU_HAVE_SUBTITLES
+ if (lr->ass) ass_library_done(lr->ass);
+#endif
+ if (lr->vr_emulation_hook[0]) pl_mpv_user_shader_destroy(&lr->vr_emulation_hook[0]);
if (lr->renderer) pl_renderer_destroy(&lr->renderer);
if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain);
#if defined STELA_API_VULKAN
@@ -578,10 +588,6 @@ void renderer_lp_free(struct camu_renderer **renderer)
if (lr->gl) pl_opengl_destroy(&lr->gl);
#endif
if (lr->logger) pl_log_destroy(&lr->logger);
- if (lr->vr_emulation_hook[0]) pl_mpv_user_shader_destroy(&lr->vr_emulation_hook[0]);
-#ifdef CAMU_HAVE_SUBTITLES
- if (lr->ass) ass_library_done(lr->ass);
-#endif
al_free(lr);
*renderer = NULL;
}
diff --git a/src/screen/screen.c b/src/screen/screen.c
index cdc42bf..ff36fe1 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -215,8 +215,12 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
if (x >= third && x <= third * 2.0) {
scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
} else {
- s32 n = (x >= third) ? 1 : -1;
- scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
+ if (scr->touch_mode) {
+ scr->subtitles_enabled = !scr->subtitles_enabled;
+ } else {
+ s32 n = (x >= third) ? 1 : -1;
+ scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
+ }
}
}
}
@@ -605,9 +609,8 @@ static nn_thread_result NNWT_THREADCALL event_thread(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
nn_thread_set_name("window_events");
- // If we decide to close within a poll, we must not expect any
- // window events after that point.
- while (scr->window->poll(scr->window, true)) {
+ while (!scr->window->closed) {
+ scr->window->poll(scr->window, true);
scr->window->process_events(scr->window);
}
return 0;
@@ -832,9 +835,8 @@ bool camu_screen_poll(struct camu_screen *scr, bool block)
}
stl_window_read_events(scr->window);
#else
- if (scr->window->poll(scr->window, block)) {
- scr->window->process_events(scr->window);
- }
+ scr->window->poll(scr->window, block);
+ scr->window->process_events(scr->window);
#endif
#ifdef STELA_PAUSE
return scr->window->should_refresh(scr->window);
diff --git a/src/util/color_palette.c b/src/util/color_palette.c
index bd923e8..f12d1f8 100644
--- a/src/util/color_palette.c
+++ b/src/util/color_palette.c
@@ -34,7 +34,7 @@ static char *normal_colors[16] = {
};
#endif
-bool camu_color_palette_init(str *path)
+bool camu_colors_maybe_init(str *path)
{
#ifdef NAUNET_HAS_JSON
struct nn_file file;
diff --git a/src/util/color_palette.h b/src/util/color_palette.h
index a71360c..7330135 100644
--- a/src/util/color_palette.h
+++ b/src/util/color_palette.h
@@ -32,4 +32,4 @@ struct camu_color_palette {
extern struct camu_color_palette global_color_palette;
-bool camu_color_palette_init(str *path);
+bool camu_colors_maybe_init(str *path);
diff --git a/subprojects/ffmpeg8.wrap b/subprojects/ffmpeg8.wrap
index 0845c5e..f8ee90f 100644
--- a/subprojects/ffmpeg8.wrap
+++ b/subprojects/ffmpeg8.wrap
@@ -1,13 +1,23 @@
[wrap-file]
#directory = ffmpeg-8.0.1
-directory = ffmpeg-8.1
+#directory = ffmpeg-8.1
+#directory = ffmpeg-8.1.1
+directory = ffmpeg-8.1.2
#source_url = https://ffmpeg.org/releases/ffmpeg-8.0.1.tar.gz
-source_url = https://ffmpeg.org/releases/ffmpeg-8.1.tar.gz
+#source_url = https://ffmpeg.org/releases/ffmpeg-8.1.tar.gz
+#source_url = https://ffmpeg.org/releases/ffmpeg-8.1.1.tar.gz
+source_url = https://ffmpeg.org/releases/ffmpeg-8.1.2.tar.gz
#source_filename = ffmpeg-8.0.1.tar.gz
-source_filename = ffmpeg-8.1.tar.gz
+#source_filename = ffmpeg-8.1.tar.gz
+#source_filename = ffmpeg-8.1.1.tar.gz
+source_filename = ffmpeg-8.1.2.tar.gz
#source_hash = ed1cfade43aab7711c88937a0afc15b7b22efdc528c6ff074b4027c55a3c175c
-source_hash = b13510e7a6a4ca28fa04307f2be54ef5a31e168eb2bbe055a7f4e4d2cadd51b1
+#source_hash = b13510e7a6a4ca28fa04307f2be54ef5a31e168eb2bbe055a7f4e4d2cadd51b1
+#source_hash = 1b856f26a07082b6879f3e5300d81e8c7ce3b410ade5898b14382d90c2904634
+source_hash = 32faba5ef67340d54724941eae1425580791195312a4fd13bf6f820a2818bf22
patch_directory = ffmpeg
#diff_files = ffmpeg/version_8.0.1.diff, ffmpeg/msvc_build_conform.diff
-diff_files = ffmpeg/version_8.1.diff
+#diff_files = ffmpeg/version_8.1.diff
+#diff_files = ffmpeg/version_8.1.1.diff
+diff_files = ffmpeg/version_8.1.2.diff
diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap
index 55964d7..07c333c 100644
--- a/subprojects/harfbuzz.wrap
+++ b/subprojects/harfbuzz.wrap
@@ -1,5 +1,5 @@
[wrap-git]
-directory = harfbuzz-14.1.0
+directory = harfbuzz-14.2.1
url = https://github.com/harfbuzz/harfbuzz.git
-revision = 14.1.0
+revision = 14.2.1
depth = 1
diff --git a/subprojects/libass.wrap b/subprojects/libass.wrap
index fa50802..2b9ecdd 100644
--- a/subprojects/libass.wrap
+++ b/subprojects/libass.wrap
@@ -1,6 +1,6 @@
[wrap-git]
-directory = libass-0.17.4
+directory = libass-0.17.5
url = https://github.com/libass/libass.git
-revision = 0.17.4
+revision = 0.17.5
clone-recursive = true
depth = 1
diff --git a/subprojects/libplacebo.wrap b/subprojects/libplacebo.wrap
index b0575cf..a16dd82 100644
--- a/subprojects/libplacebo.wrap
+++ b/subprojects/libplacebo.wrap
@@ -1,7 +1,7 @@
[wrap-git]
-directory = libplacebo-54e5275
+directory = libplacebo-05ac2cc
url = https://code.videolan.org/videolan/libplacebo.git
-revision = 54e527552fa74467bcc7692e6985d35540861d19
+revision = 05ac2cca6571c04d06369a26825d207781b73f32
clone-recursive = true
depth = 1
diff --git a/subprojects/packagefiles/ffmpeg/meson.build b/subprojects/packagefiles/ffmpeg/meson.build
index 36bae60..7481dea 100644
--- a/subprojects/packagefiles/ffmpeg/meson.build
+++ b/subprojects/packagefiles/ffmpeg/meson.build
@@ -107,10 +107,10 @@ if ffmpeg_image_codecs
zlib = dependency('zlib', required: false)
if zlib.found()
extra_options += ['--enable-zlib']
- decoders += ',png,apng,mjpeg,jpeg2000,webp,gif,'
+ decoders += ',png,apng,mjpeg,jpeg2000,webp,gif,psd'
if not get_option('sink-only')
- demuxers += ',image_png_pipe,image2,mjpeg,image2pipe,image_jpeg_pipe,image_webp_pipe,gif'
- parsers += ',png,mjpeg,jpeg2000,webp,gif'
+ demuxers += ',image_png_pipe,image2,mjpeg,image2pipe,image_jpeg_pipe,image_webp_pipe,gif,image_psd_pipe'
+ parsers += ',png,mjpeg,jpeg2000,webp,gif,psd'
endif
deps += [zlib]
else
diff --git a/subprojects/packagefiles/ffmpeg/version_3.3.9.diff b/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
index 90911d5..7e91e5d 100644
--- a/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
+++ b/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2025-11-30 11:51:43.747121512 -0500
-+++ b/meson.build 2025-11-30 12:55:07.519116860 -0500
+--- a/meson.build 2026-07-02 16:36:02.258920727 -0400
++++ b/meson.build 2026-07-02 16:49:06.795636508 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '3.3.9', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -35,10 +35,6 @@
+@@ -40,10 +40,6 @@
extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')]
endif
@@ -17,27 +17,22 @@
extra_options += ['--enable-static', '--disable-shared']
if is_windows
-@@ -68,18 +64,7 @@
- decoders += ',dca,eac3'
+@@ -74,14 +70,6 @@
decoders += ',pcm_dvd,mpegvideo,mpeg2video'
+ decoders += ',av1'
#decoders += ',ass,srt'
--if get_option('codec-hwaccels').length() == 0
-- if not is_msvc
-- libdav1d = dependency('dav1d', required: false)
-- if libdav1d.found()
-- decoders += ',libdav1d'
-- extra_options += ['--enable-libdav1d']
-- deps += [libdav1d]
-- endif
+-#if get_option('codec-hwaccels').length() == 0
+- libdav1d = dependency('dav1d', required: false)
+- if libdav1d.found()
+- decoders += ',libdav1d'
+- extra_options += ['--enable-libdav1d']
+- deps += [libdav1d]
- endif
--else
-- decoders += ',av1'
--endif
-+decoders += ',av1'
+-#endif
demuxers = ''
parsers = ''
-@@ -195,12 +180,8 @@
+@@ -197,12 +185,8 @@
# Disable unused hwaccels.
extra_options += [
@@ -50,7 +45,7 @@
'--disable-nvenc',
'--disable-vdpau',
'--disable-audiotoolbox',
-@@ -243,6 +224,15 @@
+@@ -245,6 +229,15 @@
args += ['-DCAMU_HAVE_SOXR']
endif
@@ -66,7 +61,7 @@
ext_proj = import('unstable-external_project')
proj = ext_proj.add_project('configure',
-@@ -252,7 +242,6 @@
+@@ -254,7 +247,6 @@
'--incdir=@PREFIX@/@INCLUDEDIR@',
'--enable-pic',
'--disable-all',
@@ -74,7 +69,7 @@
'--disable-everything',
'--disable-programs',
'--disable-doc',
-@@ -277,11 +266,14 @@
+@@ -279,11 +271,14 @@
'--enable-swscale',
'--disable-indevs',
'--disable-outdevs',
@@ -89,7 +84,7 @@
avutil = proj.dependency('avutil')
avformat = proj.dependency('avformat')
avcodec = proj.dependency('avcodec')
-@@ -290,14 +282,14 @@
+@@ -292,14 +287,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_8.1.1.diff b/subprojects/packagefiles/ffmpeg/version_8.1.1.diff
new file mode 100644
index 0000000..8976dd2
--- /dev/null
+++ b/subprojects/packagefiles/ffmpeg/version_8.1.1.diff
@@ -0,0 +1,29 @@
+--- a/meson.build 2025-08-23 18:44:34.634014892 -0400
++++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
+@@ -1,4 +1,4 @@
+-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
++project('ffmpeg', 'c', version: '8.1.1', meson_version: '>=0.57.0')
+
+ compiler = meson.get_compiler('c')
+
+@@ -268,14 +268,14 @@
+ swscale = proj.dependency('swscale')
+ include = include_directories('.', 'build/')
+ meson.override_dependency('libavutil', declare_dependency(
+- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
++ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.26.101'))
+ meson.override_dependency('libavformat', declare_dependency(
+- dependencies: [avformat], include_directories: include, version: ''))
++ dependencies: [avformat], include_directories: include, version: '62.12.101'))
+ meson.override_dependency('libavcodec', declare_dependency(
+- dependencies: [avcodec], include_directories: include, version: ''))
++ dependencies: [avcodec], include_directories: include, version: '62.28.101'))
+ meson.override_dependency('libavdevice', declare_dependency(
+- dependencies: [avdevice], include_directories: include, version: ''))
++ dependencies: [avdevice], include_directories: include, version: '62.3.101'))
+ meson.override_dependency('libswresample', declare_dependency(
+- dependencies: [swresample], include_directories: include, version: ''))
++ dependencies: [swresample], include_directories: include, version: '6.3.101'))
+ meson.override_dependency('libswscale', declare_dependency(
+- dependencies: [swscale], include_directories: include, version: ''))
++ dependencies: [swscale], include_directories: include, version: '9.5.101'))
diff --git a/subprojects/packagefiles/ffmpeg/version_8.1.2.diff b/subprojects/packagefiles/ffmpeg/version_8.1.2.diff
new file mode 100644
index 0000000..e1b52a4
--- /dev/null
+++ b/subprojects/packagefiles/ffmpeg/version_8.1.2.diff
@@ -0,0 +1,29 @@
+--- a/meson.build 2025-08-23 18:44:34.634014892 -0400
++++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
+@@ -1,4 +1,4 @@
+-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
++project('ffmpeg', 'c', version: '8.1.2', meson_version: '>=0.57.0')
+
+ compiler = meson.get_compiler('c')
+
+@@ -268,14 +268,14 @@
+ swscale = proj.dependency('swscale')
+ include = include_directories('.', 'build/')
+ meson.override_dependency('libavutil', declare_dependency(
+- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
++ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.26.102'))
+ meson.override_dependency('libavformat', declare_dependency(
+- dependencies: [avformat], include_directories: include, version: ''))
++ dependencies: [avformat], include_directories: include, version: '62.12.102'))
+ meson.override_dependency('libavcodec', declare_dependency(
+- dependencies: [avcodec], include_directories: include, version: ''))
++ dependencies: [avcodec], include_directories: include, version: '62.28.102'))
+ meson.override_dependency('libavdevice', declare_dependency(
+- dependencies: [avdevice], include_directories: include, version: ''))
++ dependencies: [avdevice], include_directories: include, version: '62.3.102'))
+ meson.override_dependency('libswresample', declare_dependency(
+- dependencies: [swresample], include_directories: include, version: ''))
++ dependencies: [swresample], include_directories: include, version: '6.3.102'))
+ meson.override_dependency('libswscale', declare_dependency(
+- dependencies: [swscale], include_directories: include, version: ''))
++ dependencies: [swscale], include_directories: include, version: '9.5.102'))
diff --git a/subprojects/packagefiles/shaderc/spirv_tools_build_version.diff b/subprojects/packagefiles/shaderc/spirv_tools_build_version.diff
new file mode 100644
index 0000000..de50787
--- /dev/null
+++ b/subprojects/packagefiles/shaderc/spirv_tools_build_version.diff
@@ -0,0 +1,21 @@
+diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
+index 8e918de0..5dbc0dd1 100644
+--- a/source/CMakeLists.txt
++++ b/source/CMakeLists.txt
+@@ -148,6 +148,7 @@ add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC}
+ DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
+ ${SPIRV_TOOLS_CHANGES_FILE}
+ COMMENT "Update build-version.inc in the SPIRV-Tools build directory (if necessary).")
++add_custom_target(build_version DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC})
+
+ list(APPEND PCH_DEPENDS
+ ${CORE_TABLES_HEADER_INC_FILE}
+@@ -334,7 +335,7 @@ function(spirv_tools_default_target_options target)
+ )
+ set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
+ spvtools_check_symbol_exports(${target})
+- add_dependencies(${target} core_tables extinst_tables)
++ add_dependencies(${target} core_tables extinst_tables build_version)
+ endfunction()
+
+ # Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
diff --git a/subprojects/shaderc.wrap b/subprojects/shaderc.wrap
index e724e01..f541df9 100644
--- a/subprojects/shaderc.wrap
+++ b/subprojects/shaderc.wrap
@@ -1,7 +1,7 @@
[wrap-git]
-directory = shaderc-v2026.1
+directory = shaderc-v2026.2
url = https://github.com/google/shaderc.git
-revision = v2026.1
+revision = v2026.2
depth = 1
method = cmake
patch_directory = shaderc
diff --git a/subprojects/stela.wrap b/subprojects/stela.wrap
index d2b9aeb..a1889c4 100644
--- a/subprojects/stela.wrap
+++ b/subprojects/stela.wrap
@@ -1,5 +1,5 @@
[wrap-git]
-directory = stela-0d027c4
+directory = stela-a35c47d
url = https://git.akon.city/stela.git
push-url = git@git.akon.city:stela.git
-revision = 0d027c466c199f9857b0872ed76ebab2ed501e43
+revision = a35c47d401335e81f25c2c78611dcb7785f703da