// Copyright 2018 The Chromium 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 UI_LATENCY_STREAM_ANALYZER_H_ #define UI_LATENCY_STREAM_ANALYZER_H_ #include #include #include #include "base/macros.h" #include "base/trace_event/trace_event_argument.h" #include "ui/latency/fixed_point.h" #include "ui/latency/histograms.h" #include "ui/latency/windowed_analyzer.h" namespace ui { // Used to communicate fraction of time the value of a metric was greater than // or equal to the threshold. struct ThresholdResult { double threshold = 0.0; double ge_fraction = 0.0; }; namespace frame_metrics { // The StreamAnalyzerClient interface is currently the same as // WindowedAnalyzerClient and can rely on the same implementation. using StreamAnalyzerClient = WindowedAnalyzerClient; // Tracks the overall mean, RMS, and SMR for a metric and also owns // the Histogram and WindowedAnalyzer. class StreamAnalyzer { public: StreamAnalyzer(const StreamAnalyzerClient* client, const SharedWindowedAnalyzerClient* shared_client, std::vector thresholds, std::unique_ptr histogram); ~StreamAnalyzer(); // Resets all statistics and history. void Reset(); // Resets the statistics without throwing away recent sample history in the // WindowedAnalyzer. void StartNewReportPeriod(); // To play well with the histogram range, |value| should be within the // range [0,64000000]. If the units are milliseconds, that's 64 seconds. // Otherwise, the histogram will clip the result. // |weight| may be the duration the frame was active in microseconds // or it may be 1 in case every frame is to be weighed equally. void AddSample(const uint32_t value, const uint32_t weight); // The mean, root-mean-squared, and squared-mean-root of all samples // received since the last call to StartNewReportPeriod(). // The units are the same as the values added in AddSample(). double ComputeMean() const; double ComputeRMS() const; double ComputeSMR() const; // StdDev calculates the standard deviation of all values in the stream. // The units are the same as the values added in AddSample(). // The work to track this is the same as RMS, so we effectively get this for // free. Given two of the Mean, RMS, and StdDev, we can calculate the third. double ComputeStdDev() const; // VarianceOfRoots calculates the variance of all square roots of values. // The units end up being the same as the values added in AddSample(). // The work to track this is the same as SMR. // Given two of the Mean, SMR, and VarianceOfRoots, we can calculate the // third. Note: We don't track something like RootStdDevOfSquares since it // would be difficult to track values raised to the fourth power. // TODO(brianderon): Remove VarianceOfRoots if it's not useful. double ComputeVarianceOfRoots() const; // Thresholds returns a percentile for threshold values given to the // constructor. This is useful for tracking improvements in really good // sources, but it's dynamic range is limited, which prevents it from // detecting improvements in sources where most of the frames are "bad". std::vector ComputeThresholds() const; // CalculatePercentiles returns a value for certain percentiles. // It is only an estimate, since the values are calculated from a histogram // rather than from the entire history of actual values. // This is useful for tracking improvements even in really bad sources // since it's dynamic range includes all possible values. PercentileResults ComputePercentiles() const; // Expose the WindowedAnalyzer as const to make it's accessors // available directly. const WindowedAnalyzer& window() const { return windowed_analyzer_; } std::unique_ptr AsValue() const; void AsValueInto(base::trace_event::TracedValue* state) const; protected: double VarianceHelper(double accum, double square_accum) const; struct ThresholdState { explicit ThresholdState(uint32_t value) : threshold(value) {} void ResetAccumulators(); uint32_t threshold; uint32_t ge_weight = 0; uint32_t lt_weight = 0; }; const StreamAnalyzerClient* const client_; std::vector thresholds_; std::unique_ptr histogram_; WindowedAnalyzer windowed_analyzer_; uint64_t total_weight_ = 0; uint64_t accumulator_ = 0; uint64_t root_accumulator_ = 0; Accumulator96b square_accumulator_; DISALLOW_COPY_AND_ASSIGN(StreamAnalyzer); }; } // namespace frame_metrics } // namespace ui #endif // UI_LATENCY_STREAM_ANALYZER_H_