| /* | 
 |  * Copyright 2018 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | #pragma once | 
 |  | 
 | #include <timestatsproto/TimeStatsHelper.h> | 
 | #include <timestatsproto/TimeStatsProtoHeader.h> | 
 |  | 
 | #include <ui/FenceTime.h> | 
 |  | 
 | #include <utils/String16.h> | 
 | #include <utils/String8.h> | 
 | #include <utils/Vector.h> | 
 |  | 
 | #include <deque> | 
 | #include <mutex> | 
 | #include <optional> | 
 | #include <unordered_map> | 
 |  | 
 | using namespace android::surfaceflinger; | 
 |  | 
 | namespace android { | 
 | class String8; | 
 |  | 
 | class TimeStats { | 
 |     // TODO(zzyiwei): Bound the timeStatsTracker with weighted LRU | 
 |     // static const size_t MAX_NUM_LAYER_RECORDS = 200; | 
 |     static const size_t MAX_NUM_TIME_RECORDS = 64; | 
 |  | 
 |     struct FrameTime { | 
 |         uint64_t frameNumber = 0; | 
 |         nsecs_t postTime = 0; | 
 |         nsecs_t latchTime = 0; | 
 |         nsecs_t acquireTime = 0; | 
 |         nsecs_t desiredTime = 0; | 
 |         nsecs_t presentTime = 0; | 
 |     }; | 
 |  | 
 |     struct TimeRecord { | 
 |         bool ready = false; | 
 |         FrameTime frameTime; | 
 |         std::shared_ptr<FenceTime> acquireFence; | 
 |         std::shared_ptr<FenceTime> presentFence; | 
 |     }; | 
 |  | 
 |     struct LayerRecord { | 
 |         // This is the index in timeRecords, at which the timestamps for that | 
 |         // specific frame are still not fully received. This is not waiting for | 
 |         // fences to signal, but rather waiting to receive those fences/timestamps. | 
 |         int32_t waitData = -1; | 
 |         TimeRecord prevTimeRecord; | 
 |         std::deque<TimeRecord> timeRecords; | 
 |     }; | 
 |  | 
 | public: | 
 |     static TimeStats& getInstance(); | 
 |     void parseArgs(bool asProto, const Vector<String16>& args, size_t& index, String8& result); | 
 |     void incrementTotalFrames(); | 
 |     void incrementMissedFrames(); | 
 |     void incrementClientCompositionFrames(); | 
 |  | 
 |     void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime); | 
 |     void setLatchTime(const std::string& layerName, uint64_t frameNumber, nsecs_t latchTime); | 
 |     void setDesiredTime(const std::string& layerName, uint64_t frameNumber, nsecs_t desiredTime); | 
 |     void setAcquireTime(const std::string& layerName, uint64_t frameNumber, nsecs_t acquireTime); | 
 |     void setAcquireFence(const std::string& layerName, uint64_t frameNumber, | 
 |                          const std::shared_ptr<FenceTime>& acquireFence); | 
 |     void setPresentTime(const std::string& layerName, uint64_t frameNumber, nsecs_t presentTime); | 
 |     void setPresentFence(const std::string& layerName, uint64_t frameNumber, | 
 |                          const std::shared_ptr<FenceTime>& presentFence); | 
 |     void onDisconnect(const std::string& layerName); | 
 |     void clearLayerRecord(const std::string& layerName); | 
 |     void removeTimeRecord(const std::string& layerName, uint64_t frameNumber); | 
 |  | 
 | private: | 
 |     TimeStats() = default; | 
 |  | 
 |     bool recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord); | 
 |     void flushAvailableRecordsToStatsLocked(const std::string& layerName); | 
 |  | 
 |     void enable(); | 
 |     void disable(); | 
 |     void clear(); | 
 |     bool isEnabled(); | 
 |     void dump(bool asProto, std::optional<uint32_t> maxLayers, String8& result); | 
 |  | 
 |     std::atomic<bool> mEnabled = false; | 
 |     std::mutex mMutex; | 
 |     TimeStatsHelper::TimeStatsGlobal timeStats; | 
 |     std::unordered_map<std::string, LayerRecord> timeStatsTracker; | 
 | }; | 
 |  | 
 | } // namespace android |