fix: reduce memory usage on web
This commit is contained in:
+25
-2
@@ -208,6 +208,8 @@ pub struct Uniforms {
|
|||||||
/// * `color_view` — the colourise pass's output; the blit source.
|
/// * `color_view` — the colourise pass's output; the blit source.
|
||||||
/// plus the bind groups that read them.
|
/// plus the bind groups that read them.
|
||||||
struct CacheTarget {
|
struct CacheTarget {
|
||||||
|
/// Kept so they can be `destroy()`ed on resize (see `ensure_cache`).
|
||||||
|
textures: [wgpu::Texture; 3],
|
||||||
data_view: wgpu::TextureView,
|
data_view: wgpu::TextureView,
|
||||||
data_aa_view: wgpu::TextureView,
|
data_aa_view: wgpu::TextureView,
|
||||||
color_view: wgpu::TextureView,
|
color_view: wgpu::TextureView,
|
||||||
@@ -591,6 +593,19 @@ impl FractalRenderer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the old textures explicitly. On the web backend dropping a
|
||||||
|
// `wgpu::Texture` does not release its GPU memory — that waits for the
|
||||||
|
// JS garbage collector — and this runs on every size change (including
|
||||||
|
// each switch in/out of the downscaled interactive resolution), so the
|
||||||
|
// stale Rgba32Float textures piled up until WebGPU ran out of memory.
|
||||||
|
// Any commands using them were submitted on earlier frames, and
|
||||||
|
// `destroy()` defers the actual free until those finish.
|
||||||
|
if let Some(old) = self.cache.take() {
|
||||||
|
for t in &old.textures {
|
||||||
|
t.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let extent = wgpu::Extent3d {
|
let extent = wgpu::Extent3d {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@@ -684,6 +699,7 @@ impl FractalRenderer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.cache = Some(CacheTarget {
|
self.cache = Some(CacheTarget {
|
||||||
|
textures: [data_texture, data_aa_texture, color_texture],
|
||||||
data_view,
|
data_view,
|
||||||
data_aa_view,
|
data_aa_view,
|
||||||
color_view,
|
color_view,
|
||||||
@@ -1132,8 +1148,15 @@ impl egui_wgpu::CallbackTrait for FractalCallback {
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
|
|
||||||
let width = self.size_px[0].max(1);
|
// Clamp to the device's texture-size limit, keeping the aspect ratio
|
||||||
let height = self.size_px[1].max(1);
|
// (the iterate pass maps pixels through NDC, so the view is unchanged;
|
||||||
|
// the blit just upsamples). The 2× 3D supersample on a large/HiDPI
|
||||||
|
// screen can otherwise exceed it.
|
||||||
|
let max_dim = device.limits().max_texture_dimension_2d;
|
||||||
|
let [w, h] = self.size_px.map(|v| v.max(1));
|
||||||
|
let scale = (max_dim as f64 / w.max(h) as f64).min(1.0);
|
||||||
|
let width = ((w as f64 * scale) as u32).clamp(1, max_dim);
|
||||||
|
let height = ((h as f64 * scale) as u32).clamp(1, max_dim);
|
||||||
renderer.ensure_cache(device, width, height);
|
renderer.ensure_cache(device, width, height);
|
||||||
|
|
||||||
// Iteration (expensive) re-runs only when the geometry inputs change;
|
// Iteration (expensive) re-runs only when the geometry inputs change;
|
||||||
|
|||||||
Reference in New Issue
Block a user