@@ -54,6 +54,47 @@ pub struct TargetTexture {
5454 size : UVec2 ,
5555}
5656
57+ impl TargetTexture {
58+ /// Ensures the texture has the specified size, creating a new one if needed.
59+ /// This allows reusing the same texture across frames when the size hasn't changed.
60+ pub fn ensure_size ( & mut self , device : & wgpu:: Device , size : UVec2 ) {
61+ let size = size. max ( UVec2 :: ONE ) ;
62+ if self . size == size {
63+ return ;
64+ }
65+
66+ let texture = device. create_texture ( & wgpu:: TextureDescriptor {
67+ label : None ,
68+ size : wgpu:: Extent3d {
69+ width : size. x ,
70+ height : size. y ,
71+ depth_or_array_layers : 1 ,
72+ } ,
73+ mip_level_count : 1 ,
74+ sample_count : 1 ,
75+ dimension : wgpu:: TextureDimension :: D2 ,
76+ usage : wgpu:: TextureUsages :: STORAGE_BINDING | wgpu:: TextureUsages :: TEXTURE_BINDING | wgpu:: TextureUsages :: COPY_SRC ,
77+ format : VELLO_SURFACE_FORMAT ,
78+ view_formats : & [ ] ,
79+ } ) ;
80+ let view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
81+
82+ self . texture = texture;
83+ self . view = view;
84+ self . size = size;
85+ }
86+
87+ /// Returns a reference to the texture view for rendering.
88+ pub fn view ( & self ) -> & wgpu:: TextureView {
89+ & self . view
90+ }
91+
92+ /// Returns a reference to the underlying texture.
93+ pub fn texture ( & self ) -> & wgpu:: Texture {
94+ & self . texture
95+ }
96+ }
97+
5798#[ cfg( target_family = "wasm" ) ]
5899pub type Window = web_sys:: HtmlCanvasElement ;
59100#[ cfg( not( target_family = "wasm" ) ) ]
@@ -71,19 +112,14 @@ impl WgpuExecutor {
71112 self . render_vello_scene_to_target_texture ( scene, size, context, background, & mut output) . await ?;
72113 Ok ( output. unwrap ( ) . texture )
73114 }
74-
75- async fn render_vello_scene_to_target_texture ( & self , scene : & Scene , size : UVec2 , context : & RenderContext , background : Color , output : & mut Option < TargetTexture > ) -> Result < ( ) > {
76- let size = size. max ( UVec2 :: ONE ) ;
77- let target_texture = if let Some ( target_texture) = output
78- && target_texture. size == size
79- {
80- target_texture
81- } else {
115+ pub async fn render_vello_scene_to_target_texture ( & self , scene : & Scene , size : UVec2 , context : & RenderContext , background : Color , output : & mut Option < TargetTexture > ) -> Result < ( ) > {
116+ // Initialize with a minimal texture if this is the first call
117+ if output. is_none ( ) {
82118 let texture = self . context . device . create_texture ( & wgpu:: TextureDescriptor {
83119 label : None ,
84120 size : wgpu:: Extent3d {
85- width : size . x ,
86- height : size . y ,
121+ width : 1 ,
122+ height : 1 ,
87123 depth_or_array_layers : 1 ,
88124 } ,
89125 mip_level_count : 1 ,
@@ -94,9 +130,11 @@ impl WgpuExecutor {
94130 view_formats : & [ ] ,
95131 } ) ;
96132 let view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
97- * output = Some ( TargetTexture { texture, view, size } ) ;
98- output. as_mut ( ) . unwrap ( )
99- } ;
133+ * output = Some ( TargetTexture { texture, view, size : UVec2 :: ONE } ) ;
134+ }
135+
136+ let target_texture = output. as_mut ( ) . unwrap ( ) ;
137+ target_texture. ensure_size ( & self . context . device , size) ;
100138
101139 let [ r, g, b, a] = background. to_rgba8_srgb ( ) ;
102140 let render_params = RenderParams {
@@ -117,7 +155,7 @@ impl WgpuExecutor {
117155 } ;
118156 renderer. override_image ( & image_brush. image , Some ( texture_view) ) ;
119157 }
120- renderer. render_to_texture ( & self . context . device , & self . context . queue , scene, & target_texture. view , & render_params) ?;
158+ renderer. render_to_texture ( & self . context . device , & self . context . queue , scene, target_texture. view ( ) , & render_params) ?;
121159 for ( image_brush, _) in context. resource_overrides . iter ( ) {
122160 renderer. override_image ( & image_brush. image , None ) ;
123161 }
0 commit comments