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