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
|
// 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_DECIDER_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_FRAME_INTERVAL_DECIDER_H_
#include <memory>
#include <optional>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ref.h"
#include "base/time/time.h"
#include "components/viz/common/quads/frame_interval_inputs.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/service/display/frame_interval_matchers.h"
#include "components/viz/service/surfaces/surface_observer.h"
#include "components/viz/service/viz_service_export.h"
namespace viz {
class SurfaceManager;
// This class computes the ideal frame interval the display should use. It does
// this by using an ordered list of `FrameIntervalMatcher`. Matchers should
// generally be stateless to support updating the list at run time. This is the
// replacement for `FrameRateDecider`.
class VIZ_SERVICE_EXPORT FrameIntervalDecider {
public:
using FrameIntervalClass = FrameIntervalMatcher::FrameIntervalClass;
using ResultInterval = FrameIntervalMatcher::ResultInterval;
using Result = FrameIntervalMatcher::Result;
using ResultCallback = FrameIntervalMatcher::ResultCallback;
using FixedIntervalSettings = FrameIntervalMatcher::FixedIntervalSettings;
using ContinuousRangeSettings = FrameIntervalMatcher::ContinuousRangeSettings;
using Settings = FrameIntervalMatcher::Settings;
// This object should be created and held for the duration when surface
// aggregation for a frame to be presented by the display is in progress. It
// is used by the FrameIntervalDecider to keep track of drawn surfaces.
// Constructed by calling `FrameIntervalDecider::WrapAggregate`.
class VIZ_SERVICE_EXPORT ScopedAggregate : public SurfaceObserver {
public:
~ScopedAggregate() override;
ScopedAggregate(const ScopedAggregate&) = delete;
ScopedAggregate& operator=(ScopedAggregate& other) = delete;
// SurfaceObserver implementation.
void OnSurfaceWillBeDrawn(Surface* surface) override;
private:
friend FrameIntervalDecider;
ScopedAggregate(FrameIntervalDecider& decider,
SurfaceManager& surface_manager,
base::TimeTicks frame_time);
const raw_ref<FrameIntervalDecider> decider_;
const raw_ref<SurfaceManager> surface_manager_;
const base::TimeTicks frame_time_;
base::flat_map<FrameSinkId, FrameIntervalInputs> drawn_frame_sinks_;
};
FrameIntervalDecider();
~FrameIntervalDecider();
const Settings& settings() const { return settings_; }
void UpdateSettings(
Settings settings,
std::vector<std::unique_ptr<FrameIntervalMatcher>> matchers);
ScopedAggregate WrapAggregate(SurfaceManager& surface_manager,
base::TimeTicks frame_time);
private:
void Decide(base::TimeTicks frame_time,
base::flat_map<FrameSinkId, FrameIntervalInputs> inputs_map);
// It's not possible to compare `FrameIntervalClass` and frame interval
// directly, so assume true if result changes type.
static bool MayDecreaseFrameInterval(const std::optional<Result>& from,
const std::optional<Result>& to);
Settings settings_;
std::vector<std::unique_ptr<FrameIntervalMatcher>> matchers_;
base::TimeTicks current_result_frame_time_;
std::optional<Result> current_result_;
uint64_t frame_id_ = 0u;
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_FRAME_INTERVAL_DECIDER_H_
|