egui/load/
texture_loader.rs

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