performance_overlay.dart 6.02 KB
Newer Older
1 2 3 4
// 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.

5 6
import 'box.dart';
import 'object.dart';
7
import 'layer.dart';
8

9 10 11 12 13 14
/// 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

15 16 17 18 19 20 21 22
  /// 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,
23

24 25 26 27 28
  /// 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,
29

30 31 32 33 34 35 36
  /// 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,
37

38 39 40 41 42 43
  /// 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,
}
44

45 46 47 48 49 50 51 52 53 54 55 56 57
/// Displays performance statistics.
///
/// The overlay show 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]
58
/// to true.
59
class RenderPerformanceOverlay extends RenderBox {
60 61
  /// Creates a performance overlay render object.
  ///
62 63
  /// The [optionsMask], [rasterizerThreshold] and [checkerboardRasterCacheImages]
  /// arguments must not be null.
64 65
  RenderPerformanceOverlay({
    int optionsMask: 0,
66 67
    int rasterizerThreshold: 0,
    bool checkerboardRasterCacheImages: false,
68
  }) : _optionsMask = optionsMask,
69 70 71 72 73 74
      _rasterizerThreshold = rasterizerThreshold,
      _checkerboardRasterCacheImages = checkerboardRasterCacheImages {
    assert(optionsMask != null);
    assert(rasterizerThreshold != null);
    assert(checkerboardRasterCacheImages != null);
  }
75

76
  /// The mask is created by shifting 1 by the index of the specific
77
  /// [PerformanceOverlayOption] to enable.
78
  int get optionsMask => _optionsMask;
79
  int _optionsMask;
80
  set optionsMask(int mask) {
81
    assert(mask != null);
82
    if (mask == _optionsMask)
83 84 85 86 87
      return;
    _optionsMask = mask;
    markNeedsPaint();
  }

88 89 90
  /// 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.
91
  int get rasterizerThreshold => _rasterizerThreshold;
92
  int _rasterizerThreshold;
93
  set rasterizerThreshold (int threshold) {
94
    assert(threshold != null);
95
    if (threshold == _rasterizerThreshold)
96 97 98 99 100
      return;
    _rasterizerThreshold = threshold;
    markNeedsPaint();
  }

101 102 103 104 105 106 107 108 109 110 111
  /// Whether the raster cache should checkerboard cached entries.
  bool get checkerboardRasterCacheImages => _checkerboardRasterCacheImages;
  bool _checkerboardRasterCacheImages;
  set checkerboardRasterCacheImages (bool checkerboard) {
    assert(checkerboard != null);
    if (checkerboard == _checkerboardRasterCacheImages)
      return;
    _checkerboardRasterCacheImages = checkerboard;
    markNeedsPaint();
  }

112
  @override
113
  bool get sizedByParent => true;
114 115

  @override
116
  bool get alwaysNeedsCompositing => true;
117

118
  @override
119
  double computeMinIntrinsicWidth(double height) {
120
    return 0.0;
121 122
  }

123
  @override
124
  double computeMaxIntrinsicWidth(double height) {
125
    return 0.0;
126 127
  }

128
  double get _intrinsicHeight {
Hixie's avatar
Hixie committed
129
    const double kDefaultGraphHeight = 80.0;
130
    double result = 0.0;
131 132
    if ((optionsMask | (1 << PerformanceOverlayOption.displayRasterizerStatistics.index) > 0) ||
        (optionsMask | (1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index) > 0))
Hixie's avatar
Hixie committed
133
      result += kDefaultGraphHeight;
134 135
    if ((optionsMask | (1 << PerformanceOverlayOption.displayEngineStatistics.index) > 0) ||
        (optionsMask | (1 << PerformanceOverlayOption.visualizeEngineStatistics.index) > 0))
Hixie's avatar
Hixie committed
136
      result += kDefaultGraphHeight;
137
    return result;
138 139
  }

140
  @override
141
  double computeMinIntrinsicHeight(double width) {
142
    return _intrinsicHeight;
143 144
  }

145
  @override
146
  double computeMaxIntrinsicHeight(double width) {
147
    return _intrinsicHeight;
148 149
  }

150
  @override
151
  void performResize() {
152
    size = constraints.constrain(new Size(double.INFINITY, _intrinsicHeight));
153 154
  }

155
  @override
156
  void paint(PaintingContext context, Offset offset) {
157
    assert(needsCompositing);
158 159 160
    context.addLayer(new PerformanceOverlayLayer(
      overlayRect: new Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
      optionsMask: optionsMask,
161 162
      rasterizerThreshold: rasterizerThreshold,
      checkerboardRasterCacheImages: checkerboardRasterCacheImages,
163
    ));
164 165
  }
}