diff --git a/crates/media/src/gif_anim.rs b/crates/media/src/gif_anim.rs index 01a40eacd..30161b0b9 100644 --- a/crates/media/src/gif_anim.rs +++ b/crates/media/src/gif_anim.rs @@ -15,8 +15,12 @@ use crate::{MediaError, Result}; /// The `Footage::codec` of an animated GIF. pub(crate) const CODEC: &str = "GIF"; -/// Decoded frames of one GIF are kept as 8-bit RGBA, up to this many bytes. +/// Decoded frames of one GIF are kept as 8-bit RGBA, up to this many bytes (less in a browser tab, +/// whose wasm32 heap is 4 GiB at most and shared with everything else). +#[cfg(not(target_arch = "wasm32"))] const MAX_BYTES: usize = 1 << 30; +#[cfg(target_arch = "wasm32")] +const MAX_BYTES: usize = 256 << 20; /// Frames read from a GIF's headers when probing. const MAX_FRAMES: usize = 100_000; diff --git a/crates/media/src/pool.rs b/crates/media/src/pool.rs index 8bb31fca6..2a80eb058 100644 --- a/crates/media/src/pool.rs +++ b/crates/media/src/pool.rs @@ -304,13 +304,15 @@ impl MediaPool { let mut c = lock(&self.inner.cache); c.lru = Lru::default(); c.last.clear(); + drop(c); + // Decoded GIFs sit outside the frame budget; Purge frees them too. + lock(&self.inner.gifs).clear(); } /// Drop every cached frame and decoder. pub fn clear(&self) { self.clear_frames(); lock(&self.inner.sources).clear(); - lock(&self.inner.gifs).clear(); } /// Forget a file (after it changed on disk, or to retry a file that failed to open).