提交 1ea911f0 编写于 作者: A Adam Barth

Switch painting over to using PictureLayer

Currently we have a single PictureLayer that everyone draws into. A future
patch will teach the system to use multiple PictureLayers.
上级 9d389471
......@@ -8,6 +8,7 @@ import 'dart:sky' as sky;
import 'package:sky/base/debug.dart';
import 'package:sky/painting/box_painter.dart';
import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/layer.dart';
import 'package:sky/rendering/object.dart';
import 'package:vector_math/vector_math.dart';
......@@ -1703,6 +1704,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
markNeedsLayout();
}
ContainerLayer _rootLayer;
// We never call layout() on this class, so this should never get
// checked. (This class is laid out using scheduleInitialLayout().)
bool debugDoesMeetConstraints() { assert(false); return false; }
......@@ -1746,15 +1749,22 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
void paintFrame() {
sky.tracing.begin('RenderView.paintFrame');
try {
double devicePixelRatio = sky.view.devicePixelRatio;
sky.PictureRecorder recorder = new sky.PictureRecorder();
Rect cullRect = Point.origin & (size * devicePixelRatio);
PaintingCanvas canvas = new PaintingCanvas(recorder, cullRect);
PaintingContext context = new PaintingContext(canvas);
canvas.drawColor(const Color(0xFF000000), sky.TransferMode.src);
canvas.scale(devicePixelRatio, devicePixelRatio);
final double devicePixelRatio = sky.view.devicePixelRatio;
// TODO(abarth): Really |_rootLayer| should be a TransformLayer that
// applies the devicePixelRatio.
Rect scaledBounds = Point.origin & (size * devicePixelRatio);
PaintingContext context = new PaintingContext(scaledBounds);
_rootLayer = new ContainerLayer(bounds: Point.origin & size);
_rootLayer.add(context.layer);
context.canvas.drawColor(const Color(0xFF000000), sky.TransferMode.src);
context.canvas.scale(devicePixelRatio, devicePixelRatio);
context.paintChild(child, Point.origin);
sky.view.picture = recorder.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 {
sky.tracing.end('RenderView.paintFrame');
}
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:sky' as sky;
import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
import 'package:vector_math/vector_math.dart';
class Layer {
Layer({ this.bounds });
Rect bounds;
ContainerLayer _parent;
ContainerLayer get parent => _parent;
Layer _nextSibling;
Layer get nextSibling => _nextSibling;
Layer _previousSibling;
Layer get previousSibling => _previousSibling;
void detach() {
if (_parent != null)
_parent.remove(this);
}
}
class PictureLayer extends Layer {
PictureLayer({ Rect bounds })
: super(bounds: bounds);
sky.Picture picture;
}
class ContainerLayer extends Layer {
ContainerLayer({ Rect bounds }) : super(bounds: bounds);
Layer _firstChild;
Layer get firstChild => _firstChild;
Layer _lastChild;
Layer get lastChild => _lastChild;
bool _debugUltimatePreviousSiblingOf(Layer child, { Layer equals }) {
while (child._previousSibling != null) {
assert(child._previousSibling != child);
child = child._previousSibling;
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(Layer child, { Layer equals }) {
while (child._nextSibling != null) {
assert(child._nextSibling != child);
child = child._nextSibling;
}
return child == equals;
}
void add(Layer child, { Layer before }) {
assert(child != this);
assert(before != this);
assert(child != before);
assert(child != _firstChild);
assert(child != _lastChild);
assert(child._parent == null);
assert(child._nextSibling == null);
assert(child._previousSibling == null);
child._parent = this;
if (before == null) {
child._previousSibling = _lastChild;
if (_lastChild != null)
_lastChild._nextSibling = child;
_lastChild = child;
if (_firstChild == null)
_firstChild = child;
} else {
assert(_firstChild != null);
assert(_lastChild != null);
assert(_debugUltimatePreviousSiblingOf(before, equals: _firstChild));
assert(_debugUltimateNextSiblingOf(before, equals: _lastChild));
if (before._previousSibling == null) {
assert(before == _firstChild);
child._nextSibling = before;
before._previousSibling = child;
_firstChild = child;
} else {
child._previousSibling = before._previousSibling;
child._nextSibling = before;
child._previousSibling._nextSibling = child;
child._nextSibling._previousSibling = child;
assert(before._previousSibling == child);
}
}
}
void remove(Layer child) {
assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
assert(child._parent == this);
if (child._previousSibling == null) {
assert(_firstChild == child);
_firstChild = child._nextSibling;
} else {
child._previousSibling._nextSibling = child._nextSibling;
}
if (child._nextSibling == null) {
assert(_lastChild == child);
_lastChild = child._previousSibling;
} else {
child._nextSibling._previousSibling = child._previousSibling;
}
child._previousSibling = null;
child._nextSibling = null;
child._parent = null;
}
}
class TransformLayer extends ContainerLayer {
TransformLayer({ this.transform, Rect bounds }) : super(bounds: bounds);
Matrix4 transform;
}
class ClipLayer extends ContainerLayer {
ClipLayer({ Rect bounds }) : super(bounds: bounds);
}
class ColorFilterLayer extends ContainerLayer {
ColorFilterLayer({
Rect bounds,
this.color,
this.transferMode
}) : super(bounds: bounds);
Color color;
sky.TransferMode transferMode;
}
......@@ -10,6 +10,7 @@ import 'package:sky/base/debug.dart';
import 'package:sky/base/hit_test.dart';
import 'package:sky/base/node.dart';
import 'package:sky/base/scheduler.dart' as scheduler;
import 'package:sky/rendering/layer.dart';
import 'package:vector_math/vector_math.dart';
export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
......@@ -32,9 +33,27 @@ class PaintingCanvas extends sky.Canvas {
}
class PaintingContext {
final PaintingCanvas canvas;
PaintingCanvas canvas;
PaintingContext(this.canvas);
PictureLayer get layer => _layer;
PictureLayer _layer;
sky.PictureRecorder _recorder;
PaintingContext(Rect bounds) {
_layer = new PictureLayer(bounds: bounds);
_recorder = new sky.PictureRecorder();
canvas = new PaintingCanvas(_recorder, bounds);
}
PaintingContext.forTesting(this.canvas);
void endRecording() {
canvas = null;
_layer.picture = _recorder.endRecording();
_recorder = null;
_layer = null;
}
void paintChild(RenderObject child, Point point) {
// TODO(abarth): Support compositing.
......@@ -318,6 +337,12 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
bool _needsPaint = true;
bool get needsPaint => _needsPaint;
PictureLayer _layer;
PictureLayer get layer {
assert(requiresCompositing);
return _layer;
}
void markNeedsPaint() {
assert(!debugDoingPaint);
if (!attached) return; // Don't try painting things that aren't in the hierarchy
......@@ -357,9 +382,11 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
void _repaint() {
assert(!_needsLayout);
assert(requiresCompositing);
sky.PictureRecorder recorder = new sky.PictureRecorder();
sky.Canvas canvas = new sky.Canvas(recorder, paintBounds);
PaintingContext context = new PaintingContext(canvas);
assert(_layer != null);
PaintingContext context = new PaintingContext(paintBounds);
_layer.parent.add(context.layer, before: _layer);
_layer.detach();
_layer = context._layer;
_needsPaint = false;
try {
_paintWithContext(context, Offset.zero);
......
......@@ -116,7 +116,9 @@ class TestPaintingCanvas extends PaintingCanvas {
}
class TestPaintingContext extends PaintingContext {
TestPaintingContext(TestPaintingCanvas canvas) : super(canvas);
TestPaintingContext(TestPaintingCanvas canvas) : super.forTesting(canvas);
TestPaintingCanvas get canvas => super.canvas;
void paintChild(RenderObject child, Point position) {
canvas.log("paintChild ${child.runtimeType} at $position");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册