[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