Commit fc576814 authored by Adam Barth's avatar Adam Barth

Refactor PaintingContext

This patch simplifies PaintingContext with several goals:

1) We now call a callback instead of assuming the caller has a single child to
   paint. This change will let us handle render objects that wish to paint more
   than one child.
2) We now avoid creating lots of empty picture layers because we don't eagerly
   start recording pictures. Instead, we wait for the first caller to touch the
   canvas before creating the picture recorder.
3) We now are more consistent about which values have incorporated the painting
   offset.
parent 5734821f
...@@ -282,7 +282,7 @@ class RenderSectorRing extends RenderSectorWithChildren { ...@@ -282,7 +282,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
super.paint(context, offset); super.paint(context, offset);
RenderSector child = firstChild; RenderSector child = firstChild;
while (child != null) { while (child != null) {
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
final SectorChildListParentData childParentData = child.parentData; final SectorChildListParentData childParentData = child.parentData;
child = childParentData.nextSibling; child = childParentData.nextSibling;
} }
...@@ -388,7 +388,7 @@ class RenderSectorSlice extends RenderSectorWithChildren { ...@@ -388,7 +388,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
RenderSector child = firstChild; RenderSector child = firstChild;
while (child != null) { while (child != null) {
assert(child.parentData is SectorChildListParentData); assert(child.parentData is SectorChildListParentData);
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
final SectorChildListParentData childParentData = child.parentData; final SectorChildListParentData childParentData = child.parentData;
child = childParentData.nextSibling; child = childParentData.nextSibling;
} }
...@@ -470,7 +470,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil ...@@ -470,7 +470,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
if (child != null) { if (child != null) {
Rect bounds = offset & size; Rect bounds = offset & size;
// we move the offset to the center of the circle for the RenderSectors // we move the offset to the center of the circle for the RenderSectors
context.paintChild(child, bounds.center); context.paintChild(child, bounds.center.toOffset());
} }
} }
......
...@@ -232,7 +232,7 @@ class _RenderTabBar extends RenderBox with ...@@ -232,7 +232,7 @@ class _RenderTabBar extends RenderBox with
RenderBox child = firstChild; RenderBox child = firstChild;
while (child != null) { while (child != null) {
final _TabBarParentData childParentData = child.parentData; final _TabBarParentData childParentData = child.parentData;
context.paintChild(child, childParentData.position + offset); context.paintChild(child, childParentData.offset + offset);
if (index++ == selectedIndex) if (index++ == selectedIndex)
_paintIndicator(context.canvas, child, offset); _paintIndicator(context.canvas, child, offset);
child = childParentData.nextSibling; child = childParentData.nextSibling;
......
...@@ -287,6 +287,8 @@ class BoxHitTestEntry extends HitTestEntry { ...@@ -287,6 +287,8 @@ class BoxHitTestEntry extends HitTestEntry {
/// Parent data used by [RenderBox] and its subclasses /// Parent data used by [RenderBox] and its subclasses
class BoxParentData extends ParentData { class BoxParentData extends ParentData {
// TODO(abarth): Switch to using an Offset rather than a Point here. This
// value is really the offset from the parent.
Point _position = Point.origin; Point _position = Point.origin;
/// The point at which to paint the child in the parent's coordinate system /// The point at which to paint the child in the parent's coordinate system
Point get position => _position; Point get position => _position;
...@@ -294,6 +296,7 @@ class BoxParentData extends ParentData { ...@@ -294,6 +296,7 @@ class BoxParentData extends ParentData {
assert(RenderObject.debugDoingLayout); assert(RenderObject.debugDoingLayout);
_position = value; _position = value;
} }
Offset get offset => _position.toOffset();
String toString() => 'position=$position'; String toString() => 'position=$position';
} }
...@@ -771,7 +774,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ...@@ -771,7 +774,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
RenderBox child = firstChild; RenderBox child = firstChild;
while (child != null) { while (child != null) {
final ParentDataType childParentData = child.parentData; final ParentDataType childParentData = child.parentData;
context.paintChild(child, childParentData.position + offset); context.paintChild(child, childParentData.offset + offset);
child = childParentData.nextSibling; child = childParentData.nextSibling;
} }
} }
......
...@@ -131,7 +131,7 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render ...@@ -131,7 +131,7 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
} }
void debugDescribeSettings(List<String> settings) { void debugDescribeSettings(List<String> settings) {
...@@ -198,7 +198,7 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R ...@@ -198,7 +198,7 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
} }
} }
......
...@@ -77,7 +77,7 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox ...@@ -77,7 +77,7 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
} }
} }
...@@ -501,10 +501,12 @@ class RenderOpacity extends RenderProxyBox { ...@@ -501,10 +501,12 @@ class RenderOpacity extends RenderProxyBox {
int a = _alpha; int a = _alpha;
if (a == 0) if (a == 0)
return; return;
if (a == 255) if (a == 255) {
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
else return;
context.paintChildWithOpacity(child, offset.toPoint(), null, a); }
// TODO(abarth): We should pass bounds here.
context.pushOpacity(needsCompositing, offset, null, a, super.paint);
} }
} }
...@@ -540,7 +542,7 @@ class RenderShaderMask extends RenderProxyBox { ...@@ -540,7 +542,7 @@ class RenderShaderMask extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChildWithShaderMask(child, offset.toPoint(), offset & size, _shaderCallback, _transferMode); context.pushShaderMask(needsCompositing, offset, Point.origin & size, _shaderCallback, _transferMode, super.paint);
} }
} }
...@@ -552,7 +554,7 @@ class RenderClipRect extends RenderProxyBox { ...@@ -552,7 +554,7 @@ class RenderClipRect extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChildWithClipRect(child, offset.toPoint(), offset & size); context.pushClipRect(needsCompositing, offset, Point.origin & size, super.paint);
} }
} }
...@@ -598,9 +600,9 @@ class RenderClipRRect extends RenderProxyBox { ...@@ -598,9 +600,9 @@ class RenderClipRRect extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
Rect rect = offset & size; Rect rect = Point.origin & size;
ui.RRect rrect = new ui.RRect.fromRectXY(rect, xRadius, yRadius); ui.RRect rrect = new ui.RRect.fromRectXY(rect, xRadius, yRadius);
context.paintChildWithClipRRect(child, offset.toPoint(), rect, rrect); context.pushClipRRect(needsCompositing, offset, rect, rrect, super.paint);
} }
} }
} }
...@@ -615,7 +617,7 @@ class RenderClipOval extends RenderProxyBox { ...@@ -615,7 +617,7 @@ class RenderClipOval extends RenderProxyBox {
Rect _cachedRect; Rect _cachedRect;
Path _cachedPath; Path _cachedPath;
Path _getPath(Rect rect) { Path _getClipPath(Rect rect) {
if (rect != _cachedRect) { if (rect != _cachedRect) {
_cachedRect = rect; _cachedRect = rect;
_cachedPath = new Path()..addOval(_cachedRect); _cachedPath = new Path()..addOval(_cachedRect);
...@@ -634,8 +636,8 @@ class RenderClipOval extends RenderProxyBox { ...@@ -634,8 +636,8 @@ class RenderClipOval extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
Rect rect = offset & size; Rect bounds = Point.origin & size;
context.paintChildWithClipPath(child, offset.toPoint(), rect, _getPath(rect)); context.pushClipPath(needsCompositing, offset, bounds, _getClipPath(bounds), super.paint);
} }
} }
} }
...@@ -863,7 +865,7 @@ class RenderTransform extends RenderProxyBox { ...@@ -863,7 +865,7 @@ class RenderTransform extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChildWithTransform(child, offset.toPoint(), _effectiveTransform); context.pushTransform(needsCompositing, offset, _effectiveTransform, super.paint);
} }
void applyPaintTransform(Matrix4 transform) { void applyPaintTransform(Matrix4 transform) {
......
...@@ -56,7 +56,7 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi ...@@ -56,7 +56,7 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
final BoxParentData childParentData = child.parentData; final BoxParentData childParentData = child.parentData;
context.paintChild(child, childParentData.position + offset); context.paintChild(child, childParentData.offset + offset);
} }
} }
......
...@@ -489,6 +489,6 @@ class RenderIndexedStack extends RenderStackBase { ...@@ -489,6 +489,6 @@ class RenderIndexedStack extends RenderStackBase {
return; return;
RenderBox child = _childAtIndex(); RenderBox child = _childAtIndex();
final StackParentData childParentData = child.parentData; final StackParentData childParentData = child.parentData;
context.paintChild(child, childParentData.position + offset); context.paintChild(child, childParentData.offset + offset);
} }
} }
...@@ -54,6 +54,6 @@ class RenderStatisticsBox extends RenderBox { ...@@ -54,6 +54,6 @@ class RenderStatisticsBox extends RenderBox {
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
context.paintStatistics(optionsMask, rasterizerThreshold, offset, size); context.pushStatistics(offset, optionsMask, rasterizerThreshold, size);
} }
} }
...@@ -110,7 +110,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -110,7 +110,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null)
context.paintChild(child, offset.toPoint()); context.paintChild(child, offset);
} }
/// Uploads the composited layer tree to the engine /// Uploads the composited layer tree to the engine
......
...@@ -146,12 +146,15 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox ...@@ -146,12 +146,15 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
Offset roundedScrollOffset = _scrollOffsetRoundedToIntegerDevicePixels; Offset roundedScrollOffset = _scrollOffsetRoundedToIntegerDevicePixels;
bool _needsClip = offset < Offset.zero || bool _needsClip = offset < Offset.zero
!(offset & size).contains(((offset - roundedScrollOffset) & child.size).bottomRight); || !(offset & size).contains(((offset - roundedScrollOffset) & child.size).bottomRight);
if (_needsClip) if (_needsClip) {
context.paintChildWithClipRect(child, (offset - roundedScrollOffset).toPoint(), offset & size); context.pushClipRect(needsCompositing, offset, Point.origin & size, (PaintingContext context, Offset offset) {
else context.paintChild(child, offset - roundedScrollOffset);
context.paintChild(child, (offset - roundedScrollOffset).toPoint()); });
} else {
context.paintChild(child, offset - roundedScrollOffset);
}
} }
} }
......
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