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
|
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <android-base/thread_annotations.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <utility>
#include <vector>
#include "EventThread.h"
#include "FrameRateCompatibility.h"
#include "RefreshRateSelector.h"
namespace android {
class Layer;
namespace scheduler {
class LayerInfo;
struct LayerProps;
class LayerHistory {
public:
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
using LayerVoteType = RefreshRateSelector::LayerVoteType;
static constexpr std::chrono::nanoseconds kMaxPeriodForHistory = 1s;
LayerHistory();
~LayerHistory();
// Layers are unregistered when the weak reference expires.
void registerLayer(Layer*, bool contentDetectionEnabled,
FrameRateCompatibility frameRateCompatibility);
// Sets the display size. Client is responsible for synchronization.
void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }
// Sets whether a mode change is pending to be applied
void setModeChangePending(bool pending) { mModeChangePending = pending; }
// Represents which layer activity is recorded
enum class LayerUpdateType {
Buffer, // a new buffer queued
AnimationTX, // a new transaction with eAnimation flag set
SetFrameRate, // setFrameRate API was called
};
// Marks the layer as active, and records the given state to its history.
void record(int32_t id, const LayerProps& props, nsecs_t presentTime, nsecs_t now,
LayerUpdateType updateType);
// Updates the default frame rate compatibility which takes effect when the app
// does not set a preference for refresh rate.
void setDefaultFrameRateCompatibility(int32_t id, FrameRateCompatibility frameRateCompatibility,
bool contentDetectionEnabled);
void setLayerProperties(int32_t id, const LayerProps&);
using Summary = std::vector<RefreshRateSelector::LayerRequirement>;
// Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
Summary summarize(const RefreshRateSelector&, nsecs_t now);
void clear();
void deregisterLayer(Layer*);
std::string dump() const;
// return the frames per second of the layer with the given sequence id.
float getLayerFramerate(nsecs_t now, int32_t id) const;
bool isSmallDirtyArea(uint32_t dirtyArea, float threshold) const;
// Updates the frame rate override set by game mode intervention
void updateGameModeFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
// Updates the frame rate override set by game default frame rate
void updateGameDefaultFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
std::pair<Fps, Fps> getGameFrameRateOverride(uid_t uid) const EXCLUDES(mLock);
std::pair<Fps, Fps> getGameFrameRateOverrideLocked(uid_t uid) const REQUIRES(mLock);
private:
friend class LayerHistoryTest;
friend class LayerHistoryIntegrationTest;
friend class TestableScheduler;
using LayerPair = std::pair<Layer*, std::unique_ptr<LayerInfo>>;
// keyed by id as returned from Layer::getSequence()
using LayerInfos = std::unordered_map<int32_t, LayerPair>;
std::string dumpGameFrameRateOverridesLocked() const REQUIRES(mLock);
// Iterates over layers maps moving all active layers to mActiveLayerInfos and all inactive
// layers to mInactiveLayerInfos. Layer's active state is determined by multiple factors
// such as update activity, visibility, and frame rate vote.
// worst case time complexity is O(2 * inactive + active)
// now: the current time (system time) when calling the method
// isVrrDevice: true if the device has DisplayMode with VrrConfig specified.
void partitionLayers(nsecs_t now, bool isVrrDevice) REQUIRES(mLock);
enum class LayerStatus {
NotFound,
LayerInActiveMap,
LayerInInactiveMap,
};
// looks up a layer by sequence id in both layerInfo maps.
// The first element indicates if and where the item was found
std::pair<LayerStatus, LayerPair*> findLayer(int32_t id) REQUIRES(mLock);
std::pair<LayerStatus, const LayerPair*> findLayer(int32_t id) const REQUIRES(mLock) {
return const_cast<LayerHistory*>(this)->findLayer(id);
}
mutable std::mutex mLock;
// Partitioned into two maps to facility two kinds of retrieval:
// 1. retrieval of a layer by id (attempt lookup in both maps)
// 2. retrieval of all active layers (iterate that map)
// The partitioning is allowed to become out of date but calling partitionLayers refreshes the
// validity of each map.
LayerInfos mActiveLayerInfos GUARDED_BY(mLock);
LayerInfos mInactiveLayerInfos GUARDED_BY(mLock);
uint32_t mDisplayArea = 0;
// Whether to emit systrace output and debug logs.
const bool mTraceEnabled;
// Whether to use priority sent from WindowManager to determine the relevancy of the layer.
const bool mUseFrameRatePriority;
// Whether a mode change is in progress or not
std::atomic<bool> mModeChangePending = false;
// A list to look up the game frame rate overrides
// Each entry includes:
// 1. the uid of the app
// 2. a pair of game mode intervention frame frame and game default frame rate override
// set to 0.0 if there is no such override
std::map<uid_t, std::pair<Fps, Fps>> mGameFrameRateOverride GUARDED_BY(mLock);
};
} // namespace scheduler
} // namespace android
|