1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 14:50:03 -04:00

Prevent accidentally dropping TexturesDelta (#8356)

We had a ton of issues around `TexturesDelta` that weren't properly
applied because we early-out of some function:
* https://github.com/emilk/egui/pull/8313
* https://github.com/emilk/egui/pull/8250
* https://github.com/emilk/egui/pull/8279

This PR changes texture updates, so that we always store them after
taking them out of `FullOutput` and keep the delta around until it's
actually applied (by passing &mut refs and draining instead of
iterating). So even if we add a new early return somewhere, that can't
break texture updates.

It also optimizes `TexturesDelta::append` by dropping any previous
deltas if there's a new `whole` delta or a `free`.

It also adds a debug assert that any `TexturesDelta` is empty when
dropped, as an additional safeguard in case the bug sneaks back in.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lucas Meurer
2026-07-29 18:16:48 +02:00
committed by GitHub
parent d99b665ec0
commit 6268c84d8a
21 changed files with 291 additions and 130 deletions

View File

@@ -137,15 +137,23 @@ impl crate::TestRenderer for WgpuTestRenderer {
frame.wgpu_render_state = Some(self.render_state.clone());
}
fn handle_delta(&mut self, delta: &TexturesDelta) {
fn handle_delta(&mut self, delta: &mut TexturesDelta) {
let mut renderer = self.render_state.renderer.write();
for (id, image) in &delta.set {
renderer.update_texture(
&self.render_state.device,
&self.render_state.queue,
*id,
image,
);
#[expect(clippy::iter_over_hash_type)] // Order doesn't matter here
for (id, images) in delta.set.drain() {
for image in images {
renderer.update_texture(
&self.render_state.device,
&self.render_state.queue,
id,
&image,
);
}
}
#[expect(clippy::iter_over_hash_type)] // Order doesn't matter here
for id in delta.free.drain() {
renderer.free_texture(&id);
}
}