Commit 48e1350e authored by Ian Hickson's avatar Ian Hickson

Add more debugging options to the stocks app.

- Add an option to enable debugPaintSizeEnabled.
- Add an option to enable the StatisticsOverlay.
- Add support for the StatisticsOverlay in MaterialApp.
- Change the layout behaviour of RenderStatisticsBox:
   - Give it a zero intrinsic width.
   - Give it an accurate intrinsic height that depends on the flags
     set. (Also, move the enum to the rendering/ layer from the
     widgets/ layer to enable this.)
   - Make the box automatically size itself full-width and the correct
     height, so that you can actually embed it (though most of the
     time you'd just put it in a Stack so this doesn't matter as
     much, really).
- Some style nit fixes in statistics_box.dart.
parent c4545da2
......@@ -6,12 +6,14 @@ material-design-icons:
- name: action/assessment
- name: action/backup
- name: action/help
- name: action/picture_in_picture
- name: action/search
- name: action/settings
- name: action/thumb_down
- name: action/thumb_up
- name: content/add
- name: device/dvr
- name: editor/border_all
- name: editor/border_clear
- name: navigation/arrow_back
- name: navigation/menu
......
......@@ -40,7 +40,9 @@ class StocksAppState extends State<StocksApp> {
StockConfiguration _configuration = new StockConfiguration(
stockMode: StockMode.optimistic,
backupMode: BackupMode.enabled,
showGrid: false
debugShowGrid: false,
debugShowSizes: false,
showRenderingStatistics: false
);
void initState() {
......@@ -98,10 +100,15 @@ class StocksAppState extends State<StocksApp> {
}
Widget build(BuildContext context) {
assert(() {
debugPaintSizeEnabled = _configuration.debugShowSizes;
return true;
});
return new MaterialApp(
title: 'Stocks',
theme: theme,
debugShowMaterialGrid: _configuration.showGrid,
debugShowMaterialGrid: _configuration.debugShowGrid,
showRenderingPerformanceOverlay: _configuration.showRenderingStatistics,
routes: <String, RouteBuilder>{
'/': (RouteArguments args) => new StockHome(_stocks, _symbols, _configuration, configurationUpdater),
'/settings': (RouteArguments args) => new StockSettings(_configuration, configurationUpdater)
......
......@@ -24,7 +24,15 @@ class StockSettingsState extends State<StockSettings> {
}
void _handleShowGridChanged(bool value) {
sendUpdates(config.configuration.copyWith(showGrid: value));
sendUpdates(config.configuration.copyWith(debugShowGrid: value));
}
void _handleShowSizesChanged(bool value) {
sendUpdates(config.configuration.copyWith(debugShowSizes: value));
}
void _handleShowRenderingStatisticsChanged(bool value) {
sendUpdates(config.configuration.copyWith(showRenderingStatistics: value));
}
void _confirmOptimismChange() {
......@@ -93,22 +101,44 @@ class StockSettingsState extends State<StockSettings> {
),
])
),
new DrawerItem(
icon: 'action/picture_in_picture',
onPressed: () { _handleShowRenderingStatisticsChanged(!config.configuration.showRenderingStatistics); },
child: new Row(<Widget>[
new Flexible(child: new Text('Show rendering performance overlay')),
new Switch(
value: config.configuration.showRenderingStatistics,
onChanged: _handleShowRenderingStatisticsChanged
),
])
),
];
assert(() {
// material grid is only available in checked mode
rows.add(
// material grid and size construction lines are only available in checked mode
rows.addAll([
new DrawerItem(
icon: 'editor/border_clear',
onPressed: () { _handleShowGridChanged(!config.configuration.showGrid); },
onPressed: () { _handleShowGridChanged(!config.configuration.debugShowGrid); },
child: new Row(<Widget>[
new Flexible(child: new Text('Show material grid (for debugging)')),
new Switch(
value: config.configuration.showGrid,
value: config.configuration.debugShowGrid,
onChanged: _handleShowGridChanged
),
])
),
new DrawerItem(
icon: 'editor/border_all',
onPressed: () { _handleShowSizesChanged(!config.configuration.debugShowSizes); },
child: new Row(<Widget>[
new Flexible(child: new Text('Show construction lines (for debugging)')),
new Switch(
value: config.configuration.debugShowSizes,
onChanged: _handleShowSizesChanged
),
])
)
);
]);
return true;
});
return new Block(
......
......@@ -11,26 +11,36 @@ class StockConfiguration {
StockConfiguration({
this.stockMode,
this.backupMode,
this.showGrid
this.debugShowGrid,
this.debugShowSizes,
this.showRenderingStatistics
}) {
assert(stockMode != null);
assert(backupMode != null);
assert(showGrid != null);
assert(debugShowGrid != null);
assert(debugShowSizes != null);
assert(showRenderingStatistics != null);
}
final StockMode stockMode;
final BackupMode backupMode;
final bool showGrid;
final bool debugShowGrid;
final bool debugShowSizes;
final bool showRenderingStatistics;
StockConfiguration copyWith({
StockMode stockMode,
BackupMode backupMode,
bool showGrid
bool debugShowGrid,
bool debugShowSizes,
bool showRenderingStatistics
}) {
return new StockConfiguration(
stockMode: stockMode ?? this.stockMode,
backupMode: backupMode ?? this.backupMode,
showGrid: showGrid ?? this.showGrid
debugShowGrid: debugShowGrid ?? this.debugShowGrid,
debugShowSizes: debugShowSizes ?? this.debugShowSizes,
showRenderingStatistics: showRenderingStatistics ?? this.showRenderingStatistics
);
}
}
\ No newline at end of file
......@@ -48,11 +48,13 @@ class MaterialApp extends StatefulComponent {
this.routes: const <String, RouteBuilder>{},
this.onGenerateRoute,
this.onLocaleChanged,
this.debugShowMaterialGrid: false
this.debugShowMaterialGrid: false,
this.showRenderingPerformanceOverlay: false
}) : super(key: key) {
assert(routes != null);
assert(routes.containsKey(Navigator.defaultRouteName) || onGenerateRoute != null);
assert(debugShowMaterialGrid != null);
assert(showRenderingPerformanceOverlay != null);
}
final String title;
......@@ -61,6 +63,7 @@ class MaterialApp extends StatefulComponent {
final RouteFactory onGenerateRoute;
final LocaleChangedCallback onLocaleChanged;
final bool debugShowMaterialGrid;
final bool showRenderingPerformanceOverlay;
_MaterialAppState createState() => new _MaterialAppState();
}
......@@ -171,6 +174,12 @@ class _MaterialAppState extends State<MaterialApp> implements BindingObserver {
}
return true;
});
if (config.showRenderingPerformanceOverlay) {
result = new Stack([
result,
new Positioned(bottom: 0.0, left: 0.0, right: 0.0, child: new StatisticsOverlay.allEnabled()),
]);
}
return result;
}
......
......@@ -5,28 +5,57 @@
import 'box.dart';
import 'object.dart';
class RenderStatisticsBox extends RenderBox {
/// 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,
}
RenderStatisticsBox({int optionsMask: 0, int rasterizerThreshold: 0})
class RenderStatisticsBox extends RenderBox {
RenderStatisticsBox({ int optionsMask: 0, int rasterizerThreshold: 0 })
: _optionsMask = optionsMask,
_rasterizerThreshold = rasterizerThreshold;
int _optionsMask;
/// The mask is created by shifting 1 by the index of the specific
/// StatisticOption to enable.
int get optionsMask => _optionsMask;
void set optionsMask (int mask) {
if (mask == _optionsMask) {
int _optionsMask;
void set optionsMask(int mask) {
if (mask == _optionsMask)
return;
}
_optionsMask = mask;
markNeedsPaint();
}
int _rasterizerThreshold;
int get rasterizerThreshold => _rasterizerThreshold;
int _rasterizerThreshold;
void set rasterizerThreshold (int threshold) {
if (threshold == _rasterizerThreshold) {
if (threshold == _rasterizerThreshold)
return;
}
_rasterizerThreshold = threshold;
markNeedsPaint();
}
......@@ -34,27 +63,35 @@ class RenderStatisticsBox extends RenderBox {
bool get sizedByParent => true;
double getMinIntrinsicWidth(BoxConstraints constraints) {
assert(constraints.isNormalized);
return constraints.minWidth;
return constraints.constrainWidth(0.0);
}
double getMaxIntrinsicWidth(BoxConstraints constraints) {
assert(constraints.isNormalized);
return constraints.maxWidth;
return constraints.constrainWidth(0.0);
}
double get intrinsicHeight {
const double kGraphHeight = 80.0; // must match value in statistics_layer.cc
double result = 0.0;
if ((optionsMask | (1 << StatisticsOption.displayRasterizerStatistics.index) > 0) ||
(optionsMask | (1 << StatisticsOption.visualizeRasterizerStatistics.index) > 0))
result += kGraphHeight;
if ((optionsMask | (1 << StatisticsOption.displayEngineStatistics.index) > 0) ||
(optionsMask | (1 << StatisticsOption.visualizeEngineStatistics.index) > 0))
result += kGraphHeight;
return result;
}
double getMinIntrinsicHeight(BoxConstraints constraints) {
assert(constraints.isNormalized);
return constraints.minHeight;
return constraints.constrainHeight(intrinsicHeight);
}
double getMaxIntrinsicHeight(BoxConstraints constraints) {
assert(constraints.isNormalized);
return constraints.maxHeight;
return constraints.constrainHeight(intrinsicHeight);
}
void performResize() {
size = constraints.biggest;
size = constraints.constrain(new Size(double.INFINITY, intrinsicHeight));
}
void paint(PaintingContext context, Offset offset) {
......
......@@ -6,44 +6,14 @@ import 'package:flutter/rendering.dart';
import 'framework.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,
}
/// Displays performance statistics.
class StatisticsOverlay extends LeafRenderObjectWidget {
// TODO(abarth): We should have a page on the web site with a screenshot and
// an explanation of all the various readouts.
/// 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.
/// mask is created by shifting 1 by the index of the specific
/// [StatisticOption] to enable.
StatisticsOverlay({ this.optionsMask, this.rasterizerThreshold: 0, Key key }) : super(key: key);
/// Create a statistics overaly that displays all available statistics
......
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