File: frame_interval_matchers.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (196 lines) | stat: -rw-r--r-- 7,353 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_FRAME_INTERVAL_MATCHERS_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_FRAME_INTERVAL_MATCHERS_H_

#include <optional>
#include <string>
#include <variant>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ref.h"
#include "base/time/time.h"
#include "components/viz/common/constants.h"
#include "components/viz/common/quads/frame_interval_inputs.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/service/viz_service_export.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"

namespace viz {

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class FrameIntervalMatcherType {
  kNone = 0,
  kInputBoost = 1,
  kOnlyVideo = 2,
  kVideoConference = 3,
  kOnlyAnimatingImage = 4,
  kOnlyScrollBarFadeOut = 5,
  kUserInputBoost = 6,
  kSlowScrollThrottle = 7,
  kMaxValue = kSlowScrollThrottle,
};

// Works with `FrameIntervalDecider` to compute the ideal frame interval.
// Matchers are independent and each matcher matches a specific scenario. Note
// however matcher order is important.
// Matchers should generally be stateless as they can be recreated at run time,
// and any input or state should be stored in `FrameIntervalDecider`.
// Matcher should generally not be platform-specific.
class VIZ_SERVICE_EXPORT FrameIntervalMatcher {
 public:
  // Result can either be an interval class or a specific frame interval,
  // depending on setting and the inputs.
  enum class FrameIntervalClass {
    // These are ordered from lowest frame interval to highest.
    kBoost,    // Used for latency or smoothness sensitive situation such as
               // scrolling.
    kDefault,  // Used if nothing matched.
  };
  enum class ResultIntervalType {
    kExact,
    kAtLeast,
  };
  struct ResultInterval {
    base::TimeDelta interval;
    ResultIntervalType type = ResultIntervalType::kExact;
    bool operator==(const ResultInterval& other) const;
  };
  using Result = std::variant<FrameIntervalClass, ResultInterval>;
  using ResultCallback =
      base::RepeatingCallback<void(Result, FrameIntervalMatcherType)>;

  // Settings for configuration where display supports a fixed set of discrete
  // frame intervals.
  struct VIZ_SERVICE_EXPORT FixedIntervalSettings {
    FixedIntervalSettings();
    FixedIntervalSettings(const FixedIntervalSettings&);
    ~FixedIntervalSettings();

    base::TimeDelta default_interval;  // Used for FrameIntervalClass::kDefault.
    base::flat_set<base::TimeDelta> supported_intervals;  // Cannot be empty.
  };

  // Settings for configuration where display supports a continuous range of
  // frame intervals.
  struct VIZ_SERVICE_EXPORT ContinuousRangeSettings {
    ContinuousRangeSettings();
    ContinuousRangeSettings(const ContinuousRangeSettings&);
    ~ContinuousRangeSettings();

    base::TimeDelta default_interval;  // Used for FrameIntervalClass::kDefault.
    base::TimeDelta min_interval;
    base::TimeDelta max_interval;
  };

  struct VIZ_SERVICE_EXPORT Settings {
    Settings();
    ~Settings();

    Settings(const Settings& other);
    Settings& operator=(const Settings& other);
    Settings(Settings&& other);
    Settings& operator=(Settings&& other);

    // Called with desired display frame interval Result. Must remain valid to
    // call for the lifetime of FrameIntervalDecider.
    ResultCallback result_callback;

    // Settings for what intervals are supported by the display. If this is
    // provided, then `FrameIntervalDecider` matchers should never return a
    // FrameIntervalClass result, and instead should pick one of the
    // supported intervals. If this is set to `monostate`, then
    // `FrameIntervalClass` as well as any frame interval can be returned.
    std::variant<std::monostate, FixedIntervalSettings, ContinuousRangeSettings>
        interval_settings;

    // Timeout to wait for when increasing frame interval, to avoid blip when
    // rapidly switching frame intervals..
    base::TimeDelta increase_frame_interval_timeout = base::Milliseconds(100);

    // For matchers where relevant, frame sinks that has not updated in this
    // time will be assumed to be static and ignored for computation.
    base::TimeDelta ignore_frame_sink_timeout = base::Milliseconds(250);

    // Used for time delta equality comparisons.
    base::TimeDelta epsilon = base::Milliseconds(0.5);

    // Passed into `media::VideoCadenceEstimator::HasSimpleCadence` to compute
    // ideal frame interval.
    base::TimeDelta max_time_until_next_glitch = kMaxTimeUntilNextGlitch;
  };

  struct VIZ_SERVICE_EXPORT Inputs {
    Inputs(const Settings& settings, uint64_t frame_id);
    ~Inputs();

    Inputs(const Inputs& other);
    Inputs& operator=(const Inputs& other);

    // Serializes this struct into a trace.
    void WriteIntoTrace(perfetto::TracedValue trace_context) const;

    base::raw_ref<const Settings> settings;
    // Increasing id for each viz frame.
    uint64_t frame_id;
    base::TimeTicks aggregated_frame_time;
    base::flat_map<FrameSinkId, FrameIntervalInputs> inputs_map;
  };

  static std::string ResultToString(const Result& result);
  static std::string MatcherTypeToString(FrameIntervalMatcherType type);

  static bool AreAlmostEqual(base::TimeDelta a,
                             base::TimeDelta b,
                             base::TimeDelta epsilon);

  virtual ~FrameIntervalMatcher() = default;

  FrameIntervalMatcherType type() const { return type_; }

  virtual std::optional<Result> Match(const Inputs& matcher_inputs) = 0;

 protected:
  explicit FrameIntervalMatcher(FrameIntervalMatcherType type);

 private:
  const FrameIntervalMatcherType type_;
};

#define DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(ClassName)                \
  class VIZ_SERVICE_EXPORT ClassName : public FrameIntervalMatcher {    \
   public:                                                              \
    ClassName();                                                        \
    ~ClassName() override;                                              \
    std::optional<Result> Match(const Inputs& matcher_inputs) override; \
  }

DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(InputBoostMatcher);
DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(OnlyVideoMatcher);
DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(VideoConferenceMatcher);
DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(OnlyAnimatingImageMatcher);
DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(OnlyScrollBarFadeOutAnimationMatcher);
DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER(UserInputBoostMatcher);

#undef DECLARE_SIMPLE_FRAME_INTERVAL_MATCHER

class VIZ_SERVICE_EXPORT SlowScrollThrottleMatcher
    : public FrameIntervalMatcher {
 public:
  explicit SlowScrollThrottleMatcher(float device_scale_factor);
  ~SlowScrollThrottleMatcher() override;
  std::optional<Result> Match(const Inputs& matcher_inputs) override;

 private:
  const float device_scale_factor_;
  uint64_t last_frame_id_matched_without_extra_update_ = 0u;
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_FRAME_INTERVAL_MATCHERS_H_