Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Unified Diff: sky/sdk/lib/rendering/object.dart

Issue 1216833003: Make rendering use PaintingNodes for increased efficiency. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/rendering/object.dart
diff --git a/sky/sdk/lib/rendering/object.dart b/sky/sdk/lib/rendering/object.dart
index b384d029deb69cd6a74e850ff5500b1c7c57906b..e201ce26bd17b78ce1174e359b91f8365c00d8bc 100644
--- a/sky/sdk/lib/rendering/object.dart
+++ b/sky/sdk/lib/rendering/object.dart
@@ -27,10 +27,22 @@ class ParentData {
}
class PaintingCanvas extends sky.Canvas {
- PaintingCanvas(sky.PictureRecorder recorder, Size bounds) : super(recorder, bounds);
+ PaintingCanvas(sky.PictureRecorder recorder, Rect bounds) : super(recorder, bounds);
+ List<RenderObject> _children; // used by _doPaint() to find out which RenderObjects to ask to paint
Hixie 2015/07/02 00:19:54 rename this to _descendantsWithPaintNodes or some
iansf 2015/07/06 18:22:01 Done.
void paintChild(RenderObject child, Point point) {
- child.paint(this, point.toOffset());
+ if (child.createNewDisplayList) {
+ if (_children == null)
+ _children = new List<RenderObject>();
+ assert(!_children.contains(child));
+ _children.add(child);
+
Hixie 2015/07/02 00:19:54 remove this blank line
iansf 2015/07/06 18:22:01 Done.
+ translate(point.x, point.y);
+ drawPaintingNode(child._paintingNode);
+ translate(-point.x, -point.y);
+ } else {
+ child.performPaint(this, point.toOffset());
+ }
}
}
@@ -138,6 +150,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(_relayoutSubtreeRoot == null);
_relayoutSubtreeRoot = this;
_nodesNeedingLayout.add(this);
+ _nodesNeedingPaint.add(this);
scheduler.ensureVisualUpdate();
}
static void flushLayout() {
@@ -238,10 +251,79 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
// PAINTING
- static bool debugDoingPaint = false;
+ static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>();
+ static bool _debugDoingPaint = false;
+ static bool get debugDoingPaint => _debugDoingPaint;
+
+ sky.PaintingNode _paintingNode = new sky.PaintingNode(); // only set if createNewDisplayList is true
+ sky.PaintingNode get paintingNode => _paintingNode;
+ bool _needsPaint = true;
+ bool get needsPaint => _needsPaint;
+ bool get createNewDisplayList => true;
+
void markNeedsPaint() {
assert(!debugDoingPaint);
- scheduler.ensureVisualUpdate();
+ if (_needsPaint) return;
+ if (createNewDisplayList) {
+ _needsPaint = true;
+ _nodesNeedingPaint.add(this);
+
Hixie 2015/07/02 00:19:54 remove this random blank line :-)
iansf 2015/07/06 18:22:01 Done.
+ scheduler.ensureVisualUpdate();
+ } else if (parent != null) {
+ if (parent is RenderObject) {
+ (parent as RenderObject).markNeedsPaint(); // TODO(ianh): remove the cast once the analyzer is cleverer
+ }
+ }
+ }
+
+ static void flushPaint() {
+ _debugDoingPaint = true;
+ List<RenderObject> dirtyNodes = _nodesNeedingPaint;
+ _nodesNeedingPaint = new List<RenderObject>();
+ dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) {
+ if (node._needsPaint && node.attached)
+ node._doPaint();
+ });
+ assert(_nodesNeedingPaint.length == 0);
+ _debugDoingPaint = false;
+ }
+
+ void _doPaint() {
Hixie 2015/07/02 00:19:54 call this _paintOnPaintNode() or _updatePaintNode(
iansf 2015/07/06 18:22:01 Done.
+ assert(!_needsLayout);
+ assert(createNewDisplayList);
+ sky.PictureRecorder recorder = new sky.PictureRecorder();
+ PaintingCanvas canvas = new PaintingCanvas(recorder, paintBounds);
+ _needsPaint = false;
+ try {
+ performPaint(canvas, Point.origin.toOffset());
Hixie 2015/07/02 00:19:54 use Offset.zero instead
iansf 2015/07/06 18:22:01 Done.
+ } catch (e, stack) {
+ print('Exception raised during paint of ${this.runtimeType}: ${e}');
Hixie 2015/07/02 00:19:54 make this match the style in layout()
iansf 2015/07/06 18:22:01 Done.
+ print(stack);
+ return;
+ }
+ assert(!_needsLayout); // check that the paint() method didn't mark us dirty again
+ assert(!_needsPaint); // check that the paint() method didn't mark us dirty again
+ _paintingNode.setBackingDrawable(recorder.endRecordingAsDrawable());
+
+ if (canvas._children != null) {
+ canvas._children.forEach((node) {
+ assert(node.attached == attached);
+ if (node._needsPaint)
+ node._doPaint();
+ });
+ }
+
+ }
+
+ Rect get paintBounds;
Hixie 2015/07/02 00:19:54 move this below performPaint()
iansf 2015/07/06 18:22:01 Done.
+
+ void performPaint(PaintingCanvas canvas, Offset offset) {
Hixie 2015/07/02 00:19:54 call this _paintOnCanvas() or some such.
iansf 2015/07/06 18:22:01 Done.
+ _needsPaint = false;
+ paint(canvas, offset);
+ assert(!_needsPaint);
+ }
+
+
}
void paint(PaintingCanvas canvas, Offset offset) { }
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698