1 /*
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 
19 #include <android-base/thread_annotations.h>
20 #include <utils/RefBase.h>
21 #include <utils/Timers.h>
22 
23 #include <memory>
24 #include <mutex>
25 #include <utility>
26 #include <vector>
27 
28 #include "RefreshRateConfigs.h"
29 
30 namespace android {
31 
32 class Layer;
33 class TestableScheduler;
34 
35 namespace scheduler {
36 
37 class LayerHistoryTest;
38 class LayerHistoryTestV2;
39 class LayerInfo;
40 class LayerInfoV2;
41 
42 class LayerHistory {
43 public:
44     using LayerVoteType = RefreshRateConfigs::LayerVoteType;
45 
46     virtual ~LayerHistory() = default;
47 
48     // Layers are unregistered when the weak reference expires.
49     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;
54 
55     // Sets whether a config change is pending to be applied
56     virtual void setConfigChangePending(bool pending) = 0;
57 
58     // Represents which layer activity is recorded
59     enum class LayerUpdateType {
60         Buffer,       // a new buffer queued
61         AnimationTX,  // a new transaction with eAnimation flag set
62         SetFrameRate, // setFrameRate API was called
63     };
64 
65     // Marks the layer as active, and records the given state to its history.
66     virtual void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) = 0;
67 
68     using Summary = std::vector<RefreshRateConfigs::LayerRequirement>;
69 
70     // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
71     virtual Summary summarize(nsecs_t now) = 0;
72 
73     virtual void clear() = 0;
74 };
75 
76 namespace impl {
77 // Records per-layer history of scheduling-related information (primarily present time),
78 // heuristically categorizes layers as active or inactive, and summarizes stats about
79 // active layers (primarily maximum refresh rate). See go/content-fps-detection-in-scheduler.
80 class LayerHistory : public android::scheduler::LayerHistory {
81 public:
82     LayerHistory();
83     virtual ~LayerHistory();
84 
85     // Layers are unregistered when the weak reference expires.
86     void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
87                        LayerVoteType type) override;
88 
setDisplayArea(uint32_t)89     void setDisplayArea(uint32_t /*displayArea*/) override {}
90 
setConfigChangePending(bool)91     void setConfigChangePending(bool /*pending*/) override {}
92 
93     // Marks the layer as active, and records the given state to its history.
94     void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override;
95 
96     // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
97     android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override;
98 
99     void clear() override;
100 
101 private:
102     friend class android::scheduler::LayerHistoryTest;
103     friend TestableScheduler;
104 
105     using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfo>>;
106     using LayerInfos = std::vector<LayerPair>;
107 
108     struct ActiveLayers {
109         LayerInfos& infos;
110         const size_t index;
111 
beginActiveLayers112         auto begin() { return infos.begin(); }
endActiveLayers113         auto end() { return begin() + static_cast<long>(index); }
114     };
115 
activeLayers()116     ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
117 
118     // Iterates over layers in a single pass, swapping pairs such that active layers precede
119     // inactive layers, and inactive layers precede expired layers. Removes expired layers by
120     // truncating after inactive layers.
121     void partitionLayers(nsecs_t now) REQUIRES(mLock);
122 
123     mutable std::mutex mLock;
124 
125     // Partitioned such that active layers precede inactive layers. For fast lookup, the few active
126     // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
127     LayerInfos mLayerInfos GUARDED_BY(mLock);
128     size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
129 
130     // Whether to emit systrace output and debug logs.
131     const bool mTraceEnabled;
132 
133     // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
134     const bool mUseFrameRatePriority;
135 };
136 
137 class LayerHistoryV2 : public android::scheduler::LayerHistory {
138 public:
139     LayerHistoryV2(const scheduler::RefreshRateConfigs&);
140     virtual ~LayerHistoryV2();
141 
142     // Layers are unregistered when the weak reference expires.
143     void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate,
144                        LayerVoteType type) override;
145 
146     // Sets the display size. Client is responsible for synchronization.
setDisplayArea(uint32_t displayArea)147     void setDisplayArea(uint32_t displayArea) override { mDisplayArea = displayArea; }
148 
setConfigChangePending(bool pending)149     void setConfigChangePending(bool pending) override { mConfigChangePending = pending; }
150 
151     // Marks the layer as active, and records the given state to its history.
152     void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override;
153 
154     // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
155     android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override;
156 
157     void clear() override;
158 
159 private:
160     friend android::scheduler::LayerHistoryTestV2;
161     friend TestableScheduler;
162 
163     using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfoV2>>;
164     using LayerInfos = std::vector<LayerPair>;
165 
166     struct ActiveLayers {
167         LayerInfos& infos;
168         const size_t index;
169 
beginActiveLayers170         auto begin() { return infos.begin(); }
endActiveLayers171         auto end() { return begin() + static_cast<long>(index); }
172     };
173 
activeLayers()174     ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; }
175 
176     // Iterates over layers in a single pass, swapping pairs such that active layers precede
177     // inactive layers, and inactive layers precede expired layers. Removes expired layers by
178     // truncating after inactive layers.
179     void partitionLayers(nsecs_t now) REQUIRES(mLock);
180 
181     mutable std::mutex mLock;
182 
183     // Partitioned such that active layers precede inactive layers. For fast lookup, the few active
184     // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache.
185     LayerInfos mLayerInfos GUARDED_BY(mLock);
186     size_t mActiveLayersEnd GUARDED_BY(mLock) = 0;
187 
188     uint32_t mDisplayArea = 0;
189 
190     // Whether to emit systrace output and debug logs.
191     const bool mTraceEnabled;
192 
193     // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
194     const bool mUseFrameRatePriority;
195 
196     // Whether a config change is in progress or not
197     std::atomic<bool> mConfigChangePending = false;
198 };
199 
200 } // namespace impl
201 } // namespace scheduler
202 } // namespace android
203