xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/LayerHistory.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 <map>
24 #include <memory>
25 #include <mutex>
26 #include <string>
27 #include <utility>
28 #include <vector>
29 
30 #include "EventThread.h"
31 
32 #include "FrameRateCompatibility.h"
33 #include "RefreshRateSelector.h"
34 
35 namespace android {
36 
37 class Layer;
38 
39 namespace scheduler {
40 
41 class LayerInfo;
42 struct LayerProps;
43 
44 class LayerHistory {
45 public:
46     using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
47     using LayerVoteType = RefreshRateSelector::LayerVoteType;
48     static constexpr std::chrono::nanoseconds kMaxPeriodForHistory = 1s;
49 
50     LayerHistory();
51     ~LayerHistory();
52 
53     // Layers are unregistered when the weak reference expires.
54     void registerLayer(Layer*, bool contentDetectionEnabled,
55                        FrameRateCompatibility frameRateCompatibility);
56 
57     // Sets the display size. Client is responsible for synchronization.
setDisplayArea(uint32_t displayArea)58     void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }
59 
60     // Sets whether a mode change is pending to be applied
setModeChangePending(bool pending)61     void setModeChangePending(bool pending) { mModeChangePending = pending; }
62 
63     // Represents which layer activity is recorded
64     enum class LayerUpdateType {
65         Buffer,       // a new buffer queued
66         AnimationTX,  // a new transaction with eAnimation flag set
67         SetFrameRate, // setFrameRate API was called
68     };
69 
70     // Marks the layer as active, and records the given state to its history.
71     void record(int32_t id, const LayerProps& props, nsecs_t presentTime, nsecs_t now,
72                 LayerUpdateType updateType);
73 
74     // Updates the default frame rate compatibility which takes effect when the app
75     // does not set a preference for refresh rate.
76     void setDefaultFrameRateCompatibility(int32_t id, FrameRateCompatibility frameRateCompatibility,
77                                           bool contentDetectionEnabled);
78     void setLayerProperties(int32_t id, const LayerProps&);
79     using Summary = std::vector<RefreshRateSelector::LayerRequirement>;
80 
81     // Rebuilds sets of active/inactive layers, and accumulates stats for active layers.
82     Summary summarize(const RefreshRateSelector&, nsecs_t now);
83 
84     void clear();
85 
86     void deregisterLayer(Layer*);
87     std::string dump() const;
88 
89     // return the frames per second of the layer with the given sequence id.
90     float getLayerFramerate(nsecs_t now, int32_t id) const;
91 
92     bool isSmallDirtyArea(uint32_t dirtyArea, float threshold) const;
93 
94     // Updates the frame rate override set by game mode intervention
95     void updateGameModeFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
96 
97     // Updates the frame rate override set by game default frame rate
98     void updateGameDefaultFrameRateOverride(FrameRateOverride frameRateOverride) EXCLUDES(mLock);
99 
100     std::pair<Fps, Fps> getGameFrameRateOverride(uid_t uid) const EXCLUDES(mLock);
101     std::pair<Fps, Fps> getGameFrameRateOverrideLocked(uid_t uid) const REQUIRES(mLock);
102 
103 private:
104     friend class LayerHistoryTest;
105     friend class LayerHistoryIntegrationTest;
106     friend class TestableScheduler;
107 
108     using LayerPair = std::pair<Layer*, std::unique_ptr<LayerInfo>>;
109     // keyed by id as returned from Layer::getSequence()
110     using LayerInfos = std::unordered_map<int32_t, LayerPair>;
111 
112     std::string dumpGameFrameRateOverridesLocked() const REQUIRES(mLock);
113 
114     // Iterates over layers maps moving all active layers to mActiveLayerInfos and all inactive
115     // layers to mInactiveLayerInfos. Layer's active state is determined by multiple factors
116     // such as update activity, visibility, and frame rate vote.
117     // worst case time complexity is O(2 * inactive + active)
118     // now: the current time (system time) when calling the method
119     // isVrrDevice: true if the device has DisplayMode with VrrConfig specified.
120     void partitionLayers(nsecs_t now, bool isVrrDevice) REQUIRES(mLock);
121 
122     enum class LayerStatus {
123         NotFound,
124         LayerInActiveMap,
125         LayerInInactiveMap,
126     };
127 
128     // looks up a layer by sequence id in both layerInfo maps.
129     // The first element indicates if and where the item was found
130     std::pair<LayerStatus, LayerPair*> findLayer(int32_t id) REQUIRES(mLock);
131 
findLayer(int32_t id)132     std::pair<LayerStatus, const LayerPair*> findLayer(int32_t id) const REQUIRES(mLock) {
133         return const_cast<LayerHistory*>(this)->findLayer(id);
134     }
135 
136     mutable std::mutex mLock;
137 
138     // Partitioned into two maps to facility two kinds of retrieval:
139     // 1. retrieval of a layer by id (attempt lookup in both maps)
140     // 2. retrieval of all active layers (iterate that map)
141     // The partitioning is allowed to become out of date but calling partitionLayers refreshes the
142     // validity of each map.
143     LayerInfos mActiveLayerInfos GUARDED_BY(mLock);
144     LayerInfos mInactiveLayerInfos GUARDED_BY(mLock);
145 
146     uint32_t mDisplayArea = 0;
147 
148     // Whether to emit systrace output and debug logs.
149     const bool mTraceEnabled;
150 
151     // Whether to use priority sent from WindowManager to determine the relevancy of the layer.
152     const bool mUseFrameRatePriority;
153 
154     // Whether a mode change is in progress or not
155     std::atomic<bool> mModeChangePending = false;
156 
157     // A list to look up the game frame rate overrides
158     // Each entry includes:
159     // 1. the uid of the app
160     // 2. a pair of game mode intervention frame frame and game default frame rate override
161     // set to 0.0 if there is no such override
162     std::map<uid_t, std::pair<Fps, Fps>> mGameFrameRateOverride GUARDED_BY(mLock);
163 };
164 
165 } // namespace scheduler
166 } // namespace android
167