@@ -5,7 +5,6 @@ use ruffle_render::backend::{
55use ruffle_render:: bitmap:: BitmapHandle ;
66use ruffle_render:: error:: Error ;
77use std:: any:: Any ;
8- use std:: borrow:: Cow ;
98use std:: cell:: Cell ;
109use swf:: { Rectangle , Twips } ;
1110
@@ -1007,42 +1006,45 @@ impl Context3D for WgpuContext3D {
10071006 // BitmapData's gpu texture might be modified before we actually submit
10081007 // `buffer_command_encoder` to the device.
10091008 let dest_format = dest. texture . format ( ) ;
1010- let mut bytes_per_row = dest_format. block_copy_size ( None ) . unwrap ( )
1009+ let src_bytes_per_row = dest_format. block_copy_size ( None ) . unwrap ( )
10111010 * ( source_width / dest_format. block_dimensions ( ) . 0 ) ;
10121011
10131012 let rows_per_image = source_height / dest_format. block_dimensions ( ) . 1 ;
10141013
10151014 // Wgpu requires us to pad the image rows to a multiple of COPY_BYTES_PER_ROW_ALIGNMENT
1016- let source = if ( source_width * 4 ) % COPY_BYTES_PER_ROW_ALIGNMENT != 0
1017- && matches ! ( dest. texture. format( ) , wgpu:: TextureFormat :: Rgba8Unorm )
1018- {
1019- let padded: Vec < u8 > = source
1020- . chunks_exact ( source_width as usize * 4 )
1021- . flat_map ( |row| {
1022- let padding_len = COPY_BYTES_PER_ROW_ALIGNMENT as usize
1023- - ( row. len ( ) % COPY_BYTES_PER_ROW_ALIGNMENT as usize ) ;
1024- row. iter ( )
1025- . copied ( )
1026- . chain ( std:: iter:: repeat_n ( 0 , padding_len) )
1027- } )
1028- . collect ( ) ;
1029-
1030- bytes_per_row = padded. len ( ) as u32 / source_height;
1031-
1032- Cow :: Owned ( padded)
1033- } else {
1034- Cow :: Borrowed ( source)
1035- } ;
1015+ let dest_bytes_per_row =
1016+ if matches ! ( dest. texture. format( ) , wgpu:: TextureFormat :: Rgba8Unorm ) {
1017+ ( source_width * 4 ) . next_multiple_of ( COPY_BYTES_PER_ROW_ALIGNMENT )
1018+ } else {
1019+ src_bytes_per_row
1020+ } ;
1021+ let dest_size = dest_bytes_per_row as u64 * rows_per_image as u64 ;
1022+ assert ! (
1023+ dest_bytes_per_row >= src_bytes_per_row && dest_size >= source. len( ) as u64
1024+ ) ;
10361025
10371026 let texture_buffer = self . descriptors . device . create_buffer ( & BufferDescriptor {
10381027 label : None ,
1039- size : source . len ( ) as u64 ,
1028+ size : dest_size ,
10401029 usage : BufferUsages :: COPY_SRC ,
10411030 mapped_at_creation : true ,
10421031 } ) ;
10431032
10441033 let mut texture_buffer_view = texture_buffer. slice ( ..) . get_mapped_range_mut ( ) ;
1045- texture_buffer_view. copy_from_slice ( & source) ;
1034+ if dest_bytes_per_row == src_bytes_per_row {
1035+ // No padding, we can copy everything in one go.
1036+ texture_buffer_view. copy_from_slice ( source) ;
1037+ } else {
1038+ // Copy row by row.
1039+ for ( dest, src) in texture_buffer_view
1040+ . chunks_exact_mut ( dest_bytes_per_row as usize )
1041+ . zip ( source. chunks_exact ( src_bytes_per_row as usize ) )
1042+ {
1043+ let ( dest, padding) = dest. split_at_mut ( src_bytes_per_row as usize ) ;
1044+ dest. copy_from_slice ( src) ;
1045+ padding. fill ( 0 ) ;
1046+ }
1047+ }
10461048 drop ( texture_buffer_view) ;
10471049 texture_buffer. unmap ( ) ;
10481050
@@ -1052,7 +1054,7 @@ impl Context3D for WgpuContext3D {
10521054 // The copy source uses the padded image data, with larger rows
10531055 layout : wgpu:: TexelCopyBufferLayout {
10541056 offset : 0 ,
1055- bytes_per_row : Some ( bytes_per_row ) ,
1057+ bytes_per_row : Some ( dest_bytes_per_row ) ,
10561058 rows_per_image : Some ( rows_per_image) ,
10571059 } ,
10581060 } ,
0 commit comments