mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[canvaskit] support adding leaf layers w/o container layers (flutter/engine#24357)
This commit is contained in:
parent
aff7e22b14
commit
efa24d8bd0
@ -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;
|
||||
|
||||
|
||||
@ -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() {}
|
||||
@ -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({
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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].
|
||||
@ -48,8 +50,8 @@ class LayerTree {
|
||||
ignoreRasterCache ? null : frame.rasterCache,
|
||||
frame.viewEmbedder,
|
||||
);
|
||||
if (rootLayer!.needsPainting) {
|
||||
rootLayer!.paint(context);
|
||||
if (rootLayer.needsPainting) {
|
||||
rootLayer.paint(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
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);
|
||||
}
|
||||
CkNWayCanvas internalNodesCanvas = CkNWayCanvas();
|
||||
internalNodesCanvas.addCanvas(canvas);
|
||||
final PaintContext paintContext =
|
||||
PaintContext(internalNodesCanvas, canvas, null, null);
|
||||
if (rootLayer.needsPainting) {
|
||||
rootLayer.paint(paintContext);
|
||||
}
|
||||
return recorder.endRecording();
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user