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 <ui/FenceTime.h> 23 24 #include <utils/String16.h> 25 #include <utils/String8.h> 26 #include <utils/Vector.h> 27 28 #include <deque> 29 #include <mutex> 30 #include <optional> 31 #include <unordered_map> 32 33 using namespace android::surfaceflinger; 34 35 namespace android { 36 class String8; 37 38 class TimeStats { 39 // TODO(zzyiwei): Bound the timeStatsTracker with weighted LRU 40 // static const size_t MAX_NUM_LAYER_RECORDS = 200; 41 static const size_t MAX_NUM_TIME_RECORDS = 64; 42 43 struct TimeRecord { 44 bool ready = false; 45 uint64_t frameNumber = 0; 46 nsecs_t postTime = 0; 47 nsecs_t latchTime = 0; 48 nsecs_t acquireTime = 0; 49 nsecs_t desiredTime = 0; 50 nsecs_t presentTime = 0; 51 std::shared_ptr<FenceTime> acquireFence; 52 std::shared_ptr<FenceTime> presentFence; 53 }; 54 55 struct LayerRecord { 56 // This is the index in timeRecords, at which the timestamps for that 57 // specific frame are still not fully received. This is not waiting for 58 // fences to signal, but rather waiting to receive those fences/timestamps. 59 int32_t waitData = -1; 60 TimeRecord prevTimeRecord; 61 std::deque<TimeRecord> timeRecords; 62 }; 63 64 public: 65 static TimeStats& getInstance(); 66 void parseArgs(bool asProto, const Vector<String16>& args, size_t& index, String8& result); 67 void incrementTotalFrames(); 68 void incrementMissedFrames(); 69 void incrementClientCompositionFrames(); 70 71 void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime); 72 void setLatchTime(const std::string& layerName, uint64_t frameNumber, nsecs_t latchTime); 73 void setDesiredTime(const std::string& layerName, uint64_t frameNumber, nsecs_t desiredTime); 74 void setAcquireTime(const std::string& layerName, uint64_t frameNumber, nsecs_t acquireTime); 75 void setAcquireFence(const std::string& layerName, uint64_t frameNumber, 76 const std::shared_ptr<FenceTime>& acquireFence); 77 void setPresentTime(const std::string& layerName, uint64_t frameNumber, nsecs_t presentTime); 78 void setPresentFence(const std::string& layerName, uint64_t frameNumber, 79 const std::shared_ptr<FenceTime>& presentFence); 80 void onDisconnect(const std::string& layerName); 81 void clearLayerRecord(const std::string& layerName); 82 void removeTimeRecord(const std::string& layerName, uint64_t frameNumber); 83 84 private: 85 TimeStats() = default; 86 87 bool recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord); 88 void flushAvailableRecordsToStatsLocked(const std::string& layerName); 89 90 void enable(); 91 void disable(); 92 void clear(); 93 bool isEnabled(); 94 void dump(bool asProto, std::optional<uint32_t> maxLayers, String8& result); 95 96 std::atomic<bool> mEnabled = false; 97 std::mutex mMutex; 98 TimeStatsHelper::TimeStatsGlobal timeStats; 99 std::unordered_map<std::string, LayerRecord> timeStatsTracker; 100 }; 101 102 } // namespace android 103