blob: 470137a43167bb5ed510d8d495f597e050133a39 [file] [log] [blame]
Yiwei Zhang0102ad22018-05-02 17:37:17 -07001/*
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
Mikael Pessa2e1608f2019-07-19 11:25:35 -070019#include <hardware/hwcomposer_defs.h>
20#include <perfetto/trace/android/graphics_frame_event.pbzero.h>
21#include <perfetto/tracing.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070022#include <timestatsproto/TimeStatsHelper.h>
23#include <timestatsproto/TimeStatsProtoHeader.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070024#include <ui/FenceTime.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070025#include <utils/String16.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070026#include <utils/Vector.h>
27
Yiwei Zhangc5f2c452018-05-08 16:31:56 -070028#include <deque>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070029#include <mutex>
Yiwei Zhang8a4015c2018-05-08 16:03:47 -070030#include <optional>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070031#include <unordered_map>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070032
33using namespace android::surfaceflinger;
34
35namespace android {
Yiwei Zhang0102ad22018-05-02 17:37:17 -070036
37class TimeStats {
Alec Mourifb571ea2019-01-24 18:42:10 -080038public:
Mikael Pessa2e1608f2019-07-19 11:25:35 -070039 using FrameEvent = perfetto::protos::pbzero::GraphicsFrameEvent;
40
Alec Mourifb571ea2019-01-24 18:42:10 -080041 virtual ~TimeStats() = default;
42
Mikael Pessa2e1608f2019-07-19 11:25:35 -070043 // Sets up the perfetto tracing backend and data source.
44 virtual void initializeTracing() = 0;
45 // Registers the data source with the perfetto backend. Called as part of initializeTracing()
46 // and should not be called manually outside of tests. Public to allow for substituting a
47 // perfetto::kInProcessBackend in tests.
48 virtual void registerTracingDataSource() = 0;
49 // Starts tracking a new layer for tracing. Needs to be called once before traceTimestamp() or
50 // traceFence() for each layer.
51 virtual void traceNewLayer(int32_t layerID, const std::string& layerName) = 0;
52 // Creates a trace point at the timestamp provided.
53 virtual void traceTimestamp(int32_t layerID, uint64_t bufferID, uint64_t frameNumber,
54 nsecs_t timestamp, FrameEvent::BufferEventType type,
55 nsecs_t duration = 0) = 0;
56 // Creates a trace point after the provided fence has been signalled. If a startTime is provided
57 // the trace will have be timestamped from startTime until fence signalling time. If no
58 // startTime is provided, a durationless trace point will be created timestamped at fence
59 // signalling time. If the fence hasn't signalled yet, the trace point will be created the next
60 // time after signalling a trace call for this buffer occurs.
61 virtual void traceFence(int32_t layerID, uint64_t bufferID, uint64_t frameNumber,
62 const std::shared_ptr<FenceTime>& fence,
63 FrameEvent::BufferEventType type, nsecs_t startTime = 0) = 0;
64
Alec Mourifb571ea2019-01-24 18:42:10 -080065 virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
66 virtual bool isEnabled() = 0;
Oliver Nguyenf3b7c9c2019-05-07 13:28:07 -070067 virtual std::string miniDump() = 0;
Alec Mourifb571ea2019-01-24 18:42:10 -080068
69 virtual void incrementTotalFrames() = 0;
70 virtual void incrementMissedFrames() = 0;
71 virtual void incrementClientCompositionFrames() = 0;
72
73 virtual void setPostTime(int32_t layerID, uint64_t frameNumber, const std::string& layerName,
74 nsecs_t postTime) = 0;
75 virtual void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) = 0;
76 virtual void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) = 0;
77 virtual void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) = 0;
78 virtual void setAcquireFence(int32_t layerID, uint64_t frameNumber,
79 const std::shared_ptr<FenceTime>& acquireFence) = 0;
80 virtual void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) = 0;
81 virtual void setPresentFence(int32_t layerID, uint64_t frameNumber,
82 const std::shared_ptr<FenceTime>& presentFence) = 0;
83 // Clean up the layer record
84 virtual void onDestroy(int32_t layerID) = 0;
85 // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
86 virtual void removeTimeRecord(int32_t layerID, uint64_t frameNumber) = 0;
87
88 virtual void setPowerMode(int32_t powerMode) = 0;
89 // Source of truth is RefrehRateStats.
90 virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
91 virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
Mikael Pessa2e1608f2019-07-19 11:25:35 -070092
93 static constexpr char kTimeStatsDataSource[] = "android.surfaceflinger.timestats";
94
95 // The maximum amount of time a fence has to signal before it is discarded.
96 // Used to avoid fence's from previous traces generating new trace points in later ones.
97 // Public for testing.
98 static constexpr nsecs_t kFenceSignallingDeadline = 60'000'000'000; // 60 seconds
Alec Mourifb571ea2019-01-24 18:42:10 -080099};
100
101namespace impl {
102
103class TimeStats : public android::TimeStats {
Yiwei Zhangcf50ab92018-06-14 10:50:12 -0700104 struct FrameTime {
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700105 uint64_t frameNumber = 0;
106 nsecs_t postTime = 0;
107 nsecs_t latchTime = 0;
108 nsecs_t acquireTime = 0;
109 nsecs_t desiredTime = 0;
110 nsecs_t presentTime = 0;
Yiwei Zhangcf50ab92018-06-14 10:50:12 -0700111 };
112
113 struct TimeRecord {
114 bool ready = false;
115 FrameTime frameTime;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700116 std::shared_ptr<FenceTime> acquireFence;
117 std::shared_ptr<FenceTime> presentFence;
118 };
119
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700120 struct PendingFence {
121 uint64_t frameNumber;
122 FrameEvent::BufferEventType type;
123 std::shared_ptr<FenceTime> fence;
124 nsecs_t startTime;
125 };
126
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700127 struct LayerRecord {
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700128 std::string layerName;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700129 // This is the index in timeRecords, at which the timestamps for that
130 // specific frame are still not fully received. This is not waiting for
131 // fences to signal, but rather waiting to receive those fences/timestamps.
132 int32_t waitData = -1;
Yiwei Zhangeaeea062018-06-28 14:46:51 -0700133 uint32_t droppedFrames = 0;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700134 TimeRecord prevTimeRecord;
Yiwei Zhangc5f2c452018-05-08 16:31:56 -0700135 std::deque<TimeRecord> timeRecords;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700136 };
137
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700138 struct TraceRecord {
139 std::string layerName;
140 using BufferID = uint64_t;
141 std::unordered_map<BufferID, std::vector<PendingFence>> pendingFences;
142 };
143
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700144 struct PowerTime {
145 int32_t powerMode = HWC_POWER_MODE_OFF;
146 nsecs_t prevTime = 0;
147 };
148
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700149 struct GlobalRecord {
150 nsecs_t prevPresentTime = 0;
151 std::deque<std::shared_ptr<FenceTime>> presentFences;
152 };
153
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700154public:
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700155 class TimeStatsDataSource : public perfetto::DataSource<TimeStatsDataSource> {
156 virtual void OnSetup(const SetupArgs&) override{};
157 virtual void OnStart(const StartArgs&) override { ALOGV("TimeStats trace started"); };
158 virtual void OnStop(const StopArgs&) override { ALOGV("TimeStats trace stopped"); };
159 };
160
Yiwei Zhang7e666a52018-11-15 13:33:42 -0800161 TimeStats() = default;
Yiwei Zhang7e666a52018-11-15 13:33:42 -0800162
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700163 void initializeTracing() override;
164 void registerTracingDataSource() override;
165 void traceNewLayer(int32_t layerID, const std::string& layerName) override;
166 void traceTimestamp(int32_t layerID, uint64_t bufferID, uint64_t frameNumber, nsecs_t timestamp,
167 FrameEvent::BufferEventType type, nsecs_t duration = 0) override;
168 void traceFence(int32_t layerID, uint64_t bufferID, uint64_t frameNumber,
169 const std::shared_ptr<FenceTime>& fence, FrameEvent::BufferEventType type,
170 nsecs_t startTime = 0) override;
171
Alec Mourifb571ea2019-01-24 18:42:10 -0800172 void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override;
173 bool isEnabled() override;
Yiwei Zhang7eb58b72019-04-22 19:00:02 -0700174 std::string miniDump() override;
Yiwei Zhang7e666a52018-11-15 13:33:42 -0800175
Alec Mourifb571ea2019-01-24 18:42:10 -0800176 void incrementTotalFrames() override;
177 void incrementMissedFrames() override;
178 void incrementClientCompositionFrames() override;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700179
Yiwei Zhang8e8fe522018-11-02 18:34:07 -0700180 void setPostTime(int32_t layerID, uint64_t frameNumber, const std::string& layerName,
Alec Mourifb571ea2019-01-24 18:42:10 -0800181 nsecs_t postTime) override;
182 void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) override;
183 void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) override;
184 void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) override;
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700185 void setAcquireFence(int32_t layerID, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -0800186 const std::shared_ptr<FenceTime>& acquireFence) override;
187 void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) override;
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700188 void setPresentFence(int32_t layerID, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -0800189 const std::shared_ptr<FenceTime>& presentFence) override;
Yiwei Zhangaf8ee942018-11-22 00:15:23 -0800190 // Clean up the layer record
Alec Mourifb571ea2019-01-24 18:42:10 -0800191 void onDestroy(int32_t layerID) override;
Yiwei Zhangeaeea062018-06-28 14:46:51 -0700192 // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
Alec Mourifb571ea2019-01-24 18:42:10 -0800193 void removeTimeRecord(int32_t layerID, uint64_t frameNumber) override;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700194
Alec Mourifb571ea2019-01-24 18:42:10 -0800195 void setPowerMode(int32_t powerMode) override;
196 // Source of truth is RefrehRateStats.
197 void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
198 void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700199
Yiwei Zhangaf8ee942018-11-22 00:15:23 -0800200 static const size_t MAX_NUM_TIME_RECORDS = 64;
201
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700202private:
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700203 // Checks if any pending fences for a layer and buffer have signalled and, if they have, creates
204 // trace points for them.
205 void tracePendingFencesLocked(TimeStatsDataSource::TraceContext& ctx, int32_t layerID,
206 uint64_t bufferID);
207 // Creates a trace point by translating a start time and an end time to a timestamp and
208 // duration. If startTime is later than end time it sets end time as the timestamp and the
209 // duration to 0. Used by traceFence().
210 void traceSpanLocked(TimeStatsDataSource::TraceContext& ctx, int32_t layerID, uint64_t bufferID,
211 uint64_t frameNumber, FrameEvent::BufferEventType type, nsecs_t startTime,
212 nsecs_t endTime);
213 void traceLocked(TimeStatsDataSource::TraceContext& ctx, int32_t layerID, uint64_t bufferID,
214 uint64_t frameNumber, nsecs_t timestamp, FrameEvent::BufferEventType type,
215 nsecs_t duration = 0);
216
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700217 bool recordReadyLocked(int32_t layerID, TimeRecord* timeRecord);
218 void flushAvailableRecordsToStatsLocked(int32_t layerID);
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700219 void flushPowerTimeLocked();
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700220 void flushAvailableGlobalRecordsToStatsLocked();
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700221
222 void enable();
223 void disable();
224 void clear();
Yiwei Zhang5434a782018-12-05 18:06:32 -0800225 void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result);
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700226
227 std::atomic<bool> mEnabled = false;
228 std::mutex mMutex;
Yiwei Zhangdc224042018-10-18 15:34:00 -0700229 TimeStatsHelper::TimeStatsGlobal mTimeStats;
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700230 // Hashmap for LayerRecord with layerID as the hash key
231 std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700232 PowerTime mPowerTime;
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700233 GlobalRecord mGlobalRecord;
Yiwei Zhang7eb58b72019-04-22 19:00:02 -0700234
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700235 std::mutex mTraceMutex;
236 std::unordered_map<int32_t, TraceRecord> mTraceTracker;
237
Yiwei Zhang7eb58b72019-04-22 19:00:02 -0700238 static const size_t MAX_NUM_LAYER_RECORDS = 200;
Yiwei Zhange926ab52019-08-14 15:16:00 -0700239 static const size_t MAX_NUM_LAYER_STATS = 200;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700240};
241
Alec Mourifb571ea2019-01-24 18:42:10 -0800242} // namespace impl
243
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700244} // namespace android