// 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'; /// Measure the performance of paint bounds estimation by recording a picture /// without actually rendering it. /// /// Bounds estimation is done in two phases: /// /// * As we call drawing methods on `Canvas` we grow bounds with every paint op. /// * When we're done recording a picture we call `PictureRecorder.endRecording` /// at which point we compute the overall picture bounds and cache the result. /// /// This benchmarks puts emphasis on paint operations that trigger expensive /// math such as `transformLTRB`. To do that we push non-identity transforms /// and rotations before calling drawing methods. class BenchPictureRecording extends RawRecorder { BenchPictureRecording() : super(name: benchmarkName); static const String benchmarkName = 'bench_picture_recording'; /// Cached paint used for drawing. /// /// We want to avoid polluting the results with paint initialization logic. late Paint paint; /// A prelaid out and cached paragraph. /// /// This is cached to remove text layout time from the benchmark time. late Paragraph paragraph; @override Future setUpAll() async { paint = Paint(); paragraph = (ParagraphBuilder(ParagraphStyle())..addText('abcd edfh ijkl mnop qrst uvwx yz')).build() ..layout(const ParagraphConstraints(width: 50)); } @override void body(Profile profile) { final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); profile.record('recordPaintCommands', () { for (int i = 1; i <= 100; i++) { canvas.translate((10 + i).toDouble(), (10 + i).toDouble()); canvas.save(); for (int j = 0; j < 10; j++) { canvas.drawRect(const Rect.fromLTWH(10, 10, 10, 10), paint); canvas.drawCircle(const Offset(50, 50), 50, paint); canvas.rotate(1.0); } canvas.restore(); canvas.save(); for (int j = 0; j < 10; j++) { canvas.translate(1, 1); canvas.clipRect(Rect.fromLTWH(20, 20, 40 / i, 40)); canvas.drawRRect( RRect.fromRectAndRadius(const Rect.fromLTWH(10, 10, 10, 10), const Radius.circular(2)), paint, ); canvas.drawParagraph(paragraph, Offset.zero); } canvas.restore(); } }, reported: true); profile.record('estimatePaintBounds', () { recorder.endRecording(); }, reported: true); } }