Revert "Reland [skwasm] Scene builder optimizations for platform view placement (#55468)" (#55715)

This reverts commit def85c709fa1239df33147189769c67ae8185be0 (https://github.com/flutter/engine/pull/55468)

Reason for revert, devtools has been having rendering issues since this commit. See https://github.com/flutter/devtools/issues/8401
diff --git a/lib/web_ui/lib/src/engine/color_filter.dart b/lib/web_ui/lib/src/engine/color_filter.dart
index a74145c..83a7ca2 100644
--- a/lib/web_ui/lib/src/engine/color_filter.dart
+++ b/lib/web_ui/lib/src/engine/color_filter.dart
@@ -135,7 +135,4 @@
         return 'ColorFilter.srgbToLinearGamma()';
     }
   }
-
-  @override
-  Matrix4? get transform => null;
 }
diff --git a/lib/web_ui/lib/src/engine/layers.dart b/lib/web_ui/lib/src/engine/layers.dart
index 538b6d5..f3658dd 100644
--- a/lib/web_ui/lib/src/engine/layers.dart
+++ b/lib/web_ui/lib/src/engine/layers.dart
@@ -5,51 +5,15 @@
 import 'dart:typed_data';
 
 import 'package:meta/meta.dart';
-import 'package:ui/src/engine.dart';
+import 'package:ui/src/engine/scene_painting.dart';
+import 'package:ui/src/engine/vector_math.dart';
 import 'package:ui/ui.dart' as ui;
 
-class EngineRootLayer with PictureEngineLayer {
-  @override
-  final NoopOperation operation = const NoopOperation();
-
-  @override
-  EngineRootLayer emptyClone() => EngineRootLayer();
-}
-
-class NoopOperation implements LayerOperation {
-  const NoopOperation();
-
-  @override
-  PlatformViewStyling createPlatformViewStyling() => const PlatformViewStyling();
-
-  @override
-  ui.Rect mapRect(ui.Rect contentRect) => contentRect;
-
-  @override
-  void pre(SceneCanvas canvas) {
-    canvas.save();
-  }
-
-  @override
-  void post(SceneCanvas canvas) {
-    canvas.restore();
-  }
-
-  @override
-  bool get shouldDrawIfEmpty => false;
-}
+class EngineRootLayer with PictureEngineLayer {}
 
 class BackdropFilterLayer
   with PictureEngineLayer
-  implements ui.BackdropFilterEngineLayer {
-  BackdropFilterLayer(this.operation);
-
-  @override
-  final LayerOperation operation;
-
-  @override
-  BackdropFilterLayer emptyClone() => BackdropFilterLayer(operation);
-}
+  implements ui.BackdropFilterEngineLayer {}
 class BackdropFilterOperation implements LayerOperation {
   BackdropFilterOperation(this.filter, this.mode);
 
@@ -60,12 +24,12 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect;
 
   @override
-  void pre(SceneCanvas canvas) {
-    canvas.saveLayerWithFilter(ui.Rect.largest, ui.Paint()..blendMode = mode, filter);
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
+    canvas.saveLayerWithFilter(contentRect, ui.Paint()..blendMode = mode, filter);
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.restore();
   }
 
@@ -80,15 +44,7 @@
 
 class ClipPathLayer
   with PictureEngineLayer
-  implements ui.ClipPathEngineLayer {
-  ClipPathLayer(this.operation);
-
-  @override
-  final ClipPathOperation operation;
-
-  @override
-  ClipPathLayer emptyClone() => ClipPathLayer(operation);
-}
+  implements ui.ClipPathEngineLayer {}
 class ClipPathOperation implements LayerOperation {
   ClipPathOperation(this.path, this.clip);
 
@@ -99,7 +55,7 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect.intersect(path.getBounds());
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.save();
     canvas.clipPath(path, doAntiAlias: clip != ui.Clip.hardEdge);
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
@@ -108,7 +64,7 @@
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
       canvas.restore();
     }
@@ -126,15 +82,7 @@
 
 class ClipRectLayer
   with PictureEngineLayer
-  implements ui.ClipRectEngineLayer {
-  ClipRectLayer(this.operation);
-
-  @override
-  final ClipRectOperation operation;
-
-  @override
-  ClipRectLayer emptyClone() => ClipRectLayer(operation);
-}
+  implements ui.ClipRectEngineLayer {}
 class ClipRectOperation implements LayerOperation {
   const ClipRectOperation(this.rect, this.clip);
 
@@ -145,7 +93,7 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect.intersect(rect);
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.save();
     canvas.clipRect(rect, doAntiAlias: clip != ui.Clip.hardEdge);
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
@@ -154,7 +102,7 @@
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
       canvas.restore();
     }
@@ -172,15 +120,7 @@
 
 class ClipRRectLayer
   with PictureEngineLayer
-  implements ui.ClipRRectEngineLayer {
-  ClipRRectLayer(this.operation);
-
-  @override
-  final ClipRRectOperation operation;
-
-  @override
-  ClipRRectLayer emptyClone() => ClipRRectLayer(operation);
-}
+  implements ui.ClipRRectEngineLayer {}
 class ClipRRectOperation implements LayerOperation {
   const ClipRRectOperation(this.rrect, this.clip);
 
@@ -191,7 +131,7 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect.intersect(rrect.outerRect);
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.save();
     canvas.clipRRect(rrect, doAntiAlias: clip != ui.Clip.hardEdge);
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
@@ -200,7 +140,7 @@
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     if (clip == ui.Clip.antiAliasWithSaveLayer) {
       canvas.restore();
     }
@@ -218,15 +158,7 @@
 
 class ColorFilterLayer
   with PictureEngineLayer
-  implements ui.ColorFilterEngineLayer {
-  ColorFilterLayer(this.operation);
-
-  @override
-  final ColorFilterOperation operation;
-
-  @override
-  ColorFilterLayer emptyClone() => ColorFilterLayer(operation);
-}
+  implements ui.ColorFilterEngineLayer {}
 class ColorFilterOperation implements LayerOperation {
   ColorFilterOperation(this.filter);
 
@@ -236,12 +168,12 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect;
 
   @override
-  void pre(SceneCanvas canvas) {
-    canvas.saveLayer(ui.Rect.largest, ui.Paint()..colorFilter = filter);
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
+    canvas.saveLayer(contentRect, ui.Paint()..colorFilter = filter);
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.restore();
   }
 
@@ -254,15 +186,7 @@
 
 class ImageFilterLayer
   with PictureEngineLayer
-  implements ui.ImageFilterEngineLayer {
-  ImageFilterLayer(this.operation);
-
-  @override
-  final ImageFilterOperation operation;
-
-  @override
-  ImageFilterLayer emptyClone() => ImageFilterLayer(operation);
-}
+  implements ui.ImageFilterEngineLayer {}
 class ImageFilterOperation implements LayerOperation {
   ImageFilterOperation(this.filter, this.offset);
 
@@ -273,16 +197,17 @@
   ui.Rect mapRect(ui.Rect contentRect) => filter.filterBounds(contentRect);
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
     if (offset != ui.Offset.zero) {
       canvas.save();
       canvas.translate(offset.dx, offset.dy);
     }
-    canvas.saveLayer(ui.Rect.largest, ui.Paint()..imageFilter = filter);
+    final ui.Rect adjustedContentRect = filter.filterBounds(contentRect);
+    canvas.saveLayer(adjustedContentRect, ui.Paint()..imageFilter = filter);
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     if (offset != ui.Offset.zero) {
       canvas.restore();
     }
@@ -291,22 +216,13 @@
 
   @override
   PlatformViewStyling createPlatformViewStyling() {
-    PlatformViewStyling styling = const PlatformViewStyling();
     if (offset != ui.Offset.zero) {
-      styling = PlatformViewStyling(
+      return PlatformViewStyling(
         position: PlatformViewPosition.offset(offset)
       );
+    } else {
+      return const PlatformViewStyling();
     }
-    final Matrix4? transform = filter.transform;
-    if (transform != null) {
-      styling = PlatformViewStyling.combine(
-        styling,
-        PlatformViewStyling(
-          position: PlatformViewPosition.transform(transform),
-        ),
-      );
-    }
-    return const PlatformViewStyling();
   }
 
   @override
@@ -315,15 +231,7 @@
 
 class OffsetLayer
   with PictureEngineLayer
-  implements ui.OffsetEngineLayer {
-  OffsetLayer(this.operation);
-
-  @override
-  final OffsetOperation operation;
-
-  @override
-  OffsetLayer emptyClone() => OffsetLayer(operation);
-}
+  implements ui.OffsetEngineLayer {}
 class OffsetOperation implements LayerOperation {
   OffsetOperation(this.dx, this.dy);
 
@@ -334,13 +242,13 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect.shift(ui.Offset(dx, dy));
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect cullRect) {
     canvas.save();
     canvas.translate(dx, dy);
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.restore();
   }
 
@@ -355,15 +263,7 @@
 
 class OpacityLayer
   with PictureEngineLayer
-  implements ui.OpacityEngineLayer {
-  OpacityLayer(this.operation);
-
-  @override
-  final OpacityOperation operation;
-
-  @override
-  OpacityLayer emptyClone() => OpacityLayer(operation);
-}
+  implements ui.OpacityEngineLayer {}
 class OpacityOperation implements LayerOperation {
   OpacityOperation(this.alpha, this.offset);
 
@@ -374,19 +274,20 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect.shift(offset);
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect cullRect) {
     if (offset != ui.Offset.zero) {
       canvas.save();
       canvas.translate(offset.dx, offset.dy);
+      cullRect = cullRect.shift(-offset);
     }
     canvas.saveLayer(
-      ui.Rect.largest,
+      cullRect,
       ui.Paint()..color = ui.Color.fromARGB(alpha, 0, 0, 0)
     );
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.restore();
     if (offset != ui.Offset.zero) {
       canvas.restore();
@@ -405,15 +306,7 @@
 
 class TransformLayer
   with PictureEngineLayer
-  implements ui.TransformEngineLayer {
-  TransformLayer(this.operation);
-
-  @override
-  final TransformOperation operation;
-
-  @override
-  TransformLayer emptyClone() => TransformLayer(operation);
-}
+  implements ui.TransformEngineLayer {}
 class TransformOperation implements LayerOperation {
   TransformOperation(this.transform);
 
@@ -426,13 +319,13 @@
   ui.Rect mapRect(ui.Rect contentRect) => matrix.transformRect(contentRect);
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect cullRect) {
     canvas.save();
     canvas.transform(transform);
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.restore();
   }
 
@@ -447,15 +340,7 @@
 
 class ShaderMaskLayer
   with PictureEngineLayer
-  implements ui.ShaderMaskEngineLayer {
-  ShaderMaskLayer(this.operation);
-
-  @override
-  final ShaderMaskOperation operation;
-
-  @override
-  ShaderMaskLayer emptyClone() => ShaderMaskLayer(operation);
-}
+  implements ui.ShaderMaskEngineLayer {}
 class ShaderMaskOperation implements LayerOperation {
   ShaderMaskOperation(this.shader, this.maskRect, this.blendMode);
 
@@ -467,15 +352,15 @@
   ui.Rect mapRect(ui.Rect contentRect) => contentRect;
 
   @override
-  void pre(SceneCanvas canvas) {
+  void pre(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.saveLayer(
-      ui.Rect.largest,
+      contentRect,
       ui.Paint(),
     );
   }
 
   @override
-  void post(SceneCanvas canvas) {
+  void post(SceneCanvas canvas, ui.Rect contentRect) {
     canvas.save();
     canvas.translate(maskRect.left, maskRect.top);
     canvas.drawRect(
@@ -504,43 +389,47 @@
   final ui.Rect bounds;
 
   final PlatformViewStyling styling;
-
-  @override
-  String toString() {
-    return 'PlatformView(viewId: $viewId, bounds: $bounds, styling: $styling)';
-  }
 }
 
-class LayerSlice {
-  LayerSlice(this.picture, this.platformViews);
+sealed class LayerSlice {
+  void dispose();
+}
 
-  // The picture of native flutter content to be rendered
+// A slice that contains one or more platform views to be rendered.
+class PlatformViewSlice implements LayerSlice {
+  PlatformViewSlice(this.views, this.occlusionRect);
+
+  List<PlatformView> views;
+
+  // A conservative estimate of what area platform views in this slice may cover.
+  // This is expressed in the coordinate space of the parent.
+  ui.Rect? occlusionRect;
+
+  @override
+  void dispose() {}
+}
+
+// A slice that contains flutter content to be rendered int he form of a single
+// ScenePicture.
+class PictureSlice implements LayerSlice {
+  PictureSlice(this.picture);
+
   ScenePicture picture;
 
-  // Platform views to be placed on top of the flutter content.
-  final List<PlatformView> platformViews;
-
-  void dispose() {
-    picture.dispose();
-  }
+  @override
+  void dispose() => picture.dispose();
 }
 
 mixin PictureEngineLayer implements ui.EngineLayer {
-  // Each layer is represented as a series of "slices" which contain flutter content
-  // with platform views on top. This is ordered from bottommost to topmost.
-  List<LayerSlice?> slices = [];
-
-  List<LayerDrawCommand> drawCommands = [];
-  PlatformViewStyling platformViewStyling = const PlatformViewStyling();
-
-  LayerOperation get operation;
-
-  PictureEngineLayer emptyClone();
+  // Each layer is represented as a series of "slices" which contain either
+  // flutter content or platform views. Slices in this list are ordered from
+  // bottom to top.
+  List<LayerSlice> slices = <LayerSlice>[];
 
   @override
   void dispose() {
-    for (final LayerSlice? slice in slices) {
-      slice?.dispose();
+    for (final LayerSlice slice in slices) {
+      slice.dispose();
     }
   }
 }
@@ -553,8 +442,8 @@
   // layer operation.
   ui.Rect mapRect(ui.Rect contentRect);
 
-  void pre(SceneCanvas canvas);
-  void post(SceneCanvas canvas);
+  void pre(SceneCanvas canvas, ui.Rect contentRect);
+  void post(SceneCanvas canvas, ui.Rect contentRect);
 
   PlatformViewStyling createPlatformViewStyling();
 
@@ -564,29 +453,11 @@
   bool get shouldDrawIfEmpty;
 }
 
-sealed class LayerDrawCommand {
-}
+class PictureDrawCommand {
+  PictureDrawCommand(this.offset, this.picture);
 
-class PictureDrawCommand extends LayerDrawCommand {
-  PictureDrawCommand(this.offset, this.picture, this.sliceIndex);
-
-  final int sliceIndex;
-  final ui.Offset offset;
-  final ScenePicture picture;
-}
-
-class PlatformViewDrawCommand extends LayerDrawCommand {
-  PlatformViewDrawCommand(this.viewId, this.bounds, this.sliceIndex);
-
-  final int sliceIndex;
-  final int viewId;
-  final ui.Rect bounds;
-}
-
-class RetainedLayerDrawCommand extends LayerDrawCommand {
-  RetainedLayerDrawCommand(this.layer);
-
-  final PictureEngineLayer layer;
+  ui.Offset offset;
+  ui.Picture picture;
 }
 
 // Represents how a platform view should be positioned in the scene.
@@ -606,17 +477,6 @@
 
   bool get isZero => (offset == null) && (transform == null);
 
-  ui.Rect mapLocalToGlobal(ui.Rect rect) {
-    if (offset != null) {
-      return rect.shift(offset!);
-    }
-    if (transform != null) {
-      return transform!.transformRect(rect);
-    }
-    return rect;
-  }
-
-  // Note that by construction only one of these can be set at any given time, not both.
   final ui.Offset? offset;
   final Matrix4? transform;
 
@@ -667,17 +527,6 @@
   int get hashCode {
     return Object.hash(offset, transform);
   }
-
-  @override
-  String toString() {
-    if (offset != null) {
-      return 'PlatformViewPosition(offset: $offset)';
-    }
-    if (transform != null) {
-      return 'PlatformViewPosition(transform: $transform)';
-    }
-    return 'PlatformViewPosition(zero)';
-  }
 }
 
 // Represents the styling to be performed on a platform view when it is
@@ -696,10 +545,6 @@
   final double opacity;
   final PlatformViewClip clip;
 
-  ui.Rect mapLocalToGlobal(ui.Rect rect) {
-    return position.mapLocalToGlobal(rect).intersect(clip.outerRect);
-  }
-
   static PlatformViewStyling combine(PlatformViewStyling outer, PlatformViewStyling inner) {
     // Attempt to reuse one of the existing immutable objects.
     if (outer.isDefault) {
@@ -730,11 +575,6 @@
   int get hashCode {
     return Object.hash(position, opacity, clip);
   }
-
-  @override
-  String toString() {
-    return 'PlatformViewStyling(position: $position, clip: $clip, opacity: $opacity)';
-  }
 }
 
 sealed class PlatformViewClip {
@@ -802,7 +642,7 @@
   ui.Rect get innerRect => ui.Rect.zero;
 
   @override
-  ui.Rect get outerRect => ui.Rect.largest;
+  ui.Rect get outerRect => ui.Rect.zero;
 }
 
 class PlatformViewRectClip implements PlatformViewClip {
@@ -923,137 +763,164 @@
   ui.Rect get outerRect => path.getBounds();
 }
 
-class LayerSliceBuilder {
-  factory LayerSliceBuilder() {
-    final (recorder, canvas) = debugRecorderFactory != null ? debugRecorderFactory!() : defaultRecorderFactory();
-    return LayerSliceBuilder._(recorder, canvas);
-  }
-  LayerSliceBuilder._(this.recorder, this.canvas);
-
-  @visibleForTesting
-  static (ui.PictureRecorder, SceneCanvas) Function()? debugRecorderFactory;
-
-  static (ui.PictureRecorder, SceneCanvas) defaultRecorderFactory() {
-    final ui.PictureRecorder recorder = ui.PictureRecorder();
-    final SceneCanvas canvas = ui.Canvas(recorder, ui.Rect.largest) as SceneCanvas;
-    return (recorder, canvas);
-  }
-
-  final ui.PictureRecorder recorder;
-  final SceneCanvas canvas;
-  final List<PlatformView> platformViews = <PlatformView>[];
-}
-
 class LayerBuilder {
   factory LayerBuilder.rootLayer() {
-    return LayerBuilder._(null, EngineRootLayer());
+    return LayerBuilder._(null, EngineRootLayer(), null);
   }
 
   factory LayerBuilder.childLayer({
     required LayerBuilder parent,
     required PictureEngineLayer layer,
+    required LayerOperation operation
   }) {
-    return LayerBuilder._(parent, layer);
+    return LayerBuilder._(parent, layer, operation);
   }
 
   LayerBuilder._(
     this.parent,
-    this.layer);
+    this.layer,
+    this.operation);
+
+  @visibleForTesting
+  static (ui.PictureRecorder, SceneCanvas) Function(ui.Rect)? debugRecorderFactory;
 
   final LayerBuilder? parent;
   final PictureEngineLayer layer;
-
-  final List<LayerSliceBuilder?> sliceBuilders = <LayerSliceBuilder?>[];
-  final List<LayerDrawCommand> drawCommands = <LayerDrawCommand>[];
+  final LayerOperation? operation;
+  final List<PictureDrawCommand> pendingPictures = <PictureDrawCommand>[];
+  List<PlatformView> pendingPlatformViews = <PlatformView>[];
+  ui.Rect? picturesRect;
+  ui.Rect? platformViewRect;
 
   PlatformViewStyling? _memoizedPlatformViewStyling;
+
   PlatformViewStyling get platformViewStyling {
-    return _memoizedPlatformViewStyling ??= layer.operation.createPlatformViewStyling();
+    return _memoizedPlatformViewStyling ??= operation?.createPlatformViewStyling() ?? const PlatformViewStyling();
   }
 
-  PlatformViewStyling? _memoizedGlobalPlatformViewStyling;
-  PlatformViewStyling get globalPlatformViewStyling {
-    if (_memoizedGlobalPlatformViewStyling != null) {
-      return _memoizedGlobalPlatformViewStyling!;
+  (ui.PictureRecorder, SceneCanvas) _createRecorder(ui.Rect rect) {
+    if (debugRecorderFactory != null) {
+      return debugRecorderFactory!(rect);
     }
-    if (parent != null) {
-      return _memoizedGlobalPlatformViewStyling ??= PlatformViewStyling.combine(parent!.globalPlatformViewStyling, platformViewStyling);
-    }
-    return _memoizedGlobalPlatformViewStyling ??= platformViewStyling;
+    final ui.PictureRecorder recorder = ui.PictureRecorder();
+    final SceneCanvas canvas = ui.Canvas(recorder, rect) as SceneCanvas;
+    return (recorder, canvas);
   }
 
-  LayerSliceBuilder getOrCreateSliceBuilderAtIndex(int index) {
-    while (sliceBuilders.length <= index) {
-      sliceBuilders.add(null);
+  void flushSlices() {
+    if (pendingPictures.isNotEmpty || (operation?.shouldDrawIfEmpty ?? false)) {
+      // Merge the existing draw commands into a single picture and add a slice
+      // with that picture to the slice list.
+      final ui.Rect drawnRect = picturesRect ?? ui.Rect.zero;
+      final ui.Rect rect = operation?.mapRect(drawnRect) ?? drawnRect;
+      final (ui.PictureRecorder recorder, SceneCanvas canvas) = _createRecorder(rect);
+
+      operation?.pre(canvas, rect);
+      for (final PictureDrawCommand command in pendingPictures) {
+        if (command.offset != ui.Offset.zero) {
+          canvas.save();
+          canvas.translate(command.offset.dx, command.offset.dy);
+          canvas.drawPicture(command.picture);
+          canvas.restore();
+        } else {
+          canvas.drawPicture(command.picture);
+        }
+      }
+      operation?.post(canvas, rect);
+      final ui.Picture picture = recorder.endRecording();
+      layer.slices.add(PictureSlice(picture as ScenePicture));
     }
-    final LayerSliceBuilder? existingSliceBuilder = sliceBuilders[index];
-    if (existingSliceBuilder != null) {
-      return existingSliceBuilder;
+
+    if (pendingPlatformViews.isNotEmpty) {
+      // Take any pending platform views and lower them into a platform view
+      // slice.
+      ui.Rect? occlusionRect = platformViewRect;
+      if (occlusionRect != null && operation != null) {
+        occlusionRect = operation!.mapRect(occlusionRect);
+      }
+      layer.slices.add(PlatformViewSlice(pendingPlatformViews, occlusionRect));
     }
-    final LayerSliceBuilder newSliceBuilder = LayerSliceBuilder();
-    layer.operation.pre(newSliceBuilder.canvas);
-    sliceBuilders[index] = newSliceBuilder;
-    return newSliceBuilder;
+
+    pendingPictures.clear();
+    pendingPlatformViews = <PlatformView>[];
+
+    // All the pictures and platform views have been lowered into slices. Clear
+    // our occlusion rectangles.
+    picturesRect = null;
+    platformViewRect = null;
   }
 
   void addPicture(
     ui.Offset offset,
     ui.Picture picture, {
-      required int sliceIndex,
+    bool isComplexHint = false,
+    bool willChangeHint = false
   }) {
-    final LayerSliceBuilder sliceBuilder = getOrCreateSliceBuilderAtIndex(sliceIndex);
-    final SceneCanvas canvas = sliceBuilder.canvas;
-    if (offset != ui.Offset.zero) {
-      canvas.save();
-      canvas.translate(offset.dx, offset.dy);
-      canvas.drawPicture(picture);
-      canvas.restore();
-    } else {
-      canvas.drawPicture(picture);
+    final ui.Rect cullRect = (picture as ScenePicture).cullRect;
+    final ui.Rect shiftedRect = cullRect.shift(offset);
+
+    final ui.Rect? currentPlatformViewRect = platformViewRect;
+    if (currentPlatformViewRect != null) {
+      // Whenever we add a picture to our layer, we try to see if the picture
+      // will overlap with any platform views that are currently on top of our
+      // drawing surface. If they don't overlap with the platform views, they
+      // can be grouped with the existing pending pictures.
+      if (pendingPictures.isEmpty || currentPlatformViewRect.overlaps(shiftedRect)) {
+        // If they do overlap with the platform views, however, we should flush
+        // all the current content into slices and start anew with a fresh
+        // group of pictures and platform views that will be rendered on top of
+        // the previous content. Note that we also flush if we have no pending
+        // pictures to group with. This is the case when platform views are
+        // the first thing in our stack of objects to composite, and it doesn't
+        // make sense to try to put a picture slice below the first platform
+        // view slice, even if the picture doesn't overlap.
+        flushSlices();
+      }
     }
-    drawCommands.add(PictureDrawCommand(offset, picture as ScenePicture, sliceIndex));
+    pendingPictures.add(PictureDrawCommand(offset, picture));
+    picturesRect = picturesRect?.expandToInclude(shiftedRect) ?? shiftedRect;
   }
 
   void addPlatformView(
     int viewId, {
-    required ui.Rect bounds,
-    required int sliceIndex,
+    ui.Offset offset = ui.Offset.zero,
+    double width = 0.0,
+    double height = 0.0
   }) {
-    final LayerSliceBuilder sliceBuilder = getOrCreateSliceBuilderAtIndex(sliceIndex);
-    sliceBuilder.platformViews.add(PlatformView(viewId, bounds, platformViewStyling));
-    drawCommands.add(PlatformViewDrawCommand(viewId, bounds, sliceIndex));
+    final ui.Rect bounds = ui.Rect.fromLTWH(offset.dx, offset.dy, width, height);
+    platformViewRect = platformViewRect?.expandToInclude(bounds) ?? bounds;
+    pendingPlatformViews.add(PlatformView(viewId, bounds, platformViewStyling));
   }
 
   void mergeLayer(PictureEngineLayer layer) {
-    for (int i = 0; i < layer.slices.length; i++) {
-      final LayerSlice? slice = layer.slices[i];
-      if (slice != null) {
-        final LayerSliceBuilder sliceBuilder = getOrCreateSliceBuilderAtIndex(i);
-        sliceBuilder.canvas.drawPicture(slice.picture);
-        sliceBuilder.platformViews.addAll(slice.platformViews.map((PlatformView view) {
-          return PlatformView(view.viewId, view.bounds, PlatformViewStyling.combine(platformViewStyling, view.styling));
-        }));
+    // When we merge layers, we attempt to merge slices as much as possible as
+    // well, based on ordering of pictures and platform views and reusing the
+    // occlusion logic for determining where we can lower each picture.
+    for (final LayerSlice slice in layer.slices) {
+      switch (slice) {
+        case PictureSlice():
+          addPicture(ui.Offset.zero, slice.picture);
+        case PlatformViewSlice():
+          final ui.Rect? occlusionRect = slice.occlusionRect;
+          if (occlusionRect != null) {
+            platformViewRect = platformViewRect?.expandToInclude(occlusionRect) ?? occlusionRect;
+          }
+          for (final PlatformView view in slice.views) {
+            // Merge the platform view styling of this layer with the nested
+            // platform views.
+            final PlatformViewStyling styling = PlatformViewStyling.combine(
+              platformViewStyling,
+              view.styling,
+            );
+            pendingPlatformViews.add(PlatformView(view.viewId, view.bounds, styling));
+          }
       }
     }
-    drawCommands.add(RetainedLayerDrawCommand(layer));
-  }
-
-  PictureEngineLayer sliceUp() {
-    final List<LayerSlice?> slices = sliceBuilders.map((LayerSliceBuilder? builder) {
-      if (builder == null) {
-        return null;
-      }
-      layer.operation.post(builder.canvas);
-      final ScenePicture picture = builder.recorder.endRecording() as ScenePicture;
-      return LayerSlice(picture, builder.platformViews);
-    }).toList();
-    layer.slices = slices;
-    return layer;
   }
 
   PictureEngineLayer build() {
-    layer.drawCommands = drawCommands;
-    layer.platformViewStyling = platformViewStyling;
-    return sliceUp();
+    // Lower any pending pictures or platform views to their respective slices.
+    flushSlices();
+    return layer;
   }
 }
diff --git a/lib/web_ui/lib/src/engine/scene_builder.dart b/lib/web_ui/lib/src/engine/scene_builder.dart
index 6d6db06..af84cb0 100644
--- a/lib/web_ui/lib/src/engine/scene_builder.dart
+++ b/lib/web_ui/lib/src/engine/scene_builder.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:math' as math;
 import 'dart:typed_data';
 
 import 'package:ui/src/engine.dart';
@@ -63,115 +62,17 @@
     final ui.Rect canvasRect = ui.Rect.fromLTWH(0, 0, width.toDouble(), height.toDouble());
     final ui.Canvas canvas = ui.Canvas(recorder, canvasRect);
 
-    // Only rasterizes the pictures.
-    for (final LayerSlice? slice in rootLayer.slices) {
-      if (slice != null) {
-        canvas.drawPicture(slice.picture);
-      }
+    // Only rasterizes the picture slices.
+    for (final PictureSlice slice in rootLayer.slices.whereType<PictureSlice>()) {
+      canvas.drawPicture(slice.picture);
     }
     return recorder.endRecording().toImageSync(width, height);
   }
 }
 
-sealed class OcclusionMapNode {
-  bool overlaps(ui.Rect rect);
-  OcclusionMapNode insert(ui.Rect rect);
-  ui.Rect get boundingBox;
-}
-
-class OcclusionMapEmpty implements OcclusionMapNode {
-  @override
-  ui.Rect get boundingBox => ui.Rect.zero;
-
-  @override
-  OcclusionMapNode insert(ui.Rect rect) => OcclusionMapLeaf(rect);
-
-  @override
-  bool overlaps(ui.Rect rect) => false;
-
-}
-
-class OcclusionMapLeaf implements OcclusionMapNode {
-  OcclusionMapLeaf(this.rect);
-
-  final ui.Rect rect;
-
-  @override
-  ui.Rect get boundingBox => rect;
-
-  @override
-  OcclusionMapNode insert(ui.Rect other) => OcclusionMapBranch(this, OcclusionMapLeaf(other));
-
-  @override
-  bool overlaps(ui.Rect other) => rect.overlaps(other);
-}
-
-class OcclusionMapBranch implements OcclusionMapNode {
-  OcclusionMapBranch(this.left, this.right)
-    : boundingBox = left.boundingBox.expandToInclude(right.boundingBox);
-
-  final OcclusionMapNode left;
-  final OcclusionMapNode right;
-
-  @override
-  final ui.Rect boundingBox;
-
-  double _areaOfUnion(ui.Rect first, ui.Rect second) {
-    return (math.max(first.right, second.right) - math.min(first.left, second.left))
-      * (math.max(first.bottom, second.bottom) - math.max(first.top, second.top));
-  }
-
-  @override
-  OcclusionMapNode insert(ui.Rect other) {
-    // Try to create nodes with the smallest possible area
-    final double leftOtherArea = _areaOfUnion(left.boundingBox, other);
-    final double rightOtherArea = _areaOfUnion(right.boundingBox, other);
-    final double leftRightArea = boundingBox.width * boundingBox.height;
-    if (leftOtherArea < rightOtherArea) {
-      if (leftOtherArea < leftRightArea) {
-        return OcclusionMapBranch(
-          left.insert(other),
-          right,
-        );
-      }
-    } else {
-      if (rightOtherArea < leftRightArea) {
-        return OcclusionMapBranch(
-          left,
-          right.insert(other),
-        );
-      }
-    }
-    return OcclusionMapBranch(this, OcclusionMapLeaf(other));
-  }
-
-  @override
-  bool overlaps(ui.Rect rect) {
-    if (!boundingBox.overlaps(rect)) {
-      return false;
-    }
-    return left.overlaps(rect) || right.overlaps(rect);
-  }
-}
-
-class OcclusionMap {
-  OcclusionMapNode root = OcclusionMapEmpty();
-
-  void addRect(ui.Rect rect) => root = root.insert(rect);
-
-  bool overlaps(ui.Rect rect) => root.overlaps(rect);
-}
-
-class SceneSlice {
-  final OcclusionMap pictureOcclusionMap = OcclusionMap();
-  final OcclusionMap platformViewOcclusionMap = OcclusionMap();
-}
-
 class EngineSceneBuilder implements ui.SceneBuilder {
   LayerBuilder currentBuilder = LayerBuilder.rootLayer();
 
-  final List<SceneSlice> sceneSlices = <SceneSlice>[SceneSlice()];
-
   @override
   void addPerformanceOverlay(int enabledOptions, ui.Rect bounds) {
     // We don't plan to implement this on the web.
@@ -185,44 +86,15 @@
     bool isComplexHint = false,
     bool willChangeHint = false
   }) {
-    final int sliceIndex = _placePicture(offset, picture as ScenePicture);
     currentBuilder.addPicture(
       offset,
       picture,
-      sliceIndex: sliceIndex,
+      isComplexHint:
+      isComplexHint,
+      willChangeHint: willChangeHint
     );
   }
 
-  // This function determines the lowest scene slice that this picture can be placed
-  // into and adds it to that slice's occlusion map.
-  //
-  // The picture is placed in the last slice where it either intersects with a picture
-  // in the slice or it intersects with a platform view in the preceding slice. If the
-  // picture intersects with a platform view in the last slice, a new slice is added at
-  // the end and the picture goes in there.
-  int _placePicture(ui.Offset offset, ScenePicture picture) {
-    final ui.Rect cullRect = picture.cullRect.shift(offset);
-    final ui.Rect mappedCullRect = currentBuilder.globalPlatformViewStyling.mapLocalToGlobal(cullRect);
-    int sliceIndex = sceneSlices.length;
-    while (sliceIndex > 0) {
-      final SceneSlice sliceBelow = sceneSlices[sliceIndex - 1];
-      if (sliceBelow.platformViewOcclusionMap.overlaps(mappedCullRect)) {
-        break;
-      }
-      sliceIndex--;
-      if (sliceBelow.pictureOcclusionMap.overlaps(mappedCullRect)) {
-        break;
-      }
-    }
-    if (sliceIndex == sceneSlices.length) {
-      // Insert a new slice.
-      sceneSlices.add(SceneSlice());
-    }
-    final SceneSlice slice = sceneSlices[sliceIndex];
-    slice.pictureOcclusionMap.addRect(mappedCullRect);
-    return sliceIndex;
-  }
-
   @override
   void addPlatformView(
     int viewId, {
@@ -230,94 +102,17 @@
     double width = 0.0,
     double height = 0.0
   }) {
-    final ui.Rect platformViewRect = ui.Rect.fromLTWH(offset.dx, offset.dy, width, height);
-    final int sliceIndex = _placePlatformView(viewId, platformViewRect);
     currentBuilder.addPlatformView(
       viewId,
-      bounds: platformViewRect,
-      sliceIndex: sliceIndex,
+      offset: offset,
+      width: width,
+      height: height
     );
   }
 
-  // This function determines the lowest scene slice this platform view can be placed
-  // into and adds it to that slice's occlusion map.
-  //
-  // The platform view is placed into the last slice where it intersects with a picture
-  // or a platform view.
-  int _placePlatformView(
-    int viewId,
-    ui.Rect rect, {
-    PlatformViewStyling styling = const PlatformViewStyling(),
-  }) {
-    final PlatformViewStyling combinedStyling = PlatformViewStyling.combine(currentBuilder.globalPlatformViewStyling, styling);
-    final ui.Rect globalPlatformViewRect = combinedStyling.mapLocalToGlobal(rect);
-    int sliceIndex = sceneSlices.length - 1;
-    while (sliceIndex > 0) {
-      final SceneSlice slice = sceneSlices[sliceIndex];
-      if (slice.platformViewOcclusionMap.overlaps(globalPlatformViewRect) ||
-          slice.pictureOcclusionMap.overlaps(globalPlatformViewRect)) {
-        break;
-      }
-      sliceIndex--;
-    }
-    final SceneSlice slice = sceneSlices[sliceIndex];
-    slice.platformViewOcclusionMap.addRect(globalPlatformViewRect);
-    return sliceIndex;
-  }
-
   @override
   void addRetained(ui.EngineLayer retainedLayer) {
-    final PictureEngineLayer placedEngineLayer = _placeRetainedLayer(retainedLayer as PictureEngineLayer);
-    currentBuilder.mergeLayer(placedEngineLayer);
-  }
-
-  PictureEngineLayer _placeRetainedLayer(PictureEngineLayer retainedLayer) {
-    bool needsRebuild = false;
-    final List<LayerDrawCommand> revisedDrawCommands = [];
-    for (final LayerDrawCommand command in retainedLayer.drawCommands) {
-      switch (command) {
-        case PictureDrawCommand(offset: final ui.Offset offset, picture: final ScenePicture picture):
-          final int sliceIndex = _placePicture(offset, picture);
-          if (command.sliceIndex != sliceIndex) {
-            needsRebuild = true;
-          }
-          revisedDrawCommands.add(PictureDrawCommand(offset, picture, sliceIndex));
-        case PlatformViewDrawCommand(viewId: final int viewId, bounds: final ui.Rect bounds):
-          final int sliceIndex = _placePlatformView(viewId, bounds);
-          if (command.sliceIndex != sliceIndex) {
-            needsRebuild = true;
-          }
-          revisedDrawCommands.add(PlatformViewDrawCommand(viewId, bounds, sliceIndex));
-        case RetainedLayerDrawCommand(layer: final PictureEngineLayer sublayer):
-          final PictureEngineLayer revisedSublayer = _placeRetainedLayer(sublayer);
-          if (sublayer != revisedSublayer) {
-            needsRebuild = true;
-          }
-          revisedDrawCommands.add(RetainedLayerDrawCommand(revisedSublayer));
-      }
-    }
-
-    if (!needsRebuild) {
-      // No elements changed which slice position they are in, so we can simply
-      // merge the existing layer down and don't have to redraw individual elements.
-      return retainedLayer;
-    }
-
-    // Otherwise, we replace the commands of the layer to create a new one.
-    currentBuilder = LayerBuilder.childLayer(parent: currentBuilder, layer: retainedLayer.emptyClone());
-    for (final LayerDrawCommand command in revisedDrawCommands) {
-      switch (command) {
-        case PictureDrawCommand(offset: final ui.Offset offset, picture: final ScenePicture picture):
-          currentBuilder.addPicture(offset, picture, sliceIndex: command.sliceIndex);
-        case PlatformViewDrawCommand(viewId: final int viewId, bounds: final ui.Rect bounds):
-          currentBuilder.addPlatformView(viewId, bounds: bounds, sliceIndex: command.sliceIndex);
-        case RetainedLayerDrawCommand(layer: final PictureEngineLayer layer):
-          currentBuilder.mergeLayer(layer);
-      }
-    }
-    final PictureEngineLayer newLayer = currentBuilder.build();
-    currentBuilder = currentBuilder.parent!;
-    return newLayer;
+    currentBuilder.mergeLayer(retainedLayer as PictureEngineLayer);
   }
 
   @override
@@ -337,21 +132,30 @@
     ui.ImageFilter filter, {
     ui.BlendMode blendMode = ui.BlendMode.srcOver,
     ui.BackdropFilterEngineLayer? oldLayer
-  }) => pushLayer<BackdropFilterLayer>(BackdropFilterLayer(BackdropFilterOperation(filter, blendMode)));
+  }) => pushLayer<BackdropFilterLayer>(
+      BackdropFilterLayer(),
+      BackdropFilterOperation(filter, blendMode),
+    );
 
   @override
   ui.ClipPathEngineLayer pushClipPath(
     ui.Path path, {
     ui.Clip clipBehavior = ui.Clip.antiAlias,
     ui.ClipPathEngineLayer? oldLayer
-  }) => pushLayer<ClipPathLayer>(ClipPathLayer(ClipPathOperation(path as ScenePath, clipBehavior)));
+  }) => pushLayer<ClipPathLayer>(
+      ClipPathLayer(),
+      ClipPathOperation(path as ScenePath, clipBehavior),
+    );
 
   @override
   ui.ClipRRectEngineLayer pushClipRRect(
     ui.RRect rrect, {
     required ui.Clip clipBehavior,
     ui.ClipRRectEngineLayer? oldLayer
-  }) => pushLayer<ClipRRectLayer>(ClipRRectLayer(ClipRRectOperation(rrect, clipBehavior)));
+  }) => pushLayer<ClipRRectLayer>(
+      ClipRRectLayer(),
+      ClipRRectOperation(rrect, clipBehavior)
+    );
 
   @override
   ui.ClipRectEngineLayer pushClipRect(
@@ -359,14 +163,20 @@
     ui.Clip clipBehavior = ui.Clip.antiAlias,
     ui.ClipRectEngineLayer? oldLayer
   }) {
-    return pushLayer<ClipRectLayer>(ClipRectLayer(ClipRectOperation(rect, clipBehavior)));
+    return pushLayer<ClipRectLayer>(
+      ClipRectLayer(),
+      ClipRectOperation(rect, clipBehavior)
+    );
   }
 
   @override
   ui.ColorFilterEngineLayer pushColorFilter(
     ui.ColorFilter filter, {
     ui.ColorFilterEngineLayer? oldLayer
-  }) => pushLayer<ColorFilterLayer>(ColorFilterLayer(ColorFilterOperation(filter)));
+  }) => pushLayer<ColorFilterLayer>(
+      ColorFilterLayer(),
+      ColorFilterOperation(filter),
+    );
 
   @override
   ui.ImageFilterEngineLayer pushImageFilter(
@@ -374,7 +184,8 @@
     ui.Offset offset = ui.Offset.zero,
     ui.ImageFilterEngineLayer? oldLayer
   }) => pushLayer<ImageFilterLayer>(
-      ImageFilterLayer(ImageFilterOperation(filter as SceneImageFilter, offset)),
+      ImageFilterLayer(),
+      ImageFilterOperation(filter as SceneImageFilter, offset),
     );
 
   @override
@@ -382,14 +193,19 @@
     double dx,
     double dy, {
     ui.OffsetEngineLayer? oldLayer
-  }) => pushLayer<OffsetLayer>(OffsetLayer(OffsetOperation(dx, dy)));
+  }) => pushLayer<OffsetLayer>(
+      OffsetLayer(),
+      OffsetOperation(dx, dy)
+    );
 
   @override
   ui.OpacityEngineLayer pushOpacity(int alpha, {
     ui.Offset offset = ui.Offset.zero,
     ui.OpacityEngineLayer? oldLayer
-  }) => pushLayer<OpacityLayer>(OpacityLayer(OpacityOperation(alpha, offset)));
-
+  }) => pushLayer<OpacityLayer>(
+      OpacityLayer(),
+      OpacityOperation(alpha, offset),
+    );
   @override
   ui.ShaderMaskEngineLayer pushShaderMask(
     ui.Shader shader,
@@ -398,14 +214,18 @@
     ui.ShaderMaskEngineLayer? oldLayer,
     ui.FilterQuality filterQuality = ui.FilterQuality.low
   }) => pushLayer<ShaderMaskLayer>(
-      ShaderMaskLayer(ShaderMaskOperation(shader, maskRect, blendMode)),
+      ShaderMaskLayer(),
+      ShaderMaskOperation(shader, maskRect, blendMode)
     );
 
   @override
   ui.TransformEngineLayer pushTransform(
     Float64List matrix4, {
     ui.TransformEngineLayer? oldLayer
-  }) => pushLayer<TransformLayer>(TransformLayer(TransformOperation(matrix4)));
+  }) => pushLayer<TransformLayer>(
+      TransformLayer(),
+      TransformOperation(matrix4),
+    );
 
   @override
   void setProperties(
@@ -440,10 +260,11 @@
     currentBuilder.mergeLayer(layer);
   }
 
-  T pushLayer<T extends PictureEngineLayer>(T layer) {
+  T pushLayer<T extends PictureEngineLayer>(T layer, LayerOperation operation) {
     currentBuilder = LayerBuilder.childLayer(
       parent: currentBuilder,
       layer: layer,
+      operation: operation
     );
     return layer;
   }
diff --git a/lib/web_ui/lib/src/engine/scene_painting.dart b/lib/web_ui/lib/src/engine/scene_painting.dart
index 4f70633..1ef39d2 100644
--- a/lib/web_ui/lib/src/engine/scene_painting.dart
+++ b/lib/web_ui/lib/src/engine/scene_painting.dart
@@ -4,8 +4,6 @@
 
 import 'package:ui/ui.dart' as ui;
 
-import 'vector_math.dart';
-
 // These are additional APIs that are not part of the `dart:ui` interface that
 // are needed internally to properly implement a `SceneBuilder` on top of the
 // generic Canvas/Picture api.
@@ -24,10 +22,6 @@
   // gives the maximum draw boundary for a picture with the given input bounds after it
   // has been processed by the filter.
   ui.Rect filterBounds(ui.Rect inputBounds);
-
-  // The matrix image filter changes the position of the content, so when positioning
-  // platform views and calculating occlusion we need to take its transform into account.
-  Matrix4? get transform;
 }
 
 abstract class ScenePath implements ui.Path {
diff --git a/lib/web_ui/lib/src/engine/scene_view.dart b/lib/web_ui/lib/src/engine/scene_view.dart
index 909c386..5350420 100644
--- a/lib/web_ui/lib/src/engine/scene_view.dart
+++ b/lib/web_ui/lib/src/engine/scene_view.dart
@@ -95,24 +95,23 @@
       flutterView.physicalSize.width,
       flutterView.physicalSize.height,
     );
-    final List<LayerSlice?> slices = scene.rootLayer.slices;
+    final List<LayerSlice> slices = scene.rootLayer.slices;
     final List<ScenePicture> picturesToRender = <ScenePicture>[];
     final List<ScenePicture> originalPicturesToRender = <ScenePicture>[];
-    for (final LayerSlice? slice in slices) {
-      if (slice == null) {
-        continue;
-      }
-      final ui.Rect clippedRect = slice.picture.cullRect.intersect(screenBounds);
-      if (clippedRect.isEmpty) {
-        // This picture is completely offscreen, so don't render it at all
-        continue;
-      } else if (clippedRect == slice.picture.cullRect) {
-        // The picture doesn't need to be clipped, just render the original
-        originalPicturesToRender.add(slice.picture);
-        picturesToRender.add(slice.picture);
-      } else {
-        originalPicturesToRender.add(slice.picture);
-        picturesToRender.add(pictureRenderer.clipPicture(slice.picture, clippedRect));
+    for (final LayerSlice slice in slices) {
+      if (slice is PictureSlice) {
+        final ui.Rect clippedRect = slice.picture.cullRect.intersect(screenBounds);
+        if (clippedRect.isEmpty) {
+          // This picture is completely offscreen, so don't render it at all
+          continue;
+        } else if (clippedRect == slice.picture.cullRect) {
+          // The picture doesn't need to be clipped, just render the original
+          originalPicturesToRender.add(slice.picture);
+          picturesToRender.add(slice.picture);
+        } else {
+          originalPicturesToRender.add(slice.picture);
+          picturesToRender.add(pictureRenderer.clipPicture(slice.picture, clippedRect));
+        }
       }
     }
     final Map<ScenePicture, DomImageBitmap> renderMap;
@@ -133,55 +132,58 @@
 
     final List<SliceContainer?> reusableContainers = List<SliceContainer?>.from(containers);
     final List<SliceContainer> newContainers = <SliceContainer>[];
-    for (final LayerSlice? slice in slices) {
-      if (slice == null) {
-        continue;
-      }
-      final DomImageBitmap? bitmap = renderMap[slice.picture];
-      if (bitmap != null) {
-        PictureSliceContainer? container;
-        for (int j = 0; j < reusableContainers.length; j++) {
-          final SliceContainer? candidate = reusableContainers[j];
-          if (candidate is PictureSliceContainer) {
-            container = candidate;
-            reusableContainers[j] = null;
-            break;
+    for (final LayerSlice slice in slices) {
+      switch (slice) {
+        case PictureSlice():
+          final DomImageBitmap? bitmap = renderMap[slice.picture];
+          if (bitmap == null) {
+            // We didn't render this slice because no part of it is visible.
+            continue;
           }
-        }
-
-        final ui.Rect clippedBounds = slice.picture.cullRect.intersect(screenBounds);
-        if (container != null) {
-          container.bounds = clippedBounds;
-        } else {
-          container = PictureSliceContainer(clippedBounds);
-        }
-        container.updateContents();
-        container.renderBitmap(bitmap);
-        newContainers.add(container);
-      }
-
-      for (final PlatformView view in slice.platformViews) {
-        // TODO(harryterkelsen): Inject the FlutterView instance from `renderScene`,
-        // instead of using `EnginePlatformDispatcher...implicitView` directly,
-        // or make the FlutterView "register" like in canvaskit.
-        // Ensure the platform view contents are injected in the DOM.
-        EnginePlatformDispatcher.instance.implicitView?.dom.injectPlatformView(view.viewId);
-
-        // Attempt to reuse a container for the existing view
-        PlatformViewContainer? container;
-        for (int j = 0; j < reusableContainers.length; j++) {
-          final SliceContainer? candidate = reusableContainers[j];
-          if (candidate is PlatformViewContainer && candidate.viewId == view.viewId) {
-            container = candidate;
-            reusableContainers[j] = null;
-            break;
+          PictureSliceContainer? container;
+          for (int j = 0; j < reusableContainers.length; j++) {
+            final SliceContainer? candidate = reusableContainers[j];
+            if (candidate is PictureSliceContainer) {
+              container = candidate;
+              reusableContainers[j] = null;
+              break;
+            }
           }
-        }
-        container ??= PlatformViewContainer(view.viewId);
-        container.bounds = view.bounds;
-        container.styling = view.styling;
-        container.updateContents();
-        newContainers.add(container);
+
+          final ui.Rect clippedBounds = slice.picture.cullRect.intersect(screenBounds);
+          if (container != null) {
+            container.bounds = clippedBounds;
+          } else {
+            container = PictureSliceContainer(clippedBounds);
+          }
+          container.updateContents();
+          container.renderBitmap(bitmap);
+          newContainers.add(container);
+
+        case PlatformViewSlice():
+          for (final PlatformView view in slice.views) {
+            // TODO(harryterkelsen): Inject the FlutterView instance from `renderScene`,
+            // instead of using `EnginePlatformDispatcher...implicitView` directly,
+            // or make the FlutterView "register" like in canvaskit.
+            // Ensure the platform view contents are injected in the DOM.
+            EnginePlatformDispatcher.instance.implicitView?.dom.injectPlatformView(view.viewId);
+
+            // Attempt to reuse a container for the existing view
+            PlatformViewContainer? container;
+            for (int j = 0; j < reusableContainers.length; j++) {
+              final SliceContainer? candidate = reusableContainers[j];
+              if (candidate is PlatformViewContainer && candidate.viewId == view.viewId) {
+                container = candidate;
+                reusableContainers[j] = null;
+                break;
+              }
+            }
+            container ??= PlatformViewContainer(view.viewId);
+            container.bounds = view.bounds;
+            container.styling = view.styling;
+            container.updateContents();
+            newContainers.add(container);
+          }
       }
     }
 
diff --git a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/filters.dart b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/filters.dart
index 06b8c47..7c611d1 100644
--- a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/filters.dart
+++ b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/filters.dart
@@ -88,9 +88,6 @@
 
   @override
   String toString() => 'ImageFilter.blur($sigmaX, $sigmaY, ${tileModeString(tileMode)})';
-
-  @override
-  Matrix4? get transform => null;
 }
 
 class SkwasmDilateFilter extends SkwasmImageFilter {
@@ -108,9 +105,6 @@
 
   @override
   String toString() => 'ImageFilter.dilate($radiusX, $radiusY)';
-
-  @override
-  Matrix4? get transform => null;
 }
 
 class SkwasmErodeFilter extends SkwasmImageFilter {
@@ -128,9 +122,6 @@
 
   @override
   String toString() => 'ImageFilter.erode($radiusX, $radiusY)';
-
-  @override
-  Matrix4? get transform => null;
 }
 
 class SkwasmMatrixFilter extends SkwasmImageFilter {
@@ -153,9 +144,6 @@
 
   @override
   String toString() => 'ImageFilter.matrix($matrix4, $filterQuality)';
-
-  @override
-  Matrix4? get transform => Matrix4.fromFloat32List(toMatrix32(matrix4));
 }
 
 class SkwasmColorImageFilter extends SkwasmImageFilter {
@@ -174,9 +162,6 @@
 
   @override
   String toString() => filter.toString();
-
-  @override
-  Matrix4? get transform => null;
 }
 
 class SkwasmComposedImageFilter extends SkwasmImageFilter {
@@ -198,16 +183,6 @@
 
   @override
   String toString() => 'ImageFilter.compose($outer, $inner)';
-
-  @override
-  Matrix4? get transform {
-    final outerTransform = outer.transform;
-    final innerTransform = inner.transform;
-    if (outerTransform != null && innerTransform != null) {
-      return outerTransform.multiplied(innerTransform);
-    }
-    return outerTransform ?? innerTransform;
-  }
 }
 
 typedef ColorFilterHandleBorrow = void Function(ColorFilterHandle handle);
diff --git a/lib/web_ui/test/engine/scene_builder_test.dart b/lib/web_ui/test/engine/scene_builder_test.dart
index a94a651..d8826e8 100644
--- a/lib/web_ui/test/engine/scene_builder_test.dart
+++ b/lib/web_ui/test/engine/scene_builder_test.dart
@@ -16,7 +16,7 @@
 
 void testMain() {
   setUpAll(() {
-    LayerSliceBuilder.debugRecorderFactory = () {
+    LayerBuilder.debugRecorderFactory = (ui.Rect rect) {
       final StubSceneCanvas canvas = StubSceneCanvas();
       final StubPictureRecorder recorder = StubPictureRecorder(canvas);
       return (recorder, canvas);
@@ -24,7 +24,7 @@
   });
 
   tearDownAll(() {
-    LayerSliceBuilder.debugRecorderFactory = null;
+    LayerBuilder.debugRecorderFactory = null;
   });
 
   group('EngineSceneBuilder', () {
@@ -35,23 +35,23 @@
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
+      final List<LayerSlice> slices = scene.rootLayer.slices;
       expect(slices.length, 1);
-      expect(slices[0], layerSlice(withPictureRect: pictureRect));
+      expect(slices[0], pictureSliceWithRect(pictureRect));
     });
 
     test('two pictures', () {
       final EngineSceneBuilder sceneBuilder = EngineSceneBuilder();
 
       const ui.Rect pictureRect1 = ui.Rect.fromLTRB(100, 100, 200, 200);
-      const ui.Rect pictureRect2 = ui.Rect.fromLTRB(300, 300, 400, 400);
+      const ui.Rect pictureRect2 = ui.Rect.fromLTRB(300, 400, 400, 400);
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect1));
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect2));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
+      final List<LayerSlice> slices = scene.rootLayer.slices;
       expect(slices.length, 1);
-      expect(slices[0], layerSlice(withPictureRect: const ui.Rect.fromLTRB(100, 100, 400, 400)));
+      expect(slices[0], pictureSliceWithRect(const ui.Rect.fromLTRB(100, 100, 400, 400)));
     });
 
     test('picture + platform view (overlapping)', () {
@@ -68,11 +68,10 @@
       );
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
-      expect(slices.length, 1);
-      expect(slices[0], layerSlice(
-        withPictureRect: pictureRect,
-        withPlatformViews: <PlatformView>[
+      final List<LayerSlice> slices = scene.rootLayer.slices;
+      expect(slices.length, 2);
+      expect(slices[0], pictureSliceWithRect(pictureRect));
+      expect(slices[1], platformViewSliceWithViews(<PlatformView>[
         PlatformView(1, platformViewRect, const PlatformViewStyling())
       ]));
     });
@@ -91,12 +90,12 @@
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
+      final List<LayerSlice> slices = scene.rootLayer.slices;
       expect(slices.length, 2);
-      expect(slices[0], layerSlice(withPlatformViews: <PlatformView>[
+      expect(slices[0], platformViewSliceWithViews(<PlatformView>[
         PlatformView(1, platformViewRect, const PlatformViewStyling())
       ]));
-      expect(slices[1], layerSlice(withPictureRect: pictureRect));
+      expect(slices[1], pictureSliceWithRect(pictureRect));
     });
 
     test('platform view sandwich (overlapping)', () {
@@ -115,14 +114,13 @@
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect2));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
-      expect(slices.length, 2);
-      expect(slices[0], layerSlice(
-        withPictureRect: pictureRect1,
-        withPlatformViews: <PlatformView>[
+      final List<LayerSlice> slices = scene.rootLayer.slices;
+      expect(slices.length, 3);
+      expect(slices[0], pictureSliceWithRect(pictureRect1));
+      expect(slices[1], platformViewSliceWithViews(<PlatformView>[
         PlatformView(1, platformViewRect, const PlatformViewStyling())
       ]));
-      expect(slices[1], layerSlice(withPictureRect: pictureRect2));
+      expect(slices[2], pictureSliceWithRect(pictureRect2));
     });
 
     test('platform view sandwich (non-overlapping)', () {
@@ -141,15 +139,14 @@
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(pictureRect2));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
+      final List<LayerSlice> slices = scene.rootLayer.slices;
 
       // The top picture does not overlap with the platform view, so it should
       // be grouped into the slice below it to reduce the number of canvases we
       // need.
-      expect(slices.length, 1);
-      expect(slices[0], layerSlice(
-        withPictureRect: const ui.Rect.fromLTRB(50, 50, 200, 200),
-        withPlatformViews: <PlatformView>[
+      expect(slices.length, 2);
+      expect(slices[0], pictureSliceWithRect(const ui.Rect.fromLTRB(50, 50, 200, 200)));
+      expect(slices[1], platformViewSliceWithViews(<PlatformView>[
         PlatformView(1, platformViewRect, const PlatformViewStyling())
       ]));
     });
@@ -172,99 +169,34 @@
       sceneBuilder.addPicture(ui.Offset.zero, StubPicture(const ui.Rect.fromLTRB(0, 0, 100, 100)));
 
       final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
-      expect(slices.length, 2);
-      expect(slices[0], layerSlice(
-        withPictureRect: pictureRect1,
-        withPlatformViews: <PlatformView>[
+      final List<LayerSlice> slices = scene.rootLayer.slices;
+      expect(slices.length, 3);
+      expect(slices[0], pictureSliceWithRect(pictureRect1));
+      expect(slices[1], platformViewSliceWithViews(<PlatformView>[
         PlatformView(1, platformViewRect, const PlatformViewStyling(position: PlatformViewPosition.offset(ui.Offset(150, 150))))
       ]));
-      expect(slices[1], layerSlice(withPictureRect: const ui.Rect.fromLTRB(200, 200, 300, 300)));
-    });
-
-    test('grid view test', () {
-      // This test case covers a grid of elements, where each element is a platform
-      // view that has flutter content underneath it and on top of it.
-      // See a detailed explanation of this use-case in the following flutter issue:
-      // https://github.com/flutter/flutter/issues/149863
-      final EngineSceneBuilder sceneBuilder = EngineSceneBuilder();
-
-      const double padding = 10;
-      const double tileSize = 50;
-      final List<PlatformView> expectedPlatformViews = <PlatformView>[];
-      for (int x = 0; x < 10; x++) {
-        for (int y = 0; y < 10; y++) {
-          final ui.Offset offset = ui.Offset(
-            padding + (tileSize + padding) * x,
-            padding + (tileSize + padding) * y,
-          );
-          sceneBuilder.pushOffset(offset.dx, offset.dy);
-          sceneBuilder.addPicture(
-            ui.Offset.zero,
-            StubPicture(const ui.Rect.fromLTWH(0, 0, tileSize, tileSize))
-          );
-          sceneBuilder.addPlatformView(
-            1,
-            offset: const ui.Offset(5, 5),
-            width: tileSize - 10,
-            height: tileSize - 10,
-          );
-          sceneBuilder.addPicture(
-            const ui.Offset(10, 10),
-            StubPicture(const ui.Rect.fromLTWH(0, 0, tileSize - 20, tileSize - 20)),
-          );
-          sceneBuilder.pop();
-          expectedPlatformViews.add(PlatformView(
-            1,
-            const ui.Rect.fromLTRB(5.0, 5.0, tileSize - 5.0, tileSize - 5.0),
-            PlatformViewStyling(position: PlatformViewPosition.offset(offset))
-          ));
-        }
-      }
-
-      final EngineScene scene = sceneBuilder.build() as EngineScene;
-      final List<LayerSlice?> slices = scene.rootLayer.slices;
-
-      // It is important that the optimizations of the scene builder result in
-      // there only being two scene slices.
-      expect(slices.length, 2);
-      expect(slices[0], layerSlice(
-        withPictureRect: const ui.Rect.fromLTRB(
-          padding,
-          padding,
-          10 * (padding + tileSize),
-          10 * (padding + tileSize)
-        ),
-        withPlatformViews: expectedPlatformViews,
-      ));
-      expect(slices[1], layerSlice(withPictureRect: const ui.Rect.fromLTRB(
-        padding + 10,
-        padding + 10,
-        10 * (padding + tileSize) - 10,
-        10 * (padding + tileSize) - 10,
-      )));
+      expect(slices[2], pictureSliceWithRect(const ui.Rect.fromLTRB(200, 200, 300, 300)));
     });
   });
 }
 
-LayerSliceMatcher layerSlice({
-  ui.Rect withPictureRect = ui.Rect.zero,
-  List<PlatformView> withPlatformViews = const <PlatformView>[],
-}) => LayerSliceMatcher(withPictureRect, withPlatformViews);
-class LayerSliceMatcher extends Matcher {
-  LayerSliceMatcher(this.expectedPictureRect, this.expectedPlatformViews);
+PictureSliceMatcher pictureSliceWithRect(ui.Rect rect) => PictureSliceMatcher(rect);
+PlatformViewSliceMatcher platformViewSliceWithViews(List<PlatformView> views)
+  => PlatformViewSliceMatcher(views);
 
-  final ui.Rect expectedPictureRect;
-  final List<PlatformView> expectedPlatformViews;
+class PictureSliceMatcher extends Matcher {
+  PictureSliceMatcher(this.expectedRect);
+
+  final ui.Rect expectedRect;
 
   @override
   Description describe(Description description) {
-    return description.add('<picture slice with cullRect: $expectedPictureRect and platform views: $expectedPlatformViews>');
+    return description.add('<picture slice with cullRect: $expectedRect>');
   }
 
   @override
   bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
-    if (item is! LayerSlice) {
+    if (item is! PictureSlice) {
       return false;
     }
     final ScenePicture picture = item.picture;
@@ -272,28 +204,50 @@
       return false;
     }
 
-    if (picture.cullRect != expectedPictureRect) {
+    if (picture.cullRect != expectedRect) {
       return false;
     }
 
-    if (item.platformViews.length != expectedPlatformViews.length) {
+    return true;
+  }
+}
+
+class PlatformViewSliceMatcher extends Matcher {
+  PlatformViewSliceMatcher(this.expectedPlatformViews);
+
+  final List<PlatformView> expectedPlatformViews;
+
+  @override
+  Description describe(Description description) {
+    return description.add('<platform view slice with platform views: $expectedPlatformViews>');
+  }
+
+  @override
+  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
+    if (item is! PlatformViewSlice) {
       return false;
     }
 
-    for (int i = 0; i < item.platformViews.length; i++) {
+    if (item.views.length != expectedPlatformViews.length) {
+      return false;
+    }
+
+    for (int i = 0; i < item.views.length; i++) {
       final PlatformView expectedView = expectedPlatformViews[i];
-      final PlatformView actualView = item.platformViews[i];
+      final PlatformView actualView = item.views[i];
       if (expectedView.viewId != actualView.viewId) {
+        print('viewID mismatch');
         return false;
       }
       if (expectedView.bounds != actualView.bounds) {
+        print('bounds mismatch');
         return false;
       }
       if (expectedView.styling != actualView.styling) {
+        print('styling mismatch');
         return false;
       }
     }
-
     return true;
   }
 }
diff --git a/lib/web_ui/test/engine/scene_builder_utils.dart b/lib/web_ui/test/engine/scene_builder_utils.dart
index ec014e7..033177c 100644
--- a/lib/web_ui/test/engine/scene_builder_utils.dart
+++ b/lib/web_ui/test/engine/scene_builder_utils.dart
@@ -36,12 +36,8 @@
 class StubCompositePicture extends StubPicture {
   StubCompositePicture(this.children) : super(
     children.fold(null, (ui.Rect? previousValue, StubPicture child) {
-      final ui.Rect childRect = child.cullRect;
-      if (childRect.isEmpty) {
-        return previousValue;
-      }
       return previousValue?.expandToInclude(child.cullRect) ?? child.cullRect;
-    }) ?? ui.Rect.zero
+    })!
   );
 
   final List<StubPicture> children;
diff --git a/lib/web_ui/test/engine/scene_view_test.dart b/lib/web_ui/test/engine/scene_view_test.dart
index 58ff09d..80093bb 100644
--- a/lib/web_ui/test/engine/scene_view_test.dart
+++ b/lib/web_ui/test/engine/scene_view_test.dart
@@ -172,7 +172,7 @@
       120,
     ));
     final EngineRootLayer rootLayer = EngineRootLayer();
-    rootLayer.slices.add(LayerSlice(picture, <PlatformView>[]));
+    rootLayer.slices.add(PictureSlice(picture));
     final EngineScene scene = EngineScene(rootLayer);
     await sceneView.renderScene(scene, null);
 
@@ -205,7 +205,7 @@
         const ui.Rect.fromLTWH(50, 80, 100, 120),
         const PlatformViewStyling());
     final EngineRootLayer rootLayer = EngineRootLayer();
-    rootLayer.slices.add(LayerSlice(StubPicture(ui.Rect.zero), <PlatformView>[platformView]));
+    rootLayer.slices.add(PlatformViewSlice(<PlatformView>[platformView], null));
     final EngineScene scene = EngineScene(rootLayer);
     await sceneView.renderScene(scene, null);
 
@@ -246,7 +246,7 @@
       ));
       pictures.add(picture);
       final EngineRootLayer rootLayer = EngineRootLayer();
-      rootLayer.slices.add(LayerSlice(picture, <PlatformView>[]));
+      rootLayer.slices.add(PictureSlice(picture));
       final EngineScene scene = EngineScene(rootLayer);
       renderFutures.add(sceneView.renderScene(scene, null));
     }
@@ -267,7 +267,7 @@
       ));
 
       final EngineRootLayer rootLayer = EngineRootLayer();
-      rootLayer.slices.add(LayerSlice(picture, <PlatformView>[]));
+      rootLayer.slices.add(PictureSlice(picture));
       final EngineScene scene = EngineScene(rootLayer);
       await sceneView.renderScene(scene, null);
 
diff --git a/lib/web_ui/test/ui/scene_builder_test.dart b/lib/web_ui/test/ui/scene_builder_test.dart
index 428437d..8199b1f 100644
--- a/lib/web_ui/test/ui/scene_builder_test.dart
+++ b/lib/web_ui/test/ui/scene_builder_test.dart
@@ -223,7 +223,7 @@
           region: region);
     });
 
-    test('blur image filter layer', () async {
+    test('image filter layer', () async {
       final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
       sceneBuilder.pushImageFilter(ui.ImageFilter.blur(
         sigmaX: 5.0,
@@ -239,23 +239,6 @@
       await matchGoldenFile('scene_builder_image_filter.png', region: region);
     });
 
-    test('matrix image filter layer', () async {
-      final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
-      sceneBuilder.pushOffset(50.0, 50.0);
-
-      final Matrix4 matrix = Matrix4.rotationZ(math.pi / 18);
-      final ui.ImageFilter matrixFilter = ui.ImageFilter.matrix(toMatrix64(matrix.storage));
-      sceneBuilder.pushImageFilter(matrixFilter);
-      sceneBuilder.addPicture(ui.Offset.zero, drawPicture((ui.Canvas canvas) {
-        canvas.drawRect(
-          region,
-          ui.Paint()..color = const ui.Color(0xFF00FF00)
-        );
-      }));
-      await renderScene(sceneBuilder.build());
-      await matchGoldenFile('scene_builder_matrix_image_filter.png', region: region);
-    });
-
     // Regression test for https://github.com/flutter/flutter/issues/154303
     test('image filter layer with offset', () async {
       final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();