Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 59b01e0

Browse files
authored
[web] Fix repaint logic for cullrect,transform changes (#22273)
1 parent ce0a30c commit 59b01e0

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

lib/web_ui/lib/src/engine/html/picture.dart

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)