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 <memory> 24 #include <mutex> 25 #include <utility> 26 #include <vector> 27 28 #include "RefreshRateConfigs.h" 29 30 namespace android { 31 32 class Layer; 33 class TestableScheduler; 34 35 namespace scheduler { 36 37 class LayerHistoryTest; 38 class LayerHistoryTestV2; 39 class LayerInfo; 40 class LayerInfoV2; 41 42 class LayerHistory { 43 public: 44 using LayerVoteType = RefreshRateConfigs::LayerVoteType; 45 46 virtual ~LayerHistory() = default; 47 48 // Layers are unregistered when the weak reference expires. 49 virtual void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate, 50 LayerVoteType type) = 0; 51 52 // Sets the display size. Client is responsible for synchronization. 53 virtual void setDisplayArea(uint32_t displayArea) = 0; 54 55 // Sets whether a config change is pending to be applied 56 virtual void setConfigChangePending(bool pending) = 0; 57 58 // Represents which layer activity is recorded 59 enum class LayerUpdateType { 60 Buffer, // a new buffer queued 61 AnimationTX, // a new transaction with eAnimation flag set 62 SetFrameRate, // setFrameRate API was called 63 }; 64 65 // Marks the layer as active, and records the given state to its history. 66 virtual void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) = 0; 67 68 using Summary = std::vector<RefreshRateConfigs::LayerRequirement>; 69 70 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. 71 virtual Summary summarize(nsecs_t now) = 0; 72 73 virtual void clear() = 0; 74 }; 75 76 namespace impl { 77 // Records per-layer history of scheduling-related information (primarily present time), 78 // heuristically categorizes layers as active or inactive, and summarizes stats about 79 // active layers (primarily maximum refresh rate). See go/content-fps-detection-in-scheduler. 80 class LayerHistory : public android::scheduler::LayerHistory { 81 public: 82 LayerHistory(); 83 virtual ~LayerHistory(); 84 85 // Layers are unregistered when the weak reference expires. 86 void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate, 87 LayerVoteType type) override; 88 setDisplayArea(uint32_t)89 void setDisplayArea(uint32_t /*displayArea*/) override {} 90 setConfigChangePending(bool)91 void setConfigChangePending(bool /*pending*/) override {} 92 93 // Marks the layer as active, and records the given state to its history. 94 void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override; 95 96 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. 97 android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override; 98 99 void clear() override; 100 101 private: 102 friend class android::scheduler::LayerHistoryTest; 103 friend TestableScheduler; 104 105 using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfo>>; 106 using LayerInfos = std::vector<LayerPair>; 107 108 struct ActiveLayers { 109 LayerInfos& infos; 110 const size_t index; 111 beginActiveLayers112 auto begin() { return infos.begin(); } endActiveLayers113 auto end() { return begin() + static_cast<long>(index); } 114 }; 115 activeLayers()116 ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; } 117 118 // Iterates over layers in a single pass, swapping pairs such that active layers precede 119 // inactive layers, and inactive layers precede expired layers. Removes expired layers by 120 // truncating after inactive layers. 121 void partitionLayers(nsecs_t now) REQUIRES(mLock); 122 123 mutable std::mutex mLock; 124 125 // Partitioned such that active layers precede inactive layers. For fast lookup, the few active 126 // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache. 127 LayerInfos mLayerInfos GUARDED_BY(mLock); 128 size_t mActiveLayersEnd GUARDED_BY(mLock) = 0; 129 130 // Whether to emit systrace output and debug logs. 131 const bool mTraceEnabled; 132 133 // Whether to use priority sent from WindowManager to determine the relevancy of the layer. 134 const bool mUseFrameRatePriority; 135 }; 136 137 class LayerHistoryV2 : public android::scheduler::LayerHistory { 138 public: 139 LayerHistoryV2(const scheduler::RefreshRateConfigs&); 140 virtual ~LayerHistoryV2(); 141 142 // Layers are unregistered when the weak reference expires. 143 void registerLayer(Layer*, float lowRefreshRate, float highRefreshRate, 144 LayerVoteType type) override; 145 146 // Sets the display size. Client is responsible for synchronization. setDisplayArea(uint32_t displayArea)147 void setDisplayArea(uint32_t displayArea) override { mDisplayArea = displayArea; } 148 setConfigChangePending(bool pending)149 void setConfigChangePending(bool pending) override { mConfigChangePending = pending; } 150 151 // Marks the layer as active, and records the given state to its history. 152 void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType) override; 153 154 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. 155 android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override; 156 157 void clear() override; 158 159 private: 160 friend android::scheduler::LayerHistoryTestV2; 161 friend TestableScheduler; 162 163 using LayerPair = std::pair<wp<Layer>, std::unique_ptr<LayerInfoV2>>; 164 using LayerInfos = std::vector<LayerPair>; 165 166 struct ActiveLayers { 167 LayerInfos& infos; 168 const size_t index; 169 beginActiveLayers170 auto begin() { return infos.begin(); } endActiveLayers171 auto end() { return begin() + static_cast<long>(index); } 172 }; 173 activeLayers()174 ActiveLayers activeLayers() REQUIRES(mLock) { return {mLayerInfos, mActiveLayersEnd}; } 175 176 // Iterates over layers in a single pass, swapping pairs such that active layers precede 177 // inactive layers, and inactive layers precede expired layers. Removes expired layers by 178 // truncating after inactive layers. 179 void partitionLayers(nsecs_t now) REQUIRES(mLock); 180 181 mutable std::mutex mLock; 182 183 // Partitioned such that active layers precede inactive layers. For fast lookup, the few active 184 // layers are at the front, and weak pointers are stored in contiguous memory to hit the cache. 185 LayerInfos mLayerInfos GUARDED_BY(mLock); 186 size_t mActiveLayersEnd GUARDED_BY(mLock) = 0; 187 188 uint32_t mDisplayArea = 0; 189 190 // Whether to emit systrace output and debug logs. 191 const bool mTraceEnabled; 192 193 // Whether to use priority sent from WindowManager to determine the relevancy of the layer. 194 const bool mUseFrameRatePriority; 195 196 // Whether a config change is in progress or not 197 std::atomic<bool> mConfigChangePending = false; 198 }; 199 200 } // namespace impl 201 } // namespace scheduler 202 } // namespace android 203