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

Side by Side 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: Different approach to calling markNeedsPaint with unattached nodes Created 5 years, 5 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 unified diff | Download patch
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | sky/sdk/lib/rendering/sky_binding.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import 'dart:math' as math; 5 import 'dart:math' as math;
6 import 'dart:sky' as sky; 6 import 'dart:sky' as sky;
7 import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; 7 import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
8 8
9 import '../base/hit_test.dart'; 9 import '../base/hit_test.dart';
10 import '../base/node.dart'; 10 import '../base/node.dart';
11 import '../base/scheduler.dart' as scheduler; 11 import '../base/scheduler.dart' as scheduler;
12 12
13 export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; 13 export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path;
14 export '../base/hit_test.dart' show HitTestTarget, HitTestEntry, HitTestResult; 14 export '../base/hit_test.dart' show HitTestTarget, HitTestEntry, HitTestResult;
15 15
16 16
17 class ParentData { 17 class ParentData {
18 void detach() { 18 void detach() {
19 detachSiblings(); 19 detachSiblings();
20 } 20 }
21 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart 21 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart
22 void merge(ParentData other) { 22 void merge(ParentData other) {
23 // override this in subclasses to merge in data from other into this 23 // override this in subclasses to merge in data from other into this
24 assert(other.runtimeType == this.runtimeType); 24 assert(other.runtimeType == this.runtimeType);
25 } 25 }
26 String toString() => '<none>'; 26 String toString() => '<none>';
27 } 27 }
28 28
29 class PaintingCanvas extends sky.Canvas { 29 class PaintingCanvas extends sky.Canvas {
30 PaintingCanvas(sky.PictureRecorder recorder, Size bounds) : super(recorder, bo unds); 30 PaintingCanvas(sky.PictureRecorder recorder, Rect bounds) : super(recorder, bo unds);
31 31
32 List<RenderObject> _descendentsWithPaintingCanvases = new List<RenderObject>() ; // used by RenderObject._updatePaintingCanvas() to find out which RenderObject s to ask to paint
32 void paintChild(RenderObject child, Point point) { 33 void paintChild(RenderObject child, Point point) {
33 child.paint(this, point.toOffset()); 34 if (child.createNewDisplayList) {
35 assert(!_descendentsWithPaintingCanvases.contains(child));
36 _descendentsWithPaintingCanvases.add(child);
37 drawPaintingNode(child._paintingNode, point);
38 } else {
39 child._paintOnCanvas(this, point.toOffset());
40 }
34 } 41 }
35 } 42 }
36 43
37 abstract class Constraints { 44 abstract class Constraints {
38 const Constraints(); 45 const Constraints();
39 bool get isTight; 46 bool get isTight;
40 } 47 }
41 48
42 abstract class RenderObject extends AbstractNode implements HitTestTarget { 49 abstract class RenderObject extends AbstractNode implements HitTestTarget {
43 50
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 _cleanRelayoutSubtreeRootChildren(); 139 _cleanRelayoutSubtreeRootChildren();
133 } 140 }
134 } 141 }
135 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c lass mixins in Dart 142 void _cleanRelayoutSubtreeRootChildren() { } // workaround for lack of inter-c lass mixins in Dart
136 void scheduleInitialLayout() { 143 void scheduleInitialLayout() {
137 assert(attached); 144 assert(attached);
138 assert(parent == null); 145 assert(parent == null);
139 assert(_relayoutSubtreeRoot == null); 146 assert(_relayoutSubtreeRoot == null);
140 _relayoutSubtreeRoot = this; 147 _relayoutSubtreeRoot = this;
141 _nodesNeedingLayout.add(this); 148 _nodesNeedingLayout.add(this);
149 _nodesNeedingPaint.add(this);
142 scheduler.ensureVisualUpdate(); 150 scheduler.ensureVisualUpdate();
143 } 151 }
144 static void flushLayout() { 152 static void flushLayout() {
145 sky.tracing.begin('RenderObject.flushLayout'); 153 sky.tracing.begin('RenderObject.flushLayout');
146 _debugDoingLayout = true; 154 _debugDoingLayout = true;
147 try { 155 try {
148 List<RenderObject> dirtyNodes = _nodesNeedingLayout; 156 List<RenderObject> dirtyNodes = _nodesNeedingLayout;
149 _nodesNeedingLayout = new List<RenderObject>(); 157 _nodesNeedingLayout = new List<RenderObject>();
150 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) { 158 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) {
151 if (node._needsLayout && node.attached) 159 if (node._needsLayout && node.attached)
152 node.layoutWithoutResize(); 160 node.layoutWithoutResize();
153 }); 161 });
154 } finally { 162 } finally {
155 _debugDoingLayout = false; 163 _debugDoingLayout = false;
156 sky.tracing.end('RenderObject.flushLayout'); 164 sky.tracing.end('RenderObject.flushLayout');
157 } 165 }
158 } 166 }
159 void layoutWithoutResize() { 167 void layoutWithoutResize() {
160 try { 168 try {
161 assert(_relayoutSubtreeRoot == this); 169 assert(_relayoutSubtreeRoot == this);
162 _debugCanParentUseSize = false; 170 _debugCanParentUseSize = false;
163 _debugDoingThisLayout = true; 171 _debugDoingThisLayout = true;
164 RenderObject debugPreviousActiveLayout = _debugActiveLayout; 172 RenderObject debugPreviousActiveLayout = _debugActiveLayout;
165 _debugActiveLayout = this; 173 _debugActiveLayout = this;
166 performLayout(); 174 performLayout();
167 _debugActiveLayout = debugPreviousActiveLayout; 175 _debugActiveLayout = debugPreviousActiveLayout;
168 _debugDoingThisLayout = false; 176 _debugDoingThisLayout = false;
169 _debugCanParentUseSize = null; 177 _debugCanParentUseSize = null;
170 } catch (e, stack) { 178 } catch (e) {
171 print('Exception raised during layout:\n${e}\nContext:\n${this}'); 179 print('Exception raised during layout:\n${e}\nContext:\n${this}');
172 print(stack);
173 return; 180 return;
174 } 181 }
175 _needsLayout = false; 182 _needsLayout = false;
176 markNeedsPaint(); 183 markNeedsPaint();
177 } 184 }
178 void layout(Constraints constraints, { bool parentUsesSize: false }) { 185 void layout(Constraints constraints, { bool parentUsesSize: false }) {
179 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer 186 final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer
180 RenderObject relayoutSubtreeRoot; 187 RenderObject relayoutSubtreeRoot;
181 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re nderObject) 188 if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! Re nderObject)
182 relayoutSubtreeRoot = this; 189 relayoutSubtreeRoot = this;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 239
233 void rotate({ 240 void rotate({
234 int oldAngle, // 0..3 241 int oldAngle, // 0..3
235 int newAngle, // 0..3 242 int newAngle, // 0..3
236 Duration time 243 Duration time
237 }) { } 244 }) { }
238 245
239 246
240 // PAINTING 247 // PAINTING
241 248
242 static bool debugDoingPaint = false; 249 static List<RenderObject> _nodesNeedingPaint = new List<RenderObject>();
250 static bool _debugDoingPaint = false;
251 static bool get debugDoingPaint => _debugDoingPaint;
252 static void set debugDoingPaint(bool debug) {
253 _debugDoingPaint = debug;
254 }
255
256 final sky.PaintingNode _paintingNode = new sky.PaintingNode();
257 sky.PaintingNode get paintingNode {
258 assert(createNewDisplayList);
259 return _paintingNode;
260 }
261 bool _needsPaint = true;
262 bool get needsPaint => _needsPaint;
263 bool get createNewDisplayList => false;
264
243 void markNeedsPaint() { 265 void markNeedsPaint() {
244 assert(!debugDoingPaint); 266 assert(!debugDoingPaint);
245 scheduler.ensureVisualUpdate(); 267 if (!attached) return; // Don't try painting things that aren't in the hiera rchy
268 if (_needsPaint) return;
269 if (createNewDisplayList) {
270 _needsPaint = true;
271 _nodesNeedingPaint.add(this);
272 scheduler.ensureVisualUpdate();
273 } else {
274 assert(parent != null); // parent always exists on this path because the r oot node is a RenderView, which sets createNewDisplayList.
275 if (parent is RenderObject) {
276 (parent as RenderObject).markNeedsPaint(); // TODO(ianh): remove the cas t once the analyzer is cleverer
277 }
278 }
246 } 279 }
280
281 static void flushPaint() {
282 try {
283 _debugDoingPaint = true;
284 List<RenderObject> dirtyNodes = _nodesNeedingPaint;
285 _nodesNeedingPaint = new List<RenderObject>();
286 for (RenderObject node in dirtyNodes..sort((a, b) => a.depth - b.depth)) {
287 if (node._needsPaint && node.attached)
288 node._updatePaintingCanvas();
289 };
290 assert(_nodesNeedingPaint.length == 0);
291 } catch (e) {
292 print('Exception raised during flushPaint:\n${e}');
293 } finally {
294 _debugDoingPaint = false;
295 }
296 }
297
298 void _updatePaintingCanvas() {
299 assert(!_needsLayout);
300 assert(createNewDisplayList);
301 sky.PictureRecorder recorder = new sky.PictureRecorder();
302 PaintingCanvas canvas = new PaintingCanvas(recorder, paintBounds);
303 _needsPaint = false;
304 try {
305 _paintOnCanvas(canvas, Offset.zero);
306 } catch (e) {
307 print('Exception raised during _updatePaintingCanvas:\n${e}\nContext:\n${t his}');
308 return;
309 }
310 assert(!_needsLayout); // check that the paint() method didn't mark us dirty again
311 assert(!_needsPaint); // check that the paint() method didn't mark us dirty again
312 _paintingNode.setBackingDrawable(recorder.endRecordingAsDrawable());
313
314 if (canvas._descendentsWithPaintingCanvases != null) {
315 for (RenderObject node in canvas._descendentsWithPaintingCanvases) {
316 assert(node.attached == attached);
317 if (node._needsPaint)
318 node._updatePaintingCanvas();
319 };
320 }
321 }
322
323 void _paintOnCanvas(PaintingCanvas canvas, Offset offset) {
324 _needsPaint = false;
325 paint(canvas, offset);
326 assert(!_needsPaint);
327 }
328
329 Rect get paintBounds;
330
247 void paint(PaintingCanvas canvas, Offset offset) { } 331 void paint(PaintingCanvas canvas, Offset offset) { }
248 332
249 333
250 // EVENTS 334 // EVENTS
251 335
252 void handleEvent(sky.Event event, HitTestEntry entry) { 336 void handleEvent(sky.Event event, HitTestEntry entry) {
253 // override this if you have a client, to hand it to the client 337 // override this if you have a client, to hand it to the client
254 // override this if you want to do anything with the event 338 // override this if you want to do anything with the event
255 } 339 }
256 340
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 int count = 1; 614 int count = 1;
531 ChildType child = _firstChild; 615 ChildType child = _firstChild;
532 while (child != null) { 616 while (child != null) {
533 result += '${prefix}child ${count}: ${child.toString(prefix)}'; 617 result += '${prefix}child ${count}: ${child.toString(prefix)}';
534 count += 1; 618 count += 1;
535 child = child.parentData.nextSibling; 619 child = child.parentData.nextSibling;
536 } 620 }
537 return result; 621 return result;
538 } 622 }
539 } 623 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | sky/sdk/lib/rendering/sky_binding.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698