Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ abstract class ContainerLayer extends Layer {
}
}

/// The top-most layer in the layer tree.
///
/// This layer does not draw anything. It's only used so we can add leaf layers
/// to [LayerSceneBuilder] without requiring a [ContainerLayer].
class RootLayer extends ContainerLayer {
@override
void paint(PaintContext context) {
paintChildren(context);
}
}

class BackdropFilterEngineLayer extends ContainerLayer implements ui.BackdropFilterEngineLayer {
final ui.ImageFilter _filter;

Expand Down
37 changes: 14 additions & 23 deletions lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ part of engine;
class LayerScene implements ui.Scene {
final LayerTree layerTree;

LayerScene(Layer? rootLayer) : layerTree = LayerTree() {
layerTree.rootLayer = rootLayer;
}
LayerScene(RootLayer rootLayer) : layerTree = LayerTree(rootLayer);

@override
void dispose() {}
Expand All @@ -23,8 +21,12 @@ class LayerScene implements ui.Scene {
}

class LayerSceneBuilder implements ui.SceneBuilder {
Layer? rootLayer;
ContainerLayer? currentLayer;
LayerSceneBuilder() : rootLayer = RootLayer() {
currentLayer = rootLayer;
}

final RootLayer rootLayer;
late ContainerLayer currentLayer;

@override
void addChildScene({
Expand All @@ -50,16 +52,13 @@ class LayerSceneBuilder implements ui.SceneBuilder {
bool isComplexHint = false,
bool willChangeHint = false,
}) {
currentLayer!.add(PictureLayer(
currentLayer.add(PictureLayer(
picture as CkPicture, offset, isComplexHint, willChangeHint));
}

@override
void addRetained(ui.EngineLayer retainedLayer) {
if (currentLayer == null) {
return;
}
currentLayer!.add(retainedLayer as Layer);
currentLayer.add(retainedLayer as Layer);
}

@override
Expand All @@ -82,7 +81,7 @@ class LayerSceneBuilder implements ui.SceneBuilder {
double height = 0.0,
Object? webOnlyPaintedBy,
}) {
currentLayer!.add(PlatformViewLayer(viewId, offset, width, height));
currentLayer.add(PlatformViewLayer(viewId, offset, width, height));
}

@override
Expand All @@ -92,10 +91,11 @@ class LayerSceneBuilder implements ui.SceneBuilder {

@override
void pop() {
if (currentLayer == null) {
if (currentLayer == rootLayer) {
// Don't pop the root layer. It must always be there.
return;
}
currentLayer = currentLayer!.parent;
currentLayer = currentLayer.parent!;
}

@override
Expand Down Expand Up @@ -221,16 +221,7 @@ class LayerSceneBuilder implements ui.SceneBuilder {
}

T pushLayer<T extends ContainerLayer>(T layer) {
if (rootLayer == null) {
rootLayer = currentLayer = layer;
return layer;
}

if (currentLayer == null) {
return layer;
}

currentLayer!.add(layer);
currentLayer.add(layer);
currentLayer = layer;
return layer;
}
Expand Down
30 changes: 15 additions & 15 deletions lib/web_ui/lib/src/engine/canvaskit/layer_tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ part of engine;

/// A tree of [Layer]s that, together with a [Size] compose a frame.
class LayerTree {
LayerTree(this.rootLayer);

/// The root of the layer tree.
Layer? rootLayer;
final RootLayer rootLayer;

/// The size (in physical pixels) of the frame to paint this layer tree into.
final ui.Size frameSize = ui.window.physicalSize;
Expand All @@ -27,7 +29,7 @@ class LayerTree {
ignoreRasterCache ? null : frame.rasterCache,
frame.viewEmbedder,
);
rootLayer!.preroll(context, Matrix4.identity());
rootLayer.preroll(context, Matrix4.identity());
}

/// Paints the layer tree into the given [frame].
Expand All @@ -48,8 +50,8 @@ class LayerTree {
ignoreRasterCache ? null : frame.rasterCache,
frame.viewEmbedder,
);
if (rootLayer!.needsPainting) {
rootLayer!.paint(context);
if (rootLayer.needsPainting) {
rootLayer.paint(context);
}
}

Expand All @@ -59,17 +61,15 @@ class LayerTree {
ui.Picture flatten() {
CkPictureRecorder recorder = CkPictureRecorder();
CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
if (rootLayer != null) {
final PrerollContext prerollContext = PrerollContext(null, null);
rootLayer!.preroll(prerollContext, Matrix4.identity());

CkNWayCanvas internalNodesCanvas = CkNWayCanvas();
internalNodesCanvas.addCanvas(canvas);
final PaintContext paintContext =
PaintContext(internalNodesCanvas, canvas, null, null);
if (rootLayer!.needsPainting) {
rootLayer!.paint(paintContext);
}
final PrerollContext prerollContext = PrerollContext(null, null);
rootLayer.preroll(prerollContext, Matrix4.identity());

CkNWayCanvas internalNodesCanvas = CkNWayCanvas();
internalNodesCanvas.addCanvas(canvas);
final PaintContext paintContext =
PaintContext(internalNodesCanvas, canvas, null, null);
if (rootLayer.needsPainting) {
rootLayer.paint(paintContext);
}
return recorder.endRecording();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/canvaskit/canvas_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ void testMain() {

// Render the scene once without painting the shadow bounds just to
// preroll the scene to compute the shadow bounds.
buildTestScene(paintShadowBounds: false).rootLayer!.preroll(
buildTestScene(paintShadowBounds: false).rootLayer.preroll(
PrerollContext(
RasterCache(),
HtmlViewEmbedder(),
Expand Down
8 changes: 7 additions & 1 deletion lib/web_ui/test/canvaskit/layer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,18 @@ void testMain() {
sb.addPicture(ui.Offset.zero, picture);
final LayerTree layerTree = sb.build().layerTree;
dispatcher.rasterizer!.draw(layerTree);
final ClipRectEngineLayer clipRect = layerTree.rootLayer as ClipRectEngineLayer;
final ClipRectEngineLayer clipRect = layerTree.rootLayer.debugLayers.single as ClipRectEngineLayer;
expect(clipRect.paintBounds, ui.Rect.fromLTRB(15, 15, 30, 30));

final TransformEngineLayer transform = clipRect.debugLayers.single as TransformEngineLayer;
expect(transform.paintBounds, ui.Rect.fromLTRB(0, 0, 30, 30));
});

test('can push a leaf layer without a container layer', () async {
final CkPictureRecorder recorder = CkPictureRecorder();
recorder.beginRecording(ui.Rect.zero);
LayerSceneBuilder().addPicture(ui.Offset.zero, recorder.endRecording());
});
// TODO: https://github.com/flutter/flutter/issues/60040
}, skip: isIosSafari);
}