From 9831d70bfa40cadbb302f39855ce325a9f17925b Mon Sep 17 00:00:00 2001 From: arnav-hiwarkar Date: Thu, 12 Nov 2026 15:11:13 +0530 Subject: [PATCH] #3539: a cache purge gives the viewers' frames new keys Reload Footage Changed on Disk of a file whose metadata didn't change keeps the project's revision; PurgeCaches emptied the viewer frame cache but the new frame came back under the key of the one on screen, so neither the Composition viewer nor the passive viewers uploaded it. Count purges and mix the count into the frame key's options, as #3493 does with the LUT generation. --- crates/ui-egui/src/app.rs | 1 + crates/ui-egui/src/app/frame.rs | 6 +++++- crates/ui-egui/src/app/viewer_frames.rs | 10 +++++++++- crates/ui-egui/src/lib.rs | 2 ++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs index bf5964ba6..518f4e809 100644 --- a/crates/ui-egui/src/app.rs +++ b/crates/ui-egui/src/app.rs @@ -99,6 +99,7 @@ impl EffectcraftApp { footage_watch_key: None, lut_watcher: None, lut_generation: effectcraft_engine::lut_reload::generation(), + purges: 0, device_lost_close: None, dialog_answers: std::sync::mpsc::channel(), file_dialogs: FileDialogsUp::default(), diff --git a/crates/ui-egui/src/app/frame.rs b/crates/ui-egui/src/app/frame.rs index 488b3c5ef..b78c38c73 100644 --- a/crates/ui-egui/src/app/frame.rs +++ b/crates/ui-egui/src/app/frame.rs @@ -151,7 +151,11 @@ impl EffectcraftApp { self.ui.status = e; } } - effectcraft_engine::Event::PurgeCaches => self.frames.clear(), + effectcraft_engine::Event::PurgeCaches => { + self.frames.clear(); + // (frames made after it get keys of their own: see `Self::purge_stamp`) + self.purges = self.purges.wrapping_add(1); + } effectcraft_engine::Event::CopyImage { width, height, rgba } => { if let Err(e) = copy_image(ctx, width, height, &rgba) { self.ui.status = e; diff --git a/crates/ui-egui/src/app/viewer_frames.rs b/crates/ui-egui/src/app/viewer_frames.rs index a76c88b2d..d9e6e84f2 100644 --- a/crates/ui-egui/src/app/viewer_frames.rs +++ b/crates/ui-egui/src/app/viewer_frames.rs @@ -128,7 +128,7 @@ impl EffectcraftApp { frame: 0, scale: (scale * 1000.0).round() as u32, view: self.view_hash(comp), - opts: frames::opts_hash(&self.frame_opts(comp, scale)) ^ self.roto_model_stamp() ^ self.lut_stamp(), + opts: frames::opts_hash(&self.frame_opts(comp, scale)) ^ self.roto_model_stamp() ^ self.lut_stamp() ^ self.purge_stamp(), } } @@ -149,6 +149,14 @@ impl EffectcraftApp { self.lut_generation.wrapping_mul(0x9e37_79b9_7f4a_7c15) } + /// Changes when the caches are purged (Event::PurgeCaches: footage reloaded, Purge): the + /// frames on screen and the ones still rendering may show the files as they were, and a reload + /// that changes no metadata keeps the project's revision, so the new frames must not share + /// their keys (#3539; the viewers show a frame again only when its key changes). 0 until then. + fn purge_stamp(&self) -> u64 { + self.purges.wrapping_mul(0xc2b2_ae3d_27d4_eb4f) + } + /// The frame series the viewer of `comp` shows now (its scale, view and options, for the /// comp's current content): what the cache bars count. pub fn shown_series(&self, comp: ItemId) -> FrameKey { diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 699f68e0f..1558ce743 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -377,6 +377,8 @@ pub struct EffectcraftApp { lut_watcher: Option, /// The LUT generation the frames kept were rendered at ([`effectcraft_engine::lut_reload::generation`]). lut_generation: u64, + /// How many times the caches were purged ([`Self::purge_stamp`]). + purges: u64, /// The graphics device was lost and the window is closing (see `close_after_device_loss`); /// `true` keeps crash recovery for the next launch. device_lost_close: Option,