@@ -42,6 +42,7 @@ pub struct Surface {
4242}
4343
4444pub struct TargetTexture {
45+ texture : wgpu:: Texture ,
4546 view : wgpu:: TextureView ,
4647 size : UVec2 ,
4748}
@@ -60,29 +61,6 @@ const VELLO_SURFACE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unor
6061impl WgpuExecutor {
6162 pub async fn render_vello_scene ( & self , scene : & Scene , surface : & WgpuSurface , size : UVec2 , context : & RenderContext , background : Color ) -> Result < ( ) > {
6263 let mut guard = surface. surface . target_texture . lock ( ) . await ;
63- let target_texture = if let Some ( target_texture) = & * guard
64- && target_texture. size == size
65- {
66- target_texture
67- } else {
68- let texture = self . context . device . create_texture ( & wgpu:: TextureDescriptor {
69- label : None ,
70- size : wgpu:: Extent3d {
71- width : size. x ,
72- height : size. y ,
73- depth_or_array_layers : 1 ,
74- } ,
75- mip_level_count : 1 ,
76- sample_count : 1 ,
77- dimension : wgpu:: TextureDimension :: D2 ,
78- usage : wgpu:: TextureUsages :: STORAGE_BINDING | wgpu:: TextureUsages :: TEXTURE_BINDING ,
79- format : VELLO_SURFACE_FORMAT ,
80- view_formats : & [ ] ,
81- } ) ;
82- let view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
83- * guard = Some ( TargetTexture { size, view } ) ;
84- guard. as_ref ( ) . unwrap ( )
85- } ;
8664
8765 let surface_inner = & surface. surface . inner ;
8866 let surface_caps = surface_inner. get_capabilities ( & self . context . adapter ) ;
@@ -100,39 +78,14 @@ impl WgpuExecutor {
10078 } ,
10179 ) ;
10280
103- let [ r, g, b, _] = background. to_rgba8_srgb ( ) ;
104- let render_params = RenderParams {
105- // We are using an explicit opaque color here to eliminate the alpha premultiplication step
106- // which would be required to support a transparent webgpu canvas
107- base_color : vello:: peniko:: Color :: from_rgba8 ( r, g, b, 0xff ) ,
108- width : size. x ,
109- height : size. y ,
110- antialiasing_method : AaConfig :: Msaa16 ,
111- } ;
112-
113- {
114- let mut renderer = self . vello_renderer . lock ( ) . await ;
115- for ( image, texture) in context. resource_overrides . iter ( ) {
116- let texture_view = wgpu:: TexelCopyTextureInfoBase {
117- texture : texture. clone ( ) ,
118- mip_level : 0 ,
119- origin : Origin3d :: ZERO ,
120- aspect : TextureAspect :: All ,
121- } ;
122- renderer. override_image ( image, Some ( texture_view) ) ;
123- }
124- renderer. render_to_texture ( & self . context . device , & self . context . queue , scene, & target_texture. view , & render_params) ?;
125- for ( image, _) in context. resource_overrides . iter ( ) {
126- renderer. override_image ( image, None ) ;
127- }
128- }
81+ self . render_vello_scene_to_target_texture ( scene, size, context, background, & mut guard) . await ?;
12982
13083 let surface_texture = surface_inner. get_current_texture ( ) ?;
13184 let mut encoder = self . context . device . create_command_encoder ( & wgpu:: CommandEncoderDescriptor { label : Some ( "Surface Blit" ) } ) ;
13285 surface. surface . blitter . copy (
13386 & self . context . device ,
13487 & mut encoder,
135- & target_texture . view ,
88+ & guard . as_ref ( ) . unwrap ( ) . view ,
13689 & surface_texture. texture . create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ,
13790 ) ;
13891 self . context . queue . submit ( [ encoder. finish ( ) ] ) ;
@@ -142,21 +95,35 @@ impl WgpuExecutor {
14295 }
14396
14497 pub async fn render_vello_scene_to_texture ( & self , scene : & Scene , size : UVec2 , context : & RenderContext , background : Color ) -> Result < wgpu:: Texture > {
145- let texture = self . context . device . create_texture ( & wgpu:: TextureDescriptor {
146- label : None ,
147- size : wgpu:: Extent3d {
148- width : size. x . max ( 1 ) ,
149- height : size. y . max ( 1 ) ,
150- depth_or_array_layers : 1 ,
151- } ,
152- mip_level_count : 1 ,
153- sample_count : 1 ,
154- dimension : wgpu:: TextureDimension :: D2 ,
155- usage : wgpu:: TextureUsages :: STORAGE_BINDING | wgpu:: TextureUsages :: TEXTURE_BINDING ,
156- format : VELLO_SURFACE_FORMAT ,
157- view_formats : & [ ] ,
158- } ) ;
159- let view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
98+ let mut output = None ;
99+ self . render_vello_scene_to_target_texture ( scene, size, context, background, & mut output) . await ?;
100+ Ok ( output. unwrap ( ) . texture )
101+ }
102+
103+ async fn render_vello_scene_to_target_texture ( & self , scene : & Scene , size : UVec2 , context : & RenderContext , background : Color , output : & mut Option < TargetTexture > ) -> Result < ( ) > {
104+ let target_texture = if let Some ( target_texture) = output
105+ && target_texture. size == size
106+ {
107+ target_texture
108+ } else {
109+ let texture = self . context . device . create_texture ( & wgpu:: TextureDescriptor {
110+ label : None ,
111+ size : wgpu:: Extent3d {
112+ width : size. x ,
113+ height : size. y ,
114+ depth_or_array_layers : 1 ,
115+ } ,
116+ mip_level_count : 1 ,
117+ sample_count : 1 ,
118+ dimension : wgpu:: TextureDimension :: D2 ,
119+ usage : wgpu:: TextureUsages :: STORAGE_BINDING | wgpu:: TextureUsages :: TEXTURE_BINDING ,
120+ format : VELLO_SURFACE_FORMAT ,
121+ view_formats : & [ ] ,
122+ } ) ;
123+ let view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
124+ * output = Some ( TargetTexture { texture, view, size } ) ;
125+ output. as_mut ( ) . unwrap ( )
126+ } ;
160127
161128 let [ r, g, b, _] = background. to_rgba8_srgb ( ) ;
162129 let render_params = RenderParams {
@@ -179,13 +146,12 @@ impl WgpuExecutor {
179146 } ;
180147 renderer. override_image ( image, Some ( texture_view) ) ;
181148 }
182- renderer. render_to_texture ( & self . context . device , & self . context . queue , scene, & view, & render_params) ?;
149+ renderer. render_to_texture ( & self . context . device , & self . context . queue , scene, & target_texture . view , & render_params) ?;
183150 for ( image, _) in context. resource_overrides . iter ( ) {
184151 renderer. override_image ( image, None ) ;
185152 }
186153 }
187-
188- Ok ( texture)
154+ Ok ( ( ) )
189155 }
190156
191157 #[ cfg( target_arch = "wasm32" ) ]
@@ -214,26 +180,9 @@ impl WgpuExecutor {
214180
215181impl WgpuExecutor {
216182 pub async fn new ( ) -> Option < Self > {
217- let context = Context :: new ( ) . await ?;
218-
219- let vello_renderer = Renderer :: new (
220- & context. device ,
221- RendererOptions {
222- // surface_format: Some(wgpu::TextureFormat::Rgba8Unorm),
223- pipeline_cache : None ,
224- use_cpu : false ,
225- antialiasing_support : AaSupport :: all ( ) ,
226- num_init_threads : std:: num:: NonZeroUsize :: new ( 1 ) ,
227- } ,
228- )
229- . map_err ( |e| anyhow:: anyhow!( "Failed to create Vello renderer: {:?}" , e) )
230- . ok ( ) ?;
231-
232- Some ( Self {
233- context,
234- vello_renderer : vello_renderer. into ( ) ,
235- } )
183+ Self :: with_context ( Context :: new ( ) . await ?)
236184 }
185+
237186 pub fn with_context ( context : Context ) -> Option < Self > {
238187 let vello_renderer = Renderer :: new (
239188 & context. device ,
0 commit comments