提交 321d0693 编写于 作者: A Adam Barth

Separate the notions of offset and size in compositing

Separating these notions makes them easier to work with because offset is
relative to the parent layer whereas size is intrinsic to the layer itself.
This patch fixes the underpainting bugs when compositing the stocks example.
上级 998d9a13
......@@ -1751,10 +1751,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
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<RenderBox>
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 {
......
......@@ -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();
}
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册