Commit 298f4a6e authored by Adam Barth's avatar Adam Barth

Reduce record time in Stocks drawer animation by 55%

Now we use a ForcedLayer in the navigator overlay to cache the recording for
each entry in the overlay. This mechanism just caches the display list, not the
underlying pixels.

Also, remove the "dispose" notification in the Layer tree because it was
disposing layer too eagerly. We don't actually need this notification for
anything other than eagerly freeing some C++ memory.
parent 904acc83
......@@ -59,10 +59,6 @@ abstract class Layer {
_nextSibling = null;
_previousSibling = null;
_parent = null;
_dispose();
}
void _dispose() {
}
/// Override this function to upload this layer to the engine
......@@ -88,11 +84,6 @@ class PictureLayer extends Layer {
/// The picture's coodinate system matches this layer's coodinate system
ui.Picture picture;
void _dispose() {
super._dispose();
picture.dispose();
}
void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
builder.addPicture(offset + layerOffset, picture, paintBounds);
}
......@@ -190,7 +181,6 @@ class ContainerLayer extends Layer {
child._previousSibling = null;
child._nextSibling = null;
child._parent = null;
child._dispose();
}
/// Removes all of this layer's children from its child list
......@@ -201,23 +191,12 @@ class ContainerLayer extends Layer {
child._previousSibling = null;
child._nextSibling = null;
child._parent = null;
child._dispose();
child = next;
}
_firstChild = null;
_lastChild = null;
}
void _dispose() {
super._dispose();
Layer child = _firstChild;
while (child != null) {
Layer next = child.nextSibling;
child._dispose();
child = next;
}
}
void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
addChildrenToScene(builder, offset + layerOffset);
}
......
......@@ -1052,6 +1052,19 @@ class RenderPointerListener extends RenderProxyBox {
}
}
/// Force this subtree to have a layer
///
/// This render object creates a separate display list for its child, which
/// can improve performance if the subtree repaints at different times than
/// the surrounding parts of the tree. Specifically, when the child does not
/// repaint but its parent does, we can re-use the display list we recorded
/// previously. Similarly, when the child repaints but the surround tree does
/// not, we can re-record its display list without re-recording the display list
/// for the surround tree.
class RenderForcedLayer extends RenderProxyBox {
bool get hasLayer => true;
}
/// Is invisible during hit testing.
///
/// When [ignoring] is true, this render object (and its subtree) is invisible
......
......@@ -1321,6 +1321,11 @@ class Listener extends OneChildRenderObjectWidget {
}
}
class ForcedLayer extends OneChildRenderObjectWidget {
ForcedLayer({ Key key, Widget child }) : super(key: key, child: child);
RenderForcedLayer createRenderObject() => new RenderForcedLayer();
}
class IgnorePointer extends OneChildRenderObjectWidget {
IgnorePointer({ Key key, Widget child, this.ignoring: true })
: super(key: key, child: child);
......
......@@ -39,7 +39,9 @@ class OverlayRoute extends Route {
void didPush(OverlayState overlay, OverlayEntry insertionPoint) {
for (WidgetBuilder builder in builders) {
_overlayEntries.add(new OverlayEntry(builder: builder));
_overlayEntries.add(new OverlayEntry(builder: (BuildContext context) {
return new ForcedLayer(child: builder(context));
}));
overlay?.insert(_overlayEntries.last, above: insertionPoint);
insertionPoint = _overlayEntries.last;
}
......
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