| // Copyright 2013 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. | |
| #ifndef FLUTTER_FLOW_STOPWATCH_H_ | |
| #define FLUTTER_FLOW_STOPWATCH_H_ | |
| #include <vector> | |
| #include "flutter/display_list/dl_canvas.h" | |
| #include "flutter/fml/macros.h" | |
| #include "flutter/fml/time/time_delta.h" | |
| #include "flutter/fml/time/time_point.h" | |
| namespace flutter { | |
| class Stopwatch { | |
| public: | |
| // The number of samples that will be accumulated for performance monitoring | |
| static const size_t kMaxSamples = 120; | |
| /// The refresh rate interface for `Stopwatch`. | |
| class RefreshRateUpdater { | |
| public: | |
| /// Time limit for a smooth frame. | |
| /// See: `DisplayManager::GetMainDisplayRefreshRate`. | |
| virtual fml::Milliseconds GetFrameBudget() const = 0; | |
| }; | |
| /// The constructor with a updater parameter, it will update frame_budget | |
| /// everytime when `GetFrameBudget()` is called. | |
| explicit Stopwatch(const RefreshRateUpdater& updater); | |
| ~Stopwatch(); | |
| const fml::TimeDelta& GetLap(size_t index) const; | |
| /// Return a reference to all the laps. | |
| size_t GetLapsCount() const; | |
| size_t GetCurrentSample() const; | |
| const fml::TimeDelta& LastLap() const; | |
| fml::TimeDelta MaxDelta() const; | |
| fml::TimeDelta AverageDelta() const; | |
| void Start(); | |
| void Stop(); | |
| void SetLapTime(const fml::TimeDelta& delta); | |
| /// All places which want to get frame_budget should call this function. | |
| fml::Milliseconds GetFrameBudget() const; | |
| private: | |
| const RefreshRateUpdater& refresh_rate_updater_; | |
| fml::TimePoint start_; | |
| std::vector<fml::TimeDelta> laps_; | |
| size_t current_sample_ = kMaxSamples - 1u; | |
| FML_DISALLOW_COPY_AND_ASSIGN(Stopwatch); | |
| }; | |
| /// Used for fixed refresh rate query cases. | |
| class FixedRefreshRateUpdater : public Stopwatch::RefreshRateUpdater { | |
| fml::Milliseconds GetFrameBudget() const override; | |
| public: | |
| explicit FixedRefreshRateUpdater( | |
| fml::Milliseconds fixed_frame_budget = fml::kDefaultFrameBudget); | |
| private: | |
| fml::Milliseconds fixed_frame_budget_; | |
| }; | |
| /// Used for fixed refresh rate cases. | |
| class FixedRefreshRateStopwatch : public Stopwatch { | |
| public: | |
| explicit FixedRefreshRateStopwatch( | |
| fml::Milliseconds fixed_frame_budget = fml::kDefaultFrameBudget); | |
| private: | |
| FixedRefreshRateUpdater fixed_delegate_; | |
| }; | |
| //------------------------------------------------------------------------------ | |
| /// @brief Abstract class for visualizing (i.e. drawing) a stopwatch. | |
| /// | |
| /// @note This was originally folded into the |Stopwatch| class, but | |
| /// was separated out to make it easier to change the underlying | |
| /// implementation (which relied directly on Skia, not showing on | |
| /// Impeller: https://github.com/flutter/flutter/issues/126009). | |
| class StopwatchVisualizer { | |
| public: | |
| explicit StopwatchVisualizer(const Stopwatch& stopwatch) | |
| : stopwatch_(stopwatch) { | |
| // Looking up the frame budget from the stopwatch delegate class may call | |
| // into JNI or make platform calls which are slow. This value is safe to | |
| // cache since the StopwatchVisualizer is recreated on each frame. | |
| frame_budget_ = stopwatch_.GetFrameBudget(); | |
| } | |
| virtual ~StopwatchVisualizer() = default; | |
| /// @brief Renders the stopwatch as a graph. | |
| /// | |
| /// @param canvas The canvas to draw on. | |
| /// @param[in] rect The rectangle to draw in. | |
| virtual void Visualize(DlCanvas* canvas, const DlRect& rect) const = 0; | |
| FML_DISALLOW_COPY_AND_ASSIGN(StopwatchVisualizer); | |
| protected: | |
| /// @brief Converts a raster time to a unit interval. | |
| double UnitFrameInterval(double time_ms) const; | |
| /// @brief Converts a raster time to a unit height. | |
| double UnitHeight(double time_ms, double max_height) const; | |
| fml::Milliseconds GetFrameBudget() const { return frame_budget_; } | |
| const Stopwatch& stopwatch_; | |
| fml::Milliseconds frame_budget_; | |
| }; | |
| } // namespace flutter | |
| #endif // FLUTTER_FLOW_STOPWATCH_H_ |