• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 <cinttypes>
20 #include <cstdint>
21 #include <deque>
22 #include <mutex>
23 #include <numeric>
24 #include <string>
25 
26 #include <log/log.h>
27 
28 #include <utils/Mutex.h>
29 #include <utils/Timers.h>
30 
31 #include "SchedulerUtils.h"
32 
33 namespace android {
34 namespace scheduler {
35 
36 /*
37  * This class represents information about individial layers.
38  */
39 class LayerInfo {
40     /**
41      * Struct that keeps the information about the refresh rate for last
42      * HISTORY_SIZE frames. This is used to better determine the refresh rate
43      * for individual layers.
44      */
45     class RefreshRateHistory {
46     public:
RefreshRateHistory(nsecs_t minRefreshDuration)47         explicit RefreshRateHistory(nsecs_t minRefreshDuration)
48               : mMinRefreshDuration(minRefreshDuration) {}
insertRefreshRate(nsecs_t refreshRate)49         void insertRefreshRate(nsecs_t refreshRate) {
50             mElements.push_back(refreshRate);
51             if (mElements.size() > HISTORY_SIZE) {
52                 mElements.pop_front();
53             }
54         }
55 
getRefreshRateAvg()56         float getRefreshRateAvg() const {
57             nsecs_t refreshDuration = mMinRefreshDuration;
58             if (mElements.size() == HISTORY_SIZE) {
59                 refreshDuration = scheduler::calculate_mean(mElements);
60             }
61 
62             return 1e9f / refreshDuration;
63         }
clearHistory()64         void clearHistory() { mElements.clear(); }
65 
66     private:
67         std::deque<nsecs_t> mElements;
68         static constexpr size_t HISTORY_SIZE = 30;
69         const nsecs_t mMinRefreshDuration;
70     };
71 
72     /**
73      * Struct that keeps the information about the present time for last
74      * HISTORY_SIZE frames. This is used to better determine whether the given layer
75      * is still relevant and it's refresh rate should be considered.
76      */
77     class PresentTimeHistory {
78     public:
insertPresentTime(nsecs_t presentTime)79         void insertPresentTime(nsecs_t presentTime) {
80             mElements.push_back(presentTime);
81             if (mElements.size() > HISTORY_SIZE) {
82                 mElements.pop_front();
83             }
84         }
85 
86         // Checks whether the present time that was inserted HISTORY_SIZE ago is within a
87         // certain threshold: TIME_EPSILON_NS.
isRelevant()88         bool isRelevant() const {
89             const int64_t obsoleteEpsilon = systemTime() - scheduler::TIME_EPSILON_NS.count();
90             // The layer had to publish at least HISTORY_SIZE of updates, and the first
91             // update should not be older than TIME_EPSILON_NS nanoseconds.
92             if (mElements.size() == HISTORY_SIZE &&
93                 mElements.at(HISTORY_SIZE - 1) > obsoleteEpsilon) {
94                 return true;
95             }
96             return false;
97         }
98 
clearHistory()99         void clearHistory() { mElements.clear(); }
100 
101     private:
102         std::deque<nsecs_t> mElements;
103         static constexpr size_t HISTORY_SIZE = 10;
104     };
105 
106 public:
107     LayerInfo(const std::string name, float maxRefreshRate);
108     ~LayerInfo();
109 
110     LayerInfo(const LayerInfo&) = delete;
111     LayerInfo& operator=(const LayerInfo&) = delete;
112 
113     // Records the last requested oresent time. It also stores information about when
114     // the layer was last updated. If the present time is farther in the future than the
115     // updated time, the updated time is the present time.
116     void setLastPresentTime(nsecs_t lastPresentTime);
117 
setHDRContent(bool isHdr)118     void setHDRContent(bool isHdr) {
119         std::lock_guard lock(mLock);
120         mIsHDR = isHdr;
121     }
122 
setVisibility(bool visible)123     void setVisibility(bool visible) {
124         std::lock_guard lock(mLock);
125         mIsVisible = visible;
126     }
127 
128     // Checks the present time history to see whether the layer is relevant.
isRecentlyActive()129     bool isRecentlyActive() const {
130         std::lock_guard lock(mLock);
131         return mPresentTimeHistory.isRelevant();
132     }
133 
134     // Calculate the average refresh rate.
getDesiredRefreshRate()135     float getDesiredRefreshRate() const {
136         std::lock_guard lock(mLock);
137         return mRefreshRateHistory.getRefreshRateAvg();
138     }
139 
getHDRContent()140     bool getHDRContent() {
141         std::lock_guard lock(mLock);
142         return mIsHDR;
143     }
144 
isVisible()145     bool isVisible() {
146         std::lock_guard lock(mLock);
147         return mIsVisible;
148     }
149 
150     // Return the last updated time. If the present time is farther in the future than the
151     // updated time, the updated time is the present time.
getLastUpdatedTime()152     nsecs_t getLastUpdatedTime() {
153         std::lock_guard lock(mLock);
154         return mLastUpdatedTime;
155     }
156 
getName()157     std::string getName() const { return mName; }
158 
clearHistory()159     void clearHistory() {
160         std::lock_guard lock(mLock);
161         mRefreshRateHistory.clearHistory();
162         mPresentTimeHistory.clearHistory();
163     }
164 
165 private:
166     const std::string mName;
167     const nsecs_t mMinRefreshDuration;
168     mutable std::mutex mLock;
169     nsecs_t mLastUpdatedTime GUARDED_BY(mLock) = 0;
170     nsecs_t mLastPresentTime GUARDED_BY(mLock) = 0;
171     RefreshRateHistory mRefreshRateHistory GUARDED_BY(mLock);
172     PresentTimeHistory mPresentTimeHistory GUARDED_BY(mLock);
173     bool mIsHDR GUARDED_BY(mLock) = false;
174     bool mIsVisible GUARDED_BY(mLock) = false;
175 };
176 
177 } // namespace scheduler
178 } // namespace android