Skip to content

Commit 7fb901f

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

File tree

1 file changed

+75
-74
lines changed

1 file changed

+75
-74
lines changed

core/src/avm1/globals/glow_filter.rs

+75-74
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,58 @@ use crate::avm1::object::NativeObject;
55
use crate::avm1::property_decl::{define_properties_on, Declaration};
66
use crate::avm1::{Activation, Error, Object, ScriptObject, TObject, Value};
77
use crate::string::StringContext;
8-
use gc_arena::{Collect, GcCell, Mutation};
9-
use std::ops::Deref;
8+
use gc_arena::{Collect, Gc, Mutation};
9+
use std::cell::Cell;
1010
use swf::{Color, Fixed16, Fixed8, GlowFilterFlags};
1111

1212
#[derive(Clone, Debug, Collect)]
1313
#[collect(require_static)]
1414
struct GlowFilterData {
15-
color: Color,
16-
quality: i32,
17-
inner: bool,
18-
knockout: bool,
19-
blur_x: f64,
20-
blur_y: f64,
15+
color: Cell<Color>,
16+
quality: Cell<i32>,
17+
inner: Cell<bool>,
18+
knockout: Cell<bool>,
19+
blur_x: Cell<f64>,
20+
blur_y: Cell<f64>,
2121
// TODO: Introduce unsigned `Fixed8`?
22-
strength: u16,
22+
strength: Cell<u16>,
2323
}
2424

2525
impl Default for GlowFilterData {
2626
fn default() -> Self {
2727
Self {
28-
color: Color::RED,
29-
quality: 1,
30-
inner: false,
31-
knockout: false,
32-
blur_x: 6.0,
33-
blur_y: 6.0,
34-
strength: 2 << 8,
28+
color: Cell::new(Color::RED),
29+
quality: Cell::new(1),
30+
inner: Cell::new(false),
31+
knockout: Cell::new(false),
32+
blur_x: Cell::new(6.0),
33+
blur_y: Cell::new(6.0),
34+
strength: Cell::new(2 << 8),
3535
}
3636
}
3737
}
3838

3939
impl GlowFilterData {
4040
pub fn strength(&self) -> f64 {
41-
f64::from(self.strength) / 256.0
41+
f64::from(self.strength.get()) / 256.0
4242
}
4343

44-
pub fn set_strength(&mut self, strength: f64) {
45-
self.strength = ((strength * 256.0) as u16).clamp(0, 0xFF00)
44+
pub fn set_strength(&self, strength: f64) {
45+
let strength = ((strength * 256.0) as u16).clamp(0, 0xFF00);
46+
self.strength.set(strength);
4647
}
4748
}
4849

4950
impl From<&GlowFilterData> for swf::GlowFilter {
5051
fn from(filter: &GlowFilterData) -> swf::GlowFilter {
5152
let mut flags = GlowFilterFlags::COMPOSITE_SOURCE;
52-
flags |= GlowFilterFlags::from_passes(filter.quality as u8);
53-
flags.set(GlowFilterFlags::KNOCKOUT, filter.knockout);
54-
flags.set(GlowFilterFlags::INNER_GLOW, filter.inner);
53+
flags |= GlowFilterFlags::from_passes(filter.quality.get() as u8);
54+
flags.set(GlowFilterFlags::KNOCKOUT, filter.knockout.get());
55+
flags.set(GlowFilterFlags::INNER_GLOW, filter.inner.get());
5556
swf::GlowFilter {
56-
color: filter.color,
57-
blur_x: Fixed16::from_f64(filter.blur_x),
58-
blur_y: Fixed16::from_f64(filter.blur_y),
57+
color: filter.color.get(),
58+
blur_x: Fixed16::from_f64(filter.blur_x.get()),
59+
blur_y: Fixed16::from_f64(filter.blur_y.get()),
5960
strength: Fixed8::from_f64(filter.strength()),
6061
flags,
6162
}
@@ -67,25 +68,25 @@ impl From<swf::GlowFilter> for GlowFilterData {
6768
let inner = filter.is_inner();
6869
let knockout = filter.is_knockout();
6970
Self {
70-
color: filter.color,
71-
quality: filter.num_passes().into(),
72-
strength: (filter.strength.to_f64() * 256.0) as u16,
73-
knockout,
74-
blur_x: filter.blur_x.into(),
75-
blur_y: filter.blur_y.into(),
76-
inner,
71+
color: Cell::new(filter.color),
72+
quality: Cell::new(filter.num_passes().into()),
73+
strength: Cell::new((filter.strength.to_f64() * 256.0) as u16),
74+
knockout: Cell::new(knockout),
75+
blur_x: Cell::new(filter.blur_x.into()),
76+
blur_y: Cell::new(filter.blur_y.into()),
77+
inner: Cell::new(inner),
7778
}
7879
}
7980
}
8081

8182
#[derive(Copy, Clone, Debug, Collect)]
8283
#[collect(no_drop)]
8384
#[repr(transparent)]
84-
pub struct GlowFilter<'gc>(GcCell<'gc, GlowFilterData>);
85+
pub struct GlowFilter<'gc>(Gc<'gc, GlowFilterData>);
8586

8687
impl<'gc> GlowFilter<'gc> {
8788
fn new(activation: &mut Activation<'_, 'gc>, args: &[Value<'gc>]) -> Result<Self, Error<'gc>> {
88-
let glow_filter = Self(GcCell::new(activation.gc(), Default::default()));
89+
let glow_filter = Self(Gc::new(activation.gc(), Default::default()));
8990
glow_filter.set_color(activation, args.get(0))?;
9091
glow_filter.set_alpha(activation, args.get(1))?;
9192
glow_filter.set_blur_x(activation, args.get(2))?;
@@ -98,145 +99,145 @@ impl<'gc> GlowFilter<'gc> {
9899
}
99100

100101
pub fn from_filter(gc_context: &Mutation<'gc>, filter: swf::GlowFilter) -> Self {
101-
Self(GcCell::new(gc_context, filter.into()))
102+
Self(Gc::new(gc_context, filter.into()))
102103
}
103104

104-
pub(crate) fn duplicate(&self, gc_context: &Mutation<'gc>) -> Self {
105-
Self(GcCell::new(gc_context, self.0.read().clone()))
105+
pub(crate) fn duplicate(self, gc_context: &Mutation<'gc>) -> Self {
106+
Self(Gc::new(gc_context, self.0.as_ref().clone()))
106107
}
107108

108-
fn color(&self) -> i32 {
109-
self.0.read().color.to_rgb() as i32
109+
fn color(self) -> i32 {
110+
self.0.color.get().to_rgb() as i32
110111
}
111112

112113
fn set_color(
113-
&self,
114+
self,
114115
activation: &mut Activation<'_, 'gc>,
115116
value: Option<&Value<'gc>>,
116117
) -> Result<(), Error<'gc>> {
117118
if let Some(value) = value {
118119
let value = value.coerce_to_u32(activation)?;
119-
let mut write = self.0.write(activation.gc());
120-
write.color = Color::from_rgb(value, write.color.a);
120+
let color = self.0.color.get();
121+
self.0.color.set(Color::from_rgb(value, color.a));
121122
}
122123
Ok(())
123124
}
124125

125-
fn alpha(&self) -> f64 {
126-
f64::from(self.0.read().color.a) / 255.0
126+
fn alpha(self) -> f64 {
127+
f64::from(self.0.color.get().a) / 255.0
127128
}
128129

129130
fn set_alpha(
130-
&self,
131+
self,
131132
activation: &mut Activation<'_, 'gc>,
132133
value: Option<&Value<'gc>>,
133134
) -> Result<(), Error<'gc>> {
134135
if let Some(value) = value {
135136
let alpha = (value.coerce_to_f64(activation)? * 255.0) as u8;
136-
self.0.write(activation.gc()).color.a = alpha;
137+
let mut color = self.0.color.get();
138+
color.a = alpha;
139+
self.0.color.set(color);
137140
}
138141
Ok(())
139142
}
140143

141-
fn quality(&self) -> i32 {
142-
self.0.read().quality
144+
fn quality(self) -> i32 {
145+
self.0.quality.get()
143146
}
144147

145148
fn set_quality(
146-
&self,
149+
self,
147150
activation: &mut Activation<'_, 'gc>,
148151
value: Option<&Value<'gc>>,
149152
) -> Result<(), Error<'gc>> {
150153
if let Some(value) = value {
151154
let quality = value.coerce_to_i32(activation)?.clamp(0, 15);
152-
self.0.write(activation.gc()).quality = quality;
155+
self.0.quality.set(quality);
153156
}
154157
Ok(())
155158
}
156159

157-
fn inner(&self) -> bool {
158-
self.0.read().inner
160+
fn inner(self) -> bool {
161+
self.0.inner.get()
159162
}
160163

161164
fn set_inner(
162-
&self,
165+
self,
163166
activation: &mut Activation<'_, 'gc>,
164167
value: Option<&Value<'gc>>,
165168
) -> Result<(), Error<'gc>> {
166169
if let Some(value) = value {
167170
let inner = value.as_bool(activation.swf_version());
168-
self.0.write(activation.gc()).inner = inner;
171+
self.0.inner.set(inner);
169172
}
170173
Ok(())
171174
}
172175

173-
fn knockout(&self) -> bool {
174-
self.0.read().knockout
176+
fn knockout(self) -> bool {
177+
self.0.knockout.get()
175178
}
176179

177180
fn set_knockout(
178-
&self,
181+
self,
179182
activation: &mut Activation<'_, 'gc>,
180183
value: Option<&Value<'gc>>,
181184
) -> Result<(), Error<'gc>> {
182185
if let Some(value) = value {
183186
let knockout = value.as_bool(activation.swf_version());
184-
self.0.write(activation.gc()).knockout = knockout;
187+
self.0.knockout.set(knockout);
185188
}
186189
Ok(())
187190
}
188191

189-
fn blur_x(&self) -> f64 {
190-
self.0.read().blur_x
192+
fn blur_x(self) -> f64 {
193+
self.0.blur_x.get()
191194
}
192195

193196
fn set_blur_x(
194-
&self,
197+
self,
195198
activation: &mut Activation<'_, 'gc>,
196199
value: Option<&Value<'gc>>,
197200
) -> Result<(), Error<'gc>> {
198201
if let Some(value) = value {
199202
let blur_x = value.coerce_to_f64(activation)?.clamp(0.0, 255.0);
200-
self.0.write(activation.gc()).blur_x = blur_x;
203+
self.0.blur_x.set(blur_x);
201204
}
202205
Ok(())
203206
}
204207

205-
fn blur_y(&self) -> f64 {
206-
self.0.read().blur_y
208+
fn blur_y(self) -> f64 {
209+
self.0.blur_y.get()
207210
}
208211

209212
fn set_blur_y(
210-
&self,
213+
self,
211214
activation: &mut Activation<'_, 'gc>,
212215
value: Option<&Value<'gc>>,
213216
) -> Result<(), Error<'gc>> {
214217
if let Some(value) = value {
215218
let blur_y = value.coerce_to_f64(activation)?.clamp(0.0, 255.0);
216-
self.0.write(activation.gc()).blur_y = blur_y;
219+
self.0.blur_y.set(blur_y);
217220
}
218221
Ok(())
219222
}
220223

221-
fn strength(&self) -> f64 {
222-
self.0.read().strength()
224+
fn strength(self) -> f64 {
225+
self.0.strength()
223226
}
224227

225228
fn set_strength(
226-
&self,
229+
self,
227230
activation: &mut Activation<'_, 'gc>,
228231
value: Option<&Value<'gc>>,
229232
) -> Result<(), Error<'gc>> {
230233
if let Some(value) = value {
231-
self.0
232-
.write(activation.gc())
233-
.set_strength(value.coerce_to_f64(activation)?);
234+
self.0.set_strength(value.coerce_to_f64(activation)?);
234235
}
235236
Ok(())
236237
}
237238

238-
pub fn filter(&self) -> swf::GlowFilter {
239-
self.0.read().deref().into()
239+
pub fn filter(self) -> swf::GlowFilter {
240+
self.0.as_ref().into()
240241
}
241242
}
242243

0 commit comments

Comments
 (0)