2
2
3
3
#![ allow( clippy:: uninlined_format_args) ]
4
4
5
- use std:: cmp;
6
5
use std:: convert:: TryInto ;
7
6
use std:: marker:: PhantomData ;
8
7
use std:: num:: NonZeroU32 ;
@@ -15,7 +14,7 @@ use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
15
14
use web_sys:: { OffscreenCanvas , OffscreenCanvasRenderingContext2d } ;
16
15
17
16
use crate :: error:: SwResultExt ;
18
- use crate :: { Rect , SoftBufferError } ;
17
+ use crate :: { util , Rect , SoftBufferError } ;
19
18
20
19
/// Display implementation for the web platform.
21
20
///
@@ -144,60 +143,36 @@ impl WebImpl {
144
143
. size
145
144
. expect ( "Must set size of surface before calling `present_with_damage()`" ) ;
146
145
147
- let mut damage_iter = damage. iter ( ) ;
148
-
149
- let first_rect = if let Some ( rect) = damage_iter. next ( ) {
146
+ let union_damage = if let Some ( rect) = util:: union_damage ( damage) {
150
147
rect
151
148
} else {
152
- // If there is no damage, there is nothing to do
153
149
return Ok ( ( ) ) ;
154
150
} ;
155
151
156
- struct UnionRegion {
157
- top : u32 ,
158
- left : u32 ,
159
- bottom : u32 ,
160
- right : u32 ,
161
- }
162
-
163
- let union_region = UnionRegion {
164
- top : first_rect. y ,
165
- left : first_rect. x ,
166
- bottom : ( first_rect. y + first_rect. height . get ( ) ) ,
167
- right : ( first_rect. x + first_rect. width . get ( ) ) ,
168
- } ;
169
-
170
- let union_region = damage_iter. fold ( union_region, |mut union, rect| {
171
- union. top = cmp:: min ( union. top , rect. y ) ;
172
- union. left = cmp:: min ( union. left , rect. x ) ;
173
- union. bottom = cmp:: max ( union. bottom , rect. y + rect. height . get ( ) ) ;
174
- union. right = cmp:: max ( union. right , rect. x + rect. width . get ( ) ) ;
175
- union
176
- } ) ;
177
-
178
- debug_assert ! ( union_region. right <= buffer_width. get( ) ) ;
179
- debug_assert ! ( union_region. bottom <= _buffer_height. get( ) ) ;
180
-
181
- let union_region_left = union_region. left as usize ;
182
- let union_region_top = union_region. top as usize ;
183
- let union_region_width = ( union_region. right - union_region. left ) as usize ;
184
- let union_region_height = ( union_region. bottom - union_region. top ) as usize ;
185
-
186
152
// Create a bitmap from the buffer.
187
153
let bitmap: Vec < _ > = self
188
154
. buffer
189
155
. chunks_exact ( buffer_width. get ( ) as usize )
190
- . skip ( union_region_top)
191
- . take ( union_region_height)
192
- . flat_map ( |row| row. iter ( ) . skip ( union_region_left) . take ( union_region_width) )
156
+ . skip ( union_damage. y as usize )
157
+ . take ( union_damage. height . get ( ) as usize )
158
+ . flat_map ( |row| {
159
+ row. iter ( )
160
+ . skip ( union_damage. x as usize )
161
+ . take ( union_damage. width . get ( ) as usize )
162
+ } )
193
163
. copied ( )
194
164
. flat_map ( |pixel| [ ( pixel >> 16 ) as u8 , ( pixel >> 8 ) as u8 , pixel as u8 , 255 ] )
195
165
. collect ( ) ;
196
166
197
- debug_assert_eq ! ( bitmap. len( ) , union_region_height * union_region_width * 4 ) ;
167
+ debug_assert_eq ! (
168
+ bitmap. len( ) as u32 ,
169
+ union_damage. width. get( ) * union_damage. height. get( ) * 4
170
+ ) ;
198
171
199
172
#[ cfg( target_feature = "atomics" ) ]
200
173
let result = {
174
+ // When using atomics, the underlying memory becomes `SharedArrayBuffer`,
175
+ // which can't be shared with `ImageData`.
201
176
use js_sys:: { Uint8Array , Uint8ClampedArray } ;
202
177
use wasm_bindgen:: prelude:: wasm_bindgen;
203
178
@@ -213,14 +188,14 @@ impl WebImpl {
213
188
let array = Uint8Array :: new_with_length ( bitmap. len ( ) as u32 ) ;
214
189
array. copy_from ( & bitmap) ;
215
190
let array = Uint8ClampedArray :: new ( & array) ;
216
- ImageDataExt :: new ( array, union_region_width as u32 )
191
+ ImageDataExt :: new ( array, union_damage . width . get ( ) )
217
192
. map ( JsValue :: from)
218
193
. map ( ImageData :: unchecked_from_js)
219
194
} ;
220
195
#[ cfg( not( target_feature = "atomics" ) ) ]
221
196
let result = ImageData :: new_with_u8_clamped_array (
222
197
wasm_bindgen:: Clamped ( & bitmap) ,
223
- union_region_width as u32 ,
198
+ union_damage . width . get ( ) ,
224
199
) ;
225
200
// This should only throw an error if the buffer we pass's size is incorrect.
226
201
let image_data = result. unwrap ( ) ;
@@ -230,10 +205,10 @@ impl WebImpl {
230
205
self . canvas
231
206
. put_image_data (
232
207
& image_data,
233
- union_region . left . into ( ) ,
234
- union_region . top . into ( ) ,
235
- ( rect. x - union_region . left ) . into ( ) ,
236
- ( rect. y - union_region . top ) . into ( ) ,
208
+ union_damage . x . into ( ) ,
209
+ union_damage . y . into ( ) ,
210
+ ( rect. x - union_damage . x ) . into ( ) ,
211
+ ( rect. y - union_damage . y ) . into ( ) ,
237
212
rect. width . get ( ) . into ( ) ,
238
213
rect. height . get ( ) . into ( ) ,
239
214
)
0 commit comments