Retired frees only images no one else holds
An image shared with something still drawing waits for a later paint.
This commit is contained in:
2 files changed
+18
-2
No files matched your search
@@ -14,9 +14,12 @@ impl Retired {
|
||||
self.0.push(image);
|
||||
}
|
||||
|
||||
/// Frees every retired image; call while painting.
|
||||
/// Frees images no one else holds; call while painting.
|
||||
pub fn release(&mut self, window: &mut Window) {
|
||||
for image in self.0.drain(..) {
|
||||
// A shared image may still be drawn; it waits.
|
||||
let (free, held): (Vec<_>, Vec<_>) = self.0.drain(..).partition(|image| Arc::strong_count(image) == 1);
|
||||
self.0 = held;
|
||||
for image in free {
|
||||
if let Err(error) = window.drop_image(image) {
|
||||
log::error!("images: a retired image stayed: {error}");
|
||||
}
|
||||
|
||||
@@ -261,4 +261,17 @@ fn a_retired_image_is_freed_at_the_next_paint(cx: &mut TestAppContext) {
|
||||
});
|
||||
cx.run_until_parked();
|
||||
assert!(view.read_with(cx, |painted, _| painted.retired.is_empty()), "the old image was freed");
|
||||
// One still held elsewhere waits until it is let go.
|
||||
let pixels = image::RgbaImage::from_pixel(2, 2, image::Rgba([4, 5, 6, 255]));
|
||||
let shared = std::sync::Arc::new(gpui::RenderImage::new([image::Frame::new(pixels)]));
|
||||
view.update(cx, |painted, cx| {
|
||||
painted.retired.push(shared.clone());
|
||||
cx.notify();
|
||||
});
|
||||
cx.run_until_parked();
|
||||
assert!(!view.read_with(cx, |painted, _| painted.retired.is_empty()), "a held image waits");
|
||||
drop(shared);
|
||||
view.update(cx, |_, cx| cx.notify());
|
||||
cx.run_until_parked();
|
||||
assert!(view.read_with(cx, |painted, _| painted.retired.is_empty()), "then it is freed");
|
||||
}
|
||||
Reference in new issue
Block a user