diff --git a/sky/packages/sky/lib/rendering/box.dart b/sky/packages/sky/lib/rendering/box.dart index f9dbd2c76..d53d51522 100644 --- a/sky/packages/sky/lib/rendering/box.dart +++ b/sky/packages/sky/lib/rendering/box.dart @@ -1751,10 +1751,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin try { final double devicePixelRatio = sky.view.devicePixelRatio; Matrix4 transform = new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0); - Rect bounds = Point.origin & size; - Rect scaledBounds = Point.origin & (size * devicePixelRatio); - _rootLayer = new TransformLayer(bounds: scaledBounds, transform: transform); - PaintingContext context = new PaintingContext(bounds); + _rootLayer = new TransformLayer(transform: transform); + PaintingContext context = new PaintingContext(Offset.zero, size); _rootLayer.add(context.layer); context.paintChild(child, Point.origin); context.endRecording(); @@ -1767,7 +1765,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin sky.tracing.begin('RenderView.compositeFrame'); try { sky.PictureRecorder recorder = new sky.PictureRecorder(); - sky.Canvas canvas = new sky.Canvas(recorder, _rootLayer.bounds); + sky.Canvas canvas = new sky.Canvas(recorder, Point.origin & (size * sky.view.devicePixelRatio)); _rootLayer.paint(canvas); sky.view.picture = recorder.endRecording(); } finally { diff --git a/sky/packages/sky/lib/rendering/layer.dart b/sky/packages/sky/lib/rendering/layer.dart index 616de5f3b..429d65033 100644 --- a/sky/packages/sky/lib/rendering/layer.dart +++ b/sky/packages/sky/lib/rendering/layer.dart @@ -8,9 +8,9 @@ import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; import 'package:vector_math/vector_math.dart'; abstract class Layer { - Layer({ this.bounds }); + Layer({ this.offset: Offset.zero }); - Rect bounds; + Offset offset; // From parent, in parent's coordinate system. ContainerLayer _parent; ContainerLayer get parent => _parent; @@ -30,18 +30,21 @@ abstract class Layer { } class PictureLayer extends Layer { - PictureLayer({ Rect bounds }) - : super(bounds: bounds); + PictureLayer({ Offset offset: Offset.zero, this.size }) + : super(offset: offset); + Size size; sky.Picture picture; void paint(sky.Canvas canvas) { + canvas.translate(offset.dx, offset.dy); canvas.drawPicture(picture); + canvas.translate(-offset.dx, -offset.dy); } } class ContainerLayer extends Layer { - ContainerLayer({ Rect bounds }) : super(bounds: bounds); + ContainerLayer({ Offset offset: Offset.zero }) : super(offset: offset); void paint(sky.Canvas canvas) { Layer child = firstChild; @@ -133,12 +136,13 @@ class ContainerLayer extends Layer { } class TransformLayer extends ContainerLayer { - TransformLayer({ this.transform, Rect bounds }) : super(bounds: bounds); + TransformLayer({ Offset offset: Offset.zero, this.transform }) : super(offset: offset); Matrix4 transform; void paint(sky.Canvas canvas) { canvas.save(); + canvas.translate(offset.dx, offset.dy); canvas.concat(transform.storage); super.paint(canvas); canvas.restore(); @@ -146,11 +150,14 @@ class TransformLayer extends ContainerLayer { } class ClipLayer extends ContainerLayer { - ClipLayer({ Rect bounds }) : super(bounds: bounds); + ClipLayer({ Offset offset: Offset.zero, this.size }) : super(offset: offset); + + Size size; void paint(sky.Canvas canvas) { canvas.save(); - canvas.clipRect(bounds); + canvas.translate(offset.dx, offset.dy); + canvas.clipRect(Point.origin & size); super.paint(canvas); canvas.restore(); } @@ -158,11 +165,13 @@ class ClipLayer extends ContainerLayer { class ColorFilterLayer extends ContainerLayer { ColorFilterLayer({ - Rect bounds, + Offset offset: Offset.zero, + this.size, this.color, this.transferMode - }) : super(bounds: bounds); + }) : super(offset: offset); + Size size; Color color; sky.TransferMode transferMode; @@ -171,7 +180,8 @@ class ColorFilterLayer extends ContainerLayer { ..color = color ..setTransferMode(transferMode); - canvas.saveLayer(bounds, paint); + canvas.saveLayer(offset & size, paint); + canvas.translate(offset.dx, offset.dy); super.paint(canvas); canvas.restore(); } diff --git a/sky/packages/sky/lib/rendering/object.dart b/sky/packages/sky/lib/rendering/object.dart index ff1ddbde4..6b4a3419a 100644 --- a/sky/packages/sky/lib/rendering/object.dart +++ b/sky/packages/sky/lib/rendering/object.dart @@ -40,19 +40,19 @@ class PaintingContext { sky.PictureRecorder _recorder; - PaintingContext(Rect bounds) { - _startRecording(bounds); + PaintingContext(Offset offest, Size size) { + _startRecording(offest, size); } PaintingContext.forTesting(this.canvas); - void _startRecording(Rect bounds) { + void _startRecording(Offset offset, Size size) { assert(_layer == null); assert(_recorder == null); assert(canvas == null); - _layer = new PictureLayer(bounds: bounds); + _layer = new PictureLayer(offset: offset, size: size); _recorder = new sky.PictureRecorder(); - canvas = new PaintingCanvas(_recorder, bounds); + canvas = new PaintingCanvas(_recorder, Point.origin & size); } void endRecording() { @@ -70,18 +70,23 @@ class PaintingContext { if (!child.requiresCompositing) return child._paintWithContext(this, offset); + _compositChild(child, offset, layer.parent, layer.nextSibling); + } - final Layer originalLayer = layer; + void _compositChild(RenderObject child, Offset offset, ContainerLayer parentLayer, Layer nextSibling) { + final PictureLayer originalLayer = _layer; endRecording(); - Rect bounds = child.paintBounds.shift(offset); - PaintingContext context = new PaintingContext(bounds); - originalLayer.parent.add(context.layer, before: originalLayer.nextSibling); - child._paintWithContext(context, Offset.zero); - context.endRecording(); + Rect childBounds = child.paintBounds; + Offset childOffset = childBounds.topLeft.toOffset(); + PaintingContext context = new PaintingContext(offset + childOffset, childBounds.size); + parentLayer.add(context.layer, before: nextSibling); + child._layer = context.layer; + child._paintWithContext(context, -childOffset); - _startRecording(originalLayer.bounds); + _startRecording(originalLayer.offset, originalLayer.size); originalLayer.parent.add(layer, before: context.layer.nextSibling); + context.endRecording(); } } @@ -411,7 +416,9 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { assert(!_needsLayout); assert(requiresCompositing); assert(_layer != null); - PaintingContext context = new PaintingContext(paintBounds); + // TODO(abarth): Using _layer.offset isn't correct if the topLeft of our + // paint bounds has changed since our last repaint. + PaintingContext context = new PaintingContext(_layer.offset, paintBounds.size); _layer.parent.add(context.layer, before: _layer); _layer.detach(); _layer = context._layer;