Skip to content

Commit 3c85d80

Browse files
committed
avm1: Replace GcCell with Gc in DisplacementMapFilter
This refactor replaces GcCell with Gc and uses interior mutability instead.
1 parent 7fb901f commit 3c85d80

File tree

1 file changed

+79
-72
lines changed

1 file changed

+79
-72
lines changed

core/src/avm1/globals/displacement_map_filter.rs

+79-72
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,53 @@ use crate::avm1::{Activation, Error, Object, ScriptObject, TObject, Value};
88
use crate::bitmap::bitmap_data::BitmapDataWrapper;
99
use crate::context::UpdateContext;
1010
use crate::string::StringContext;
11-
use gc_arena::{Collect, GcCell, Mutation};
11+
use gc_arena::barrier::unlock;
12+
use gc_arena::lock::Lock;
13+
use gc_arena::{Collect, Gc, Mutation};
1214
use ruffle_macros::istr;
1315
use ruffle_render::filters::DisplacementMapFilterMode;
16+
use std::cell::Cell;
1417
use std::fmt::Debug;
1518
use swf::{Color, Point};
1619

1720
#[derive(Clone, Collect, Debug, Default)]
1821
#[collect(no_drop)]
1922
struct DisplacementMapFilterData<'gc> {
20-
map_bitmap: Option<BitmapDataWrapper<'gc>>,
21-
#[collect(require_static)]
22-
map_point: Point<i32>,
23-
component_x: i32,
24-
component_y: i32,
25-
scale_x: f32,
26-
scale_y: f32,
27-
28-
#[collect(require_static)]
29-
mode: DisplacementMapFilterMode,
30-
31-
#[collect(require_static)]
32-
color: Color,
23+
map_bitmap: Lock<Option<BitmapDataWrapper<'gc>>>,
24+
map_point: Cell<Point<i32>>,
25+
component_x: Cell<i32>,
26+
component_y: Cell<i32>,
27+
scale_x: Cell<f32>,
28+
scale_y: Cell<f32>,
29+
mode: Cell<DisplacementMapFilterMode>,
30+
color: Cell<Color>,
3331
}
3432

3533
impl<'gc> From<ruffle_render::filters::DisplacementMapFilter> for DisplacementMapFilterData<'gc> {
3634
fn from(
3735
filter: ruffle_render::filters::DisplacementMapFilter,
3836
) -> DisplacementMapFilterData<'gc> {
3937
Self {
40-
map_bitmap: None, // TODO: We can't store this object yet
41-
map_point: Point::new(filter.map_point.0, filter.map_point.1),
42-
component_x: filter.component_x as i32,
43-
component_y: filter.component_y as i32,
44-
scale_x: filter.scale_x,
45-
scale_y: filter.scale_y,
46-
mode: filter.mode,
47-
color: filter.color,
38+
map_bitmap: Lock::new(None), // TODO: We can't store this object yet
39+
map_point: Cell::new(Point::new(filter.map_point.0, filter.map_point.1)),
40+
component_x: Cell::new(filter.component_x as i32),
41+
component_y: Cell::new(filter.component_y as i32),
42+
scale_x: Cell::new(filter.scale_x),
43+
scale_y: Cell::new(filter.scale_y),
44+
mode: Cell::new(filter.mode),
45+
color: Cell::new(filter.color),
4846
}
4947
}
5048
}
5149

5250
#[derive(Copy, Clone, Debug, Collect)]
5351
#[collect(no_drop)]
5452
#[repr(transparent)]
55-
pub struct DisplacementMapFilter<'gc>(GcCell<'gc, DisplacementMapFilterData<'gc>>);
53+
pub struct DisplacementMapFilter<'gc>(Gc<'gc, DisplacementMapFilterData<'gc>>);
5654

5755
impl<'gc> DisplacementMapFilter<'gc> {
5856
fn new(activation: &mut Activation<'_, 'gc>, args: &[Value<'gc>]) -> Result<Self, Error<'gc>> {
59-
let displacement_map_filter = Self(GcCell::new(activation.gc(), Default::default()));
57+
let displacement_map_filter = Self(Gc::new(activation.gc(), Default::default()));
6058
displacement_map_filter.set_map_bitmap(activation, args.get(0))?;
6159
displacement_map_filter.set_map_point(activation, args.get(1))?;
6260
displacement_map_filter.set_component_x(activation, args.get(2))?;
@@ -73,15 +71,15 @@ impl<'gc> DisplacementMapFilter<'gc> {
7371
gc_context: &Mutation<'gc>,
7472
filter: ruffle_render::filters::DisplacementMapFilter,
7573
) -> Self {
76-
Self(GcCell::new(gc_context, filter.into()))
74+
Self(Gc::new(gc_context, filter.into()))
7775
}
7876

79-
pub(crate) fn duplicate(&self, gc_context: &Mutation<'gc>) -> Self {
80-
Self(GcCell::new(gc_context, self.0.read().clone()))
77+
pub(crate) fn duplicate(self, gc_context: &Mutation<'gc>) -> Self {
78+
Self(Gc::new(gc_context, self.0.as_ref().clone()))
8179
}
8280

83-
fn map_bitmap(&self, context: &mut UpdateContext<'gc>) -> Option<Object<'gc>> {
84-
if let Some(map_bitmap) = self.0.read().map_bitmap {
81+
fn map_bitmap(self, context: &mut UpdateContext<'gc>) -> Option<Object<'gc>> {
82+
if let Some(map_bitmap) = self.0.map_bitmap.get() {
8583
let proto = context.avm1.prototypes().bitmap_data;
8684
let result = ScriptObject::new(&context.strings, Some(proto));
8785
result.set_native(context.gc(), NativeObject::BitmapData(map_bitmap));
@@ -92,27 +90,32 @@ impl<'gc> DisplacementMapFilter<'gc> {
9290
}
9391

9492
fn set_map_bitmap(
95-
&self,
93+
self,
9694
activation: &mut Activation<'_, 'gc>,
9795
value: Option<&Value<'gc>>,
9896
) -> Result<(), Error<'gc>> {
9997
if let Some(Value::Object(object)) = value {
10098
if let NativeObject::BitmapData(bitmap_data) = object.native() {
101-
self.0.write(activation.gc()).map_bitmap = Some(bitmap_data);
99+
unlock!(
100+
Gc::write(activation.gc(), self.0),
101+
DisplacementMapFilterData,
102+
map_bitmap
103+
)
104+
.set(Some(bitmap_data));
102105
}
103106
}
104107
Ok(())
105108
}
106109

107-
fn map_point(&self, activation: &mut Activation<'_, 'gc>) -> Result<Value<'gc>, Error<'gc>> {
108-
let map_point = self.0.read().map_point;
110+
fn map_point(self, activation: &mut Activation<'_, 'gc>) -> Result<Value<'gc>, Error<'gc>> {
111+
let map_point = self.0.map_point.get();
109112
let args = &[map_point.x.into(), map_point.y.into()];
110113
let constructor = activation.context.avm1.prototypes().point_constructor;
111114
constructor.construct(activation, args)
112115
}
113116

114117
fn set_map_point(
115-
&self,
118+
self,
116119
activation: &mut Activation<'_, 'gc>,
117120
value: Option<&Value<'gc>>,
118121
) -> Result<(), Error<'gc>> {
@@ -123,90 +126,90 @@ impl<'gc> DisplacementMapFilter<'gc> {
123126
let x = x.coerce_to_f64(activation)?.clamp_to_i32();
124127
if let Some(y) = object.get_local_stored(istr!("y"), activation, false) {
125128
let y = y.coerce_to_f64(activation)?.clamp_to_i32();
126-
self.0.write(activation.gc()).map_point = Point::new(x, y);
129+
self.0.map_point.set(Point::new(x, y));
127130
return Ok(());
128131
}
129132
}
130133
}
131134

132-
self.0.write(activation.gc()).map_point = Point::default();
135+
self.0.map_point.set(Point::default());
133136
Ok(())
134137
}
135138

136-
fn component_x(&self) -> i32 {
137-
self.0.read().component_x
139+
fn component_x(self) -> i32 {
140+
self.0.component_x.get()
138141
}
139142

140143
fn set_component_x(
141-
&self,
144+
self,
142145
activation: &mut Activation<'_, 'gc>,
143146
value: Option<&Value<'gc>>,
144147
) -> Result<(), Error<'gc>> {
145148
if let Some(value) = value {
146149
let component_x = value.coerce_to_i32(activation)?;
147-
self.0.write(activation.gc()).component_x = component_x;
150+
self.0.component_x.set(component_x);
148151
}
149152
Ok(())
150153
}
151154

152-
fn component_y(&self) -> i32 {
153-
self.0.read().component_y
155+
fn component_y(self) -> i32 {
156+
self.0.component_y.get()
154157
}
155158

156159
fn set_component_y(
157-
&self,
160+
self,
158161
activation: &mut Activation<'_, 'gc>,
159162
value: Option<&Value<'gc>>,
160163
) -> Result<(), Error<'gc>> {
161164
if let Some(value) = value {
162165
let component_y = value.coerce_to_i32(activation)?;
163-
self.0.write(activation.gc()).component_y = component_y;
166+
self.0.component_y.set(component_y);
164167
}
165168
Ok(())
166169
}
167170

168-
fn scale_x(&self) -> f32 {
169-
self.0.read().scale_x
171+
fn scale_x(self) -> f32 {
172+
self.0.scale_x.get()
170173
}
171174

172175
fn set_scale_x(
173-
&self,
176+
self,
174177
activation: &mut Activation<'_, 'gc>,
175178
value: Option<&Value<'gc>>,
176179
) -> Result<(), Error<'gc>> {
177180
if let Some(value) = value {
178181
const MAX: f64 = u16::MAX as f64;
179182
const MIN: f64 = -MAX;
180183
let scale_x = value.coerce_to_f64(activation)?.clamp_also_nan(MIN, MAX);
181-
self.0.write(activation.gc()).scale_x = scale_x as f32;
184+
self.0.scale_x.set(scale_x as f32);
182185
}
183186
Ok(())
184187
}
185188

186-
fn scale_y(&self) -> f32 {
187-
self.0.read().scale_y
189+
fn scale_y(self) -> f32 {
190+
self.0.scale_y.get()
188191
}
189192

190193
fn set_scale_y(
191-
&self,
194+
self,
192195
activation: &mut Activation<'_, 'gc>,
193196
value: Option<&Value<'gc>>,
194197
) -> Result<(), Error<'gc>> {
195198
if let Some(value) = value {
196199
const MAX: f64 = u16::MAX as f64;
197200
const MIN: f64 = -MAX;
198201
let scale_y = value.coerce_to_f64(activation)?.clamp_also_nan(MIN, MAX);
199-
self.0.write(activation.gc()).scale_y = scale_y as f32;
202+
self.0.scale_y.set(scale_y as f32);
200203
}
201204
Ok(())
202205
}
203206

204-
fn mode(&self) -> DisplacementMapFilterMode {
205-
self.0.read().mode
207+
fn mode(self) -> DisplacementMapFilterMode {
208+
self.0.mode.get()
206209
}
207210

208211
fn set_mode(
209-
&self,
212+
self,
210213
activation: &mut Activation<'_, 'gc>,
211214
value: Option<&Value<'gc>>,
212215
) -> Result<(), Error<'gc>> {
@@ -223,56 +226,60 @@ impl<'gc> DisplacementMapFilter<'gc> {
223226
DisplacementMapFilterMode::Wrap
224227
};
225228

226-
self.0.write(activation.gc()).mode = mode;
229+
self.0.mode.set(mode);
227230
}
228231
Ok(())
229232
}
230233

231-
fn color(&self) -> Color {
232-
self.0.read().color
234+
fn color(self) -> Color {
235+
self.0.color.get()
233236
}
234237

235238
fn set_color(
236-
&self,
239+
self,
237240
activation: &mut Activation<'_, 'gc>,
238241
value: Option<&Value<'gc>>,
239242
) -> Result<(), Error<'gc>> {
240243
if let Some(value) = value {
241244
let value = value.coerce_to_u32(activation)?;
242-
let mut write = self.0.write(activation.gc());
243-
write.color = Color::from_rgb(value, write.color.a);
245+
let color = self.0.color.get();
246+
self.0.color.set(Color::from_rgb(value, color.a));
244247
}
245248
Ok(())
246249
}
247250

248251
fn set_alpha(
249-
&self,
252+
self,
250253
activation: &mut Activation<'_, 'gc>,
251254
value: Option<&Value<'gc>>,
252255
) -> Result<(), Error<'gc>> {
253256
if let Some(value) = value {
254257
let alpha = value.coerce_to_f64(activation)?.clamp_also_nan(0.0, 1.0);
255-
self.0.write(activation.gc()).color.a = (alpha * 255.0) as u8;
258+
let mut color = self.0.color.get();
259+
color.a = (alpha * 255.0) as u8;
260+
self.0.color.set(color);
256261
}
257262
Ok(())
258263
}
259264

260265
pub fn filter(
261-
&self,
266+
self,
262267
context: &mut UpdateContext<'gc>,
263268
) -> ruffle_render::filters::DisplacementMapFilter {
264-
let filter = self.0.read();
269+
let filter = self.0;
270+
let map_point = filter.map_point.get();
265271
ruffle_render::filters::DisplacementMapFilter {
266-
color: filter.color,
267-
component_x: filter.component_x as u8,
268-
component_y: filter.component_y as u8,
272+
color: filter.color.get(),
273+
component_x: filter.component_x.get() as u8,
274+
component_y: filter.component_y.get() as u8,
269275
map_bitmap: filter
270276
.map_bitmap
277+
.get()
271278
.map(|b| b.bitmap_handle(context.gc(), context.renderer)),
272-
map_point: (filter.map_point.x, filter.map_point.y),
273-
mode: filter.mode,
274-
scale_x: filter.scale_x,
275-
scale_y: filter.scale_y,
279+
map_point: (map_point.x, map_point.y),
280+
mode: filter.mode.get(),
281+
scale_x: filter.scale_x.get(),
282+
scale_y: filter.scale_y.get(),
276283
viewscale_x: 1.0,
277284
viewscale_y: 1.0,
278285
}

0 commit comments

Comments
 (0)