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