Short-circuit the relayoutSubtreeRoot when the child couldn't change dimensions anyway because the parent constrained it.

The relayout subtree root concept is intended to handle the case where
a node, when it lays itself out for a second time, changes its opinion
about what dimensions it should be. In such a situation, the parent,
if it based its own opinion about what size _it_ should be on the
child's dimensions, would also need to lay itself out again. Thus,
when this scenario is possible, the child remembers the parent, and
when it would be told to relayout, we actually start the layout with
the parent.

In practice, this chains, and we end up with nodes that point to
ancestors ten or more steps up the tree such that when the inner most
child re-lays-out, the whole app ends up relaying out.

This patch tries to short-circuit this for the case where the
constraints being applied to the child are such that actually, the
child has no choice about its dimensions. In that case, the parent
can't change dimensions when the child re-lays-out.

This makes a huge difference on the stocks demo app. Without this, on
the third rendered frame, there are 72 relayoutSubtreeRoot links, the
deepest chain is 8 deep, and 9 of the chains are only 1 level deep.
With it, there are 63 relayoutSubtreeRoot links, the deepest chain is
only 4 deep, and 38 of the chains are only 1 level deep.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1196553004.
This commit is contained in:
Hixie 2015-06-22 16:51:25 -07:00
parent 14e9b5d564
commit e352ec9fc4

View file

@ -11,7 +11,7 @@ import 'package:sky/rendering/sky_binding.dart';
const double kTwoPi = 2 * math.PI;
class SectorConstraints {
class SectorConstraints extends Constraints {
const SectorConstraints({
this.minDeltaRadius: 0.0,
this.maxDeltaRadius: double.INFINITY,
@ -37,6 +37,8 @@ class SectorConstraints {
double constrainDeltaTheta(double deltaTheta) {
return clamp(min: minDeltaTheta, max: maxDeltaTheta, value: deltaTheta);
}
bool get isTight => minDeltaTheta >= maxDeltaTheta && minDeltaTheta >= maxDeltaTheta;
}
class SectorDimensions {
@ -72,7 +74,7 @@ abstract class RenderSector extends RenderObject {
return new SectorDimensions.withConstraints(constraints);
}
SectorConstraints get constraints { SectorConstraints result = super.constraints; return result; }
SectorConstraints get constraints => super.constraints;
void performResize() {
// default behaviour for subclasses that have sizedByParent = true
deltaRadius = constraints.constrainDeltaRadius(0.0);