Fix memory leak when `forget_image` is called while loading (#7380)
This is the same issue that was fixed for the http bytes loader in
239ade9a59
* [x] I have followed the instructions in the PR template
----------------
Funnily, [this
comment](https://github.com/emilk/egui/issues/3747#issuecomment-1872192997)
describes exactly how I encountered this issue:
> That assert is wrong if something calls forget between the start of
the request and the end of it.
I'm displaying lots of images in a scrolling grid (20 or so visible at a
time). It seems like image textures are never freed up automatically so
it stacks up a lot meaning I have to unload the image textures manually
with `egui::Context::forget_image()` in each `eframe::App::update()`
call for the images that are no longer shown when scrolling.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
parent
31eb4d498b
commit
8333615072
|
|
@ -94,9 +94,19 @@ impl BytesLoader for EhttpLoader {
|
||||||
Err(format!("Failed to load {uri:?}"))
|
Err(format!("Failed to load {uri:?}"))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
log::trace!("finished loading {uri:?}");
|
let mut cache = cache.lock();
|
||||||
cache.lock().insert(uri, Poll::Ready(result));
|
if let std::collections::hash_map::Entry::Occupied(mut entry) =
|
||||||
ctx.request_repaint();
|
cache.entry(uri.clone())
|
||||||
|
{
|
||||||
|
let entry = entry.get_mut();
|
||||||
|
*entry = Poll::Ready(result);
|
||||||
|
ctx.request_repaint();
|
||||||
|
log::trace!("Finished loading {uri:?}");
|
||||||
|
} else {
|
||||||
|
log::trace!(
|
||||||
|
"Canceled loading {uri:?}\nNote: This can happen if `forget_image` is called while the image is still loading."
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,14 +100,16 @@ impl ImageLoader for ImageCrateLoader {
|
||||||
let result = crate::image::load_image_bytes(&bytes)
|
let result = crate::image::load_image_bytes(&bytes)
|
||||||
.map(Arc::new)
|
.map(Arc::new)
|
||||||
.map_err(|err| err.to_string());
|
.map_err(|err| err.to_string());
|
||||||
log::trace!("ImageLoader - finished loading {uri:?}");
|
let mut cache = cache.lock();
|
||||||
let prev = cache.lock().insert(uri, Poll::Ready(result));
|
|
||||||
debug_assert!(
|
|
||||||
matches!(prev, Some(Poll::Pending)),
|
|
||||||
"Expected previous state to be Pending"
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.request_repaint();
|
if let std::collections::hash_map::Entry::Occupied(mut entry) = cache.entry(uri.clone()) {
|
||||||
|
let entry = entry.get_mut();
|
||||||
|
*entry = Poll::Ready(result);
|
||||||
|
ctx.request_repaint();
|
||||||
|
log::trace!("ImageLoader - finished loading {uri:?}");
|
||||||
|
} else {
|
||||||
|
log::trace!("ImageLoader - canceled loading {uri:?}\nNote: This can happen if `forget_image` is called while the image is still loading.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.expect("failed to spawn thread");
|
.expect("failed to spawn thread");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue