@@ -91,6 +91,10 @@ class PersistedPicture extends PersistedLeafSurface {
9191 final ui.Rect ? localPaintBounds;
9292 final int hints;
9393 double _density = 1.0 ;
94+ /// Cull rect changes and density changes due to transforms should
95+ /// call applyPaint for picture when retain() or update() is called after
96+ /// preroll is complete.
97+ bool _requiresRepaint = false ;
9498
9599 /// Cache for reusing elements such as images across picture updates.
96100 CrossFrameCache <html.HtmlElement >? _elementCache =
@@ -114,16 +118,7 @@ class PersistedPicture extends PersistedLeafSurface {
114118 ? 1.0 : _computePixelDensity (_transform, paintWidth, paintHeight);
115119 if (newDensity != _density) {
116120 _density = newDensity;
117- if (_canvas != null ) {
118- // If cull rect and density hasn't changed, this will only repaint.
119- // If density doesn't match canvas, a new canvas will be created
120- // and paint queued.
121- //
122- // Similar to preroll for transform where transform is updated, for
123- // picture this means we need to repaint so pixelation doesn't occur
124- // due to transform changing overall dpi.
125- applyPaint (_canvas);
126- }
121+ _requiresRepaint = true ;
127122 }
128123 _computeExactCullRects ();
129124 }
@@ -204,13 +199,14 @@ class PersistedPicture extends PersistedLeafSurface {
204199 }
205200 }
206201
207- bool _computeOptimalCullRect (PersistedPicture ? oldSurface) {
202+ void _computeOptimalCullRect (PersistedPicture ? oldSurface) {
208203 assert (_exactLocalCullRect != null );
209204
210205 if (oldSurface == null || ! oldSurface.picture.recordingCanvas! .didDraw) {
211206 // First useful paint.
212207 _optimalLocalCullRect = _exactLocalCullRect;
213- return true ;
208+ _requiresRepaint = true ;
209+ return ;
214210 }
215211
216212 assert (oldSurface._optimalLocalCullRect != null );
@@ -224,7 +220,10 @@ class PersistedPicture extends PersistedLeafSurface {
224220 // The clip collapsed into a zero-sized rectangle. If it was already zero,
225221 // no need to signal cull rect change.
226222 _optimalLocalCullRect = ui.Rect .zero;
227- return oldOptimalLocalCullRect != ui.Rect .zero;
223+ if (oldOptimalLocalCullRect != ui.Rect .zero) {
224+ _requiresRepaint = true ;
225+ }
226+ return ;
228227 }
229228
230229 if (rectContainsOther (oldOptimalLocalCullRect! , _exactLocalCullRect! )) {
@@ -233,7 +232,7 @@ class PersistedPicture extends PersistedLeafSurface {
233232 // a clip when it is scrolled out of the screen. In this case we do not
234233 // repaint the picture. We just let it be shrunk by the outer clip.
235234 _optimalLocalCullRect = oldOptimalLocalCullRect;
236- return false ;
235+ return ;
237236 }
238237
239238 // The new cull rect contains area not covered by a previous rect. Perhaps
@@ -270,9 +269,8 @@ class PersistedPicture extends PersistedLeafSurface {
270269 _predictTrend (bottomwardDelta, _exactLocalCullRect! .height),
271270 ).intersect (localPaintBounds! );
272271
273- final bool localCullRectChanged = _optimalLocalCullRect != newLocalCullRect;
272+ _requiresRepaint = _optimalLocalCullRect != newLocalCullRect;
274273 _optimalLocalCullRect = newLocalCullRect;
275- return localCullRectChanged;
276274 }
277275
278276 /// Predicts the delta a particular side of a clip rect will move given the
@@ -309,6 +307,7 @@ class PersistedPicture extends PersistedLeafSurface {
309307
310308 void _applyPaint (PersistedPicture ? oldSurface) {
311309 final EngineCanvas ? oldCanvas = oldSurface? ._canvas;
310+ _requiresRepaint = false ;
312311 if (! picture.recordingCanvas! .didDraw || _optimalLocalCullRect! .isEmpty) {
313312 // The picture is empty, or it has been completely clipped out. Skip
314313 // painting. This removes all the setup work and scaffolding objects
@@ -540,6 +539,7 @@ class PersistedPicture extends PersistedLeafSurface {
540539 @override
541540 void build () {
542541 _computeOptimalCullRect (null );
542+ _requiresRepaint = true ;
543543 super .build ();
544544 }
545545
@@ -556,15 +556,14 @@ class PersistedPicture extends PersistedLeafSurface {
556556 _applyTranslate ();
557557 }
558558
559- final bool cullRectChangeRequiresRepaint =
560- _computeOptimalCullRect (oldSurface);
559+ _computeOptimalCullRect (oldSurface);
561560 if (identical (picture, oldSurface.picture)) {
562561 bool densityChanged =
563562 (_canvas is BitmapCanvas &&
564563 _density != (_canvas as BitmapCanvas )._density);
565564
566565 // The picture is the same. Attempt to avoid repaint.
567- if (cullRectChangeRequiresRepaint || densityChanged) {
566+ if (_requiresRepaint || densityChanged) {
568567 // Cull rect changed such that a repaint is still necessary.
569568 _applyPaint (oldSurface);
570569 } else {
@@ -581,8 +580,8 @@ class PersistedPicture extends PersistedLeafSurface {
581580 @override
582581 void retain () {
583582 super .retain ();
584- final bool cullRectChangeRequiresRepaint = _computeOptimalCullRect (this );
585- if (cullRectChangeRequiresRepaint ) {
583+ _computeOptimalCullRect (this );
584+ if (_requiresRepaint ) {
586585 _applyPaint (this );
587586 }
588587 }
0 commit comments