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