11use cap_project:: XY ;
2+ use tracing;
23
34use crate :: {
45 DecodedSegmentFrames , PixelFormat ,
56 composite_frame:: { CompositeVideoFramePipeline , CompositeVideoFrameUniforms } ,
67 yuv_converter:: YuvToRgbaConverter ,
78} ;
89
9- fn copy_converted_texture (
10- device : & wgpu:: Device ,
11- queue : & wgpu:: Queue ,
12- src_texture : & wgpu:: Texture ,
13- dst_texture : & wgpu:: Texture ,
10+ struct PendingTextureCopy {
1411 width : u32 ,
1512 height : u32 ,
16- ) {
17- let mut encoder = device. create_command_encoder ( & wgpu:: CommandEncoderDescriptor {
18- label : Some ( "YUV Copy Encoder" ) ,
19- } ) ;
20-
21- encoder. copy_texture_to_texture (
22- wgpu:: TexelCopyTextureInfo {
23- texture : src_texture,
24- mip_level : 0 ,
25- origin : wgpu:: Origin3d :: ZERO ,
26- aspect : wgpu:: TextureAspect :: All ,
27- } ,
28- wgpu:: TexelCopyTextureInfo {
29- texture : dst_texture,
30- mip_level : 0 ,
31- origin : wgpu:: Origin3d :: ZERO ,
32- aspect : wgpu:: TextureAspect :: All ,
33- } ,
34- wgpu:: Extent3d {
35- width,
36- height,
37- depth_or_array_layers : 1 ,
38- } ,
39- ) ;
40-
41- queue. submit ( std:: iter:: once ( encoder. finish ( ) ) ) ;
13+ dst_texture_index : usize ,
4214}
4315
4416pub struct DisplayLayer {
@@ -50,6 +22,7 @@ pub struct DisplayLayer {
5022 bind_groups : [ Option < wgpu:: BindGroup > ; 2 ] ,
5123 last_recording_time : Option < f32 > ,
5224 yuv_converter : YuvToRgbaConverter ,
25+ pending_copy : Option < PendingTextureCopy > ,
5326}
5427
5528impl DisplayLayer {
@@ -77,6 +50,7 @@ impl DisplayLayer {
7750 bind_groups : [ bind_group_0, bind_group_1] ,
7851 last_recording_time : None ,
7952 yuv_converter,
53+ pending_copy : None ,
8054 }
8155 }
8256
@@ -88,6 +62,8 @@ impl DisplayLayer {
8862 frame_size : XY < u32 > ,
8963 uniforms : CompositeVideoFrameUniforms ,
9064 ) -> ( bool , u32 , u32 ) {
65+ self . pending_copy = None ;
66+
9167 let frame_data = segment_frames. screen_frame . data ( ) ;
9268 let actual_width = segment_frames. screen_frame . width ( ) ;
9369 let actual_height = segment_frames. screen_frame . height ( ) ;
@@ -149,27 +125,41 @@ impl DisplayLayer {
149125 if let ( Some ( y_data) , Some ( uv_data) ) =
150126 ( screen_frame. y_plane ( ) , screen_frame. uv_plane ( ) )
151127 {
152- if self
153- . yuv_converter
154- . convert_nv12 (
155- device,
156- queue,
157- y_data,
158- uv_data,
159- frame_size. x ,
160- frame_size. y ,
161- screen_frame. y_stride ( ) ,
162- )
163- . is_ok ( )
164- {
165- if let Some ( output_texture) = self . yuv_converter . output_texture ( ) {
166- copy_converted_texture (
167- device,
168- queue,
169- output_texture,
170- & self . frame_textures [ next_texture] ,
171- frame_size. x ,
172- frame_size. y ,
128+ let y_stride = screen_frame. y_stride ( ) ;
129+ let convert_result = self . yuv_converter . convert_nv12 (
130+ device,
131+ queue,
132+ y_data,
133+ uv_data,
134+ frame_size. x ,
135+ frame_size. y ,
136+ y_stride,
137+ ) ;
138+
139+ match convert_result {
140+ Ok ( _) => {
141+ if self . yuv_converter . output_texture ( ) . is_some ( ) {
142+ self . pending_copy = Some ( PendingTextureCopy {
143+ width : frame_size. x ,
144+ height : frame_size. y ,
145+ dst_texture_index : next_texture,
146+ } ) ;
147+ } else {
148+ tracing:: debug!(
149+ width = frame_size. x,
150+ height = frame_size. y,
151+ y_stride,
152+ "NV12 conversion succeeded but output texture is None, skipping copy"
153+ ) ;
154+ }
155+ }
156+ Err ( e) => {
157+ tracing:: debug!(
158+ error = ?e,
159+ width = frame_size. x,
160+ height = frame_size. y,
161+ y_stride,
162+ "NV12 to RGBA conversion failed"
173163 ) ;
174164 }
175165 }
@@ -196,17 +186,13 @@ impl DisplayLayer {
196186 screen_frame. uv_stride ( ) ,
197187 )
198188 . is_ok ( )
189+ && self . yuv_converter . output_texture ( ) . is_some ( )
199190 {
200- if let Some ( output_texture) = self . yuv_converter . output_texture ( ) {
201- copy_converted_texture (
202- device,
203- queue,
204- output_texture,
205- & self . frame_textures [ next_texture] ,
206- frame_size. x ,
207- frame_size. y ,
208- ) ;
209- }
191+ self . pending_copy = Some ( PendingTextureCopy {
192+ width : frame_size. x ,
193+ height : frame_size. y ,
194+ dst_texture_index : next_texture,
195+ } ) ;
210196 }
211197 }
212198 }
@@ -220,7 +206,35 @@ impl DisplayLayer {
220206 ( skipped, actual_width, actual_height)
221207 }
222208
223- pub fn copy_to_texture ( & mut self , _encoder : & mut wgpu:: CommandEncoder ) { }
209+ pub fn copy_to_texture ( & mut self , encoder : & mut wgpu:: CommandEncoder ) {
210+ let Some ( pending) = self . pending_copy . take ( ) else {
211+ return ;
212+ } ;
213+
214+ let Some ( src_texture) = self . yuv_converter . output_texture ( ) else {
215+ return ;
216+ } ;
217+
218+ encoder. copy_texture_to_texture (
219+ wgpu:: TexelCopyTextureInfo {
220+ texture : src_texture,
221+ mip_level : 0 ,
222+ origin : wgpu:: Origin3d :: ZERO ,
223+ aspect : wgpu:: TextureAspect :: All ,
224+ } ,
225+ wgpu:: TexelCopyTextureInfo {
226+ texture : & self . frame_textures [ pending. dst_texture_index ] ,
227+ mip_level : 0 ,
228+ origin : wgpu:: Origin3d :: ZERO ,
229+ aspect : wgpu:: TextureAspect :: All ,
230+ } ,
231+ wgpu:: Extent3d {
232+ width : pending. width ,
233+ height : pending. height ,
234+ depth_or_array_layers : 1 ,
235+ } ,
236+ ) ;
237+ }
224238
225239 pub fn render ( & self , pass : & mut wgpu:: RenderPass < ' _ > ) {
226240 if let Some ( bind_group) = & self . bind_groups [ self . current_texture ] {
0 commit comments