mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 18:56:55 -06:00
Render: the decoded-image cache sizes from installed memory on Windows, macOS and FreeBSD
The renderers share decoded images within a budget of an eighth of the installed memory, at most 1 GiB. The installed memory was read only on Linux, so on Windows, macOS and FreeBSD the budget was always 1 GiB, also on machines with less than 8 GiB. The installed memory is now read with GlobalMemoryStatusEx on Windows (through winsafe, which vectorcraft-cli already uses), sysctl hw.memsize on macOS and sysctl hw.physmem on FreeBSD. The budget rule is unchanged: an eighth of the installed memory, at most 1 GiB, 1 GiB where the memory can't be read, and 256 MiB in the web build.
This commit is contained in:
Generated
+1
@@ -6230,6 +6230,7 @@ dependencies = [
|
||||
"vello_cpu",
|
||||
"wat",
|
||||
"weezl 0.2.1",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -29,6 +29,11 @@ log = { workspace = true }
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
vello_cpu = { workspace = true, features = ["multithreading"] }
|
||||
|
||||
# The shared image store's budget (src/images.rs) follows the installed memory, which it reads with GlobalMemoryStatusEx
|
||||
# through winsafe's safe wrappers over Win32 (MIT), which vectorcraft-cli's src/perf.rs also uses.
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winsafe = { version = "0.0.29", default-features = false, features = ["kernel"] }
|
||||
|
||||
[dev-dependencies]
|
||||
vectorcraft-testkit = { workspace = true }
|
||||
# A variable font built in code (no font file is committed).
|
||||
|
||||
@@ -31,10 +31,17 @@ fn default_budget() -> usize {
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn default_budget() -> usize {
|
||||
physical_memory().map_or(IMAGE_CACHE_MAX, |m| usize::try_from(m / 8).unwrap_or(usize::MAX).min(IMAGE_CACHE_MAX))
|
||||
physical_memory().map_or(IMAGE_CACHE_MAX, budget_for)
|
||||
}
|
||||
|
||||
/// Installed memory in bytes, where the system says without a native call (Linux).
|
||||
/// The default budget on a machine with `memory` bytes installed: an eighth of it, at most
|
||||
/// [`IMAGE_CACHE_MAX`].
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn budget_for(memory: u64) -> usize {
|
||||
usize::try_from(memory / 8).unwrap_or(usize::MAX).min(IMAGE_CACHE_MAX)
|
||||
}
|
||||
|
||||
/// Installed memory in bytes (`MemTotal` in `/proc/meminfo`).
|
||||
#[cfg(target_os = "linux")]
|
||||
fn physical_memory() -> Option<u64> {
|
||||
let info = std::fs::read_to_string("/proc/meminfo").ok()?;
|
||||
@@ -43,7 +50,28 @@ fn physical_memory() -> Option<u64> {
|
||||
kib.checked_mul(1024)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_arch = "wasm32")))]
|
||||
/// Installed memory in bytes (`GlobalMemoryStatusEx`).
|
||||
#[cfg(windows)]
|
||||
fn physical_memory() -> Option<u64> {
|
||||
winsafe::GlobalMemoryStatusEx().ok().map(|m| m.ullTotalPhys)
|
||||
}
|
||||
|
||||
/// Installed memory in bytes, as `sysctl` prints it (`hw.memsize` on macOS, `hw.physmem` on
|
||||
/// FreeBSD).
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
fn physical_memory() -> Option<u64> {
|
||||
let (sysctl, name) = if cfg!(target_os = "macos") { ("/usr/sbin/sysctl", "hw.memsize") } else { ("/sbin/sysctl", "hw.physmem") };
|
||||
let out = std::process::Command::new(sysctl).args(["-n", name]).output().ok().filter(|o| o.status.success())?;
|
||||
sysctl_bytes(&out.stdout)
|
||||
}
|
||||
|
||||
/// The byte count `sysctl -n` prints for a memory size.
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd", test))]
|
||||
fn sysctl_bytes(out: &[u8]) -> Option<u64> {
|
||||
std::str::from_utf8(out).ok()?.trim().parse().ok()
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", windows, target_os = "macos", target_os = "freebsd", target_arch = "wasm32")))]
|
||||
fn physical_memory() -> Option<u64> {
|
||||
None
|
||||
}
|
||||
@@ -330,6 +358,27 @@ mod tests {
|
||||
assert_eq!(s.bytes(), 400);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn default_budget_is_an_eighth_of_installed_memory_at_most_1_gib() {
|
||||
assert_eq!(budget_for(4 << 30), 512 << 20);
|
||||
assert_eq!(budget_for(8 << 30), IMAGE_CACHE_MAX);
|
||||
assert_eq!(budget_for(64 << 30), IMAGE_CACHE_MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", windows, target_os = "macos", target_os = "freebsd"))]
|
||||
fn installed_memory_is_read() {
|
||||
assert!(physical_memory().is_some_and(|m| m >= 256 << 20), "{:?}", physical_memory());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sysctl_prints_the_memory_size_in_bytes() {
|
||||
assert_eq!(sysctl_bytes(b"17179869184\n"), Some(16 << 30));
|
||||
assert_eq!(sysctl_bytes(b""), None);
|
||||
assert_eq!(sysctl_bytes(b"unknown oid 'hw.memsize'\n"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn half_averages_and_rounds_up_odd_sizes() {
|
||||
let px = |v: u8| PremulRgba8 { r: v, g: v, b: v, a: 255 };
|
||||
|
||||
Reference in New Issue
Block a user