// 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.

// @dart = 2.8

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 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.
/// 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,
    ));
  }
}
