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 {
return true;
}());
}
assert(child._layer != null);
child._layer.offset = offset;
appendLayer(child._layer);
}
......@@ -488,7 +489,7 @@ class PaintingContext extends ClipContext {
/// ancestor render objects that this render object will include a composited
/// layer, which, for example, causes them to use composited clips.
void pushOpacity(Offset offset, int alpha, PaintingContextCallback painter) {
pushLayer(OpacityLayer(alpha: alpha), painter, offset);
pushLayer(OpacityLayer(alpha: alpha, offset: offset), painter, Offset.zero);
}
@override
......
......@@ -192,8 +192,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
Timeline.startSync('Compositing', arguments: timelineWhitelistArguments);
try {
final ui.SceneBuilder builder = ui.SceneBuilder();
layer.addToScene(builder);
final ui.Scene scene = builder.build();
final ui.Scene scene = layer.buildScene(builder);
if (automaticSystemUiAdjustment)
_updateSystemChrome();
ui.window.render(scene);
......
......@@ -12,6 +12,7 @@ import 'dart:ui' as ui
show
window,
ClipOp,
EngineLayer,
Image,
ImageByteFormat,
Paragraph,
......@@ -54,8 +55,8 @@ class _ProxyLayer extends Layer {
final Layer _layer;
@override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
_layer.addToScene(builder, layerOffset);
ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
return _layer.addToScene(builder, layerOffset);
}
@override
......@@ -312,8 +313,9 @@ Rect _calculateSubtreeBounds(RenderObject object) {
/// screenshots render to the scene in the local coordinate system of the layer.
class _ScreenshotContainerLayer extends OffsetLayer {
@override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
addChildrenToScene(builder, layerOffset);
return null; // this does not have an engine layer.
}
}
......@@ -588,7 +590,7 @@ class _ScreenshotPaintingContext extends PaintingContext {
// We must build the regular scene before we can build the screenshot
// scene as building the screenshot scene assumes addToScene has already
// 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);
}
......@@ -2226,9 +2228,9 @@ class _InspectorOverlayLayer extends Layer {
double _textPainterMaxWidth;
@override
void addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
ui.EngineLayer addToScene(ui.SceneBuilder builder, [Offset layerOffset = Offset.zero]) {
if (!selection.active)
return;
return null;
final RenderObject selected = selection.current;
final List<_TransformedRect> candidates = <_TransformedRect>[];
......@@ -2251,6 +2253,7 @@ class _InspectorOverlayLayer extends Layer {
_picture = _buildPicture(state);
}
builder.addPicture(layerOffset, _picture);
return null; // this does not have an engine layer.
}
ui.Picture _buildPicture(_InspectorOverlayRenderState state) {
......
......@@ -40,4 +40,73 @@ void main() {
expect(boundary.layer, isNotNull);
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