/* * Copyright 2023 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "bench/Benchmark.h" #include "include/core/SkCanvas.h" #include "include/core/SkSurface.h" #include "tools/testrunners/common/surface_manager/SurfaceManager.h" #include #include // Represents a target against which to time a benchmark. Provides an SkCanvas and all necessary // timing methods. // // Based on nanobench's Target struct: // https://skia.googlesource.com/skia/+/a063eaeaf1e09e4d6f42e0f44a5723622a46d21c/bench/nanobench.h#36. class BenchmarkTarget { public: static std::unique_ptr FromConfig(std::string surfaceConfig, Benchmark* benchmark); // Prints to standard output overall statistics collected from all benchmark targets // instantiated during the lifetime of the test runner. static void printGlobalStats(); virtual ~BenchmarkTarget() = default; // Returns the backend used by this benchmark target. virtual Benchmark::Backend getBackend() const = 0; // Should be called once, immediately before any timing or drawing. virtual void setup() const; // Estimates the number of required benchmark runs to get a meaningful measurement. Returns // the estimated number of runs, and a boolean indicating success or failure. virtual std::tuple autoTuneLoops() const = 0; // Should be called once, immediately before any timing or drawing. Implementations may time // the benchmark for the passed in number of loops multiple times until a steady state is // reached. virtual void warmUp(int loops) const {} // Times the benchmark by drawing for the given number of interations. Returns the number of // milliseconds elapsed. It can be called multiple times between the setup() and tearDown() // calls. double time(int loops) const; // Should be called once after the test runner is done with the benchmark. void tearDown() const; // Produces statistics that test runner should include in the output JSON file. virtual void dumpStats(skia_private::TArray* keys, skia_private::TArray* values) const {} // Prints various statistics to standard output. virtual void printStats() const {} SkCanvas* getCanvas() const; Benchmark* getBenchmark() const; // Returns the subset of Perf key/value pairs that are determined by the surface config. The // returned map includes keys "cpu_or_gpu" and "cpu_or_gpu_value", which are populated based // on the cpuName and gpuName arguments, and whether the surface config is CPU or GPU bound. virtual std::map getKeyValuePairs(std::string cpuName, std::string gpuName) const; // Returns an enum indicating whether the surface is CPU or GPU bound. virtual SurfaceManager::CpuOrGpu isCpuOrGpuBound() const; protected: BenchmarkTarget(std::unique_ptr surfaceManager, Benchmark* benchmark) : fSurfaceManager(std::move(surfaceManager)), fBenchmark(benchmark) {} // Called *after* the clock timer is started, before the benchmark is drawn. Most backends just // return the canvas passed in, but some may replace it. virtual SkCanvas* onBeforeDraw(SkCanvas* canvas) const { return canvas; } // Called *after* a benchmark is drawn, but before the clock timer is stopped. virtual void onAfterDraw() const {} double nowMs() const; std::unique_ptr fSurfaceManager; Benchmark* fBenchmark; };