egui/load/
texture_loader.rs
1use super::{
2 BytesLoader, Context, HashMap, ImagePoll, Mutex, SizeHint, SizedTexture, TextureHandle,
3 TextureLoadResult, TextureLoader, TextureOptions, TexturePoll,
4};
5
6#[derive(Default)]
7pub struct DefaultTextureLoader {
8 cache: Mutex<HashMap<(String, TextureOptions), TextureHandle>>,
9}
10
11impl TextureLoader for DefaultTextureLoader {
12 fn id(&self) -> &str {
13 crate::generate_loader_id!(DefaultTextureLoader)
14 }
15
16 fn load(
17 &self,
18 ctx: &Context,
19 uri: &str,
20 texture_options: TextureOptions,
21 size_hint: SizeHint,
22 ) -> TextureLoadResult {
23 let mut cache = self.cache.lock();
24 if let Some(handle) = cache.get(&(uri.into(), texture_options)) {
25 let texture = SizedTexture::from_handle(handle);
26 Ok(TexturePoll::Ready { texture })
27 } else {
28 match ctx.try_load_image(uri, size_hint)? {
29 ImagePoll::Pending { size } => Ok(TexturePoll::Pending { size }),
30 ImagePoll::Ready { image } => {
31 let handle = ctx.load_texture(uri, image, texture_options);
32 let texture = SizedTexture::from_handle(&handle);
33 cache.insert((uri.into(), texture_options), handle);
34 let reduce_texture_memory = ctx.options(|o| o.reduce_texture_memory);
35 if reduce_texture_memory {
36 let loaders = ctx.loaders();
37 loaders.include.forget(uri);
38 for loader in loaders.bytes.lock().iter().rev() {
39 loader.forget(uri);
40 }
41 for loader in loaders.image.lock().iter().rev() {
42 loader.forget(uri);
43 }
44 }
45 Ok(TexturePoll::Ready { texture })
46 }
47 }
48 }
49 }
50
51 fn forget(&self, uri: &str) {
52 #[cfg(feature = "log")]
53 log::trace!("forget {uri:?}");
54
55 self.cache.lock().retain(|(u, _), _| u != uri);
56 }
57
58 fn forget_all(&self) {
59 #[cfg(feature = "log")]
60 log::trace!("forget all");
61
62 self.cache.lock().clear();
63 }
64
65 fn end_pass(&self, _: usize) {}
66
67 fn byte_size(&self) -> usize {
68 self.cache
69 .lock()
70 .values()
71 .map(|texture| texture.byte_size())
72 .sum()
73 }
74}