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 "RefreshRateConfigs.h" 31 32 namespace android { 33 34 class Layer; 35 36 namespace scheduler { 37 38 class LayerInfo; 39 40 class LayerHistory { 41 public: 42 using LayerVoteType = RefreshRateConfigs::LayerVoteType; 43 44 LayerHistory(); 45 ~LayerHistory(); 46 47 // Layers are unregistered when the weak reference expires. 48 void registerLayer(Layer*, LayerVoteType type); 49 50 // Sets the display size. Client is responsible for synchronization. setDisplayArea(uint32_t displayArea)51 void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; } 52 53 // Sets whether a mode change is pending to be applied setModeChangePending(bool pending)54 void setModeChangePending(bool pending) { mModeChangePending = pending; } 55 56 // Represents which layer activity is recorded 57 enum class LayerUpdateType { 58 Buffer, // a new buffer queued 59 AnimationTX, // a new transaction with eAnimation flag set 60 SetFrameRate, // setFrameRate API was called 61 }; 62 63 // Marks the layer as active, and records the given state to its history. 64 void record(Layer*, nsecs_t presentTime, nsecs_t now, LayerUpdateType updateType); 65 66 using Summary = std::vector<RefreshRateConfigs::LayerRequirement>; 67 68 // Rebuilds sets of active/inactive layers, and accumulates stats for active layers. 69 Summary summarize(const RefreshRateConfigs&, nsecs_t now); 70 71 void clear(); 72 73 void deregisterLayer(Layer*); 74 std::string dump() const; 75 76 // return the frames per second of the layer with the given sequence id. 77 float getLayerFramerate(nsecs_t now, int32_t id) const; 78 79 private: 80 friend class LayerHistoryTest; 81 friend class TestableScheduler; 82 83 using LayerPair = std::pair<Layer*, std::unique_ptr<LayerInfo>>; 84 // keyed by id as returned from Layer::getSequence() 85 using LayerInfos = std::unordered_map<int32_t, LayerPair>; 86 87 // Iterates over layers maps moving all active layers to mActiveLayerInfos and all inactive 88 // layers to mInactiveLayerInfos. 89 // worst case time complexity is O(2 * inactive + active) 90 void partitionLayers(nsecs_t now) REQUIRES(mLock); 91 92 enum class LayerStatus { 93 NotFound, 94 LayerInActiveMap, 95 LayerInInactiveMap, 96 }; 97 98 // looks up a layer by sequence id in both layerInfo maps. 99 // The first element indicates if and where the item was found 100 std::pair<LayerStatus, LayerPair*> findLayer(int32_t id) REQUIRES(mLock); 101 findLayer(int32_t id)102 std::pair<LayerStatus, const LayerPair*> findLayer(int32_t id) const REQUIRES(mLock) { 103 return const_cast<LayerHistory*>(this)->findLayer(id); 104 } 105 106 mutable std::mutex mLock; 107 108 // Partitioned into two maps to facility two kinds of retrieval: 109 // 1. retrieval of a layer by id (attempt lookup in both maps) 110 // 2. retrieval of all active layers (iterate that map) 111 // The partitioning is allowed to become out of date but calling partitionLayers refreshes the 112 // validity of each map. 113 LayerInfos mActiveLayerInfos GUARDED_BY(mLock); 114 LayerInfos mInactiveLayerInfos GUARDED_BY(mLock); 115 116 uint32_t mDisplayArea = 0; 117 118 // Whether to emit systrace output and debug logs. 119 const bool mTraceEnabled; 120 121 // Whether to use priority sent from WindowManager to determine the relevancy of the layer. 122 const bool mUseFrameRatePriority; 123 124 // Whether a mode change is in progress or not 125 std::atomic<bool> mModeChangePending = false; 126 }; 127 128 } // namespace scheduler 129 } // namespace android 130