Skip to content

Commit c41d6e1

Browse files
committed
improve genetic algorithm performance
1 parent 67e1599 commit c41d6e1

4 files changed

Lines changed: 74 additions & 37 deletions

File tree

Trunk.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[build]
2-
filehash = false
2+
filehash = true

src/app.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ pub struct ObamifyApp {
154154
gui: gui::GuiState,
155155
#[cfg(not(target_arch = "wasm32"))]
156156
current_drawing_id: Arc<AtomicU32>,
157+
current_filter_mode: wgpu::FilterMode,
157158
}
158159

159160
impl ObamifyApp {
@@ -685,6 +686,7 @@ impl ObamifyApp {
685686
worker: None,
686687
#[cfg(target_arch = "wasm32")]
687688
inbox: Vec::new(),
689+
current_filter_mode: wgpu::FilterMode::Linear,
688690
}
689691
}
690692

@@ -849,14 +851,19 @@ impl ObamifyApp {
849851
(tex, view)
850852
}
851853

852-
fn ensure_registered_texture(&mut self, rs: &egui_wgpu::RenderState) {
853-
if self.egui_tex_id.is_none() {
854+
fn ensure_registered_texture(
855+
&mut self,
856+
rs: &egui_wgpu::RenderState,
857+
filter_mode: wgpu::FilterMode,
858+
) {
859+
if self.egui_tex_id.is_none() || self.current_filter_mode != filter_mode {
854860
let id = rs.renderer.write().register_native_texture(
855861
&rs.device,
856862
&self.color_view,
857-
wgpu::FilterMode::Linear,
863+
filter_mode,
858864
);
859865
self.egui_tex_id = Some(id);
866+
self.current_filter_mode = filter_mode;
860867
}
861868
}
862869

src/app/calculate/mod.rs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn _debug_print(s: String) {
1616

1717
use crate::app::calculate::util::Algorithm;
1818
use crate::app::{
19-
calculate::util::{GenerationSettings, ProgressSink, SourceImg},
19+
calculate::util::{GenerationSettings, ProgressSink},
2020
preset::{Preset, UnprocessedPreset},
2121
};
2222
use egui::ahash::AHasher;
@@ -248,7 +248,7 @@ pub fn process_optimal<S: ProgressSink>(
248248

249249
tx.send(ProgressMsg::Progress(root as f32 / nx as f32));
250250

251-
let img = make_new_img(
251+
let data = make_new_img(
252252
&source_pixels,
253253
&xy.clone()
254254
.into_iter()
@@ -258,9 +258,9 @@ pub fn process_optimal<S: ProgressSink>(
258258
);
259259

260260
tx.send(ProgressMsg::UpdatePreview {
261-
width: img.width(),
262-
height: img.height(),
263-
data: img.into_raw(),
261+
width: settings.sidelen,
262+
height: settings.sidelen,
263+
data,
264264
});
265265
}
266266
}
@@ -294,16 +294,14 @@ pub fn process_optimal<S: ProgressSink>(
294294
Ok(())
295295
}
296296

297-
fn make_new_img(source_pixels: &[(u8, u8, u8)], assignments: &[usize], sidelen: u32) -> SourceImg {
298-
let mut img = SourceImg::new(sidelen, sidelen);
299-
297+
fn make_new_img(source_pixels: &[(u8, u8, u8)], assignments: &[usize], sidelen: u32) -> Vec<u8> {
298+
let mut img = vec![0; (sidelen * sidelen * 3) as usize];
300299
for (target_idx, source_idx) in assignments.iter().enumerate() {
301-
let (x, y) = (
302-
(target_idx % sidelen as usize) as u32,
303-
(target_idx / sidelen as usize) as u32,
304-
);
305300
let (r, g, b) = source_pixels[*source_idx];
306-
img.put_pixel(x, y, image::Rgb([r, g, b]));
301+
let base = target_idx * 3;
302+
img[base] = r;
303+
img[base + 1] = g;
304+
img[base + 2] = b;
307305
}
308306
img
309307
}
@@ -349,11 +347,7 @@ impl Pixel {
349347
}
350348
}
351349

352-
#[cfg(not(target_arch = "wasm32"))]
353-
const SWAPS_PER_GENERATION_PER_PIXEL: usize = 20;
354-
355-
#[cfg(target_arch = "wasm32")]
356-
const SWAPS_PER_GENERATION_PER_PIXEL: usize = 100; // for some reason wasm is like 5x faster
350+
const SWAPS_PER_GENERATION_PER_PIXEL: usize = 128;
357351

358352
pub fn process_genetic<S: ProgressSink>(
359353
unprocessed: UnprocessedPreset,
@@ -462,11 +456,11 @@ pub fn process_genetic<S: ProgressSink>(
462456
}));
463457
return Ok(());
464458
}
465-
let img = make_new_img(&source_pixels, &assignments, settings.sidelen);
459+
let data = make_new_img(&source_pixels, &assignments, settings.sidelen);
466460
tx.send(ProgressMsg::UpdatePreview {
467-
width: img.width(),
468-
height: img.height(),
469-
data: img.into_raw(),
461+
width: settings.sidelen,
462+
height: settings.sidelen,
463+
data,
470464
});
471465
tx.send(ProgressMsg::Progress(
472466
1.0 - max_dist as f32 / settings.sidelen as f32,

src/app/gui.rs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::DRAWING_ALPHA;
33

44
use super::GuiMode;
55
use super::ObamifyApp;
6+
use crate::app::DEFAULT_RESOLUTION;
67
use crate::app::calculate;
78
use crate::app::calculate::ProgressMsg;
89
use crate::app::calculate::util::CropScale;
@@ -104,7 +105,6 @@ fn show_icons() {
104105
// show .bottom-left-icons class after processing
105106
if let Some(document) = web_sys::window().and_then(|w| w.document()) {
106107
if let Some(icons) = document.query_selector(".bottom-left-icons").ok().flatten() {
107-
web_sys::console::log_1(&"showing icons".into());
108108
let _ = icons
109109
.dyn_ref::<web_sys::HtmlElement>()
110110
.map(|e| e.style().set_property("display", "flex"));
@@ -118,7 +118,6 @@ fn hide_icons() {
118118
// hide .bottom-left-icons class while processing
119119
if let Some(document) = web_sys::window().and_then(|w| w.document()) {
120120
if let Some(icons) = document.query_selector(".bottom-left-icons").ok().flatten() {
121-
web_sys::console::log_1(&"hiding icons".into());
122121
let _ = icons
123122
.dyn_ref::<web_sys::HtmlElement>()
124123
.map(|e| e.style().set_property("display", "none"));
@@ -147,20 +146,31 @@ impl App for ObamifyApp {
147146
// }
148147

149148
// Ensure texture is registered exactly once per allocation
150-
self.ensure_registered_texture(rs);
149+
self.ensure_registered_texture(
150+
rs,
151+
if self.size.0 < 512 {
152+
wgpu::FilterMode::Nearest
153+
} else {
154+
wgpu::FilterMode::Linear
155+
},
156+
);
151157

152158
#[cfg(target_arch = "wasm32")]
153159
self.ensure_worker(ctx);
154160

155161
// Run GPU pipeline
156162
if let Some(img) = &self.preview_image {
157163
// show image
158-
let img = image::imageops::resize(
159-
img,
160-
self.size.0,
161-
self.size.1,
162-
image::imageops::FilterType::Nearest,
163-
);
164+
let img = if img.width() != self.size.0 || img.height() != self.size.1 {
165+
&image::imageops::resize(
166+
img,
167+
self.size.0,
168+
self.size.1,
169+
image::imageops::FilterType::Nearest,
170+
)
171+
} else {
172+
img
173+
};
164174
let rgba: image::ImageBuffer<image::Rgba<u8>, Vec<u8>> = img.convert();
165175
let rgba = rgba.into_raw();
166176
rs.queue.write_texture(
@@ -368,7 +378,6 @@ impl App for ObamifyApp {
368378
}
369379
})
370380
.show_ui(ui, |ui| {
371-
ui.set_max_height(300.0);
372381
let mut to_remove: Option<usize> = None;
373382
let mut close_menu = false;
374383

@@ -683,13 +692,19 @@ impl App for ObamifyApp {
683692
.add(egui::Button::new(egui::RichText::new("start!").strong()))
684693
.clicked()
685694
{
686-
if let Some((img, settings, _)) =
695+
if let Some((img, mut settings, _)) =
687696
self.gui.configuring_generation.take()
688697
{
689698
self.gui.show_progress_modal(settings.id);
690699
//self.gui.currently_processing = Some(path.clone());
691700
//self.change_sim(device, path.clone(), false);
692701

702+
// adjust for consistency across resolutions
703+
settings.proximity_importance =
704+
(settings.proximity_importance as f32
705+
/ (settings.sidelen as f32 / 128.0))
706+
as i64;
707+
693708
self.gui
694709
.process_cancelled
695710
.store(false, std::sync::atomic::Ordering::Relaxed);
@@ -701,6 +716,12 @@ impl App for ObamifyApp {
701716
source_img: img.into_raw(),
702717
};
703718

719+
self.resize_textures(
720+
device,
721+
(settings.sidelen, settings.sidelen),
722+
false,
723+
);
724+
704725
#[cfg(target_arch = "wasm32")]
705726
{
706727
self.start_job(unprocessed, settings);
@@ -755,6 +776,11 @@ impl App for ObamifyApp {
755776
match msg {
756777
ProgressMsg::Done(new_preset) => {
757778
self.preview_image = None;
779+
self.resize_textures(
780+
device,
781+
(DEFAULT_RESOLUTION, DEFAULT_RESOLUTION),
782+
false,
783+
);
758784
//self.gui.presets = get_presets();
759785
self.gui.presets.push(new_preset.clone());
760786
self.change_sim(device, new_preset, self.gui.presets.len() - 1);
@@ -782,6 +808,11 @@ impl App for ObamifyApp {
782808
}
783809
ProgressMsg::Cancelled => {
784810
self.preview_image = None;
811+
self.resize_textures(
812+
device,
813+
(DEFAULT_RESOLUTION, DEFAULT_RESOLUTION),
814+
false,
815+
);
785816
self.gui.hide_progress_modal();
786817
ui.close();
787818
}
@@ -809,6 +840,11 @@ impl App for ObamifyApp {
809840
}
810841
self.worker = None;
811842
self.preview_image = None;
843+
self.resize_textures(
844+
device,
845+
(DEFAULT_RESOLUTION, DEFAULT_RESOLUTION),
846+
false,
847+
);
812848
self.gui.hide_progress_modal();
813849
ui.close();
814850
}

0 commit comments

Comments
 (0)