@@ -13,15 +13,17 @@ use crate::prelude::*;
13
13
use crate :: tag_utils:: SwfMovie ;
14
14
use crate :: vminterface:: Instantiator ;
15
15
use core:: fmt;
16
- use gc_arena:: { Collect , GcCell , GcWeakCell , Mutation } ;
16
+ use gc_arena:: barrier:: unlock;
17
+ use gc_arena:: lock:: { Lock , RefLock } ;
18
+ use gc_arena:: { Collect , Gc , GcCell , GcWeak , Mutation } ;
17
19
use ruffle_render:: backend:: RenderBackend ;
18
20
use ruffle_render:: bitmap:: { BitmapFormat , PixelSnapping } ;
19
- use std:: cell:: { Ref , RefMut } ;
21
+ use std:: cell:: { Cell , Ref , RefMut } ;
20
22
use std:: sync:: Arc ;
21
23
22
24
#[ derive( Clone , Debug , Collect , Copy ) ]
23
25
#[ collect( no_drop) ]
24
- pub struct BitmapWeak < ' gc > ( GcWeakCell < ' gc , BitmapGraphicData < ' gc > > ) ;
26
+ pub struct BitmapWeak < ' gc > ( GcWeak < ' gc , BitmapGraphicData < ' gc > > ) ;
25
27
26
28
impl < ' gc > BitmapWeak < ' gc > {
27
29
pub fn upgrade ( self , mc : & Mutation < ' gc > ) -> Option < Bitmap < ' gc > > {
@@ -84,47 +86,46 @@ impl<'gc> BitmapClass<'gc> {
84
86
/// It can also be created in ActionScript using the `Bitmap` class.
85
87
#[ derive( Clone , Collect , Copy ) ]
86
88
#[ collect( no_drop) ]
87
- pub struct Bitmap < ' gc > ( GcCell < ' gc , BitmapGraphicData < ' gc > > ) ;
89
+ pub struct Bitmap < ' gc > ( Gc < ' gc , BitmapGraphicData < ' gc > > ) ;
88
90
89
91
impl fmt:: Debug for Bitmap < ' _ > {
90
92
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
91
93
f. debug_struct ( "Bitmap" )
92
- . field ( "ptr" , & self . 0 . as_ptr ( ) )
94
+ . field ( "ptr" , & Gc :: as_ptr ( self . 0 ) )
93
95
. finish ( )
94
96
}
95
97
}
96
98
97
99
#[ derive( Clone , Collect ) ]
98
100
#[ collect( no_drop) ]
99
101
pub struct BitmapGraphicData < ' gc > {
100
- base : DisplayObjectBase < ' gc > ,
102
+ base : RefLock < DisplayObjectBase < ' gc > > ,
101
103
id : CharacterId ,
102
104
movie : Arc < SwfMovie > ,
103
105
104
106
/// The current bitmap data object.
105
- bitmap_data : BitmapDataWrapper < ' gc > ,
107
+ bitmap_data : Lock < BitmapDataWrapper < ' gc > > ,
106
108
107
109
/// The width and height values are cached from the BitmapDataWrapper
108
110
/// when this Bitmap instance is first created,
109
111
/// and continue to be reported even if the BitmapData is disposed.
110
- width : u32 ,
111
- height : u32 ,
112
+ width : Cell < u32 > ,
113
+ height : Cell < u32 > ,
112
114
113
115
/// Whether or not bitmap smoothing is enabled.
114
- smoothing : bool ,
116
+ smoothing : Cell < bool > ,
115
117
116
118
/// How to snap this bitmap to the pixel grid
117
- #[ collect( require_static) ]
118
- pixel_snapping : PixelSnapping ,
119
+ pixel_snapping : Cell < PixelSnapping > ,
119
120
120
121
/// The AVM2 side of this object.
121
122
///
122
123
/// AVM1 code cannot directly reference `Bitmap`s, so this does not support
123
124
/// storing an AVM1 object.
124
- avm2_object : Option < Avm2Object < ' gc > > ,
125
+ avm2_object : Lock < Option < Avm2Object < ' gc > > > ,
125
126
126
127
/// The class associated with this Bitmap.
127
- avm2_bitmap_class : BitmapClass < ' gc > ,
128
+ avm2_bitmap_class : Lock < BitmapClass < ' gc > > ,
128
129
}
129
130
130
131
impl < ' gc > Bitmap < ' gc > {
@@ -148,18 +149,18 @@ impl<'gc> Bitmap<'gc> {
148
149
let width = bitmap_data. width ( ) ;
149
150
let height = bitmap_data. height ( ) ;
150
151
151
- let bitmap = Bitmap ( GcCell :: new (
152
+ let bitmap = Bitmap ( Gc :: new (
152
153
mc,
153
154
BitmapGraphicData {
154
155
base : Default :: default ( ) ,
155
156
id,
156
- bitmap_data,
157
- width,
158
- height,
159
- smoothing,
160
- pixel_snapping : PixelSnapping :: Auto ,
161
- avm2_object : None ,
162
- avm2_bitmap_class : BitmapClass :: NoSubclass ,
157
+ bitmap_data : Lock :: new ( bitmap_data ) ,
158
+ width : Cell :: new ( width ) ,
159
+ height : Cell :: new ( height ) ,
160
+ smoothing : Cell :: new ( smoothing ) ,
161
+ pixel_snapping : Cell :: new ( PixelSnapping :: Auto ) ,
162
+ avm2_object : Lock :: new ( None ) ,
163
+ avm2_bitmap_class : Lock :: new ( BitmapClass :: NoSubclass ) ,
163
164
movie : movie. clone ( ) ,
164
165
} ,
165
166
) ) ;
@@ -205,28 +206,28 @@ impl<'gc> Bitmap<'gc> {
205
206
// values on this object. See the definition of these fields
206
207
// for more information
207
208
pub fn width ( self ) -> u16 {
208
- self . 0 . read ( ) . width as u16
209
+ self . 0 . width . get ( ) as u16
209
210
}
210
211
211
212
pub fn height ( self ) -> u16 {
212
- self . 0 . read ( ) . height as u16
213
+ self . 0 . height . get ( ) as u16
213
214
}
214
215
215
216
pub fn pixel_snapping ( self ) -> PixelSnapping {
216
- self . 0 . read ( ) . pixel_snapping
217
+ self . 0 . pixel_snapping . get ( )
217
218
}
218
219
219
- pub fn set_pixel_snapping ( self , mc : & Mutation < ' gc > , value : PixelSnapping ) {
220
- self . 0 . write ( mc ) . pixel_snapping = value;
220
+ pub fn set_pixel_snapping ( self , value : PixelSnapping ) {
221
+ self . 0 . pixel_snapping . set ( value) ;
221
222
}
222
223
223
224
pub fn bitmap_data_wrapper ( self ) -> BitmapDataWrapper < ' gc > {
224
- self . 0 . read ( ) . bitmap_data
225
+ self . 0 . bitmap_data . get ( )
225
226
}
226
227
227
228
/// Retrieve the bitmap data associated with this `Bitmap`.
228
229
pub fn bitmap_data ( self , renderer : & mut dyn RenderBackend ) -> GcCell < ' gc , BitmapData < ' gc > > {
229
- self . 0 . read ( ) . bitmap_data . sync ( renderer)
230
+ self . 0 . bitmap_data . get ( ) . sync ( renderer)
230
231
}
231
232
232
233
/// Associate this `Bitmap` with new `BitmapData`.
@@ -243,72 +244,81 @@ impl<'gc> Bitmap<'gc> {
243
244
bitmap_data : BitmapDataWrapper < ' gc > ,
244
245
) {
245
246
let weak_self = DisplayObjectWeak :: Bitmap ( self . downgrade ( ) ) ;
246
- let mut write = self . 0 . write ( context. gc ( ) ) ;
247
247
248
- write
248
+ self . 0
249
249
. bitmap_data
250
+ . get ( )
250
251
. remove_display_object ( context. gc ( ) , weak_self) ;
251
252
252
253
// Refresh our cached values, even if we're writing the same BitmapData
253
254
// that we currently have stored. This will update them to '0' if the
254
255
// BitmapData has been disposed since it was originally set.
255
- write. width = bitmap_data. width ( ) ;
256
- write. height = bitmap_data. height ( ) ;
257
- write. bitmap_data = bitmap_data;
256
+ self . 0 . width . set ( bitmap_data. width ( ) ) ;
257
+ self . 0 . height . set ( bitmap_data. height ( ) ) ;
258
+ unlock ! (
259
+ Gc :: write( context. gc( ) , self . 0 ) ,
260
+ BitmapGraphicData ,
261
+ bitmap_data
262
+ )
263
+ . set ( bitmap_data) ;
258
264
259
265
bitmap_data. add_display_object ( context. gc ( ) , weak_self) ;
260
266
}
261
267
262
268
pub fn avm2_bitmapdata_class ( self ) -> Option < Avm2ClassObject < ' gc > > {
263
- match self . 0 . read ( ) . avm2_bitmap_class {
269
+ match self . 0 . avm2_bitmap_class . get ( ) {
264
270
BitmapClass :: BitmapData ( c) => Some ( c) ,
265
271
_ => None ,
266
272
}
267
273
}
268
274
269
275
pub fn avm2_bitmap_class ( self ) -> Option < Avm2ClassObject < ' gc > > {
270
- match self . 0 . read ( ) . avm2_bitmap_class {
276
+ match self . 0 . avm2_bitmap_class . get ( ) {
271
277
BitmapClass :: Bitmap ( c) => Some ( c) ,
272
278
_ => None ,
273
279
}
274
280
}
275
281
276
282
pub fn set_avm2_bitmapdata_class ( self , mc : & Mutation < ' gc > , class : BitmapClass < ' gc > ) {
277
- self . 0 . write ( mc) . avm2_bitmap_class = class;
283
+ unlock ! ( Gc :: write( mc, self . 0 ) , BitmapGraphicData , avm2_bitmap_class) . set ( class) ;
284
+ }
285
+
286
+ fn set_avm2_object ( self , mc : & Mutation < ' gc > , object : Option < Avm2Object < ' gc > > ) {
287
+ unlock ! ( Gc :: write( mc, self . 0 ) , BitmapGraphicData , avm2_object) . set ( object) ;
278
288
}
279
289
280
290
pub fn smoothing ( self ) -> bool {
281
- self . 0 . read ( ) . smoothing
291
+ self . 0 . smoothing . get ( )
282
292
}
283
293
284
- pub fn set_smoothing ( self , mc : & Mutation < ' gc > , smoothing : bool ) {
285
- self . 0 . write ( mc ) . smoothing = smoothing ;
294
+ pub fn set_smoothing ( self , smoothing : bool ) {
295
+ self . 0 . smoothing . set ( smoothing) ;
286
296
}
287
297
288
298
pub fn downgrade ( self ) -> BitmapWeak < ' gc > {
289
- BitmapWeak ( GcCell :: downgrade ( self . 0 ) )
299
+ BitmapWeak ( Gc :: downgrade ( self . 0 ) )
290
300
}
291
301
}
292
302
293
303
impl < ' gc > TDisplayObject < ' gc > for Bitmap < ' gc > {
294
304
fn base ( & self ) -> Ref < DisplayObjectBase < ' gc > > {
295
- Ref :: map ( self . 0 . read ( ) , |r| & r . base )
305
+ self . 0 . base . borrow ( )
296
306
}
297
307
298
308
fn base_mut < ' a > ( & ' a self , mc : & Mutation < ' gc > ) -> RefMut < ' a , DisplayObjectBase < ' gc > > {
299
- RefMut :: map ( self . 0 . write ( mc ) , |w| & mut w . base )
309
+ unlock ! ( Gc :: write ( mc , self . 0 ) , BitmapGraphicData , base) . borrow_mut ( )
300
310
}
301
311
302
312
fn instantiate ( & self , gc_context : & Mutation < ' gc > ) -> DisplayObject < ' gc > {
303
- Self ( GcCell :: new ( gc_context, self . 0 . read ( ) . clone ( ) ) ) . into ( )
313
+ Self ( Gc :: new ( gc_context, self . 0 . as_ref ( ) . clone ( ) ) ) . into ( )
304
314
}
305
315
306
316
fn as_ptr ( & self ) -> * const DisplayObjectPtr {
307
- self . 0 . as_ptr ( ) as * const DisplayObjectPtr
317
+ Gc :: as_ptr ( self . 0 ) as * const DisplayObjectPtr
308
318
}
309
319
310
320
fn id ( & self ) -> CharacterId {
311
- self . 0 . read ( ) . id
321
+ self . 0 . id
312
322
}
313
323
314
324
fn self_bounds ( & self ) -> Rectangle < Twips > {
@@ -345,7 +355,7 @@ impl<'gc> TDisplayObject<'gc> for Bitmap<'gc> {
345
355
bitmap_cls,
346
356
)
347
357
. expect ( "can't throw from post_instantiation -_-" ) ;
348
- self . 0 . write ( mc ) . avm2_object = Some ( bitmap. into ( ) ) ;
358
+ self . set_avm2_object ( activation . gc ( ) , Some ( bitmap. into ( ) ) ) ;
349
359
350
360
// Use a dummy BitmapData when calling the constructor on the user subclass
351
361
// - the constructor should see an invalid BitmapData before calling 'super',
@@ -379,29 +389,30 @@ impl<'gc> TDisplayObject<'gc> for Bitmap<'gc> {
379
389
return ;
380
390
}
381
391
382
- let bitmap_data = self . 0 . read ( ) ;
383
- bitmap_data
384
- . bitmap_data
385
- . render ( bitmap_data. smoothing , context, bitmap_data. pixel_snapping ) ;
392
+ self . 0 . bitmap_data . get ( ) . render (
393
+ self . 0 . smoothing . get ( ) ,
394
+ context,
395
+ self . 0 . pixel_snapping . get ( ) ,
396
+ ) ;
386
397
}
387
398
388
399
fn object2 ( & self ) -> Avm2Value < ' gc > {
389
400
self . 0
390
- . read ( )
391
401
. avm2_object
402
+ . get ( )
392
403
. map ( |o| o. into ( ) )
393
404
. unwrap_or ( Avm2Value :: Null )
394
405
}
395
406
396
407
fn set_object2 ( & self , context : & mut UpdateContext < ' gc > , to : Avm2Object < ' gc > ) {
397
- self . 0 . write ( context. gc ( ) ) . avm2_object = Some ( to) ;
408
+ self . set_avm2_object ( context. gc ( ) , Some ( to) ) ;
398
409
}
399
410
400
411
fn as_bitmap ( self ) -> Option < Bitmap < ' gc > > {
401
412
Some ( self )
402
413
}
403
414
404
415
fn movie ( & self ) -> Arc < SwfMovie > {
405
- self . 0 . read ( ) . movie . clone ( )
416
+ self . 0 . movie . clone ( )
406
417
}
407
418
}
0 commit comments