JankTracker.h revision df1742ed47da1e9b61afeae16fa448d5302a8aa0
1/*
2 * Copyright (C) 2015 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#ifndef JANKTRACKER_H_
17#define JANKTRACKER_H_
18
19#include "FrameInfo.h"
20#include "renderthread/TimeLord.h"
21#include "utils/RingBuffer.h"
22
23#include <cutils/compiler.h>
24#include <ui/DisplayInfo.h>
25
26#include <array>
27#include <memory>
28
29namespace android {
30namespace uirenderer {
31
32enum JankType {
33    kMissedVsync = 0,
34    kHighInputLatency,
35    kSlowUI,
36    kSlowSync,
37    kSlowRT,
38
39    // must be last
40    NUM_BUCKETS,
41};
42
43// Try to keep as small as possible, should match ASHMEM_SIZE in
44// GraphicsStatsService.java
45struct ProfileData {
46    std::array<uint32_t, NUM_BUCKETS> jankTypeCounts;
47    // See comments on kBucket* constants for what this holds
48    std::array<uint32_t, 57> frameCounts;
49    // Holds a histogram of frame times in 50ms increments from 150ms to 5s
50    std::array<uint16_t, 97> slowFrameCounts;
51
52    uint32_t totalFrameCount;
53    uint32_t jankFrameCount;
54    nsecs_t statStartTime;
55};
56
57enum class JankTrackerType {
58    // The default, means there's no description set
59    Generic,
60    // The profile data represents a package
61    Package,
62    // The profile data is for a specific window
63    Window,
64};
65
66// Metadata about the ProfileData being collected
67struct ProfileDataDescription {
68    JankTrackerType type;
69    std::string name;
70};
71
72// TODO: Replace DrawProfiler with this
73class JankTracker {
74public:
75    explicit JankTracker(const DisplayInfo& displayInfo);
76    ~JankTracker();
77
78    void setDescription(JankTrackerType type, const std::string&& name) {
79        mDescription.type = type;
80        mDescription.name = name;
81    }
82
83    void addFrame(const FrameInfo& frame);
84
85    void dump(int fd) { dumpData(fd, &mDescription, mData); }
86    void reset();
87
88    void rotateStorage();
89    void switchStorageToAshmem(int ashmemfd);
90
91    uint32_t findPercentile(int p) { return findPercentile(mData, p); }
92    static int32_t frameTimeForFrameCountIndex(uint32_t index);
93    static int32_t frameTimeForSlowFrameCountIndex(uint32_t index);
94
95private:
96    void freeData();
97    void setFrameInterval(nsecs_t frameIntervalNanos);
98
99    static uint32_t findPercentile(const ProfileData* data, int p);
100    static void dumpData(int fd, const ProfileDataDescription* description, const ProfileData* data);
101
102    std::array<int64_t, NUM_BUCKETS> mThresholds;
103    int64_t mFrameInterval;
104    // The amount of time we will erase from the total duration to account
105    // for SF vsync offsets with HWC2 blocking dequeueBuffers.
106    // (Vsync + mDequeueBlockTolerance) is the point at which we expect
107    // SF to have released the buffer normally, so we will forgive up to that
108    // point in time by comparing to (IssueDrawCommandsStart + DequeueDuration)
109    // This is only used if we are in pipelined mode and are using HWC2,
110    // otherwise it's 0.
111    nsecs_t mDequeueTimeForgiveness = 0;
112    ProfileData* mData;
113    bool mIsMapped = false;
114    ProfileDataDescription mDescription;
115};
116
117} /* namespace uirenderer */
118} /* namespace android */
119
120#endif /* JANKTRACKER_H_ */
121