// 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 'dart:ui';

import 'recorder.dart';

/// Repeatedly paints a grid of rectangles where each rectangle is drawn in its
/// own [Picture].
///
/// Measures the performance of updating many layers. For example, the HTML
/// rendering backend attempts to reuse the DOM nodes created for engine layers.
///
/// See also `bench_draw_rect.dart`, which draws nearly identical UI but puts all
/// rectangles into the same picture.
class BenchUpdateManyChildLayers extends SceneBuilderRecorder {
  BenchUpdateManyChildLayers() : super(name: benchmarkName);

  static const String benchmarkName = 'bench_update_many_child_layers';

  /// Number of rows in the grid.
  static const int kRows = 32;

  /// Number of columns in the grid.
  static const int kColumns = 32;

  /// Counter used to offset the rendered rects to make them wobble.
  ///
  /// The wobbling is there so a human could visually verify that the benchmark
  /// is correctly pumping frames.
  double wobbleCounter = 0;

  List<Picture> _pictures;
  Size windowSize;
  Size cellSize;
  Size rectSize;

  @override
  Future<void> setUpAll() async {
    _pictures = <Picture>[];
    windowSize = window.physicalSize;
    cellSize = Size(
      windowSize.width / kColumns,
      windowSize.height / kRows,
    );
    rectSize = cellSize * 0.8;

    final Paint paint = Paint()..color = const Color.fromARGB(255, 255, 0, 0);
    for (int i = 0; i < kRows * kColumns; i++) {
      final PictureRecorder pictureRecorder = PictureRecorder();
      final Canvas canvas = Canvas(pictureRecorder);
      canvas.drawRect(Offset.zero & rectSize, paint);
      _pictures.add(pictureRecorder.endRecording());
    }
  }

  OffsetEngineLayer _rootLayer;
  final Map<int, OffsetEngineLayer> _layers = <int, OffsetEngineLayer>{};

  @override
  void onDrawFrame(SceneBuilder sceneBuilder) {
    _rootLayer = sceneBuilder.pushOffset(0, 0, oldLayer: _rootLayer);
    for (int row = 0; row < kRows; row++) {
      for (int col = 0; col < kColumns; col++) {
        final int layerId = 1000000 * row + col;
        final OffsetEngineLayer oldLayer = _layers[layerId];
        final double wobbleOffsetX = col * cellSize.width + (wobbleCounter - 5).abs();
        final double offsetY = row * cellSize.height;
        // Retain every other layer, so we exercise the update path 50% of the
        // time and the retain path the other 50%.
        final bool shouldRetain = oldLayer != null && (row + col) % 2 == 0;
        if (shouldRetain) {
          sceneBuilder.addRetained(oldLayer);
        } else {
          _layers[layerId] = sceneBuilder.pushOffset(
            wobbleOffsetX,
            offsetY,
            oldLayer: oldLayer,
          );
          sceneBuilder.addPicture(Offset.zero, _pictures[row * kColumns + col]);
          sceneBuilder.pop();
        }
      }
    }
    sceneBuilder.pop();
    wobbleCounter += 1;
    wobbleCounter = wobbleCounter % 10;
  }
}
