add the transformPoint and transformRect benchmarks (#36026)

diff --git a/dev/benchmarks/microbenchmarks/lib/geometry/matrix_utils_transform_bench.dart b/dev/benchmarks/microbenchmarks/lib/geometry/matrix_utils_transform_bench.dart
new file mode 100644
index 0000000..51c0e90
--- /dev/null
+++ b/dev/benchmarks/microbenchmarks/lib/geometry/matrix_utils_transform_bench.dart
@@ -0,0 +1,140 @@
+// Copyright 2019 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:math' as math;
+
+import 'package:flutter/painting.dart';
+import 'package:flutter/rendering.dart';
+import 'package:vector_math/vector_math_64.dart';
+
+import '../common.dart';
+
+const int _kNumIterations = 1000000;
+const int _kNumWarmUp = 10000;
+
+void main() {
+  assert(false, "Don't run benchmarks in checked mode! Use 'flutter run --release'.");
+  print('MatrixUtils.transformRect and .transformPoint benchmark...');
+
+  Matrix4 _makePerspective(double radius, double angle, double perspective) {
+    return MatrixUtils.createCylindricalProjectionTransform(
+      radius: radius,
+      angle: angle,
+      perspective: perspective,
+    );
+  }
+
+  final List<Matrix4> _affineTransforms = <Matrix4>[
+    Matrix4.identity()..scale(1.2, 1.3, 1.0)..rotateZ(0.1),
+    Matrix4.identity()..translate(12.0, 13.0, 10.0),
+    Matrix4.identity()..scale(1.2, 1.3, 1.0)..translate(12.0, 13.0, 10.0),
+  ];
+  final List<Matrix4> _perspectiveTransforms = <Matrix4>[
+    _makePerspective(10.0, math.pi / 8.0, 0.3),
+    _makePerspective( 8.0, math.pi / 8.0, 0.2),
+    _makePerspective( 1.0, math.pi / 4.0, 0.1)..rotateX(0.1),
+  ];
+  final List<Rect> _rectangles = <Rect>[
+    const Rect.fromLTRB(1.1, 1.2, 1.5, 1.8),
+    const Rect.fromLTRB(1.1, 1.2, 0.0, 1.0),
+    const Rect.fromLTRB(1.1, 1.2, 1.3, 1.0),
+    const Rect.fromLTRB(-1.1, -1.2, 0.0, 1.0),
+    const Rect.fromLTRB(-1.1, -1.2, -1.5, -1.8),
+  ];
+  final List<Offset> _offsets = <Offset>[
+    const Offset(1.1, 1.2),
+    const Offset(1.5, 1.8),
+    const Offset(0.0, 0.0),
+    const Offset(-1.1, -1.2),
+    const Offset(-1.5, -1.8),
+  ];
+  final int nAffine = _affineTransforms.length;
+  final int nPerspective = _perspectiveTransforms.length;
+  final int nRectangles = _rectangles.length;
+  final int nOffsets = _offsets.length;
+
+  // Warm up lap
+  for (int i = 0; i < _kNumWarmUp; i += 1) {
+    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
+    final Rect rect = _rectangles[(i ~/ nPerspective) % nRectangles];
+    final Offset offset = _offsets[(i ~/ nPerspective) % nOffsets];
+    MatrixUtils.transformRect(transform, rect);
+    MatrixUtils.transformPoint(transform, offset);
+  }
+  for (int i = 0; i < _kNumWarmUp; i += 1) {
+    final Matrix4 transform = _affineTransforms[i % nAffine];
+    final Rect rect = _rectangles[(i ~/ nAffine) % nRectangles];
+    final Offset offset = _offsets[(i ~/ nAffine) % nOffsets];
+    MatrixUtils.transformRect(transform, rect);
+    MatrixUtils.transformPoint(transform, offset);
+  }
+
+  final Stopwatch watch = Stopwatch();
+  watch.start();
+  for (int i = 0; i < _kNumIterations; i += 1) {
+    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
+    final Rect rect = _rectangles[(i ~/ nPerspective) % nRectangles];
+    MatrixUtils.transformRect(transform, rect);
+  }
+  watch.stop();
+  final int rectMicrosecondsPerspective = watch.elapsedMicroseconds;
+
+  watch.reset();
+  watch.start();
+  for (int i = 0; i < _kNumIterations; i += 1) {
+    final Matrix4 transform = _affineTransforms[i % nAffine];
+    final Rect rect = _rectangles[(i ~/ nAffine) % nRectangles];
+    MatrixUtils.transformRect(transform, rect);
+  }
+  watch.stop();
+  final int rectMicrosecondsAffine = watch.elapsedMicroseconds;
+
+  watch.reset();
+  watch.start();
+  for (int i = 0; i < _kNumIterations; i += 1) {
+    final Matrix4 transform = _perspectiveTransforms[i % nPerspective];
+    final Offset offset = _offsets[(i ~/ nPerspective) % nOffsets];
+    MatrixUtils.transformPoint(transform, offset);
+  }
+  watch.stop();
+  final int pointMicrosecondsPerspective = watch.elapsedMicroseconds;
+
+  watch.reset();
+  watch.start();
+  for (int i = 0; i < _kNumIterations; i += 1) {
+    final Matrix4 transform = _affineTransforms[i % nAffine];
+    final Offset offset = _offsets[(i ~/ nAffine) % nOffsets];
+    MatrixUtils.transformPoint(transform, offset);
+  }
+  watch.stop();
+  final int pointMicrosecondsAffine = watch.elapsedMicroseconds;
+
+  final BenchmarkResultPrinter printer = BenchmarkResultPrinter();
+  const double scale = 1000.0 / _kNumIterations;
+  printer.addResult(
+    description: 'MatrixUtils.transformRectPerspective',
+    value: rectMicrosecondsPerspective * scale,
+    unit: 'ns per iteration',
+    name: 'MatrixUtils_persp_transformRect_iteration',
+  );
+  printer.addResult(
+    description: 'MatrixUtils.transformRectAffine',
+    value: rectMicrosecondsAffine * scale,
+    unit: 'ns per iteration',
+    name: 'MatrixUtils_affine_transformRect_iteration',
+  );
+  printer.addResult(
+    description: 'MatrixUtils.transformPointPerspective',
+    value: pointMicrosecondsPerspective * scale,
+    unit: 'ns per iteration',
+    name: 'MatrixUtils_persp_transformPoint_iteration',
+  );
+  printer.addResult(
+    description: 'MatrixUtils.transformPointAffine',
+    value: pointMicrosecondsAffine * scale,
+    unit: 'ns per iteration',
+    name: 'MatrixUtils_affine_transformPoint_iteration',
+  );
+  printer.printToStdout();
+}
diff --git a/dev/devicelab/lib/tasks/microbenchmarks.dart b/dev/devicelab/lib/tasks/microbenchmarks.dart
index 5cd4b7f..8ff74de 100644
--- a/dev/devicelab/lib/tasks/microbenchmarks.dart
+++ b/dev/devicelab/lib/tasks/microbenchmarks.dart
@@ -51,6 +51,7 @@
     final Map<String, double> allResults = <String, double>{
       ...await _runMicrobench('lib/stocks/layout_bench.dart'),
       ...await _runMicrobench('lib/stocks/build_bench.dart'),
+      ...await _runMicrobench('lib/geometry/matrix_utils_transform_bench.dart'),
       ...await _runMicrobench('lib/geometry/rrect_contains_bench.dart'),
       ...await _runMicrobench('lib/gestures/velocity_tracker_bench.dart'),
       ...await _runMicrobench('lib/gestures/gesture_detector_bench.dart'),