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