@@ -67,43 +67,87 @@ void CanvasPath::RegisterNatives(tonic::DartLibraryNatives* natives) {
6767 FOR_EACH_BINDING (DART_REGISTER_NATIVE)});
6868}
6969
70- CanvasPath::CanvasPath () {}
70+ CanvasPath::CanvasPath () : weak_factory_(this ) {
71+ resetVolatility ();
72+ }
73+
74+ CanvasPath::~CanvasPath () = default ;
7175
72- CanvasPath::~CanvasPath () {}
76+ void CanvasPath::resetVolatility () {
77+ if (!tracking_volatility_) {
78+ path_.setIsVolatile (true );
79+ volatile_paths_.push_back (weak_factory_.GetWeakPtr ());
80+ tracking_volatility_ = true ;
81+ }
82+ }
83+
84+ // static
85+ std::mutex CanvasPath::volatile_paths_mutex_;
86+ // static
87+ std::vector<fml::WeakPtr<CanvasPath>> CanvasPath::volatile_paths_;
88+ // static
89+ void CanvasPath::updatePathVolatility () {
90+ FML_DCHECK (UIDartState::Current ());
91+ FML_DCHECK (UIDartState::Current ()
92+ ->GetTaskRunners ()
93+ .GetUITaskRunner ()
94+ ->RunsTasksOnCurrentThread ());
95+ std::scoped_lock guard (volatile_paths_mutex_);
96+ std::vector<fml::WeakPtr<CanvasPath>> remaining_paths;
97+ for (auto weak_path : volatile_paths_) {
98+ if (weak_path) {
99+ weak_path->volatility_count_ ++;
100+ if (weak_path->volatility_count_ >= 2 ) {
101+ weak_path->path_ .setIsVolatile (false );
102+ weak_path->tracking_volatility_ = false ;
103+ } else {
104+ remaining_paths.push_back (weak_path);
105+ }
106+ }
107+ }
108+ volatile_paths_ = std::move (remaining_paths);
109+ }
73110
74111int CanvasPath::getFillType () {
75112 return static_cast <int >(path_.getFillType ());
76113}
77114
78115void CanvasPath::setFillType (int fill_type) {
79116 path_.setFillType (static_cast <SkPathFillType>(fill_type));
117+ resetVolatility ();
80118}
81119
82120void CanvasPath::moveTo (float x, float y) {
83121 path_.moveTo (x, y);
122+ resetVolatility ();
84123}
85124
86125void CanvasPath::relativeMoveTo (float x, float y) {
87126 path_.rMoveTo (x, y);
127+ resetVolatility ();
88128}
89129
90130void CanvasPath::lineTo (float x, float y) {
91131 path_.lineTo (x, y);
132+ resetVolatility ();
92133}
93134
94135void CanvasPath::relativeLineTo (float x, float y) {
95136 path_.rLineTo (x, y);
137+ resetVolatility ();
96138}
97139
98140void CanvasPath::quadraticBezierTo (float x1, float y1, float x2, float y2) {
99141 path_.quadTo (x1, y1, x2, y2);
142+ resetVolatility ();
100143}
101144
102145void CanvasPath::relativeQuadraticBezierTo (float x1,
103146 float y1,
104147 float x2,
105148 float y2) {
106149 path_.rQuadTo (x1, y1, x2, y2);
150+ resetVolatility ();
107151}
108152
109153void CanvasPath::cubicTo (float x1,
@@ -113,6 +157,7 @@ void CanvasPath::cubicTo(float x1,
113157 float x3,
114158 float y3) {
115159 path_.cubicTo (x1, y1, x2, y2, x3, y3);
160+ resetVolatility ();
116161}
117162
118163void CanvasPath::relativeCubicTo (float x1,
@@ -122,10 +167,12 @@ void CanvasPath::relativeCubicTo(float x1,
122167 float x3,
123168 float y3) {
124169 path_.rCubicTo (x1, y1, x2, y2, x3, y3);
170+ resetVolatility ();
125171}
126172
127173void CanvasPath::conicTo (float x1, float y1, float x2, float y2, float w) {
128174 path_.conicTo (x1, y1, x2, y2, w);
175+ resetVolatility ();
129176}
130177
131178void CanvasPath::relativeConicTo (float x1,
@@ -134,6 +181,7 @@ void CanvasPath::relativeConicTo(float x1,
134181 float y2,
135182 float w) {
136183 path_.rConicTo (x1, y1, x2, y2, w);
184+ resetVolatility ();
137185}
138186
139187void CanvasPath::arcTo (float left,
@@ -146,6 +194,7 @@ void CanvasPath::arcTo(float left,
146194 path_.arcTo (SkRect::MakeLTRB (left, top, right, bottom),
147195 startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI,
148196 forceMoveTo);
197+ resetVolatility ();
149198}
150199
151200void CanvasPath::arcToPoint (float arcEndX,
@@ -162,6 +211,7 @@ void CanvasPath::arcToPoint(float arcEndX,
162211
163212 path_.arcTo (radiusX, radiusY, xAxisRotation, arcSize, direction, arcEndX,
164213 arcEndY);
214+ resetVolatility ();
165215}
166216
167217void CanvasPath::relativeArcToPoint (float arcEndDeltaX,
@@ -177,14 +227,17 @@ void CanvasPath::relativeArcToPoint(float arcEndDeltaX,
177227 isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW ;
178228 path_.rArcTo (radiusX, radiusY, xAxisRotation, arcSize, direction,
179229 arcEndDeltaX, arcEndDeltaY);
230+ resetVolatility ();
180231}
181232
182233void CanvasPath::addRect (float left, float top, float right, float bottom) {
183234 path_.addRect (SkRect::MakeLTRB (left, top, right, bottom));
235+ resetVolatility ();
184236}
185237
186238void CanvasPath::addOval (float left, float top, float right, float bottom) {
187239 path_.addOval (SkRect::MakeLTRB (left, top, right, bottom));
240+ resetVolatility ();
188241}
189242
190243void CanvasPath::addArc (float left,
@@ -195,15 +248,18 @@ void CanvasPath::addArc(float left,
195248 float sweepAngle) {
196249 path_.addArc (SkRect::MakeLTRB (left, top, right, bottom),
197250 startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI);
251+ resetVolatility ();
198252}
199253
200254void CanvasPath::addPolygon (const tonic::Float32List& points, bool close) {
201255 path_.addPoly (reinterpret_cast <const SkPoint*>(points.data ()),
202256 points.num_elements () / 2 , close);
257+ resetVolatility ();
203258}
204259
205260void CanvasPath::addRRect (const RRect& rrect) {
206261 path_.addRRect (rrect.sk_rrect );
262+ resetVolatility ();
207263}
208264
209265void CanvasPath::addPath (CanvasPath* path, double dx, double dy) {
@@ -212,6 +268,7 @@ void CanvasPath::addPath(CanvasPath* path, double dx, double dy) {
212268 return ;
213269 }
214270 path_.addPath (path->path (), dx, dy, SkPath::kAppend_AddPathMode );
271+ resetVolatility ();
215272}
216273
217274void CanvasPath::addPathWithMatrix (CanvasPath* path,
@@ -229,6 +286,7 @@ void CanvasPath::addPathWithMatrix(CanvasPath* path,
229286 matrix.setTranslateY (matrix.getTranslateY () + dy);
230287 path_.addPath (path->path (), matrix, SkPath::kAppend_AddPathMode );
231288 matrix4.Release ();
289+ resetVolatility ();
232290}
233291
234292void CanvasPath::extendWithPath (CanvasPath* path, double dx, double dy) {
@@ -238,6 +296,7 @@ void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) {
238296 return ;
239297 }
240298 path_.addPath (path->path (), dx, dy, SkPath::kExtend_AddPathMode );
299+ resetVolatility ();
241300}
242301
243302void CanvasPath::extendWithPathAndMatrix (CanvasPath* path,
@@ -255,14 +314,17 @@ void CanvasPath::extendWithPathAndMatrix(CanvasPath* path,
255314 matrix.setTranslateY (matrix.getTranslateY () + dy);
256315 path_.addPath (path->path (), matrix, SkPath::kExtend_AddPathMode );
257316 matrix4.Release ();
317+ resetVolatility ();
258318}
259319
260320void CanvasPath::close () {
261321 path_.close ();
322+ resetVolatility ();
262323}
263324
264325void CanvasPath::reset () {
265326 path_.reset ();
327+ resetVolatility ();
266328}
267329
268330bool CanvasPath::contains (double x, double y) {
@@ -272,13 +334,15 @@ bool CanvasPath::contains(double x, double y) {
272334void CanvasPath::shift (Dart_Handle path_handle, double dx, double dy) {
273335 fml::RefPtr<CanvasPath> path = CanvasPath::Create (path_handle);
274336 path_.offset (dx, dy, &path->path_ );
337+ resetVolatility ();
275338}
276339
277340void CanvasPath::transform (Dart_Handle path_handle,
278341 tonic::Float64List& matrix4) {
279342 fml::RefPtr<CanvasPath> path = CanvasPath::Create (path_handle);
280343 path_.transform (ToSkMatrix (matrix4), &path->path_ );
281344 matrix4.Release ();
345+ resetVolatility ();
282346}
283347
284348tonic::Float32List CanvasPath::getBounds () {
@@ -294,6 +358,7 @@ tonic::Float32List CanvasPath::getBounds() {
294358bool CanvasPath::op (CanvasPath* path1, CanvasPath* path2, int operation) {
295359 return Op (path1->path (), path2->path (), static_cast <SkPathOp>(operation),
296360 &path_);
361+ resetVolatility ();
297362}
298363
299364void CanvasPath::clone (Dart_Handle path_handle) {
0 commit comments