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 <timestatsproto/TimeStatsHelper.h>
20 #include <timestatsproto/TimeStatsProtoHeader.h>
21 
22 #include <hardware/hwcomposer_defs.h>
23 
24 #include <ui/FenceTime.h>
25 
26 #include <utils/String16.h>
27 #include <utils/Vector.h>
28 
29 #include <deque>
30 #include <mutex>
31 #include <optional>
32 #include <unordered_map>
33 
34 using namespace android::surfaceflinger;
35 
36 namespace android {
37 
38 class TimeStats {
39 public:
40     virtual ~TimeStats() = default;
41 
42     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
43     virtual bool isEnabled() = 0;
44     virtual std::string miniDump() = 0;
45 
46     virtual void incrementTotalFrames() = 0;
47     virtual void incrementMissedFrames() = 0;
48     virtual void incrementClientCompositionFrames() = 0;
49 
50     virtual void setPostTime(int32_t layerID, uint64_t frameNumber, const std::string& layerName,
51                              nsecs_t postTime) = 0;
52     virtual void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) = 0;
53     virtual void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) = 0;
54     virtual void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) = 0;
55     virtual void setAcquireFence(int32_t layerID, uint64_t frameNumber,
56                                  const std::shared_ptr<FenceTime>& acquireFence) = 0;
57     virtual void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) = 0;
58     virtual void setPresentFence(int32_t layerID, uint64_t frameNumber,
59                                  const std::shared_ptr<FenceTime>& presentFence) = 0;
60     // Clean up the layer record
61     virtual void onDestroy(int32_t layerID) = 0;
62     // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
63     virtual void removeTimeRecord(int32_t layerID, uint64_t frameNumber) = 0;
64 
65     virtual void setPowerMode(int32_t powerMode) = 0;
66     // Source of truth is RefrehRateStats.
67     virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
68     virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
69 };
70 
71 namespace impl {
72 
73 class TimeStats : public android::TimeStats {
74     struct FrameTime {
75         uint64_t frameNumber = 0;
76         nsecs_t postTime = 0;
77         nsecs_t latchTime = 0;
78         nsecs_t acquireTime = 0;
79         nsecs_t desiredTime = 0;
80         nsecs_t presentTime = 0;
81     };
82 
83     struct TimeRecord {
84         bool ready = false;
85         FrameTime frameTime;
86         std::shared_ptr<FenceTime> acquireFence;
87         std::shared_ptr<FenceTime> presentFence;
88     };
89 
90     struct LayerRecord {
91         std::string layerName;
92         // This is the index in timeRecords, at which the timestamps for that
93         // specific frame are still not fully received. This is not waiting for
94         // fences to signal, but rather waiting to receive those fences/timestamps.
95         int32_t waitData = -1;
96         uint32_t droppedFrames = 0;
97         TimeRecord prevTimeRecord;
98         std::deque<TimeRecord> timeRecords;
99     };
100 
101     struct PowerTime {
102         int32_t powerMode = HWC_POWER_MODE_OFF;
103         nsecs_t prevTime = 0;
104     };
105 
106     struct GlobalRecord {
107         nsecs_t prevPresentTime = 0;
108         std::deque<std::shared_ptr<FenceTime>> presentFences;
109     };
110 
111 public:
112     TimeStats() = default;
113 
114     void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override;
115     bool isEnabled() override;
116     std::string miniDump() override;
117 
118     void incrementTotalFrames() override;
119     void incrementMissedFrames() override;
120     void incrementClientCompositionFrames() override;
121 
122     void setPostTime(int32_t layerID, uint64_t frameNumber, const std::string& layerName,
123                      nsecs_t postTime) override;
124     void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) override;
125     void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) override;
126     void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) override;
127     void setAcquireFence(int32_t layerID, uint64_t frameNumber,
128                          const std::shared_ptr<FenceTime>& acquireFence) override;
129     void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) override;
130     void setPresentFence(int32_t layerID, uint64_t frameNumber,
131                          const std::shared_ptr<FenceTime>& presentFence) override;
132     // Clean up the layer record
133     void onDestroy(int32_t layerID) override;
134     // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
135     void removeTimeRecord(int32_t layerID, uint64_t frameNumber) override;
136 
137     void setPowerMode(int32_t powerMode) override;
138     // Source of truth is RefrehRateStats.
139     void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
140     void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
141 
142     static const size_t MAX_NUM_TIME_RECORDS = 64;
143 
144 private:
145     bool recordReadyLocked(int32_t layerID, TimeRecord* timeRecord);
146     void flushAvailableRecordsToStatsLocked(int32_t layerID);
147     void flushPowerTimeLocked();
148     void flushAvailableGlobalRecordsToStatsLocked();
149 
150     void enable();
151     void disable();
152     void clear();
153     void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result);
154 
155     std::atomic<bool> mEnabled = false;
156     std::mutex mMutex;
157     TimeStatsHelper::TimeStatsGlobal mTimeStats;
158     // Hashmap for LayerRecord with layerID as the hash key
159     std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
160     PowerTime mPowerTime;
161     GlobalRecord mGlobalRecord;
162 
163     static const size_t MAX_NUM_LAYER_RECORDS = 200;
164 };
165 
166 } // namespace impl
167 
168 } // namespace android
169