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