Add a compositing step to the lifecycle
Now we have the ability to draw multiple PictureLayers. We still squash all the pictures together into a single SkPicture for simplicity. In the future, we'll submit them to C++ separately and composite them on the GPU thread.
This commit is contained in:
parent
7cba729110
commit
bf260f98e3
@ -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;
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
: 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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user