blob: d5bebf6d2b4dcf11cde8a51c9f03c7793a7a61d8 [file] [log] [blame]
Ana Krulec61f86db2018-11-19 14:16:35 +01001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070019#include <android-base/thread_annotations.h>
20#include <utils/RefBase.h>
Ana Krulec61f86db2018-11-19 14:16:35 +010021#include <utils/Timers.h>
22
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070023#include <memory>
24#include <mutex>
25#include <utility>
26#include <vector>
Ana Krulec434c22d2018-11-28 13:48:36 +010027
Ady Abraham8a82ba62020-01-17 12:43:17 -080028#include "RefreshRateConfigs.h"
29
Ana Krulec61f86db2018-11-19 14:16:35 +010030namespace android {
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070031
32class Layer;
Dominik Laskowski49cea512019-11-12 14:13:23 -080033class TestableScheduler;
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070034
Ady Abraham09bd3922019-04-08 10:44:56 -070035namespace scheduler {
Ana Krulec61f86db2018-11-19 14:16:35 +010036
Ady Abrahame3ed2f92020-01-06 17:01:28 -080037class LayerHistoryTest;
Ady Abraham8a82ba62020-01-17 12:43:17 -080038class LayerHistoryTestV2;
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070039class LayerInfo;
Ady Abraham8a82ba62020-01-17 12:43:17 -080040class LayerInfoV2;
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070041
Ana Krulec61f86db2018-11-19 14:16:35 +010042class LayerHistory {
43public:
Ady Abraham8a82ba62020-01-17 12:43:17 -080044 using LayerVoteType = RefreshRateConfigs::LayerVoteType;
45
Ady Abrahame3ed2f92020-01-06 17:01:28 -080046 virtual ~LayerHistory() = default;
Ana Krulec61f86db2018-11-19 14:16:35 +010047
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070048 // Layers are unregistered when the weak reference expires.
Ady Abraham8a82ba62020-01-17 12:43:17 -080049 virtual void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
50 LayerVoteType type) = 0;
51
52 // Sets the display size. Client is responsible for synchronization.
53 virtual void setDisplayArea(uint32_t displayArea) = 0;
Ady Abraham09bd3922019-04-08 10:44:56 -070054
Ady Abraham32efd542020-05-19 17:49:26 -070055 virtual void setConfigChangePending(bool pending) = 0;
56
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070057 // Marks the layer as active, and records the given state to its history.
Ady Abrahame3ed2f92020-01-06 17:01:28 -080058 virtual void record(Layer*, nsecs_t presentTime, nsecs_t now) = 0;
Ady Abrahama315ce72019-04-24 14:35:20 -070059
Ady Abraham8a82ba62020-01-17 12:43:17 -080060 using Summary = std::vector<RefreshRateConfigs::LayerRequirement>;
Ady Abraham09bd3922019-04-08 10:44:56 -070061
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070062 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
Ady Abrahame3ed2f92020-01-06 17:01:28 -080063 virtual Summary summarize(nsecs_t now) = 0;
Ady Abrahama9bf4ca2019-06-11 19:08:58 -070064
Ady Abrahame3ed2f92020-01-06 17:01:28 -080065 virtual void clear() = 0;
66};
67
68namespace impl {
69// Records per-layer history of scheduling-related information (primarily present time),
70// heuristically categorizes layers as active or inactive, and summarizes stats about
71// active layers (primarily maximum refresh rate). See go/content-fps-detection-in-scheduler.
72class LayerHistory : public android::scheduler::LayerHistory {
73public:
74 LayerHistory();
75 virtual ~LayerHistory();
76
77 // Layers are unregistered when the weak reference expires.
Ady Abraham8a82ba62020-01-17 12:43:17 -080078 void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
79 LayerVoteType type) override;
80
81 void setDisplayArea(uint32_t /*displayArea*/) override {}
Ady Abrahame3ed2f92020-01-06 17:01:28 -080082
Ady Abraham32efd542020-05-19 17:49:26 -070083 void setConfigChangePending(bool /*pending*/) override {}
84
Ady Abrahame3ed2f92020-01-06 17:01:28 -080085 // Marks the layer as active, and records the given state to its history.
86 void record(Layer*, nsecs_t presentTime, nsecs_t now) override;
87
88 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
89 android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override;
90
91 void clear() override;
Ana Krulec61f86db2018-11-19 14:16:35 +010092
93private:
Ady Abrahame3ed2f92020-01-06 17:01:28 -080094 friend class android::scheduler::LayerHistoryTest;
Dominik Laskowski49cea512019-11-12 14:13:23 -080095 friend TestableScheduler;
Ady Abraham09bd3922019-04-08 10:44:56 -070096
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -070097 using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfo>>;
98 using LayerInfos = std::vector<LayerPair>;
Ady Abraham09bd3922019-04-08 10:44:56 -070099
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700100 struct ActiveLayers {
101 LayerInfos& infos;
Ady Abrahamdec1a412020-01-24 10:23:50 -0800102 const size_t index;
Ady Abraham09bd3922019-04-08 10:44:56 -0700103
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700104 auto begin() { return infos.begin(); }
Ady Abrahamdec1a412020-01-24 10:23:50 -0800105 auto end() { return begin() + static_cast<long>(index); }
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700106 };
107
108 ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
109
110 // Iterates over layers in a single pass, swapping pairs such that active layers precede
111 // inactive layers, and inactive layers precede expired layers. Removes expired layers by
112 // truncating after inactive layers.
113 void partitionLayers(nsecs_t now) REQUIRES(mLock);
114
115 mutable std::mutex mLock;
116
117 // Partitioned such that active layers precede inactive layers. For fast lookup, the few active
118 // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
119 LayerInfos mLayerInfos GUARDED_BY(mLock);
Ady Abrahamdec1a412020-01-24 10:23:50 -0800120 size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
Ady Abraham8a82ba62020-01-17 12:43:17 -0800121
122 // Whether to emit systrace output and debug logs.
123 const bool mTraceEnabled;
124
125 // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
126 const bool mUseFrameRatePriority;
127};
128
129class LayerHistoryV2 : public android::scheduler::LayerHistory {
130public:
131 LayerHistoryV2();
132 virtual ~LayerHistoryV2();
133
134 // Layers are unregistered when the weak reference expires.
135 void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
136 LayerVoteType type) override;
137
138 // Sets the display size. Client is responsible for synchronization.
139 void setDisplayArea(uint32_t displayArea) override { mDisplayArea = displayArea; }
140
Ady Abraham32efd542020-05-19 17:49:26 -0700141 void setConfigChangePending(bool pending) override { mConfigChangePending = pending; }
142
Ady Abraham8a82ba62020-01-17 12:43:17 -0800143 // Marks the layer as active, and records the given state to its history.
144 void record(Layer*, nsecs_t presentTime, nsecs_t now) override;
145
146 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
147 android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override;
148
149 void clear() override;
150
151private:
152 friend android::scheduler::LayerHistoryTestV2;
153 friend TestableScheduler;
154
155 using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfoV2>>;
156 using LayerInfos = std::vector<LayerPair>;
157
158 struct ActiveLayers {
159 LayerInfos& infos;
160 const size_t index;
161
162 auto begin() { return infos.begin(); }
163 auto end() { return begin() + static_cast<long>(index); }
164 };
165
166 ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
167
168 // Iterates over layers in a single pass, swapping pairs such that active layers precede
169 // inactive layers, and inactive layers precede expired layers. Removes expired layers by
170 // truncating after inactive layers.
171 void partitionLayers(nsecs_t now) REQUIRES(mLock);
172
173 mutable std::mutex mLock;
174
175 // Partitioned such that active layers precede inactive layers. For fast lookup, the few active
176 // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
177 LayerInfos mLayerInfos GUARDED_BY(mLock);
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700178 size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
179
Ady Abraham8a82ba62020-01-17 12:43:17 -0800180 uint32_t mDisplayArea = 0;
181
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700182 // Whether to emit systrace output and debug logs.
183 const bool mTraceEnabled;
Ana Krulecc84d09b2019-11-02 23:10:29 +0100184
185 // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
186 const bool mUseFrameRatePriority;
Ady Abraham32efd542020-05-19 17:49:26 -0700187
188 // Whether a config change is in progress or not
189 std::atomic<bool> mConfigChangePending = false;
Ana Krulec61f86db2018-11-19 14:16:35 +0100190};
191
Ady Abrahame3ed2f92020-01-06 17:01:28 -0800192} // namespace impl
Ady Abraham09bd3922019-04-08 10:44:56 -0700193} // namespace scheduler
Dominik Laskowskif7a09ed2019-10-07 13:54:18 -0700194} // namespace android