Unverified Commit 883e2dc2 authored by liyuqian's avatar liyuqian Committed by GitHub

Maintain dirtiness and use retained engine layers (#23434)

For #21756
parent 628e8ec0
...@@ -198,6 +198,7 @@ class PaintingContext extends ClipContext { ...@@ -198,6 +198,7 @@ class PaintingContext extends ClipContext {
return true; return true;
}()); }());
} }
assert(child._layer != null);
child._layer.offset = offset; child._layer.offset = offset;
appendLayer(child._layer); appendLayer(child._layer);
} }
...@@ -488,7 +489,7 @@ class PaintingContext extends ClipContext { ...@@ -488,7 +489,7 @@ class PaintingContext extends ClipContext {
/// ancestor render objects that this render object will include a composited /// ancestor render objects that this render object will include a composited
/// layer, which, for example, causes them to use composited clips. /// layer, which, for example, causes them to use composited clips.
void pushOpacity(Offset offset, int alpha, PaintingContextCallback painter) { void pushOpacity(Offset offset, int alpha, PaintingContextCallback painter) {
pushLayer(OpacityLayer(alpha: alpha), painter, offset); pushLayer(OpacityLayer(alpha: alpha, offset: offset), painter, Offset.zero);
} }
@override @override
......
...@@ -192,8 +192,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -192,8 +192,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
Timeline.startSync('Compositing', arguments: timelineWhitelistArguments); Timeline.startSync('Compositing', arguments: timelineWhitelistArguments);
try { try {
final ui.SceneBuilder builder = ui.SceneBuilder(); final ui.SceneBuilder builder = ui.SceneBuilder();
layer.addToScene(builder); final ui.Scene scene = layer.buildScene(builder);
final ui.Scene scene = builder.build();
if (automaticSystemUiAdjustment) if (automaticSystemUiAdjustment)
_updateSystemChrome(); _updateSystemChrome();
ui.window.render(scene); ui.window.render(scene);
......
...@@ -12,6 +12,7 @@ import 'dart:ui' as ui ...@@ -12,6 +12,7 @@ import 'dart:ui' as ui
show show
window, window,
ClipOp, ClipOp,
EngineLayer,
Image, Image,
ImageByteFormat, ImageByteFormat,
Paragraph, Paragraph,
...@@ -54,8 +55,8 @@ class _ProxyLayer extends Layer { ...@@ -54,8 +55,8 @@ class _ProxyLayer extends Layer {
final Layer _layer; final Layer _layer;
@override @override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) { ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
_layer.addToScene(builder, layerOffset); return _layer.addToScene(builder, layerOffset);
} }
@override @override
...@@ -312,8 +313,9 @@ Rect _calculateSubtreeBounds(RenderObject object) { ...@@ -312,8 +313,9 @@ Rect _calculateSubtreeBounds(RenderObject object) {
/// screenshots render to the scene in the local coordinate system of the layer. /// screenshots render to the scene in the local coordinate system of the layer.
class _ScreenshotContainerLayer extends OffsetLayer { class _ScreenshotContainerLayer extends OffsetLayer {
@override @override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) { ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
addChildrenToScene(builder, layerOffset); addChildrenToScene(builder, layerOffset);
return null; // this does not have an engine layer.
} }
} }
...@@ -588,7 +590,7 @@ class _ScreenshotPaintingContext extends PaintingContext { ...@@ -588,7 +590,7 @@ class _ScreenshotPaintingContext extends PaintingContext {
// We must build the regular scene before we can build the screenshot // We must build the regular scene before we can build the screenshot
// scene as building the screenshot scene assumes addToScene has already // scene as building the screenshot scene assumes addToScene has already
// been called successfully for all layers in the regular scene. // been called successfully for all layers in the regular scene.
repaintBoundary.layer.addToScene(ui.SceneBuilder()); repaintBoundary.layer.buildScene(ui.SceneBuilder());
return data.containerLayer.toImage(renderBounds, pixelRatio: pixelRatio); return data.containerLayer.toImage(renderBounds, pixelRatio: pixelRatio);
} }
...@@ -2226,9 +2228,9 @@ class _InspectorOverlayLayer extends Layer { ...@@ -2226,9 +2228,9 @@ class _InspectorOverlayLayer extends Layer {
double _textPainterMaxWidth; double _textPainterMaxWidth;
@override @override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) { ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
if (!selection.active) if (!selection.active)
return; return null;
final RenderObject selected = selection.current; final RenderObject selected = selection.current;
final List<_TransformedRect> candidates = <_TransformedRect>[]; final List<_TransformedRect> candidates = <_TransformedRect>[];
...@@ -2251,6 +2253,7 @@ class _InspectorOverlayLayer extends Layer { ...@@ -2251,6 +2253,7 @@ class _InspectorOverlayLayer extends Layer {
_picture = _buildPicture(state); _picture = _buildPicture(state);
} }
builder.addPicture(layerOffset, _picture); builder.addPicture(layerOffset, _picture);
return null; // this does not have an engine layer.
} }
ui.Picture _buildPicture(_InspectorOverlayRenderState state) { ui.Picture _buildPicture(_InspectorOverlayRenderState state) {
......
...@@ -40,4 +40,73 @@ void main() { ...@@ -40,4 +40,73 @@ void main() {
expect(boundary.layer, isNotNull); expect(boundary.layer, isNotNull);
expect(boundary.layer.attached, isTrue); // this time it did again! expect(boundary.layer.attached, isTrue); // this time it did again!
}); });
test('layer subtree dirtiness is correctly computed', () {
final ContainerLayer a = ContainerLayer();
final ContainerLayer b = ContainerLayer();
final ContainerLayer c = ContainerLayer();
final ContainerLayer d = ContainerLayer();
final ContainerLayer e = ContainerLayer();
final ContainerLayer f = ContainerLayer();
final ContainerLayer g = ContainerLayer();
final PictureLayer h = PictureLayer(Rect.zero);
final PictureLayer i = PictureLayer(Rect.zero);
final PictureLayer j = PictureLayer(Rect.zero);
// The tree is like the following where b and j are dirty:
// a____
// / \
// (x)b___ c
// / \ \ |
// d e f g
// / \ |
// h i j(x)
a.append(b);
a.append(c);
b.append(d);
b.append(e);
b.append(f);
d.append(h);
d.append(i);
c.append(g);
g.append(j);
a.debugMarkClean();
b.markNeedsAddToScene(); // ignore: invalid_use_of_protected_member
c.debugMarkClean();
d.debugMarkClean();
e.debugMarkClean();
f.debugMarkClean();
g.debugMarkClean();
h.debugMarkClean();
i.debugMarkClean();
j.markNeedsAddToScene(); // ignore: invalid_use_of_protected_member
a.updateSubtreeNeedsAddToScene();
expect(a.debugSubtreeNeedsAddToScene, true);
expect(b.debugSubtreeNeedsAddToScene, true);
expect(c.debugSubtreeNeedsAddToScene, true);
expect(g.debugSubtreeNeedsAddToScene, true);
expect(j.debugSubtreeNeedsAddToScene, true);
expect(d.debugSubtreeNeedsAddToScene, false);
expect(e.debugSubtreeNeedsAddToScene, false);
expect(f.debugSubtreeNeedsAddToScene, false);
expect(h.debugSubtreeNeedsAddToScene, false);
expect(i.debugSubtreeNeedsAddToScene, false);
});
test('leader and follower layers are always dirty', () {
final LayerLink link = LayerLink();
final LeaderLayer leaderLayer = LeaderLayer(link: link);
final FollowerLayer followerLayer = FollowerLayer(link: link);
leaderLayer.debugMarkClean();
followerLayer.debugMarkClean();
leaderLayer.updateSubtreeNeedsAddToScene();
followerLayer.updateSubtreeNeedsAddToScene();
expect(leaderLayer.debugSubtreeNeedsAddToScene, true);
expect(followerLayer.debugSubtreeNeedsAddToScene, true);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment