mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Leave a hosted viewport's texture uploads to the viewport hosting it
A pass ends by taking the `Context`'s texture uploads for the backend to apply. That is wrong for a hosted viewport: the application paints it, and paints the viewport hosting it, so the uploads were taken by code that has no way to give them back. `TextureManager::set` and `free` both assert on ids the pass had already finished with, and a freed texture cannot be re-queued at all, since `free` decrements a retain count that has already reached zero. Leaving them in place means the hosting viewport's pass takes them, as it would have without the hosted viewport, and its backend applies them as usual. Immediate viewports keep taking theirs, because they are painted during the nested pass and their painter needs the uploads by then. `TextureManager::pending_delta` lets an application that paints part way through a frame apply what is pending without taking it. Applying an upload twice is harmless; the second time re-uploads the same data. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2599,7 +2599,17 @@ impl ContextImpl {
|
||||
}
|
||||
|
||||
// Inform the backend of all textures that have been updated (including font atlas).
|
||||
let textures_delta = self.tex_manager.0.write().take_delta();
|
||||
//
|
||||
// A hosted viewport is the exception. It is painted by the application, which also
|
||||
// paints the viewport hosting it, so leaving the uploads in place lets that one pick
|
||||
// them up. Taking them here would hand them to code with no way to give them back:
|
||||
// a freed texture cannot be re-queued, because `TextureManager::free` decrements a
|
||||
// retain count that has already reached zero.
|
||||
let textures_delta = if viewport.class == ViewportClass::Hosted {
|
||||
Default::default()
|
||||
} else {
|
||||
self.tex_manager.0.write().take_delta()
|
||||
};
|
||||
|
||||
let mut platform_output: PlatformOutput = std::mem::take(&mut viewport.output);
|
||||
|
||||
|
||||
@@ -103,6 +103,15 @@ impl TextureManager {
|
||||
std::mem::take(&mut self.delta)
|
||||
}
|
||||
|
||||
/// Changes since the last [`Self::take_delta`], without taking them.
|
||||
///
|
||||
/// Useful if you need to paint something part-way through a frame, before whoever owns
|
||||
/// the painting subsystem has had a chance to apply these. Applying them twice does no
|
||||
/// harm; the second time simply re-uploads the same data.
|
||||
pub fn pending_delta(&self) -> &TexturesDelta {
|
||||
&self.delta
|
||||
}
|
||||
|
||||
/// Get meta-data about a specific texture.
|
||||
pub fn meta(&self, id: TextureId) -> Option<&TextureMeta> {
|
||||
self.metas.get(&id)
|
||||
|
||||
Reference in New Issue
Block a user