Commit bcf18623 authored by Adam Barth's avatar Adam Barth

Merge pull request #608 from abarth/composite_frame

Add a compositing step to the lifecycle
parents 681b366a bf260f98
...@@ -1750,26 +1750,31 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -1750,26 +1750,31 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
sky.tracing.begin('RenderView.paintFrame'); sky.tracing.begin('RenderView.paintFrame');
try { try {
final double devicePixelRatio = sky.view.devicePixelRatio; final double devicePixelRatio = sky.view.devicePixelRatio;
Matrix4 transform = new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0);
// TODO(abarth): Really |_rootLayer| should be a TransformLayer that Rect bounds = Point.origin & size;
// applies the devicePixelRatio.
Rect scaledBounds = Point.origin & (size * devicePixelRatio); Rect scaledBounds = Point.origin & (size * devicePixelRatio);
PaintingContext context = new PaintingContext(scaledBounds); _rootLayer = new TransformLayer(bounds: scaledBounds, transform: transform);
_rootLayer = new ContainerLayer(bounds: Point.origin & size); PaintingContext context = new PaintingContext(bounds);
_rootLayer.add(context.layer); _rootLayer.add(context.layer);
context.canvas.drawColor(const Color(0xFF000000), sky.TransferMode.src);
context.canvas.scale(devicePixelRatio, devicePixelRatio);
context.paintChild(child, Point.origin); context.paintChild(child, Point.origin);
context.endRecording(); context.endRecording();
// TODO(abarth): Once we have more than one PictureLayer, we should walk
// the layer tree to generate the final picture.
sky.view.picture = (_rootLayer.firstChild as PictureLayer).picture;
} finally { } finally {
sky.tracing.end('RenderView.paintFrame'); sky.tracing.end('RenderView.paintFrame');
} }
} }
void compositeFrame() {
sky.tracing.begin('RenderView.compositeFrame');
try {
sky.PictureRecorder recorder = new sky.PictureRecorder();
sky.Canvas canvas = new sky.Canvas(recorder, _rootLayer.bounds);
_rootLayer.paint(canvas);
sky.view.picture = recorder.endRecording();
} finally {
sky.tracing.end('RenderView.compositeFrame');
}
}
Rect get paintBounds => Point.origin & size; Rect get paintBounds => Point.origin & size;
} }
......
...@@ -7,7 +7,7 @@ import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; ...@@ -7,7 +7,7 @@ import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
import 'package:vector_math/vector_math.dart'; import 'package:vector_math/vector_math.dart';
class Layer { abstract class Layer {
Layer({ this.bounds }); Layer({ this.bounds });
Rect bounds; Rect bounds;
...@@ -25,6 +25,8 @@ class Layer { ...@@ -25,6 +25,8 @@ class Layer {
if (_parent != null) if (_parent != null)
_parent.remove(this); _parent.remove(this);
} }
void paint(sky.Canvas canvas);
} }
class PictureLayer extends Layer { class PictureLayer extends Layer {
...@@ -32,11 +34,23 @@ class PictureLayer extends Layer { ...@@ -32,11 +34,23 @@ class PictureLayer extends Layer {
: super(bounds: bounds); : super(bounds: bounds);
sky.Picture picture; sky.Picture picture;
void paint(sky.Canvas canvas) {
canvas.drawPicture(picture);
}
} }
class ContainerLayer extends Layer { class ContainerLayer extends Layer {
ContainerLayer({ Rect bounds }) : super(bounds: bounds); ContainerLayer({ Rect bounds }) : super(bounds: bounds);
void paint(sky.Canvas canvas) {
Layer child = firstChild;
while (child != null) {
child.paint(canvas);
child = child.nextSibling;
}
}
Layer _firstChild; Layer _firstChild;
Layer get firstChild => _firstChild; Layer get firstChild => _firstChild;
...@@ -122,10 +136,24 @@ class TransformLayer extends ContainerLayer { ...@@ -122,10 +136,24 @@ class TransformLayer extends ContainerLayer {
TransformLayer({ this.transform, Rect bounds }) : super(bounds: bounds); TransformLayer({ this.transform, Rect bounds }) : super(bounds: bounds);
Matrix4 transform; Matrix4 transform;
void paint(sky.Canvas canvas) {
canvas.save();
canvas.concat(transform.storage);
super.paint(canvas);
canvas.restore();
}
} }
class ClipLayer extends ContainerLayer { class ClipLayer extends ContainerLayer {
ClipLayer({ Rect bounds }) : super(bounds: bounds); ClipLayer({ Rect bounds }) : super(bounds: bounds);
void paint(sky.Canvas canvas) {
canvas.save();
canvas.clipRect(bounds);
super.paint(canvas);
canvas.restore();
}
} }
class ColorFilterLayer extends ContainerLayer { class ColorFilterLayer extends ContainerLayer {
...@@ -137,4 +165,14 @@ class ColorFilterLayer extends ContainerLayer { ...@@ -137,4 +165,14 @@ class ColorFilterLayer extends ContainerLayer {
Color color; Color color;
sky.TransferMode transferMode; sky.TransferMode transferMode;
void paint(sky.Canvas canvas) {
Paint paint = new Paint()
..color = color
..setTransferMode(transferMode);
canvas.saveLayer(bounds, paint);
super.paint(canvas);
canvas.restore();
}
} }
...@@ -41,14 +41,24 @@ class PaintingContext { ...@@ -41,14 +41,24 @@ class PaintingContext {
sky.PictureRecorder _recorder; sky.PictureRecorder _recorder;
PaintingContext(Rect bounds) { PaintingContext(Rect bounds) {
_startRecording(bounds);
}
PaintingContext.forTesting(this.canvas);
void _startRecording(Rect bounds) {
assert(_layer == null);
assert(_recorder == null);
assert(canvas == null);
_layer = new PictureLayer(bounds: bounds); _layer = new PictureLayer(bounds: bounds);
_recorder = new sky.PictureRecorder(); _recorder = new sky.PictureRecorder();
canvas = new PaintingCanvas(_recorder, bounds); canvas = new PaintingCanvas(_recorder, bounds);
} }
PaintingContext.forTesting(this.canvas);
void endRecording() { void endRecording() {
assert(_layer != null);
assert(_recorder != null);
assert(canvas != null);
canvas = null; canvas = null;
_layer.picture = _recorder.endRecording(); _layer.picture = _recorder.endRecording();
_recorder = null; _recorder = null;
...@@ -56,9 +66,22 @@ class PaintingContext { ...@@ -56,9 +66,22 @@ class PaintingContext {
} }
void paintChild(RenderObject child, Point point) { void paintChild(RenderObject child, Point point) {
// TODO(abarth): Support compositing. final Offset offset = point.toOffset();
assert(!child.requiresCompositing);
child._paintWithContext(this, point.toOffset()); if (!child.requiresCompositing)
return child._paintWithContext(this, offset);
final Layer 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();
_startRecording(originalLayer.bounds);
originalLayer.parent.add(layer, before: context.layer.nextSibling);
} }
} }
......
...@@ -73,6 +73,7 @@ class SkyBinding { ...@@ -73,6 +73,7 @@ class SkyBinding {
RenderObject.flushLayout(); RenderObject.flushLayout();
RenderObject.flushPaint(); RenderObject.flushPaint();
_renderView.paintFrame(); _renderView.paintFrame();
_renderView.compositeFrame();
} }
final List<EventListener> _eventListeners = new List<EventListener>(); final List<EventListener> _eventListeners = new List<EventListener>();
......
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