performance_overlay.dart 5.84 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7
import 'package:flutter/rendering.dart';
8

Adam Barth's avatar
Adam Barth committed
9
import 'framework.dart';
10

11
/// Displays performance statistics.
12
///
13 14 15 16 17 18 19 20
/// 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 raster thread (formerly known as 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.
21
/// Otherwise, the performance overlay shows a red vertical line.
22 23 24
///
/// The simplest way to show the performance overlay is to set
/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay]
25
/// to true.
26
class PerformanceOverlay extends LeafRenderObjectWidget {
27 28
  // TODO(abarth): We should have a page on the web site with a screenshot and
  // an explanation of all the various readouts.
29

30
  /// Create a performance overlay that only displays specific statistics. The
31
  /// mask is created by shifting 1 by the index of the specific
32
  /// [PerformanceOverlayOption] to enable.
33
  const PerformanceOverlay({
34
    Key key,
35 36 37 38
    this.optionsMask = 0,
    this.rasterizerThreshold = 0,
    this.checkerboardRasterCacheImages = false,
    this.checkerboardOffscreenLayers = false,
39
  }) : super(key: key);
40

41
  /// Create a performance overlay that displays all available statistics
42 43 44 45 46 47
  PerformanceOverlay.allEnabled({
    Key key,
    this.rasterizerThreshold = 0,
    this.checkerboardRasterCacheImages = false,
    this.checkerboardOffscreenLayers = false,
  }) : optionsMask =
48 49 50
        1 << PerformanceOverlayOption.displayRasterizerStatistics.index |
        1 << PerformanceOverlayOption.visualizeRasterizerStatistics.index |
        1 << PerformanceOverlayOption.displayEngineStatistics.index |
51
        1 << PerformanceOverlayOption.visualizeEngineStatistics.index,
Hixie's avatar
Hixie committed
52
      super(key: key);
53

54 55
  /// The mask is created by shifting 1 by the index of the specific
  /// [PerformanceOverlayOption] to enable.
56
  final int optionsMask;
57 58 59

  /// The rasterizer threshold is an integer specifying the number of frame
  /// intervals that the rasterizer must miss before it decides that the frame
Devon Carew's avatar
Devon Carew committed
60
  /// is suitable for capturing an SkPicture trace for further analysis.
61 62
  ///
  /// For example, if you want a trace of all pictures that could not be
63
  /// rendered by the rasterizer within the frame boundary (and hence caused
64 65 66 67 68 69
  /// jank), specify 1. Specifying 2 will trace all pictures that took more
  /// more than 2 frame intervals to render. Adjust this value to only capture
  /// the particularly expensive pictures while skipping the others. Specifying
  /// 0 disables all capture.
  ///
  /// Captured traces are placed on your device in the application documents
70
  /// directory in this form "trace_<collection_time>.skp". These can
71 72 73 74 75 76 77 78 79 80
  /// be viewed in the Skia debugger.
  ///
  /// Notes:
  /// The rasterizer only takes into account the time it took to render
  /// the already constructed picture. This include the Skia calls (which is
  /// also why an SkPicture trace is generated) but not any of the time spent in
  /// dart to construct that picture. To profile that part of your code, use
  /// the instrumentation available in observatory.
  ///
  /// To decide what threshold interval to use, count the number of horizontal
81
  /// lines displayed in the performance overlay for the rasterizer (not the
82 83
  /// engine). That should give an idea of how often frames are skipped (and by
  /// how many frame intervals).
84
  final int rasterizerThreshold;
85

86 87 88 89 90 91 92 93 94 95 96 97 98
  /// Whether the raster cache should checkerboard cached entries.
  ///
  /// The compositor can sometimes decide to cache certain portions of the
  /// widget hierarchy. Such portions typically don't change often from frame to
  /// frame and are expensive to render. This can speed up overall rendering. However,
  /// there is certain upfront cost to constructing these cache entries. And, if
  /// the cache entries are not used very often, this cost may not be worth the
  /// speedup in rendering of subsequent frames. If the developer wants to be certain
  /// that populating the raster cache is not causing stutters, this option can be
  /// set. Depending on the observations made, hints can be provided to the compositor
  /// that aid it in making better decisions about caching.
  final bool checkerboardRasterCacheImages;

99 100 101 102 103 104 105 106 107 108
  /// Whether the compositor should checkerboard layers that are rendered to offscreen
  /// bitmaps. This can be useful for debugging rendering performance.
  ///
  /// Render target switches are caused by using opacity layers (via a [FadeTransition] or
  /// [Opacity] widget), clips, shader mask layers, etc. Selecting a new render target
  /// and merging it with the rest of the scene has a performance cost. This can sometimes
  /// be avoided by using equivalent widgets that do not require these layers (for example,
  /// replacing an [Opacity] widget with an [widgets.Image] using a [BlendMode]).
  final bool checkerboardOffscreenLayers;

109
  @override
110
  RenderPerformanceOverlay createRenderObject(BuildContext context) => RenderPerformanceOverlay(
111
    optionsMask: optionsMask,
112
    rasterizerThreshold: rasterizerThreshold,
113 114
    checkerboardRasterCacheImages: checkerboardRasterCacheImages,
    checkerboardOffscreenLayers: checkerboardOffscreenLayers,
115
  );
116

117
  @override
118
  void updateRenderObject(BuildContext context, RenderPerformanceOverlay renderObject) {
119 120 121
    renderObject
      ..optionsMask = optionsMask
      ..rasterizerThreshold = rasterizerThreshold;
122 123
  }
}