Skip to content

Commit 1beb06a

Browse files
committed
Fix WGPU out-of-memory crash by caching overlay textures
1 parent 1b91198 commit 1beb06a

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

  • desktop/src/render
  • node-graph/libraries/wgpu-executor/src

desktop/src/render/state.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::window::Window;
22

33
use crate::wrapper::{Color, WgpuContext, WgpuExecutor};
4+
use wgpu_executor::TargetTexture;
45

56
#[derive(derivative::Derivative)]
67
#[derivative(Debug)]
@@ -18,6 +19,7 @@ pub(crate) struct RenderState {
1819
viewport_offset: [f32; 2],
1920
viewport_texture: Option<wgpu::Texture>,
2021
overlays_texture: Option<wgpu::Texture>,
22+
overlays_target_texture: Option<TargetTexture>,
2123
ui_texture: Option<wgpu::Texture>,
2224
bind_group: Option<wgpu::BindGroup>,
2325
#[derivative(Debug = "ignore")]
@@ -182,6 +184,7 @@ impl RenderState {
182184
viewport_offset: [0.0, 0.0],
183185
viewport_texture: None,
184186
overlays_texture: None,
187+
overlays_target_texture: None,
185188
ui_texture: None,
186189
bind_group: None,
187190
overlays_scene: None,
@@ -236,12 +239,20 @@ impl RenderState {
236239
return;
237240
};
238241
let size = glam::UVec2::new(viewport_texture.width(), viewport_texture.height());
239-
let texture = futures::executor::block_on(self.executor.render_vello_scene_to_texture(&scene, size, &Default::default(), Color::TRANSPARENT));
240-
let Ok(texture) = texture else {
241-
tracing::error!("Error rendering overlays");
242+
let result = futures::executor::block_on(
243+
self.executor.render_vello_scene_to_target_texture(&scene, size, &Default::default(), Color::TRANSPARENT, &mut self.overlays_target_texture)
244+
);
245+
if let Err(e) = result {
246+
tracing::error!("Error rendering overlays: {:?}", e);
242247
return;
243-
};
244-
self.bind_overlays_texture(texture);
248+
}
249+
// Extract the texture from the cached TargetTexture
250+
if let Some(target_texture) = &self.overlays_target_texture {
251+
// Create a new texture reference - the actual GPU texture is reused
252+
let texture_view = target_texture.texture.create_view(&wgpu::TextureViewDescriptor::default());
253+
self.overlays_texture = Some(target_texture.texture.clone());
254+
self.update_bindgroup();
255+
}
245256
}
246257

247258
pub(crate) fn render(&mut self, window: &Window) -> Result<(), RenderError> {

node-graph/libraries/wgpu-executor/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ pub struct Surface {
4949
}
5050

5151
pub struct TargetTexture {
52-
texture: wgpu::Texture,
53-
view: wgpu::TextureView,
54-
size: UVec2,
52+
pub texture: wgpu::Texture,
53+
pub view: wgpu::TextureView,
54+
pub size: UVec2,
5555
}
5656

5757
#[cfg(target_family = "wasm")]
@@ -72,7 +72,7 @@ impl WgpuExecutor {
7272
Ok(output.unwrap().texture)
7373
}
7474

75-
async fn render_vello_scene_to_target_texture(&self, scene: &Scene, size: UVec2, context: &RenderContext, background: Color, output: &mut Option<TargetTexture>) -> Result<()> {
75+
pub async fn render_vello_scene_to_target_texture(&self, scene: &Scene, size: UVec2, context: &RenderContext, background: Color, output: &mut Option<TargetTexture>) -> Result<()> {
7676
let size = size.max(UVec2::ONE);
7777
let target_texture = if let Some(target_texture) = output
7878
&& target_texture.size == size

0 commit comments

Comments
 (0)