Merge pull request #608 from abarth/composite_frame
Add a compositing step to the lifecycle
This commit is contained in:
commit
bcf18623b9
@ -1750,26 +1750,31 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
|
||||
sky.tracing.begin('RenderView.paintFrame');
|
||||
try {
|
||||
final double devicePixelRatio = sky.view.devicePixelRatio;
|
||||
|
||||
// TODO(abarth): Really |_rootLayer| should be a TransformLayer that
|
||||
// applies the devicePixelRatio.
|
||||
Matrix4 transform = new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0);
|
||||
Rect bounds = Point.origin & size;
|
||||
Rect scaledBounds = Point.origin & (size * devicePixelRatio);
|
||||
PaintingContext context = new PaintingContext(scaledBounds);
|
||||
_rootLayer = new ContainerLayer(bounds: Point.origin & size);
|
||||
_rootLayer = new TransformLayer(bounds: scaledBounds, transform: transform);
|
||||
PaintingContext context = new PaintingContext(bounds);
|
||||
_rootLayer.add(context.layer);
|
||||
context.canvas.drawColor(const Color(0xFF000000), sky.TransferMode.src);
|
||||
context.canvas.scale(devicePixelRatio, devicePixelRatio);
|
||||
context.paintChild(child, Point.origin);
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
|
||||
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
class Layer {
|
||||
abstract class Layer {
|
||||
Layer({ this.bounds });
|
||||
|
||||
Rect bounds;
|
||||
@ -25,6 +25,8 @@ class Layer {
|
||||
if (_parent != null)
|
||||
_parent.remove(this);
|
||||
}
|
||||
|
||||
void paint(sky.Canvas canvas);
|
||||
}
|
||||
|
||||
class PictureLayer extends Layer {
|
||||
@ -32,11 +34,23 @@ class PictureLayer extends Layer {
|
||||
: super(bounds: bounds);
|
||||
|
||||
sky.Picture picture;
|
||||
|
||||
void paint(sky.Canvas canvas) {
|
||||
canvas.drawPicture(picture);
|
||||
}
|
||||
}
|
||||
|
||||
class ContainerLayer extends Layer {
|
||||
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 get firstChild => _firstChild;
|
||||
|
||||
@ -122,10 +136,24 @@ class TransformLayer extends ContainerLayer {
|
||||
TransformLayer({ this.transform, Rect bounds }) : super(bounds: bounds);
|
||||
|
||||
Matrix4 transform;
|
||||
|
||||
void paint(sky.Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.concat(transform.storage);
|
||||
super.paint(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
class ClipLayer extends ContainerLayer {
|
||||
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 {
|
||||
@ -137,4 +165,14 @@ class ColorFilterLayer extends ContainerLayer {
|
||||
|
||||
Color color;
|
||||
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 {
|
||||
sky.PictureRecorder _recorder;
|
||||
|
||||
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);
|
||||
_recorder = new sky.PictureRecorder();
|
||||
canvas = new PaintingCanvas(_recorder, bounds);
|
||||
}
|
||||
|
||||
PaintingContext.forTesting(this.canvas);
|
||||
|
||||
void endRecording() {
|
||||
assert(_layer != null);
|
||||
assert(_recorder != null);
|
||||
assert(canvas != null);
|
||||
canvas = null;
|
||||
_layer.picture = _recorder.endRecording();
|
||||
_recorder = null;
|
||||
@ -56,9 +66,22 @@ class PaintingContext {
|
||||
}
|
||||
|
||||
void paintChild(RenderObject child, Point point) {
|
||||
// TODO(abarth): Support compositing.
|
||||
assert(!child.requiresCompositing);
|
||||
child._paintWithContext(this, point.toOffset());
|
||||
final Offset offset = 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 {
|
||||
RenderObject.flushLayout();
|
||||
RenderObject.flushPaint();
|
||||
_renderView.paintFrame();
|
||||
_renderView.compositeFrame();
|
||||
}
|
||||
|
||||
final List<EventListener> _eventListeners = new List<EventListener>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user