Skip to content

Commit

Permalink
Avoid allocations for loader cache lookup (#5584)
Browse files Browse the repository at this point in the history
[ x ] I have ~~followed~~ _read_ the instructions in the PR template

Unfortunately i had several issues:
- Some snapshot-tests didn't run successfully on osx. diff shows errors
around fonts or missing menu items)
- cargo clippy doesn't run successfully (egui_kittest cannot find `wgpu`
and `image`)
- ./scripts/check.sh had other issues on my system (env: python: No such
file or directory), even if python3 can be called via python in my shell
 
Is there a system independent, standard way to run these tools (e.g. via
Docker?)
I submit the pr anyway, because there changes are very simple and
shouldn't cause issues.
  • Loading branch information
mineichen authored Jan 6, 2025
1 parent 9073516 commit 0fac8ea
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 10 deletions.
8 changes: 5 additions & 3 deletions crates/egui/src/load/texture_loader.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::borrow::Cow;

use super::{
BytesLoader, Context, HashMap, ImagePoll, Mutex, SizeHint, SizedTexture, TextureHandle,
TextureLoadResult, TextureLoader, TextureOptions, TexturePoll,
};

#[derive(Default)]
pub struct DefaultTextureLoader {
cache: Mutex<HashMap<(String, TextureOptions), TextureHandle>>,
cache: Mutex<HashMap<(Cow<'static, str>, TextureOptions), TextureHandle>>,
}

impl TextureLoader for DefaultTextureLoader {
Expand All @@ -21,7 +23,7 @@ impl TextureLoader for DefaultTextureLoader {
size_hint: SizeHint,
) -> TextureLoadResult {
let mut cache = self.cache.lock();
if let Some(handle) = cache.get(&(uri.into(), texture_options)) {
if let Some(handle) = cache.get(&(Cow::Borrowed(uri), texture_options)) {
let texture = SizedTexture::from_handle(handle);
Ok(TexturePoll::Ready { texture })
} else {
Expand All @@ -30,7 +32,7 @@ impl TextureLoader for DefaultTextureLoader {
ImagePoll::Ready { image } => {
let handle = ctx.load_texture(uri, image, texture_options);
let texture = SizedTexture::from_handle(&handle);
cache.insert((uri.into(), texture_options), handle);
cache.insert((Cow::Owned(uri.to_owned()), texture_options), handle);
let reduce_texture_memory = ctx.options(|o| o.reduce_texture_memory);
if reduce_texture_memory {
let loaders = ctx.loaders();
Expand Down
12 changes: 5 additions & 7 deletions crates/egui_extras/src/loaders/svg_loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{mem::size_of, path::Path, sync::Arc};
use std::{borrow::Cow, mem::size_of, path::Path, sync::Arc};

use ahash::HashMap;

Expand All @@ -12,7 +12,7 @@ type Entry = Result<Arc<ColorImage>, String>;

#[derive(Default)]
pub struct SvgLoader {
cache: Mutex<HashMap<(String, SizeHint), Entry>>,
cache: Mutex<HashMap<(Cow<'static, str>, SizeHint), Entry>>,
}

impl SvgLoader {
Expand All @@ -37,23 +37,21 @@ impl ImageLoader for SvgLoader {
return Err(LoadError::NotSupported);
}

let uri = uri.to_owned();

let mut cache = self.cache.lock();
// We can't avoid the `uri` clone here without unsafe code.
if let Some(entry) = cache.get(&(uri.clone(), size_hint)).cloned() {
if let Some(entry) = cache.get(&(Cow::Borrowed(uri), size_hint)).cloned() {
match entry {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Loading(err)),
}
} else {
match ctx.try_load_bytes(&uri) {
match ctx.try_load_bytes(uri) {
Ok(BytesPoll::Ready { bytes, .. }) => {
log::trace!("started loading {uri:?}");
let result = crate::image::load_svg_bytes_with_size(&bytes, Some(size_hint))
.map(Arc::new);
log::trace!("finished loading {uri:?}");
cache.insert((uri, size_hint), result.clone());
cache.insert((Cow::Owned(uri.to_owned()), size_hint), result.clone());
match result {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Loading(err)),
Expand Down

0 comments on commit 0fac8ea

Please sign in to comment.