• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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