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