Commit 904acc83 authored by Adam Barth's avatar Adam Barth

Merge pull request #470 from abarth/dart_timeline

Switch from ui.tracing to dart:Developer Timeline
parents e1b721f0 c964a1f1
...@@ -2,43 +2,44 @@ ...@@ -2,43 +2,44 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:developer';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' as ui;
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui;
Duration timeBase = null; Duration timeBase = null;
void beginFrame(Duration timeStamp) { void beginFrame(Duration timeStamp) {
ui.tracing.begin('beginFrame'); Timeline.timeSync('beginFrame', () {
if (timeBase == null) if (timeBase == null)
timeBase = timeStamp; timeBase = timeStamp;
double delta = (timeStamp - timeBase).inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND; double delta = (timeStamp - timeBase).inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
// paint // paint
ui.Rect paintBounds = ui.Point.origin & ui.window.size; ui.Rect paintBounds = ui.Point.origin & ui.window.size;
ui.PictureRecorder recorder = new ui.PictureRecorder(); ui.PictureRecorder recorder = new ui.PictureRecorder();
ui.Canvas canvas = new ui.Canvas(recorder, paintBounds); ui.Canvas canvas = new ui.Canvas(recorder, paintBounds);
canvas.translate(paintBounds.width / 2.0, paintBounds.height / 2.0); canvas.translate(paintBounds.width / 2.0, paintBounds.height / 2.0);
canvas.rotate(math.PI * delta / 1800); canvas.rotate(math.PI * delta / 1800);
canvas.drawRect(new ui.Rect.fromLTRB(-100.0, -100.0, 100.0, 100.0), canvas.drawRect(new ui.Rect.fromLTRB(-100.0, -100.0, 100.0, 100.0),
new ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0)); new ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0));
ui.Picture picture = recorder.endRecording(); ui.Picture picture = recorder.endRecording();
// composite // composite
final double devicePixelRatio = ui.window.devicePixelRatio; final double devicePixelRatio = ui.window.devicePixelRatio;
ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio); ui.Rect sceneBounds = new ui.Rect.fromLTWH(0.0, 0.0, ui.window.size.width * devicePixelRatio, ui.window.size.height * devicePixelRatio);
Float64List deviceTransform = new Float64List(16) Float64List deviceTransform = new Float64List(16)
..[0] = devicePixelRatio ..[0] = devicePixelRatio
..[5] = devicePixelRatio ..[5] = devicePixelRatio
..[10] = 1.0 ..[10] = 1.0
..[15] = 1.0; ..[15] = 1.0;
ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds) ui.SceneBuilder sceneBuilder = new ui.SceneBuilder(sceneBounds)
..pushTransform(deviceTransform) ..pushTransform(deviceTransform)
..addPicture(ui.Offset.zero, picture, paintBounds) ..addPicture(ui.Offset.zero, picture, paintBounds)
..pop(); ..pop();
ui.window.render(sceneBuilder.build()); ui.window.render(sceneBuilder.build());
});
ui.tracing.end('beginFrame');
ui.window.scheduleFrame(); ui.window.scheduleFrame();
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:collection'; import 'dart:collection';
import 'dart:developer';
import 'dart:ui' as ui; import 'dart:ui' as ui;
/// Slows down animations by this factor to help in development. /// Slows down animations by this factor to help in development.
...@@ -42,6 +43,19 @@ class Scheduler { ...@@ -42,6 +43,19 @@ class Scheduler {
int get transientCallbackCount => _transientCallbacks.length; int get transientCallbackCount => _transientCallbacks.length;
void _invokeAnimationCallbacks(Duration timeStamp) {
Timeline.startSync('Animate');
assert(_inFrame);
Map<int, SchedulerCallback> callbacks = _transientCallbacks;
_transientCallbacks = new Map<int, SchedulerCallback>();
callbacks.forEach((int id, SchedulerCallback callback) {
if (!_removedIds.contains(id))
invokeCallback(callback, timeStamp);
});
_removedIds.clear();
Timeline.finishSync();
}
/// Called by the engine to produce a new frame. /// Called by the engine to produce a new frame.
/// ///
/// This function first calls all the callbacks registered by /// This function first calls all the callbacks registered by
...@@ -49,19 +63,13 @@ class Scheduler { ...@@ -49,19 +63,13 @@ class Scheduler {
/// [addPersistentFrameCallback], which typically drive the rendering pipeline, /// [addPersistentFrameCallback], which typically drive the rendering pipeline,
/// and finally calls the callbacks registered by [requestPostFrameCallback]. /// and finally calls the callbacks registered by [requestPostFrameCallback].
void beginFrame(Duration rawTimeStamp) { void beginFrame(Duration rawTimeStamp) {
Timeline.startSync('Begin frame');
assert(!_inFrame); assert(!_inFrame);
_inFrame = true; _inFrame = true;
Duration timeStamp = new Duration( Duration timeStamp = new Duration(
microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round()); microseconds: (rawTimeStamp.inMicroseconds / timeDilation).round());
_haveScheduledVisualUpdate = false; _haveScheduledVisualUpdate = false;
_invokeAnimationCallbacks(timeStamp);
Map<int, SchedulerCallback> callbacks = _transientCallbacks;
_transientCallbacks = new Map<int, SchedulerCallback>();
callbacks.forEach((int id, SchedulerCallback callback) {
if (!_removedIds.contains(id))
invokeCallback(callback, timeStamp);
});
_removedIds.clear();
for (SchedulerCallback callback in _persistentCallbacks) for (SchedulerCallback callback in _persistentCallbacks)
invokeCallback(callback, timeStamp); invokeCallback(callback, timeStamp);
...@@ -73,6 +81,7 @@ class Scheduler { ...@@ -73,6 +81,7 @@ class Scheduler {
invokeCallback(callback, timeStamp); invokeCallback(callback, timeStamp);
_inFrame = false; _inFrame = false;
Timeline.finishSync();
} }
void invokeCallback(SchedulerCallback callback, Duration timeStamp) { void invokeCallback(SchedulerCallback callback, Duration timeStamp) {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:developer';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
...@@ -610,7 +611,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -610,7 +611,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// ///
/// See [FlutterBinding] for an example of how this function is used. /// See [FlutterBinding] for an example of how this function is used.
static void flushLayout() { static void flushLayout() {
ui.tracing.begin('RenderObject.flushLayout'); Timeline.startSync('Layout');
_debugDoingLayout = true; _debugDoingLayout = true;
try { try {
// TODO(ianh): assert that we're not allowing previously dirty nodes to redirty themeselves // TODO(ianh): assert that we're not allowing previously dirty nodes to redirty themeselves
...@@ -624,7 +625,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -624,7 +625,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
} }
} finally { } finally {
_debugDoingLayout = false; _debugDoingLayout = false;
ui.tracing.end('RenderObject.flushLayout'); Timeline.finishSync();
} }
} }
void _layoutWithoutResize() { void _layoutWithoutResize() {
...@@ -962,7 +963,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -962,7 +963,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// ///
/// See [FlutterBinding] for an example of how this function is used. /// See [FlutterBinding] for an example of how this function is used.
static void flushPaint() { static void flushPaint() {
ui.tracing.begin('RenderObject.flushPaint'); Timeline.startSync('Paint');
_debugDoingPaint = true; _debugDoingPaint = true;
try { try {
List<RenderObject> dirtyNodes = _nodesNeedingPaint; List<RenderObject> dirtyNodes = _nodesNeedingPaint;
...@@ -976,7 +977,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -976,7 +977,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(_nodesNeedingPaint.length == 0); assert(_nodesNeedingPaint.length == 0);
} finally { } finally {
_debugDoingPaint = false; _debugDoingPaint = false;
ui.tracing.end('RenderObject.flushPaint'); Timeline.finishSync();
} }
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:developer';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
...@@ -116,7 +117,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -116,7 +117,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
/// ///
/// Actually causes the output of the rendering pipeline to appear on screen. /// Actually causes the output of the rendering pipeline to appear on screen.
void compositeFrame() { void compositeFrame() {
ui.tracing.begin('RenderView.compositeFrame'); Timeline.startSync('Composite');
try { try {
(layer as TransformLayer).transform = _logicalToDeviceTransform; (layer as TransformLayer).transform = _logicalToDeviceTransform;
Rect bounds = Point.origin & (size * ui.window.devicePixelRatio); Rect bounds = Point.origin & (size * ui.window.devicePixelRatio);
...@@ -126,7 +127,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> ...@@ -126,7 +127,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
ui.window.render(scene); ui.window.render(scene);
scene.dispose(); scene.dispose();
} finally { } finally {
ui.tracing.end('RenderView.compositeFrame'); Timeline.finishSync();
} }
} }
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:developer';
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -47,6 +49,7 @@ class WidgetFlutterBinding extends FlutterBinding { ...@@ -47,6 +49,7 @@ class WidgetFlutterBinding extends FlutterBinding {
void buildDirtyElements() { void buildDirtyElements() {
if (_dirtyElements.isEmpty) if (_dirtyElements.isEmpty)
return; return;
Timeline.startSync('Build');
BuildableElement.lockState(() { BuildableElement.lockState(() {
_dirtyElements.sort((BuildableElement a, BuildableElement b) => a.depth - b.depth); _dirtyElements.sort((BuildableElement a, BuildableElement b) => a.depth - b.depth);
int dirtyCount = _dirtyElements.length; int dirtyCount = _dirtyElements.length;
...@@ -63,6 +66,7 @@ class WidgetFlutterBinding extends FlutterBinding { ...@@ -63,6 +66,7 @@ class WidgetFlutterBinding extends FlutterBinding {
_dirtyElements.clear(); _dirtyElements.clear();
}, building: true); }, building: true);
assert(_dirtyElements.isEmpty); assert(_dirtyElements.isEmpty);
Timeline.finishSync();
} }
/// The [Element] that is at the root of the hierarchy (and which wraps the /// The [Element] that is at the root of the hierarchy (and which wraps the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment