1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2018 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <cstdint> 20*38e8c45fSAndroid Build Coastguard Worker #include <deque> 21*38e8c45fSAndroid Build Coastguard Worker #include <mutex> 22*38e8c45fSAndroid Build Coastguard Worker #include <optional> 23*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map> 24*38e8c45fSAndroid Build Coastguard Worker #include <variant> 25*38e8c45fSAndroid Build Coastguard Worker 26*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/graphics/composer/2.4/IComposerClient.h> 27*38e8c45fSAndroid Build Coastguard Worker #include <gui/JankInfo.h> 28*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerMetadata.h> 29*38e8c45fSAndroid Build Coastguard Worker #include <timestatsproto/TimeStatsHelper.h> 30*38e8c45fSAndroid Build Coastguard Worker #include <timestatsproto/TimeStatsProtoHeader.h> 31*38e8c45fSAndroid Build Coastguard Worker #include <ui/FenceTime.h> 32*38e8c45fSAndroid Build Coastguard Worker #include <utils/String16.h> 33*38e8c45fSAndroid Build Coastguard Worker #include <utils/Vector.h> 34*38e8c45fSAndroid Build Coastguard Worker 35*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Fps.h> 36*38e8c45fSAndroid Build Coastguard Worker 37*38e8c45fSAndroid Build Coastguard Worker using android::gui::GameMode; 38*38e8c45fSAndroid Build Coastguard Worker using android::gui::LayerMetadata; 39*38e8c45fSAndroid Build Coastguard Worker using namespace android::surfaceflinger; 40*38e8c45fSAndroid Build Coastguard Worker 41*38e8c45fSAndroid Build Coastguard Worker namespace android { 42*38e8c45fSAndroid Build Coastguard Worker 43*38e8c45fSAndroid Build Coastguard Worker class TimeStats { 44*38e8c45fSAndroid Build Coastguard Worker public: 45*38e8c45fSAndroid Build Coastguard Worker using SetFrameRateVote = TimeStatsHelper::SetFrameRateVote; 46*38e8c45fSAndroid Build Coastguard Worker 47*38e8c45fSAndroid Build Coastguard Worker virtual ~TimeStats() = default; 48*38e8c45fSAndroid Build Coastguard Worker 49*38e8c45fSAndroid Build Coastguard Worker // Process a pull request from statsd. 50*38e8c45fSAndroid Build Coastguard Worker virtual bool onPullAtom(const int atomId, std::vector<uint8_t>* pulledData) = 0; 51*38e8c45fSAndroid Build Coastguard Worker 52*38e8c45fSAndroid Build Coastguard Worker virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0; 53*38e8c45fSAndroid Build Coastguard Worker virtual bool isEnabled() = 0; 54*38e8c45fSAndroid Build Coastguard Worker virtual std::string miniDump() = 0; 55*38e8c45fSAndroid Build Coastguard Worker 56*38e8c45fSAndroid Build Coastguard Worker virtual void incrementTotalFrames() = 0; 57*38e8c45fSAndroid Build Coastguard Worker virtual void incrementMissedFrames() = 0; 58*38e8c45fSAndroid Build Coastguard Worker // Increments the number of times the display refresh rate changed. 59*38e8c45fSAndroid Build Coastguard Worker virtual void incrementRefreshRateSwitches() = 0; 60*38e8c45fSAndroid Build Coastguard Worker 61*38e8c45fSAndroid Build Coastguard Worker // Records the start and end times for a frame. 62*38e8c45fSAndroid Build Coastguard Worker // The start time is the same as the beginning of a SurfaceFlinger 63*38e8c45fSAndroid Build Coastguard Worker // invalidate message. 64*38e8c45fSAndroid Build Coastguard Worker // The end time corresponds to when SurfaceFlinger finishes submitting the 65*38e8c45fSAndroid Build Coastguard Worker // request to HWC to present a frame. 66*38e8c45fSAndroid Build Coastguard Worker virtual void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) = 0; 67*38e8c45fSAndroid Build Coastguard Worker // Records the start time and end times for when RenderEngine begins work. 68*38e8c45fSAndroid Build Coastguard Worker // The start time corresponds to the beginning of RenderEngine::drawLayers. 69*38e8c45fSAndroid Build Coastguard Worker // The end time corresponds to when RenderEngine finishes rendering. 70*38e8c45fSAndroid Build Coastguard Worker virtual void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) = 0; 71*38e8c45fSAndroid Build Coastguard Worker // Same as above, but passes in a fence representing the end time. 72*38e8c45fSAndroid Build Coastguard Worker virtual void recordRenderEngineDuration(nsecs_t startTime, 73*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& readyFence) = 0; 74*38e8c45fSAndroid Build Coastguard Worker 75*38e8c45fSAndroid Build Coastguard Worker virtual void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, 76*38e8c45fSAndroid Build Coastguard Worker uid_t uid, nsecs_t postTime, GameMode) = 0; 77*38e8c45fSAndroid Build Coastguard Worker virtual void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) = 0; 78*38e8c45fSAndroid Build Coastguard Worker // Reasons why latching a particular buffer may be skipped 79*38e8c45fSAndroid Build Coastguard Worker enum class LatchSkipReason { 80*38e8c45fSAndroid Build Coastguard Worker // If the acquire fence did not fire on some devices we skip latching 81*38e8c45fSAndroid Build Coastguard Worker // the buffer until the fence fires. 82*38e8c45fSAndroid Build Coastguard Worker LateAcquire, 83*38e8c45fSAndroid Build Coastguard Worker }; 84*38e8c45fSAndroid Build Coastguard Worker // Increments the counter of skipped latch buffers. 85*38e8c45fSAndroid Build Coastguard Worker virtual void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) = 0; 86*38e8c45fSAndroid Build Coastguard Worker // Increments the counter of bad desired present times for this layer. 87*38e8c45fSAndroid Build Coastguard Worker // Bad desired present times are "implausible" and cause SurfaceFlinger to 88*38e8c45fSAndroid Build Coastguard Worker // latch a buffer immediately to avoid stalling. 89*38e8c45fSAndroid Build Coastguard Worker virtual void incrementBadDesiredPresent(int32_t layerId) = 0; 90*38e8c45fSAndroid Build Coastguard Worker virtual void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) = 0; 91*38e8c45fSAndroid Build Coastguard Worker virtual void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) = 0; 92*38e8c45fSAndroid Build Coastguard Worker virtual void setAcquireFence(int32_t layerId, uint64_t frameNumber, 93*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& acquireFence) = 0; 94*38e8c45fSAndroid Build Coastguard Worker // SetPresent{Time, Fence} are not expected to be called in the critical 95*38e8c45fSAndroid Build Coastguard Worker // rendering path, as they flush prior fences if those fences have fired. 96*38e8c45fSAndroid Build Coastguard Worker virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime, 97*38e8c45fSAndroid Build Coastguard Worker Fps displayRefreshRate, std::optional<Fps> renderRate, 98*38e8c45fSAndroid Build Coastguard Worker SetFrameRateVote frameRateVote, GameMode) = 0; 99*38e8c45fSAndroid Build Coastguard Worker virtual void setPresentFence(int32_t layerId, uint64_t frameNumber, 100*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& presentFence, 101*38e8c45fSAndroid Build Coastguard Worker Fps displayRefreshRate, std::optional<Fps> renderRate, 102*38e8c45fSAndroid Build Coastguard Worker SetFrameRateVote frameRateVote, GameMode) = 0; 103*38e8c45fSAndroid Build Coastguard Worker 104*38e8c45fSAndroid Build Coastguard Worker // Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName} 105*38e8c45fSAndroid Build Coastguard Worker // key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the 106*38e8c45fSAndroid Build Coastguard Worker // infrastructure responsible for computing jank in the system, this is expected to be called 107*38e8c45fSAndroid Build Coastguard Worker // from FrameTimeline, rather than directly from SurfaceFlinger or individual layers. If there 108*38e8c45fSAndroid Build Coastguard Worker // are no jank reasons, then total frames are incremented but jank is not, for accurate 109*38e8c45fSAndroid Build Coastguard Worker // accounting of janky frames. 110*38e8c45fSAndroid Build Coastguard Worker // displayDeadlineDelta, displayPresentJitter, and appDeadlineDelta are also provided in order 111*38e8c45fSAndroid Build Coastguard Worker // to provide contextual information about a janky frame. These values may only be uploaded if 112*38e8c45fSAndroid Build Coastguard Worker // there was an associated valid jank reason, and they must be positive. When these frame counts 113*38e8c45fSAndroid Build Coastguard Worker // are incremented, these are also aggregated into a global reporting packet to help with data 114*38e8c45fSAndroid Build Coastguard Worker // validation and assessing of overall device health. 115*38e8c45fSAndroid Build Coastguard Worker struct JankyFramesInfo { 116*38e8c45fSAndroid Build Coastguard Worker Fps refreshRate; 117*38e8c45fSAndroid Build Coastguard Worker std::optional<Fps> renderRate; 118*38e8c45fSAndroid Build Coastguard Worker uid_t uid = 0; 119*38e8c45fSAndroid Build Coastguard Worker std::string layerName; 120*38e8c45fSAndroid Build Coastguard Worker GameMode gameMode = GameMode::Unsupported; 121*38e8c45fSAndroid Build Coastguard Worker int32_t reasons = 0; 122*38e8c45fSAndroid Build Coastguard Worker nsecs_t displayDeadlineDelta = 0; 123*38e8c45fSAndroid Build Coastguard Worker nsecs_t displayPresentJitter = 0; 124*38e8c45fSAndroid Build Coastguard Worker nsecs_t appDeadlineDelta = 0; 125*38e8c45fSAndroid Build Coastguard Worker isOptApproxEqualJankyFramesInfo126*38e8c45fSAndroid Build Coastguard Worker static bool isOptApproxEqual(std::optional<Fps> lhs, std::optional<Fps> rhs) { 127*38e8c45fSAndroid Build Coastguard Worker return (!lhs && !rhs) || (lhs && rhs && isApproxEqual(*lhs, *rhs)); 128*38e8c45fSAndroid Build Coastguard Worker } 129*38e8c45fSAndroid Build Coastguard Worker 130*38e8c45fSAndroid Build Coastguard Worker bool operator==(const JankyFramesInfo& o) const { 131*38e8c45fSAndroid Build Coastguard Worker return isApproxEqual(refreshRate, o.refreshRate) && 132*38e8c45fSAndroid Build Coastguard Worker isOptApproxEqual(renderRate, o.renderRate) && uid == o.uid && 133*38e8c45fSAndroid Build Coastguard Worker layerName == o.layerName && gameMode == o.gameMode && reasons == o.reasons && 134*38e8c45fSAndroid Build Coastguard Worker displayDeadlineDelta == o.displayDeadlineDelta && 135*38e8c45fSAndroid Build Coastguard Worker displayPresentJitter == o.displayPresentJitter && 136*38e8c45fSAndroid Build Coastguard Worker appDeadlineDelta == o.appDeadlineDelta; 137*38e8c45fSAndroid Build Coastguard Worker } 138*38e8c45fSAndroid Build Coastguard Worker 139*38e8c45fSAndroid Build Coastguard Worker friend std::ostream& operator<<(std::ostream& os, const JankyFramesInfo& info) { 140*38e8c45fSAndroid Build Coastguard Worker os << "JankyFramesInfo {"; 141*38e8c45fSAndroid Build Coastguard Worker os << "\n .refreshRate = " << info.refreshRate; 142*38e8c45fSAndroid Build Coastguard Worker os << "\n .renderRate = " 143*38e8c45fSAndroid Build Coastguard Worker << (info.renderRate ? to_string(*info.renderRate) : "nullopt"); 144*38e8c45fSAndroid Build Coastguard Worker os << "\n .uid = " << info.uid; 145*38e8c45fSAndroid Build Coastguard Worker os << "\n .layerName = " << info.layerName; 146*38e8c45fSAndroid Build Coastguard Worker os << "\n .reasons = " << info.reasons; 147*38e8c45fSAndroid Build Coastguard Worker os << "\n .displayDeadlineDelta = " << info.displayDeadlineDelta; 148*38e8c45fSAndroid Build Coastguard Worker os << "\n .displayPresentJitter = " << info.displayPresentJitter; 149*38e8c45fSAndroid Build Coastguard Worker os << "\n .appDeadlineDelta = " << info.appDeadlineDelta; 150*38e8c45fSAndroid Build Coastguard Worker return os << "\n}"; 151*38e8c45fSAndroid Build Coastguard Worker } 152*38e8c45fSAndroid Build Coastguard Worker }; 153*38e8c45fSAndroid Build Coastguard Worker 154*38e8c45fSAndroid Build Coastguard Worker struct ClientCompositionRecord { 155*38e8c45fSAndroid Build Coastguard Worker // Frame had client composition or mixed composition 156*38e8c45fSAndroid Build Coastguard Worker bool hadClientComposition = false; 157*38e8c45fSAndroid Build Coastguard Worker // Composition changed between hw composition and mixed/client composition 158*38e8c45fSAndroid Build Coastguard Worker bool changed = false; 159*38e8c45fSAndroid Build Coastguard Worker // Frame reused the client composition result from a previous frame 160*38e8c45fSAndroid Build Coastguard Worker bool reused = false; 161*38e8c45fSAndroid Build Coastguard Worker // Composition strategy predicted for frame 162*38e8c45fSAndroid Build Coastguard Worker bool predicted = false; 163*38e8c45fSAndroid Build Coastguard Worker // Composition strategy prediction succeeded 164*38e8c45fSAndroid Build Coastguard Worker bool predictionSucceeded = false; 165*38e8c45fSAndroid Build Coastguard Worker 166*38e8c45fSAndroid Build Coastguard Worker // Whether there is data we want to record. hasInterestingDataClientCompositionRecord167*38e8c45fSAndroid Build Coastguard Worker bool hasInterestingData() const { 168*38e8c45fSAndroid Build Coastguard Worker return hadClientComposition || changed || reused || predicted; 169*38e8c45fSAndroid Build Coastguard Worker } 170*38e8c45fSAndroid Build Coastguard Worker }; 171*38e8c45fSAndroid Build Coastguard Worker 172*38e8c45fSAndroid Build Coastguard Worker virtual void incrementJankyFrames(const JankyFramesInfo& info) = 0; 173*38e8c45fSAndroid Build Coastguard Worker // Clean up the layer record 174*38e8c45fSAndroid Build Coastguard Worker virtual void onDestroy(int32_t layerId) = 0; 175*38e8c45fSAndroid Build Coastguard Worker // If SF skips or rejects a buffer, remove the corresponding TimeRecord. 176*38e8c45fSAndroid Build Coastguard Worker virtual void removeTimeRecord(int32_t layerId, uint64_t frameNumber) = 0; 177*38e8c45fSAndroid Build Coastguard Worker 178*38e8c45fSAndroid Build Coastguard Worker virtual void setPowerMode( 179*38e8c45fSAndroid Build Coastguard Worker hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) = 0; 180*38e8c45fSAndroid Build Coastguard Worker // Source of truth is RefrehRateStats. 181*38e8c45fSAndroid Build Coastguard Worker virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0; 182*38e8c45fSAndroid Build Coastguard Worker virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0; 183*38e8c45fSAndroid Build Coastguard Worker virtual void pushCompositionStrategyState(const ClientCompositionRecord&) = 0; 184*38e8c45fSAndroid Build Coastguard Worker }; 185*38e8c45fSAndroid Build Coastguard Worker 186*38e8c45fSAndroid Build Coastguard Worker namespace impl { 187*38e8c45fSAndroid Build Coastguard Worker 188*38e8c45fSAndroid Build Coastguard Worker class TimeStats : public android::TimeStats { 189*38e8c45fSAndroid Build Coastguard Worker using PowerMode = android::hardware::graphics::composer::V2_4::IComposerClient::PowerMode; 190*38e8c45fSAndroid Build Coastguard Worker 191*38e8c45fSAndroid Build Coastguard Worker struct FrameTime { 192*38e8c45fSAndroid Build Coastguard Worker uint64_t frameNumber = 0; 193*38e8c45fSAndroid Build Coastguard Worker nsecs_t postTime = 0; 194*38e8c45fSAndroid Build Coastguard Worker nsecs_t latchTime = 0; 195*38e8c45fSAndroid Build Coastguard Worker nsecs_t acquireTime = 0; 196*38e8c45fSAndroid Build Coastguard Worker nsecs_t desiredTime = 0; 197*38e8c45fSAndroid Build Coastguard Worker nsecs_t presentTime = 0; 198*38e8c45fSAndroid Build Coastguard Worker }; 199*38e8c45fSAndroid Build Coastguard Worker 200*38e8c45fSAndroid Build Coastguard Worker struct TimeRecord { 201*38e8c45fSAndroid Build Coastguard Worker bool ready = false; 202*38e8c45fSAndroid Build Coastguard Worker FrameTime frameTime; 203*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<FenceTime> acquireFence; 204*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<FenceTime> presentFence; 205*38e8c45fSAndroid Build Coastguard Worker }; 206*38e8c45fSAndroid Build Coastguard Worker 207*38e8c45fSAndroid Build Coastguard Worker struct LayerRecord { 208*38e8c45fSAndroid Build Coastguard Worker uid_t uid; 209*38e8c45fSAndroid Build Coastguard Worker std::string layerName; 210*38e8c45fSAndroid Build Coastguard Worker GameMode gameMode = GameMode::Unsupported; 211*38e8c45fSAndroid Build Coastguard Worker // This is the index in timeRecords, at which the timestamps for that 212*38e8c45fSAndroid Build Coastguard Worker // specific frame are still not fully received. This is not waiting for 213*38e8c45fSAndroid Build Coastguard Worker // fences to signal, but rather waiting to receive those fences/timestamps. 214*38e8c45fSAndroid Build Coastguard Worker int32_t waitData = -1; 215*38e8c45fSAndroid Build Coastguard Worker uint32_t droppedFrames = 0; 216*38e8c45fSAndroid Build Coastguard Worker uint32_t lateAcquireFrames = 0; 217*38e8c45fSAndroid Build Coastguard Worker uint32_t badDesiredPresentFrames = 0; 218*38e8c45fSAndroid Build Coastguard Worker TimeRecord prevTimeRecord; 219*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> prevPresentToPresentMs; 220*38e8c45fSAndroid Build Coastguard Worker std::deque<TimeRecord> timeRecords; 221*38e8c45fSAndroid Build Coastguard Worker }; 222*38e8c45fSAndroid Build Coastguard Worker 223*38e8c45fSAndroid Build Coastguard Worker struct PowerTime { 224*38e8c45fSAndroid Build Coastguard Worker PowerMode powerMode = PowerMode::OFF; 225*38e8c45fSAndroid Build Coastguard Worker nsecs_t prevTime = 0; 226*38e8c45fSAndroid Build Coastguard Worker }; 227*38e8c45fSAndroid Build Coastguard Worker 228*38e8c45fSAndroid Build Coastguard Worker struct RenderEngineDuration { 229*38e8c45fSAndroid Build Coastguard Worker nsecs_t startTime; 230*38e8c45fSAndroid Build Coastguard Worker std::variant<nsecs_t, std::shared_ptr<FenceTime>> endTime; 231*38e8c45fSAndroid Build Coastguard Worker }; 232*38e8c45fSAndroid Build Coastguard Worker 233*38e8c45fSAndroid Build Coastguard Worker struct GlobalRecord { 234*38e8c45fSAndroid Build Coastguard Worker nsecs_t prevPresentTime = 0; 235*38e8c45fSAndroid Build Coastguard Worker std::deque<std::shared_ptr<FenceTime>> presentFences; 236*38e8c45fSAndroid Build Coastguard Worker std::deque<RenderEngineDuration> renderEngineDurations; 237*38e8c45fSAndroid Build Coastguard Worker }; 238*38e8c45fSAndroid Build Coastguard Worker 239*38e8c45fSAndroid Build Coastguard Worker public: 240*38e8c45fSAndroid Build Coastguard Worker TimeStats(); 241*38e8c45fSAndroid Build Coastguard Worker // For testing only for injecting custom dependencies. 242*38e8c45fSAndroid Build Coastguard Worker TimeStats(std::optional<size_t> maxPulledLayers, 243*38e8c45fSAndroid Build Coastguard Worker std::optional<size_t> maxPulledHistogramBuckets); 244*38e8c45fSAndroid Build Coastguard Worker 245*38e8c45fSAndroid Build Coastguard Worker bool onPullAtom(const int atomId, std::vector<uint8_t>* pulledData) override; 246*38e8c45fSAndroid Build Coastguard Worker void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override; 247*38e8c45fSAndroid Build Coastguard Worker bool isEnabled() override; 248*38e8c45fSAndroid Build Coastguard Worker std::string miniDump() override; 249*38e8c45fSAndroid Build Coastguard Worker 250*38e8c45fSAndroid Build Coastguard Worker void incrementTotalFrames() override; 251*38e8c45fSAndroid Build Coastguard Worker void incrementMissedFrames() override; 252*38e8c45fSAndroid Build Coastguard Worker void incrementRefreshRateSwitches() override; 253*38e8c45fSAndroid Build Coastguard Worker 254*38e8c45fSAndroid Build Coastguard Worker void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override; 255*38e8c45fSAndroid Build Coastguard Worker void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) override; 256*38e8c45fSAndroid Build Coastguard Worker void recordRenderEngineDuration(nsecs_t startTime, 257*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& readyFence) override; 258*38e8c45fSAndroid Build Coastguard Worker 259*38e8c45fSAndroid Build Coastguard Worker void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, uid_t uid, 260*38e8c45fSAndroid Build Coastguard Worker nsecs_t postTime, GameMode) override; 261*38e8c45fSAndroid Build Coastguard Worker void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) override; 262*38e8c45fSAndroid Build Coastguard Worker void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) override; 263*38e8c45fSAndroid Build Coastguard Worker void incrementBadDesiredPresent(int32_t layerId) override; 264*38e8c45fSAndroid Build Coastguard Worker void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) override; 265*38e8c45fSAndroid Build Coastguard Worker void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) override; 266*38e8c45fSAndroid Build Coastguard Worker void setAcquireFence(int32_t layerId, uint64_t frameNumber, 267*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& acquireFence) override; 268*38e8c45fSAndroid Build Coastguard Worker void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime, 269*38e8c45fSAndroid Build Coastguard Worker Fps displayRefreshRate, std::optional<Fps> renderRate, SetFrameRateVote, 270*38e8c45fSAndroid Build Coastguard Worker GameMode) override; 271*38e8c45fSAndroid Build Coastguard Worker void setPresentFence(int32_t layerId, uint64_t frameNumber, 272*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate, 273*38e8c45fSAndroid Build Coastguard Worker std::optional<Fps> renderRate, SetFrameRateVote, GameMode) override; 274*38e8c45fSAndroid Build Coastguard Worker 275*38e8c45fSAndroid Build Coastguard Worker void incrementJankyFrames(const JankyFramesInfo& info) override; 276*38e8c45fSAndroid Build Coastguard Worker // Clean up the layer record 277*38e8c45fSAndroid Build Coastguard Worker void onDestroy(int32_t layerId) override; 278*38e8c45fSAndroid Build Coastguard Worker // If SF skips or rejects a buffer, remove the corresponding TimeRecord. 279*38e8c45fSAndroid Build Coastguard Worker void removeTimeRecord(int32_t layerId, uint64_t frameNumber) override; 280*38e8c45fSAndroid Build Coastguard Worker 281*38e8c45fSAndroid Build Coastguard Worker void setPowerMode( 282*38e8c45fSAndroid Build Coastguard Worker hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) override; 283*38e8c45fSAndroid Build Coastguard Worker // Source of truth is RefrehRateStats. 284*38e8c45fSAndroid Build Coastguard Worker void recordRefreshRate(uint32_t fps, nsecs_t duration) override; 285*38e8c45fSAndroid Build Coastguard Worker void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override; 286*38e8c45fSAndroid Build Coastguard Worker 287*38e8c45fSAndroid Build Coastguard Worker void pushCompositionStrategyState(const ClientCompositionRecord&) override; 288*38e8c45fSAndroid Build Coastguard Worker 289*38e8c45fSAndroid Build Coastguard Worker static const size_t MAX_NUM_TIME_RECORDS = 64; 290*38e8c45fSAndroid Build Coastguard Worker 291*38e8c45fSAndroid Build Coastguard Worker private: 292*38e8c45fSAndroid Build Coastguard Worker bool populateGlobalAtom(std::vector<uint8_t>* pulledData); 293*38e8c45fSAndroid Build Coastguard Worker bool populateLayerAtom(std::vector<uint8_t>* pulledData); 294*38e8c45fSAndroid Build Coastguard Worker bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord); 295*38e8c45fSAndroid Build Coastguard Worker void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate, 296*38e8c45fSAndroid Build Coastguard Worker std::optional<Fps> renderRate, SetFrameRateVote, 297*38e8c45fSAndroid Build Coastguard Worker GameMode); 298*38e8c45fSAndroid Build Coastguard Worker void flushPowerTimeLocked(); 299*38e8c45fSAndroid Build Coastguard Worker void flushAvailableGlobalRecordsToStatsLocked(); 300*38e8c45fSAndroid Build Coastguard Worker bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName, GameMode); 301*38e8c45fSAndroid Build Coastguard Worker 302*38e8c45fSAndroid Build Coastguard Worker void enable(); 303*38e8c45fSAndroid Build Coastguard Worker void disable(); 304*38e8c45fSAndroid Build Coastguard Worker void clearAll(); 305*38e8c45fSAndroid Build Coastguard Worker void clearGlobalLocked(); 306*38e8c45fSAndroid Build Coastguard Worker void clearLayersLocked(); 307*38e8c45fSAndroid Build Coastguard Worker void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result); 308*38e8c45fSAndroid Build Coastguard Worker 309*38e8c45fSAndroid Build Coastguard Worker std::atomic<bool> mEnabled = false; 310*38e8c45fSAndroid Build Coastguard Worker std::mutex mMutex; 311*38e8c45fSAndroid Build Coastguard Worker TimeStatsHelper::TimeStatsGlobal mTimeStats; 312*38e8c45fSAndroid Build Coastguard Worker // Hashmap for LayerRecord with layerId as the hash key 313*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker; 314*38e8c45fSAndroid Build Coastguard Worker PowerTime mPowerTime; 315*38e8c45fSAndroid Build Coastguard Worker GlobalRecord mGlobalRecord; 316*38e8c45fSAndroid Build Coastguard Worker 317*38e8c45fSAndroid Build Coastguard Worker static const size_t MAX_NUM_LAYER_RECORDS = 200; 318*38e8c45fSAndroid Build Coastguard Worker 319*38e8c45fSAndroid Build Coastguard Worker static const size_t REFRESH_RATE_BUCKET_WIDTH = 30; 320*38e8c45fSAndroid Build Coastguard Worker static const size_t RENDER_RATE_BUCKET_WIDTH = REFRESH_RATE_BUCKET_WIDTH; 321*38e8c45fSAndroid Build Coastguard Worker static const size_t MAX_NUM_LAYER_STATS = 200; 322*38e8c45fSAndroid Build Coastguard Worker static const size_t MAX_NUM_PULLED_LAYERS = MAX_NUM_LAYER_STATS; 323*38e8c45fSAndroid Build Coastguard Worker size_t mMaxPulledLayers = MAX_NUM_PULLED_LAYERS; 324*38e8c45fSAndroid Build Coastguard Worker size_t mMaxPulledHistogramBuckets = 6; 325*38e8c45fSAndroid Build Coastguard Worker }; 326*38e8c45fSAndroid Build Coastguard Worker 327*38e8c45fSAndroid Build Coastguard Worker } // namespace impl 328*38e8c45fSAndroid Build Coastguard Worker 329*38e8c45fSAndroid Build Coastguard Worker } // namespace android 330