Commit e17aa1b6 authored by Adam Barth's avatar Adam Barth

Add a compositing update phase

We need to compute whether a RenderObject has a composited descendant so that
we can decide whether to use canvas.saveLayer or to create a new composited
layer while walking down the tree during painting.

The compositing update walks the tree from the root only to places where the
tree's structure has been mutated. In the common case during an animation loop,
we won't need to visit any render object beyond the root.
parent 86da2f9b
...@@ -120,6 +120,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -120,6 +120,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
setupParentData(child); setupParentData(child);
super.adoptChild(child); super.adoptChild(child);
markNeedsLayout(); markNeedsLayout();
markNeedsCompositingUpdate();
} }
void dropChild(RenderObject child) { // only for use by subclasses void dropChild(RenderObject child) { // only for use by subclasses
assert(debugCanPerformMutations); assert(debugCanPerformMutations);
...@@ -129,6 +130,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -129,6 +130,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
child.parentData.detach(); child.parentData.detach();
super.dropChild(child); super.dropChild(child);
markNeedsLayout(); markNeedsLayout();
markNeedsCompositingUpdate();
} }
// Override in subclasses with children and call the visitor for each child. // Override in subclasses with children and call the visitor for each child.
...@@ -367,15 +369,46 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -367,15 +369,46 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>(); static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>();
bool _needsPaint = true;
bool get needsPaint => _needsPaint;
PictureLayer _layer; PictureLayer _layer;
PictureLayer get layer { PictureLayer get layer {
assert(requiresCompositing); assert(requiresCompositing);
return _layer; return _layer;
} }
bool get requiresCompositing => false;
bool _hasCompositedDescendant = false;
bool get hasCompositedDescendant {
assert(!_needsCompositingUpdate);
return _hasCompositedDescendant;
}
bool _needsCompositingUpdate = false;
void markNeedsCompositingUpdate() {
if (_needsCompositingUpdate)
return;
_needsCompositingUpdate = true;
final AbstractNode parent = this.parent;
if (parent is RenderObject)
parent.markNeedsCompositingUpdate();
}
void updateCompositing() {
if (!_needsCompositingUpdate)
return;
visitChildren((RenderObject child) {
child.updateCompositing();
if (child.hasCompositedDescendant)
_hasCompositedDescendant = true;
});
if (requiresCompositing)
_hasCompositedDescendant = true;
_needsCompositingUpdate = false;
}
bool _needsPaint = true;
bool get needsPaint => _needsPaint;
void markNeedsPaint() { void markNeedsPaint() {
assert(!debugDoingPaint); assert(!debugDoingPaint);
if (!attached) return; // Don't try painting things that aren't in the hierarchy if (!attached) return; // Don't try painting things that aren't in the hierarchy
...@@ -461,7 +494,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -461,7 +494,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(!_needsPaint); assert(!_needsPaint);
} }
bool get requiresCompositing => false;
Rect get paintBounds; Rect get paintBounds;
void debugPaint(PaintingContext context, Offset offset) { } void debugPaint(PaintingContext context, Offset offset) { }
void paint(PaintingContext context, Offset offset) { } void paint(PaintingContext context, Offset offset) { }
......
...@@ -71,6 +71,7 @@ class SkyBinding { ...@@ -71,6 +71,7 @@ class SkyBinding {
} }
void beginFrame(double timeStamp) { void beginFrame(double timeStamp) {
RenderObject.flushLayout(); RenderObject.flushLayout();
_renderView.updateCompositing();
RenderObject.flushPaint(); RenderObject.flushPaint();
_renderView.paintFrame(); _renderView.paintFrame();
_renderView.compositeFrame(); _renderView.compositeFrame();
......
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