blob: 65e5cf4419d16974d07d9c350f639245ff782b01 [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>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070020#include <timestatsproto/TimeStatsHelper.h>
21#include <timestatsproto/TimeStatsProtoHeader.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070022#include <ui/FenceTime.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070023#include <utils/String16.h>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070024#include <utils/Vector.h>
25
Yiwei Zhangc5f2c452018-05-08 16:31:56 -070026#include <deque>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070027#include <mutex>
Yiwei Zhang8a4015c2018-05-08 16:03:47 -070028#include <optional>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070029#include <unordered_map>
Alec Mourie4034bb2019-11-19 12:45:54 -080030#include <variant>
Yiwei Zhang0102ad22018-05-02 17:37:17 -070031
32using namespace android::surfaceflinger;
33
34namespace android {
Yiwei Zhang0102ad22018-05-02 17:37:17 -070035
36class TimeStats {
Alec Mourifb571ea2019-01-24 18:42:10 -080037public:
38 virtual ~TimeStats() = default;
39
40 virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
41 virtual bool isEnabled() = 0;
Oliver Nguyenf3b7c9c2019-05-07 13:28:07 -070042 virtual std::string miniDump() = 0;
Alec Mourifb571ea2019-01-24 18:42:10 -080043
44 virtual void incrementTotalFrames() = 0;
45 virtual void incrementMissedFrames() = 0;
46 virtual void incrementClientCompositionFrames() = 0;
47
Alec Mouri9519bf12019-11-15 16:54:44 -080048 // Records the start and end times for a frame.
49 // The start time is the same as the beginning of a SurfaceFlinger
50 // invalidate message.
51 // The end time corresponds to when SurfaceFlinger finishes submitting the
52 // request to HWC to present a frame.
53 virtual void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) = 0;
Alec Mourie4034bb2019-11-19 12:45:54 -080054 // Records the start time and end times for when RenderEngine begins work.
55 // The start time corresponds to the beginning of RenderEngine::drawLayers.
56 // The end time corresponds to when RenderEngine finishes rendering.
57 virtual void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) = 0;
58 // Same as above, but passes in a fence representing the end time.
59 virtual void recordRenderEngineDuration(nsecs_t startTime,
60 const std::shared_ptr<FenceTime>& readyFence) = 0;
Alec Mouri9519bf12019-11-15 16:54:44 -080061
Yiwei Zhang1a88c402019-11-18 10:43:58 -080062 virtual void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName,
Alec Mourifb571ea2019-01-24 18:42:10 -080063 nsecs_t postTime) = 0;
Yiwei Zhang1a88c402019-11-18 10:43:58 -080064 virtual void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) = 0;
65 virtual void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) = 0;
66 virtual void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) = 0;
67 virtual void setAcquireFence(int32_t layerId, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -080068 const std::shared_ptr<FenceTime>& acquireFence) = 0;
Alec Mourie4034bb2019-11-19 12:45:54 -080069 // SetPresent{Time, Fence} are not expected to be called in the critical
70 // rendering path, as they flush prior fences if those fences have fired.
Yiwei Zhang1a88c402019-11-18 10:43:58 -080071 virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime) = 0;
72 virtual void setPresentFence(int32_t layerId, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -080073 const std::shared_ptr<FenceTime>& presentFence) = 0;
74 // Clean up the layer record
Yiwei Zhang1a88c402019-11-18 10:43:58 -080075 virtual void onDestroy(int32_t layerId) = 0;
Alec Mourifb571ea2019-01-24 18:42:10 -080076 // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
Yiwei Zhang1a88c402019-11-18 10:43:58 -080077 virtual void removeTimeRecord(int32_t layerId, uint64_t frameNumber) = 0;
Alec Mourifb571ea2019-01-24 18:42:10 -080078
79 virtual void setPowerMode(int32_t powerMode) = 0;
80 // Source of truth is RefrehRateStats.
81 virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
82 virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
83};
84
85namespace impl {
86
87class TimeStats : public android::TimeStats {
Yiwei Zhangcf50ab92018-06-14 10:50:12 -070088 struct FrameTime {
Yiwei Zhang0102ad22018-05-02 17:37:17 -070089 uint64_t frameNumber = 0;
90 nsecs_t postTime = 0;
91 nsecs_t latchTime = 0;
92 nsecs_t acquireTime = 0;
93 nsecs_t desiredTime = 0;
94 nsecs_t presentTime = 0;
Yiwei Zhangcf50ab92018-06-14 10:50:12 -070095 };
96
97 struct TimeRecord {
98 bool ready = false;
99 FrameTime frameTime;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700100 std::shared_ptr<FenceTime> acquireFence;
101 std::shared_ptr<FenceTime> presentFence;
102 };
103
104 struct LayerRecord {
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700105 std::string layerName;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700106 // This is the index in timeRecords, at which the timestamps for that
107 // specific frame are still not fully received. This is not waiting for
108 // fences to signal, but rather waiting to receive those fences/timestamps.
109 int32_t waitData = -1;
Yiwei Zhangeaeea062018-06-28 14:46:51 -0700110 uint32_t droppedFrames = 0;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700111 TimeRecord prevTimeRecord;
Yiwei Zhangc5f2c452018-05-08 16:31:56 -0700112 std::deque<TimeRecord> timeRecords;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700113 };
114
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700115 struct PowerTime {
116 int32_t powerMode = HWC_POWER_MODE_OFF;
117 nsecs_t prevTime = 0;
118 };
119
Alec Mourie4034bb2019-11-19 12:45:54 -0800120 struct RenderEngineDuration {
121 nsecs_t startTime;
122 std::variant<nsecs_t, std::shared_ptr<FenceTime>> endTime;
123 };
124
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700125 struct GlobalRecord {
126 nsecs_t prevPresentTime = 0;
127 std::deque<std::shared_ptr<FenceTime>> presentFences;
Alec Mourie4034bb2019-11-19 12:45:54 -0800128 std::deque<RenderEngineDuration> renderEngineDurations;
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700129 };
130
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700131public:
Alec Mourib3885ad2019-09-06 17:08:55 -0700132 TimeStats();
Yiwei Zhang7e666a52018-11-15 13:33:42 -0800133
Alec Mourifb571ea2019-01-24 18:42:10 -0800134 void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override;
135 bool isEnabled() override;
Yiwei Zhang7eb58b72019-04-22 19:00:02 -0700136 std::string miniDump() override;
Yiwei Zhang7e666a52018-11-15 13:33:42 -0800137
Alec Mourifb571ea2019-01-24 18:42:10 -0800138 void incrementTotalFrames() override;
139 void incrementMissedFrames() override;
140 void incrementClientCompositionFrames() override;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700141
Alec Mouri9519bf12019-11-15 16:54:44 -0800142 void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
Alec Mourie4034bb2019-11-19 12:45:54 -0800143 void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) override;
144 void recordRenderEngineDuration(nsecs_t startTime,
145 const std::shared_ptr<FenceTime>& readyFence) override;
Alec Mouri9519bf12019-11-15 16:54:44 -0800146
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800147 void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName,
Alec Mourifb571ea2019-01-24 18:42:10 -0800148 nsecs_t postTime) override;
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800149 void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) override;
150 void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) override;
151 void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) override;
152 void setAcquireFence(int32_t layerId, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -0800153 const std::shared_ptr<FenceTime>& acquireFence) override;
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800154 void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime) override;
155 void setPresentFence(int32_t layerId, uint64_t frameNumber,
Alec Mourifb571ea2019-01-24 18:42:10 -0800156 const std::shared_ptr<FenceTime>& presentFence) override;
Yiwei Zhangaf8ee942018-11-22 00:15:23 -0800157 // Clean up the layer record
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800158 void onDestroy(int32_t layerId) override;
Yiwei Zhangeaeea062018-06-28 14:46:51 -0700159 // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800160 void removeTimeRecord(int32_t layerId, uint64_t frameNumber) override;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700161
Alec Mourifb571ea2019-01-24 18:42:10 -0800162 void setPowerMode(int32_t powerMode) override;
163 // Source of truth is RefrehRateStats.
164 void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
165 void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700166
Yiwei Zhangaf8ee942018-11-22 00:15:23 -0800167 static const size_t MAX_NUM_TIME_RECORDS = 64;
168
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700169private:
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800170 bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
171 void flushAvailableRecordsToStatsLocked(int32_t layerId);
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700172 void flushPowerTimeLocked();
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700173 void flushAvailableGlobalRecordsToStatsLocked();
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700174
175 void enable();
176 void disable();
Alec Mouride64c562020-01-16 18:01:40 +0000177 void clear();
Yiwei Zhang5434a782018-12-05 18:06:32 -0800178 void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result);
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700179
180 std::atomic<bool> mEnabled = false;
181 std::mutex mMutex;
Yiwei Zhangdc224042018-10-18 15:34:00 -0700182 TimeStatsHelper::TimeStatsGlobal mTimeStats;
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800183 // Hashmap for LayerRecord with layerId as the hash key
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700184 std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
Yiwei Zhang3a226d22018-10-16 09:23:03 -0700185 PowerTime mPowerTime;
Yiwei Zhangce6ebc02018-10-20 12:42:38 -0700186 GlobalRecord mGlobalRecord;
Yiwei Zhang7eb58b72019-04-22 19:00:02 -0700187
188 static const size_t MAX_NUM_LAYER_RECORDS = 200;
Yiwei Zhange926ab52019-08-14 15:16:00 -0700189 static const size_t MAX_NUM_LAYER_STATS = 200;
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700190};
191
Alec Mourifb571ea2019-01-24 18:42:10 -0800192} // namespace impl
193
Yiwei Zhang0102ad22018-05-02 17:37:17 -0700194} // namespace android