-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperformance_overlay.dart
179 lines (159 loc) · 6.62 KB
/
performance_overlay.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright 2014 The Flutter 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 'box.dart';
import 'layer.dart';
import 'object.dart';
/// The options that control whether the performance overlay displays certain
/// aspects of the compositor.
enum PerformanceOverlayOption {
// these must be in the order needed for their index values to match the
// constants in //engine/src/sky/compositor/performance_overlay_layer.h
/// 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 engine as a fraction of the total frame slice. When the bar
/// turns red, a frame is lost.
visualizeEngineStatistics,
}
/// Displays performance statistics.
///
/// The overlay shows two time series. The first shows how much time was
/// required on this thread to produce each frame. The second shows how much
/// time was required on the GPU thread to produce each frame. Ideally, both
/// these values would be less than the total frame budget for the hardware on
/// which the app is running. For example, if the hardware has a screen that
/// updates at 60 Hz, each thread should ideally spend less than 16ms producing
/// each frame. This ideal condition is indicated by a green vertical line for
/// each thread. Otherwise, the performance overlay shows a red vertical line.
///
/// The simplest way to show the performance overlay is to set
/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay]
/// to true.
class RenderPerformanceOverlay extends RenderBox {
/// Creates a performance overlay render object.
///
/// The [optionsMask], [rasterizerThreshold], [checkerboardRasterCacheImages],
/// and [checkerboardOffscreenLayers] arguments must not be null.
RenderPerformanceOverlay({
int optionsMask = 0,
int rasterizerThreshold = 0,
bool checkerboardRasterCacheImages = false,
bool checkerboardOffscreenLayers = false,
}) : assert(optionsMask != null),
assert(rasterizerThreshold != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
_optionsMask = optionsMask,
_rasterizerThreshold = rasterizerThreshold,
_checkerboardRasterCacheImages = checkerboardRasterCacheImages,
_checkerboardOffscreenLayers = checkerboardOffscreenLayers;
/// The mask is created by shifting 1 by the index of the specific
/// [PerformanceOverlayOption] to enable.
int get optionsMask => _optionsMask;
int _optionsMask;
set optionsMask(int value) {
assert(value != null);
if (value == _optionsMask)
return;
_optionsMask = value;
markNeedsPaint();
}
/// The rasterizer threshold is an integer specifying the number of frame
/// intervals that the rasterizer must miss before it decides that the frame
/// is suitable for capturing an SkPicture trace for further analysis.
int get rasterizerThreshold => _rasterizerThreshold;
int _rasterizerThreshold;
set rasterizerThreshold(int value) {
assert(value != null);
if (value == _rasterizerThreshold)
return;
_rasterizerThreshold = value;
markNeedsPaint();
}
/// Whether the raster cache should checkerboard cached entries.
bool get checkerboardRasterCacheImages => _checkerboardRasterCacheImages;
bool _checkerboardRasterCacheImages;
set checkerboardRasterCacheImages(bool value) {
assert(value != null);
if (value == _checkerboardRasterCacheImages)
return;
_checkerboardRasterCacheImages = value;
markNeedsPaint();
}
/// Whether the compositor should checkerboard layers rendered to offscreen bitmaps.
bool get checkerboardOffscreenLayers => _checkerboardOffscreenLayers;
bool _checkerboardOffscreenLayers;
set checkerboardOffscreenLayers(bool value) {
assert(value != null);
if (value == _checkerboardOffscreenLayers)
return;
_checkerboardOffscreenLayers = value;
markNeedsPaint();
}
@override
bool get sizedByParent => true;
@override
bool get alwaysNeedsCompositing => true;
@override
double computeMinIntrinsicWidth(double height) {
return 0.0;
}
@override
double computeMaxIntrinsicWidth(double height) {
return 0.0;
}
double get _intrinsicHeight {
const double kDefaultGraphHeight = 80.0;
double result = 0.0;
if ((optionsMask | (1 << PerformanceOverlayOption.displayRasterizerStatistics.index) > 0) ||
(optionsMask | (1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index) > 0))
result += kDefaultGraphHeight;
if ((optionsMask | (1 << PerformanceOverlayOption.displayEngineStatistics.index) > 0) ||
(optionsMask | (1 << PerformanceOverlayOption.visualizeEngineStatistics.index) > 0))
result += kDefaultGraphHeight;
return result;
}
@override
double computeMinIntrinsicHeight(double width) {
return _intrinsicHeight;
}
@override
double computeMaxIntrinsicHeight(double width) {
return _intrinsicHeight;
}
@override
void performResize() {
size = constraints.constrain(Size(double.infinity, _intrinsicHeight));
}
@override
void paint(PaintingContext context, Offset offset) {
assert(needsCompositing);
context.addLayer(PerformanceOverlayLayer(
overlayRect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
optionsMask: optionsMask,
rasterizerThreshold: rasterizerThreshold,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
));
}
}