Browse Source

Add `Options::reduce_texture_memory` to free up RAM (#4431)

## Summary

This PR introduces a new configuration option `reduce_texture_memory` in
`egui`.

## Changes

- Added `reduce_texture_memory` option in `egui`. When set to `true`,
`egui` will discard the loaded image data after the texture is uploaded
to the GPU, reducing memory usage. This is beneficial when handling a
large number of images and retaining the image data is unnecessary,
potentially saving substantial memory. However, this makes it impossible
to serialize the loaded images or render on non-GPU systems. Default is
`false`.

## Impact

This new configuration option gives users more control over their memory
usage, especially when dealing with a large number or large resolution
of images. It allows users to optimize their applications based on their
specific needs and constraints.
pull/4515/merge
Varphone Wong 5 months ago
committed by GitHub
parent
commit
6f59a14c4d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      crates/egui/src/load/texture_loader.rs
  2. 17
      crates/egui/src/memory.rs
  3. 5
      crates/egui_demo_app/src/apps/image_viewer.rs

11
crates/egui/src/load/texture_loader.rs

@ -28,6 +28,17 @@ impl TextureLoader for DefaultTextureLoader {
let handle = ctx.load_texture(uri, image, texture_options);
let texture = SizedTexture::from_handle(&handle);
cache.insert((uri.into(), texture_options), handle);
let reduce_texture_memory = ctx.options(|o| o.reduce_texture_memory);
if reduce_texture_memory {
let loaders = ctx.loaders();
loaders.include.forget(uri);
for loader in loaders.bytes.lock().iter().rev() {
loader.forget(uri);
}
for loader in loaders.image.lock().iter().rev() {
loader.forget(uri);
}
}
Ok(TexturePoll::Ready { texture })
}
}

17
crates/egui/src/memory.rs

@ -235,6 +235,19 @@ pub struct Options {
/// Controls the speed at which we zoom in when doing ctrl/cmd + scroll.
pub scroll_zoom_speed: f32,
/// If `true`, `egui` will discard the loaded image data after
/// the texture is loaded onto the GPU to reduce memory usage.
///
/// In modern GPU rendering, the texture data is not required after the texture is loaded.
///
/// This is beneficial when using a large number or resolution of images and there is no need to
/// retain the image data, potentially saving a significant amount of memory.
///
/// The drawback is that it becomes impossible to serialize the loaded images or render in non-GPU systems.
///
/// Default is `false`.
pub reduce_texture_memory: bool,
}
impl Default for Options {
@ -260,6 +273,7 @@ impl Default for Options {
// Input:
line_scroll_speed,
scroll_zoom_speed: 1.0 / 200.0,
reduce_texture_memory: false,
}
}
}
@ -279,6 +293,7 @@ impl Options {
line_scroll_speed,
scroll_zoom_speed,
reduce_texture_memory,
} = self;
use crate::Widget as _;
@ -297,6 +312,8 @@ impl Options {
);
ui.checkbox(warn_on_id_clash, "Warn if two widgets have the same Id");
ui.checkbox(reduce_texture_memory, "Reduce texture memory");
});
use crate::containers::*;

5
crates/egui_demo_app/src/apps/image_viewer.rs

@ -184,6 +184,11 @@ impl eframe::App for ImageViewer {
ui.add_space(5.0);
ui.label("Aspect ratio is maintained by scaling both sides as necessary");
ui.checkbox(&mut self.maintain_aspect_ratio, "Maintain aspect ratio");
// forget all images
if ui.button("Forget all images").clicked() {
ui.ctx().forget_all_images();
}
});
egui::CentralPanel::default().show(ctx, |ui| {

Loading…
Cancel
Save