[web] Fix child removal after reuse by other BitmapCanvas (#18604)
* Fix child removal after reuse by other BitmapCanvas
* Address review comments
diff --git a/lib/web_ui/lib/src/engine/bitmap_canvas.dart b/lib/web_ui/lib/src/engine/bitmap_canvas.dart
index 18cb130..2bdd3fe 100644
--- a/lib/web_ui/lib/src/engine/bitmap_canvas.dart
+++ b/lib/web_ui/lib/src/engine/bitmap_canvas.dart
@@ -118,7 +118,7 @@
}
/// Setup cache for reusing DOM elements across frames.
- set elementCache(CrossFrameCache<html.HtmlElement> cache) {
+ void setElementCache(CrossFrameCache<html.HtmlElement> cache) {
_elementCache = cache;
}
@@ -178,7 +178,11 @@
_canvasPool.clear();
final int len = _children.length;
for (int i = 0; i < len; i++) {
- _children[i].remove();
+ html.Element child = _children[i];
+ // Don't remove children that have been reused by CrossFrameCache.
+ if (child.parent == rootElement) {
+ child.remove();
+ }
}
_children.clear();
_cachedLastStyle = null;
diff --git a/lib/web_ui/lib/src/engine/surface/picture.dart b/lib/web_ui/lib/src/engine/surface/picture.dart
index 0dd702f..cb67a0e 100644
--- a/lib/web_ui/lib/src/engine/surface/picture.dart
+++ b/lib/web_ui/lib/src/engine/surface/picture.dart
@@ -244,6 +244,7 @@
}
oldCanvas.bounds = _optimalLocalCullRect;
_canvas = oldCanvas;
+ oldCanvas.setElementCache(_elementCache);
_canvas.clear();
picture.recordingCanvas.apply(_canvas, _optimalLocalCullRect);
} else {
@@ -258,6 +259,8 @@
canvasSize: _optimalLocalCullRect.size,
paintCallback: () {
_canvas = _findOrCreateCanvas(_optimalLocalCullRect);
+ assert(_canvas is BitmapCanvas
+ && (_canvas as BitmapCanvas)._elementCache == _elementCache);
if (_debugExplainSurfaceStats) {
final BitmapCanvas bitmapCanvas = _canvas;
_surfaceStatsFor(this).paintPixelCount +=
@@ -332,7 +335,7 @@
DebugCanvasReuseOverlay.instance.reusedCount++;
}
bestRecycledCanvas.bounds = bounds;
- bestRecycledCanvas.elementCache = _elementCache;
+ bestRecycledCanvas.setElementCache(_elementCache);
return bestRecycledCanvas;
}
@@ -340,7 +343,7 @@
DebugCanvasReuseOverlay.instance.createdCount++;
}
final BitmapCanvas canvas = BitmapCanvas(bounds);
- canvas.elementCache = _elementCache;
+ canvas.setElementCache(_elementCache);
if (_debugExplainSurfaceStats) {
_surfaceStatsFor(this)
..allocateBitmapCanvasCount += 1