Allow displaying compositor statistics via a widget
Example:
import 'package:sky/widgets.dart';
void main() => runApp(new Center(child:
new StatisticsOverlay.allEnabled()));
diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart
index 49d1e3d..1e22221 100644
--- a/packages/flutter/lib/src/rendering/layer.dart
+++ b/packages/flutter/lib/src/rendering/layer.dart
@@ -87,6 +87,29 @@
}
+/// A layer that indicates to the compositor that it should display
+/// certain statistics within it
+class StatisticsLayer extends Layer {
+ StatisticsLayer({
+ Offset offset: Offset.zero,
+ this.paintBounds,
+ this.optionsMask
+ }) : super(offset: offset);
+
+ /// The rectangle in this layer's coodinate system that bounds the recording
+ Rect paintBounds;
+
+ /// A mask specifying the statistics to display
+ int optionsMask;
+
+ void addToScene(sky.SceneBuilder builder, Offset layerOffset) {
+ assert(optionsMask != null);
+ builder.addStatistics(optionsMask, paintBounds.shift(layerOffset));
+ }
+
+}
+
+
/// A composited layer that has a list of children
class ContainerLayer extends Layer {
ContainerLayer({ Offset offset: Offset.zero }) : super(offset: offset);
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index 07cee15..0daaab2 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -130,6 +130,15 @@
}
}
+ void paintStatistics(int optionsMask, Offset offset, Size size) {
+ StatisticsLayer statsLayer = new StatisticsLayer(
+ offset: offset,
+ paintBounds: new Rect.fromLTWH(0.0, 0.0, size.width, size.height),
+ optionsMask : optionsMask
+ );
+ _containerLayer.append(statsLayer);
+ }
+
// Below we have various variants of the paintChild() method, which
// do additional work, such as clipping or transforming, at the same
// time as painting the children.
diff --git a/packages/flutter/lib/src/rendering/statistics_box.dart b/packages/flutter/lib/src/rendering/statistics_box.dart
new file mode 100644
index 0000000..98780ea
--- /dev/null
+++ b/packages/flutter/lib/src/rendering/statistics_box.dart
@@ -0,0 +1,47 @@
+// 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 'package:sky/src/rendering/box.dart';
+import 'package:sky/src/rendering/object.dart';
+
+class StatisticsBox extends RenderBox {
+
+ StatisticsBox({int optionsMask: 0}) : _optionsMask = optionsMask;
+
+ int _optionsMask;
+ int get optionsMask => _optionsMask;
+ void set optionsMask (int mask) {
+ if (mask == _optionsMask) {
+ return;
+ }
+ _optionsMask = mask;
+ markNeedsPaint();
+ }
+
+ bool get sizedByParent => true;
+
+ double getMinIntrinsicWidth(BoxConstraints constraints) {
+ return constraints.minWidth;
+ }
+
+ double getMaxIntrinsicWidth(BoxConstraints constraints) {
+ return constraints.maxWidth;
+ }
+
+ double getMinIntrinsicHeight(BoxConstraints constraints) {
+ return constraints.minHeight;
+ }
+
+ double getMaxIntrinsicHeight(BoxConstraints constraints) {
+ return constraints.maxHeight;
+ }
+
+ void performResize() {
+ size = constraints.constrain(Size.infinite);
+ }
+
+ void paint(PaintingContext context, Offset offset) {
+ context.paintStatistics(optionsMask, offset, size);
+ }
+}
diff --git a/packages/flutter/lib/src/widgets/statistics_overlay.dart b/packages/flutter/lib/src/widgets/statistics_overlay.dart
new file mode 100644
index 0000000..e3d62fc
--- /dev/null
+++ b/packages/flutter/lib/src/widgets/statistics_overlay.dart
@@ -0,0 +1,60 @@
+// 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 'package:sky/src/widgets/framework.dart';
+import 'package:sky/src/rendering/statistics_box.dart';
+
+/// The options that control whether the statistics overlay displays certain
+/// aspects of the compositor
+enum StatisticsOption {
+ /// Display the frame time and FPS of the last frame rendered. This field is
+ /// updated every frame.
+ ///
+ /// This is the time spent by the rasterizer as it tries
+ /// to convert the layer tree obtained from the widgets into OpenGL commands
+ /// and tries to flush them onto the screen. When the total time taken by this
+ /// step exceeds the frame slice, a frame is lost.
+ displayRasterizerStatistics,
+ /// Display the rasterizer frame times as they change over a set period of
+ /// time in the form of a graph. The y axis of the graph denotes the total
+ /// time spent by the rasterizer as a fraction of the total frame slice. When
+ /// the bar turns red, a frame is lost.
+ visualizeRasterizerStatistics,
+ /// Display the frame time and FPS at which the interface can construct a
+ /// layer tree for the rasterizer (whose behavior is described above) to
+ /// consume.
+ ///
+ /// This involves all layout, animations, etc. When the total time taken by
+ /// this step exceeds the frame slice, a frame is lost.
+ displayEngineStatistics,
+ /// Display the engine frame times as they change over a set period of time
+ /// in the form of a graph. The y axis of the graph denotes the total time
+ /// spent by the eninge as a fraction of the total frame slice. When the bar
+ /// turns red, a frame is lost.
+ visualizeEngineStatistics,
+}
+
+class StatisticsOverlay extends LeafRenderObjectWidget {
+
+ /// Create a statistics overlay that only displays specific statistics. The
+ /// mask is created by shifting 1 by the index of the specific StatisticOption
+ /// to enable.
+ StatisticsOverlay({ this.optionsMask, Key key }) : super(key: key);
+
+ /// Create a statistics overaly that displays all available statistics
+ StatisticsOverlay.allEnabled({ Key key }) : super(key: key), optionsMask = (
+ 1 << StatisticsOption.displayRasterizerStatistics.index |
+ 1 << StatisticsOption.visualizeRasterizerStatistics.index |
+ 1 << StatisticsOption.displayEngineStatistics.index |
+ 1 << StatisticsOption.visualizeEngineStatistics.index
+ );
+
+ final int optionsMask;
+
+ StatisticsBox createRenderObject() => new StatisticsBox(optionsMask: optionsMask);
+
+ void updateRenderObject(StatisticsBox renderObject, RenderObjectWidget oldWidget) {
+ renderObject.optionsMask = optionsMask;
+ }
+}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index 3e7f257..28e2553 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -43,6 +43,7 @@
export 'src/widgets/raised_button.dart';
export 'src/widgets/scaffold.dart';
export 'src/widgets/scrollable.dart';
+export 'src/widgets/statistics_overlay.dart';
export 'src/widgets/snack_bar.dart';
export 'src/widgets/switch.dart';
export 'src/widgets/tabs.dart';