xref: /aosp_15_r20/frameworks/base/libs/hwui/JankTracker.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include "JankTracker.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <cutils/ashmem.h>
20*d57664e9SAndroid Build Coastguard Worker #include <cutils/trace.h>
21*d57664e9SAndroid Build Coastguard Worker #include <errno.h>
22*d57664e9SAndroid Build Coastguard Worker #include <inttypes.h>
23*d57664e9SAndroid Build Coastguard Worker #include <log/log.h>
24*d57664e9SAndroid Build Coastguard Worker 
25*d57664e9SAndroid Build Coastguard Worker #include <algorithm>
26*d57664e9SAndroid Build Coastguard Worker #include <cmath>
27*d57664e9SAndroid Build Coastguard Worker #include <cstdio>
28*d57664e9SAndroid Build Coastguard Worker #include <limits>
29*d57664e9SAndroid Build Coastguard Worker #include <sstream>
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker #include "DeviceInfo.h"
32*d57664e9SAndroid Build Coastguard Worker #include "Properties.h"
33*d57664e9SAndroid Build Coastguard Worker #include "utils/TimeUtils.h"
34*d57664e9SAndroid Build Coastguard Worker #include "utils/Trace.h"
35*d57664e9SAndroid Build Coastguard Worker 
36*d57664e9SAndroid Build Coastguard Worker namespace android {
37*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
38*d57664e9SAndroid Build Coastguard Worker 
39*d57664e9SAndroid Build Coastguard Worker struct Comparison {
40*d57664e9SAndroid Build Coastguard Worker     JankType type;
41*d57664e9SAndroid Build Coastguard Worker     std::function<int64_t(nsecs_t)> computeThreadshold;
42*d57664e9SAndroid Build Coastguard Worker     FrameInfoIndex start;
43*d57664e9SAndroid Build Coastguard Worker     FrameInfoIndex end;
44*d57664e9SAndroid Build Coastguard Worker };
45*d57664e9SAndroid Build Coastguard Worker 
46*d57664e9SAndroid Build Coastguard Worker static const std::array<Comparison, 4> COMPARISONS{
__anon9f1275350102() 47*d57664e9SAndroid Build Coastguard Worker         Comparison{JankType::kMissedVsync, [](nsecs_t) { return 1; }, FrameInfoIndex::IntendedVsync,
48*d57664e9SAndroid Build Coastguard Worker                    FrameInfoIndex::Vsync},
49*d57664e9SAndroid Build Coastguard Worker 
50*d57664e9SAndroid Build Coastguard Worker         Comparison{JankType::kSlowUI,
__anon9f1275350202() 51*d57664e9SAndroid Build Coastguard Worker                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.5 * frameInterval); },
52*d57664e9SAndroid Build Coastguard Worker                    FrameInfoIndex::Vsync, FrameInfoIndex::SyncStart},
53*d57664e9SAndroid Build Coastguard Worker 
54*d57664e9SAndroid Build Coastguard Worker         Comparison{JankType::kSlowSync,
__anon9f1275350302() 55*d57664e9SAndroid Build Coastguard Worker                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.2 * frameInterval); },
56*d57664e9SAndroid Build Coastguard Worker                    FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart},
57*d57664e9SAndroid Build Coastguard Worker 
58*d57664e9SAndroid Build Coastguard Worker         Comparison{JankType::kSlowRT,
__anon9f1275350402() 59*d57664e9SAndroid Build Coastguard Worker                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.75 * frameInterval); },
60*d57664e9SAndroid Build Coastguard Worker                    FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::FrameCompleted},
61*d57664e9SAndroid Build Coastguard Worker };
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker // If the event exceeds 10 seconds throw it away, this isn't a jank event
64*d57664e9SAndroid Build Coastguard Worker // it's an ANR and will be handled as such
65*d57664e9SAndroid Build Coastguard Worker static const int64_t IGNORE_EXCEEDING = seconds_to_nanoseconds(10);
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker /*
68*d57664e9SAndroid Build Coastguard Worker  * We don't track direct-drawing via Surface:lockHardwareCanvas()
69*d57664e9SAndroid Build Coastguard Worker  * for now
70*d57664e9SAndroid Build Coastguard Worker  *
71*d57664e9SAndroid Build Coastguard Worker  * TODO: kSurfaceCanvas can negatively impact other drawing by using up
72*d57664e9SAndroid Build Coastguard Worker  * time on the RenderThread, figure out how to attribute that as a jank-causer
73*d57664e9SAndroid Build Coastguard Worker  */
74*d57664e9SAndroid Build Coastguard Worker static const int64_t EXEMPT_FRAMES_FLAGS = FrameInfoFlags::SurfaceCanvas;
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker // For testing purposes to try and eliminate test infra overhead we will
77*d57664e9SAndroid Build Coastguard Worker // consider any unknown delay of frame start as part of the test infrastructure
78*d57664e9SAndroid Build Coastguard Worker // and filter it out of the frame profile data
79*d57664e9SAndroid Build Coastguard Worker static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
80*d57664e9SAndroid Build Coastguard Worker 
JankTracker(ProfileDataContainer * globalData)81*d57664e9SAndroid Build Coastguard Worker JankTracker::JankTracker(ProfileDataContainer* globalData)
82*d57664e9SAndroid Build Coastguard Worker         : mData(globalData->getDataMutex())
83*d57664e9SAndroid Build Coastguard Worker         , mDataMutex(globalData->getDataMutex()) {
84*d57664e9SAndroid Build Coastguard Worker     mGlobalData = globalData;
85*d57664e9SAndroid Build Coastguard Worker     nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod();
86*d57664e9SAndroid Build Coastguard Worker     nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
87*d57664e9SAndroid Build Coastguard Worker     nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
88*d57664e9SAndroid Build Coastguard Worker     // There are two different offset cases. If the offsetDelta is positive
89*d57664e9SAndroid Build Coastguard Worker     // and small, then the intention is to give apps extra time by leveraging
90*d57664e9SAndroid Build Coastguard Worker     // pipelining between the UI & RT threads. If the offsetDelta is large or
91*d57664e9SAndroid Build Coastguard Worker     // negative, the intention is to subtract time from the total duration
92*d57664e9SAndroid Build Coastguard Worker     // in which case we can't afford to wait for dequeueBuffer blockage.
93*d57664e9SAndroid Build Coastguard Worker     if (offsetDelta <= 4_ms && offsetDelta >= 0) {
94*d57664e9SAndroid Build Coastguard Worker         // SF will begin composition at VSYNC-app + offsetDelta. If we are triple
95*d57664e9SAndroid Build Coastguard Worker         // buffered, this is the expected time at which dequeueBuffer will
96*d57664e9SAndroid Build Coastguard Worker         // return due to the staggering of VSYNC-app & VSYNC-sf.
97*d57664e9SAndroid Build Coastguard Worker         mDequeueTimeForgivenessLegacy = offsetDelta + 4_ms;
98*d57664e9SAndroid Build Coastguard Worker     }
99*d57664e9SAndroid Build Coastguard Worker     mFrameIntervalLegacy = frameIntervalNanos;
100*d57664e9SAndroid Build Coastguard Worker }
101*d57664e9SAndroid Build Coastguard Worker 
calculateLegacyJank(FrameInfo & frame)102*d57664e9SAndroid Build Coastguard Worker void JankTracker::calculateLegacyJank(FrameInfo& frame) REQUIRES(mDataMutex) {
103*d57664e9SAndroid Build Coastguard Worker     // Fast-path for jank-free frames
104*d57664e9SAndroid Build Coastguard Worker     int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted);
105*d57664e9SAndroid Build Coastguard Worker     if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) {
106*d57664e9SAndroid Build Coastguard Worker         nsecs_t expectedDequeueDuration = mDequeueTimeForgivenessLegacy
107*d57664e9SAndroid Build Coastguard Worker                                           + frame[FrameInfoIndex::Vsync]
108*d57664e9SAndroid Build Coastguard Worker                                           - frame[FrameInfoIndex::IssueDrawCommandsStart];
109*d57664e9SAndroid Build Coastguard Worker         if (expectedDequeueDuration > 0) {
110*d57664e9SAndroid Build Coastguard Worker             // Forgive only up to the expected amount, but not more than
111*d57664e9SAndroid Build Coastguard Worker             // the actual time spent blocked.
112*d57664e9SAndroid Build Coastguard Worker             nsecs_t forgiveAmount =
113*d57664e9SAndroid Build Coastguard Worker                     std::min(expectedDequeueDuration, frame[FrameInfoIndex::DequeueBufferDuration]);
114*d57664e9SAndroid Build Coastguard Worker             if (forgiveAmount >= totalDuration) {
115*d57664e9SAndroid Build Coastguard Worker                 ALOGV("Impossible dequeue duration! dequeue duration reported %" PRId64
116*d57664e9SAndroid Build Coastguard Worker                       ", total duration %" PRId64,
117*d57664e9SAndroid Build Coastguard Worker                       forgiveAmount, totalDuration);
118*d57664e9SAndroid Build Coastguard Worker                 return;
119*d57664e9SAndroid Build Coastguard Worker             }
120*d57664e9SAndroid Build Coastguard Worker             totalDuration -= forgiveAmount;
121*d57664e9SAndroid Build Coastguard Worker         }
122*d57664e9SAndroid Build Coastguard Worker     }
123*d57664e9SAndroid Build Coastguard Worker 
124*d57664e9SAndroid Build Coastguard Worker     if (totalDuration <= 0) {
125*d57664e9SAndroid Build Coastguard Worker         ALOGV("Impossible totalDuration %" PRId64 " start=%" PRIi64 " gpuComplete=%" PRIi64,
126*d57664e9SAndroid Build Coastguard Worker               totalDuration, frame[FrameInfoIndex::IntendedVsync],
127*d57664e9SAndroid Build Coastguard Worker               frame[FrameInfoIndex::GpuCompleted]);
128*d57664e9SAndroid Build Coastguard Worker         return;
129*d57664e9SAndroid Build Coastguard Worker     }
130*d57664e9SAndroid Build Coastguard Worker 
131*d57664e9SAndroid Build Coastguard Worker     // Only things like Surface.lockHardwareCanvas() are exempt from tracking
132*d57664e9SAndroid Build Coastguard Worker     if (CC_UNLIKELY(frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS)) {
133*d57664e9SAndroid Build Coastguard Worker         return;
134*d57664e9SAndroid Build Coastguard Worker     }
135*d57664e9SAndroid Build Coastguard Worker 
136*d57664e9SAndroid Build Coastguard Worker     if (totalDuration > mFrameIntervalLegacy) {
137*d57664e9SAndroid Build Coastguard Worker         mData->reportJankLegacy();
138*d57664e9SAndroid Build Coastguard Worker         (*mGlobalData)->reportJankLegacy();
139*d57664e9SAndroid Build Coastguard Worker     }
140*d57664e9SAndroid Build Coastguard Worker 
141*d57664e9SAndroid Build Coastguard Worker     if (mSwapDeadlineLegacy < 0) {
142*d57664e9SAndroid Build Coastguard Worker         mSwapDeadlineLegacy = frame[FrameInfoIndex::IntendedVsync] + mFrameIntervalLegacy;
143*d57664e9SAndroid Build Coastguard Worker     }
144*d57664e9SAndroid Build Coastguard Worker     bool isTripleBuffered = (mSwapDeadlineLegacy - frame[FrameInfoIndex::IntendedVsync])
145*d57664e9SAndroid Build Coastguard Worker             > (mFrameIntervalLegacy * 0.1);
146*d57664e9SAndroid Build Coastguard Worker 
147*d57664e9SAndroid Build Coastguard Worker     mSwapDeadlineLegacy = std::max(mSwapDeadlineLegacy + mFrameIntervalLegacy,
148*d57664e9SAndroid Build Coastguard Worker                              frame[FrameInfoIndex::IntendedVsync] + mFrameIntervalLegacy);
149*d57664e9SAndroid Build Coastguard Worker 
150*d57664e9SAndroid Build Coastguard Worker     // If we hit the deadline, cool!
151*d57664e9SAndroid Build Coastguard Worker     if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadlineLegacy
152*d57664e9SAndroid Build Coastguard Worker             || totalDuration < mFrameIntervalLegacy) {
153*d57664e9SAndroid Build Coastguard Worker         if (isTripleBuffered) {
154*d57664e9SAndroid Build Coastguard Worker             mData->reportJankType(JankType::kHighInputLatency);
155*d57664e9SAndroid Build Coastguard Worker             (*mGlobalData)->reportJankType(JankType::kHighInputLatency);
156*d57664e9SAndroid Build Coastguard Worker         }
157*d57664e9SAndroid Build Coastguard Worker         return;
158*d57664e9SAndroid Build Coastguard Worker     }
159*d57664e9SAndroid Build Coastguard Worker 
160*d57664e9SAndroid Build Coastguard Worker     mData->reportJankType(JankType::kMissedDeadlineLegacy);
161*d57664e9SAndroid Build Coastguard Worker     (*mGlobalData)->reportJankType(JankType::kMissedDeadlineLegacy);
162*d57664e9SAndroid Build Coastguard Worker 
163*d57664e9SAndroid Build Coastguard Worker     // Janked, reset the swap deadline
164*d57664e9SAndroid Build Coastguard Worker     nsecs_t jitterNanos = frame[FrameInfoIndex::FrameCompleted] - frame[FrameInfoIndex::Vsync];
165*d57664e9SAndroid Build Coastguard Worker     nsecs_t lastFrameOffset = jitterNanos % mFrameIntervalLegacy;
166*d57664e9SAndroid Build Coastguard Worker     mSwapDeadlineLegacy = frame[FrameInfoIndex::FrameCompleted]
167*d57664e9SAndroid Build Coastguard Worker             - lastFrameOffset + mFrameIntervalLegacy;
168*d57664e9SAndroid Build Coastguard Worker }
169*d57664e9SAndroid Build Coastguard Worker 
finishFrame(FrameInfo & frame,std::unique_ptr<FrameMetricsReporter> & reporter,int64_t frameNumber,int32_t surfaceControlId)170*d57664e9SAndroid Build Coastguard Worker void JankTracker::finishFrame(FrameInfo& frame, std::unique_ptr<FrameMetricsReporter>& reporter,
171*d57664e9SAndroid Build Coastguard Worker                               int64_t frameNumber, int32_t surfaceControlId) {
172*d57664e9SAndroid Build Coastguard Worker     std::lock_guard lock(mDataMutex);
173*d57664e9SAndroid Build Coastguard Worker 
174*d57664e9SAndroid Build Coastguard Worker     calculateLegacyJank(frame);
175*d57664e9SAndroid Build Coastguard Worker 
176*d57664e9SAndroid Build Coastguard Worker     // Fast-path for jank-free frames
177*d57664e9SAndroid Build Coastguard Worker     int64_t totalDuration = frame.duration(FrameInfoIndex::IntendedVsync,
178*d57664e9SAndroid Build Coastguard Worker             FrameInfoIndex::FrameCompleted);
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker     if (totalDuration <= 0) {
181*d57664e9SAndroid Build Coastguard Worker         ALOGV("Impossible totalDuration %" PRId64, totalDuration);
182*d57664e9SAndroid Build Coastguard Worker         return;
183*d57664e9SAndroid Build Coastguard Worker     }
184*d57664e9SAndroid Build Coastguard Worker     mData->reportFrame(totalDuration);
185*d57664e9SAndroid Build Coastguard Worker     (*mGlobalData)->reportFrame(totalDuration);
186*d57664e9SAndroid Build Coastguard Worker 
187*d57664e9SAndroid Build Coastguard Worker     // Only things like Surface.lockHardwareCanvas() are exempt from tracking
188*d57664e9SAndroid Build Coastguard Worker     if (CC_UNLIKELY(frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS)) {
189*d57664e9SAndroid Build Coastguard Worker         return;
190*d57664e9SAndroid Build Coastguard Worker     }
191*d57664e9SAndroid Build Coastguard Worker 
192*d57664e9SAndroid Build Coastguard Worker     int64_t frameInterval = frame[FrameInfoIndex::FrameInterval];
193*d57664e9SAndroid Build Coastguard Worker 
194*d57664e9SAndroid Build Coastguard Worker     // If we starter earlier than the intended frame start assuming an unstuffed scenario, it means
195*d57664e9SAndroid Build Coastguard Worker     // that we are in a triple buffering situation.
196*d57664e9SAndroid Build Coastguard Worker     bool isTripleBuffered = (mNextFrameStartUnstuffed - frame[FrameInfoIndex::IntendedVsync])
197*d57664e9SAndroid Build Coastguard Worker                     > (frameInterval * 0.1);
198*d57664e9SAndroid Build Coastguard Worker 
199*d57664e9SAndroid Build Coastguard Worker     int64_t deadline = frame[FrameInfoIndex::FrameDeadline];
200*d57664e9SAndroid Build Coastguard Worker 
201*d57664e9SAndroid Build Coastguard Worker     // If we are in triple buffering, we have enough buffers in queue to sustain a single frame
202*d57664e9SAndroid Build Coastguard Worker     // drop without jank, so adjust the frame interval to the deadline.
203*d57664e9SAndroid Build Coastguard Worker     if (isTripleBuffered) {
204*d57664e9SAndroid Build Coastguard Worker         int64_t originalDeadlineDuration = deadline - frame[FrameInfoIndex::IntendedVsync];
205*d57664e9SAndroid Build Coastguard Worker         deadline = mNextFrameStartUnstuffed + originalDeadlineDuration;
206*d57664e9SAndroid Build Coastguard Worker         frame.set(FrameInfoIndex::FrameDeadline) = deadline;
207*d57664e9SAndroid Build Coastguard Worker     }
208*d57664e9SAndroid Build Coastguard Worker 
209*d57664e9SAndroid Build Coastguard Worker     // If we hit the deadline, cool!
210*d57664e9SAndroid Build Coastguard Worker     if (frame[FrameInfoIndex::GpuCompleted] < deadline) {
211*d57664e9SAndroid Build Coastguard Worker         if (isTripleBuffered) {
212*d57664e9SAndroid Build Coastguard Worker             mData->reportJankType(JankType::kHighInputLatency);
213*d57664e9SAndroid Build Coastguard Worker             (*mGlobalData)->reportJankType(JankType::kHighInputLatency);
214*d57664e9SAndroid Build Coastguard Worker 
215*d57664e9SAndroid Build Coastguard Worker             // Buffer stuffing state gets carried over to next frame, unless there is a "pause"
216*d57664e9SAndroid Build Coastguard Worker             mNextFrameStartUnstuffed += frameInterval;
217*d57664e9SAndroid Build Coastguard Worker         }
218*d57664e9SAndroid Build Coastguard Worker     } else {
219*d57664e9SAndroid Build Coastguard Worker         mData->reportJankType(JankType::kMissedDeadline);
220*d57664e9SAndroid Build Coastguard Worker         (*mGlobalData)->reportJankType(JankType::kMissedDeadline);
221*d57664e9SAndroid Build Coastguard Worker         mData->reportJank();
222*d57664e9SAndroid Build Coastguard Worker         (*mGlobalData)->reportJank();
223*d57664e9SAndroid Build Coastguard Worker 
224*d57664e9SAndroid Build Coastguard Worker         // Janked, store the adjust deadline to detect triple buffering in next frame correctly.
225*d57664e9SAndroid Build Coastguard Worker         nsecs_t jitterNanos = frame[FrameInfoIndex::GpuCompleted]
226*d57664e9SAndroid Build Coastguard Worker                 - frame[FrameInfoIndex::Vsync];
227*d57664e9SAndroid Build Coastguard Worker         nsecs_t lastFrameOffset = jitterNanos % frameInterval;
228*d57664e9SAndroid Build Coastguard Worker 
229*d57664e9SAndroid Build Coastguard Worker         // Note the time when the next frame would start in an unstuffed situation. If it starts
230*d57664e9SAndroid Build Coastguard Worker         // earlier, we are in a stuffed situation.
231*d57664e9SAndroid Build Coastguard Worker         mNextFrameStartUnstuffed = frame[FrameInfoIndex::GpuCompleted]
232*d57664e9SAndroid Build Coastguard Worker                 - lastFrameOffset + frameInterval;
233*d57664e9SAndroid Build Coastguard Worker 
234*d57664e9SAndroid Build Coastguard Worker         recomputeThresholds(frameInterval);
235*d57664e9SAndroid Build Coastguard Worker         for (auto& comparison : COMPARISONS) {
236*d57664e9SAndroid Build Coastguard Worker             int64_t delta = frame.duration(comparison.start, comparison.end);
237*d57664e9SAndroid Build Coastguard Worker             if (delta >= mThresholds[comparison.type] && delta < IGNORE_EXCEEDING) {
238*d57664e9SAndroid Build Coastguard Worker                 mData->reportJankType(comparison.type);
239*d57664e9SAndroid Build Coastguard Worker                 (*mGlobalData)->reportJankType(comparison.type);
240*d57664e9SAndroid Build Coastguard Worker             }
241*d57664e9SAndroid Build Coastguard Worker         }
242*d57664e9SAndroid Build Coastguard Worker 
243*d57664e9SAndroid Build Coastguard Worker         // Log daveys since they are weird and we don't know what they are (b/70339576)
244*d57664e9SAndroid Build Coastguard Worker         if (totalDuration >= 700_ms) {
245*d57664e9SAndroid Build Coastguard Worker             static int sDaveyCount = 0;
246*d57664e9SAndroid Build Coastguard Worker             std::stringstream ss;
247*d57664e9SAndroid Build Coastguard Worker             ss << "Davey! duration=" << ns2ms(totalDuration) << "ms; ";
248*d57664e9SAndroid Build Coastguard Worker             for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
249*d57664e9SAndroid Build Coastguard Worker                 ss << FrameInfoNames[i] << "=" << frame[i] << ", ";
250*d57664e9SAndroid Build Coastguard Worker             }
251*d57664e9SAndroid Build Coastguard Worker             ALOGI("%s", ss.str().c_str());
252*d57664e9SAndroid Build Coastguard Worker             // Just so we have something that counts up, the value is largely irrelevant
253*d57664e9SAndroid Build Coastguard Worker             ATRACE_INT(ss.str().c_str(), ++sDaveyCount);
254*d57664e9SAndroid Build Coastguard Worker         }
255*d57664e9SAndroid Build Coastguard Worker     }
256*d57664e9SAndroid Build Coastguard Worker 
257*d57664e9SAndroid Build Coastguard Worker     int64_t totalGPUDrawTime = frame.gpuDrawTime();
258*d57664e9SAndroid Build Coastguard Worker     if (totalGPUDrawTime >= 0) {
259*d57664e9SAndroid Build Coastguard Worker         mData->reportGPUFrame(totalGPUDrawTime);
260*d57664e9SAndroid Build Coastguard Worker         (*mGlobalData)->reportGPUFrame(totalGPUDrawTime);
261*d57664e9SAndroid Build Coastguard Worker     }
262*d57664e9SAndroid Build Coastguard Worker 
263*d57664e9SAndroid Build Coastguard Worker     if (CC_UNLIKELY(reporter.get() != nullptr)) {
264*d57664e9SAndroid Build Coastguard Worker         reporter->reportFrameMetrics(frame.data(), false /* hasPresentTime */, frameNumber,
265*d57664e9SAndroid Build Coastguard Worker                                      surfaceControlId);
266*d57664e9SAndroid Build Coastguard Worker     }
267*d57664e9SAndroid Build Coastguard Worker }
268*d57664e9SAndroid Build Coastguard Worker 
recomputeThresholds(int64_t frameBudget)269*d57664e9SAndroid Build Coastguard Worker void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex) {
270*d57664e9SAndroid Build Coastguard Worker     if (mThresholdsFrameBudget == frameBudget) {
271*d57664e9SAndroid Build Coastguard Worker         return;
272*d57664e9SAndroid Build Coastguard Worker     }
273*d57664e9SAndroid Build Coastguard Worker     mThresholdsFrameBudget = frameBudget;
274*d57664e9SAndroid Build Coastguard Worker     for (auto& comparison : COMPARISONS) {
275*d57664e9SAndroid Build Coastguard Worker         mThresholds[comparison.type] = comparison.computeThreadshold(frameBudget);
276*d57664e9SAndroid Build Coastguard Worker     }
277*d57664e9SAndroid Build Coastguard Worker }
278*d57664e9SAndroid Build Coastguard Worker 
dumpData(int fd,const ProfileDataDescription * description,const ProfileData * data)279*d57664e9SAndroid Build Coastguard Worker void JankTracker::dumpData(int fd, const ProfileDataDescription* description,
280*d57664e9SAndroid Build Coastguard Worker                            const ProfileData* data) {
281*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__
282*d57664e9SAndroid Build Coastguard Worker     if (description) {
283*d57664e9SAndroid Build Coastguard Worker         switch (description->type) {
284*d57664e9SAndroid Build Coastguard Worker             case JankTrackerType::Generic:
285*d57664e9SAndroid Build Coastguard Worker                 break;
286*d57664e9SAndroid Build Coastguard Worker             case JankTrackerType::Package:
287*d57664e9SAndroid Build Coastguard Worker                 dprintf(fd, "\nPackage: %s", description->name.c_str());
288*d57664e9SAndroid Build Coastguard Worker                 break;
289*d57664e9SAndroid Build Coastguard Worker             case JankTrackerType::Window:
290*d57664e9SAndroid Build Coastguard Worker                 dprintf(fd, "\nWindow: %s", description->name.c_str());
291*d57664e9SAndroid Build Coastguard Worker                 break;
292*d57664e9SAndroid Build Coastguard Worker         }
293*d57664e9SAndroid Build Coastguard Worker     }
294*d57664e9SAndroid Build Coastguard Worker     if (sFrameStart != FrameInfoIndex::IntendedVsync) {
295*d57664e9SAndroid Build Coastguard Worker         dprintf(fd, "\nNote: Data has been filtered!");
296*d57664e9SAndroid Build Coastguard Worker     }
297*d57664e9SAndroid Build Coastguard Worker     data->dump(fd);
298*d57664e9SAndroid Build Coastguard Worker     dprintf(fd, "\n");
299*d57664e9SAndroid Build Coastguard Worker #endif
300*d57664e9SAndroid Build Coastguard Worker }
301*d57664e9SAndroid Build Coastguard Worker 
dumpFrames(int fd)302*d57664e9SAndroid Build Coastguard Worker void JankTracker::dumpFrames(int fd) {
303*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__
304*d57664e9SAndroid Build Coastguard Worker     dprintf(fd, "\n\n---PROFILEDATA---\n");
305*d57664e9SAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
306*d57664e9SAndroid Build Coastguard Worker         dprintf(fd, "%s", FrameInfoNames[i]);
307*d57664e9SAndroid Build Coastguard Worker         dprintf(fd, ",");
308*d57664e9SAndroid Build Coastguard Worker     }
309*d57664e9SAndroid Build Coastguard Worker     for (size_t i = 0; i < mFrames.size(); i++) {
310*d57664e9SAndroid Build Coastguard Worker         FrameInfo& frame = mFrames[i];
311*d57664e9SAndroid Build Coastguard Worker         if (frame[FrameInfoIndex::SyncStart] == 0) {
312*d57664e9SAndroid Build Coastguard Worker             continue;
313*d57664e9SAndroid Build Coastguard Worker         }
314*d57664e9SAndroid Build Coastguard Worker         dprintf(fd, "\n");
315*d57664e9SAndroid Build Coastguard Worker         for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) {
316*d57664e9SAndroid Build Coastguard Worker             dprintf(fd, "%" PRId64 ",", frame[i]);
317*d57664e9SAndroid Build Coastguard Worker         }
318*d57664e9SAndroid Build Coastguard Worker     }
319*d57664e9SAndroid Build Coastguard Worker     dprintf(fd, "\n---PROFILEDATA---\n\n");
320*d57664e9SAndroid Build Coastguard Worker #endif
321*d57664e9SAndroid Build Coastguard Worker }
322*d57664e9SAndroid Build Coastguard Worker 
reset()323*d57664e9SAndroid Build Coastguard Worker void JankTracker::reset() REQUIRES(mDataMutex) {
324*d57664e9SAndroid Build Coastguard Worker     mFrames.clear();
325*d57664e9SAndroid Build Coastguard Worker     mData->reset();
326*d57664e9SAndroid Build Coastguard Worker     (*mGlobalData)->reset();
327*d57664e9SAndroid Build Coastguard Worker     sFrameStart = Properties::filterOutTestOverhead ? FrameInfoIndex::HandleInputStart
328*d57664e9SAndroid Build Coastguard Worker                                                     : FrameInfoIndex::IntendedVsync;
329*d57664e9SAndroid Build Coastguard Worker }
330*d57664e9SAndroid Build Coastguard Worker 
331*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */
332*d57664e9SAndroid Build Coastguard Worker } /* namespace android */
333