blob: 9be194c952e17bec9356ab7900f4b962a8bb78d1 [file] [log] [blame]
John Reck7075c792017-07-05 14:03:43 -07001/*
2 * Copyright (C) 2017 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
Stan Iliev637ba5e2019-08-16 13:43:08 -040019#include "Properties.h"
John Reck7075c792017-07-05 14:03:43 -070020#include "utils/Macros.h"
21
22#include <utils/Timers.h>
23
24#include <array>
25#include <functional>
26#include <tuple>
27
28namespace android {
29namespace uirenderer {
30
31enum JankType {
32 kMissedVsync = 0,
33 kHighInputLatency,
34 kSlowUI,
35 kSlowSync,
36 kSlowRT,
John Reck0e486472018-03-19 14:06:16 -070037 kMissedDeadline,
Jorim Jaggi10f328c2021-01-19 00:08:02 +010038 kMissedDeadlineLegacy,
John Reck7075c792017-07-05 14:03:43 -070039
40 // must be last
41 NUM_BUCKETS,
42};
43
44// For testing
45class MockProfileData;
46
47// Try to keep as small as possible, should match ASHMEM_SIZE in
48// GraphicsStatsService.java
49class ProfileData {
50 PREVENT_COPY_AND_ASSIGN(ProfileData);
51
52public:
53 ProfileData() { reset(); }
54
55 void reset();
56 void mergeWith(const ProfileData& other);
57 void dump(int fd) const;
58 uint32_t findPercentile(int percentile) const;
Stan Iliev7203e1f2019-07-25 13:12:02 -040059 uint32_t findGPUPercentile(int percentile) const;
John Reck7075c792017-07-05 14:03:43 -070060
61 void reportFrame(int64_t duration);
Stan Iliev7203e1f2019-07-25 13:12:02 -040062 void reportGPUFrame(int64_t duration);
John Reck7075c792017-07-05 14:03:43 -070063 void reportJank() { mJankFrameCount++; }
Jorim Jaggi10f328c2021-01-19 00:08:02 +010064 void reportJankLegacy() { mJankLegacyFrameCount++; }
John Reck7075c792017-07-05 14:03:43 -070065 void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; }
66
67 uint32_t totalFrameCount() const { return mTotalFrameCount; }
68 uint32_t jankFrameCount() const { return mJankFrameCount; }
Jorim Jaggi10f328c2021-01-19 00:08:02 +010069 uint32_t jankLegacyFrameCount() const { return mJankLegacyFrameCount; }
John Reck7075c792017-07-05 14:03:43 -070070 nsecs_t statsStartTime() const { return mStatStartTime; }
71 uint32_t jankTypeCount(JankType type) const { return mJankTypeCounts[static_cast<int>(type)]; }
Stan Iliev637ba5e2019-08-16 13:43:08 -040072 RenderPipelineType pipelineType() const { return mPipelineType; }
John Reck7075c792017-07-05 14:03:43 -070073
74 struct HistogramEntry {
75 uint32_t renderTimeMs;
76 uint32_t frameCount;
77 };
78 void histogramForEach(const std::function<void(HistogramEntry)>& callback) const;
Stan Iliev7203e1f2019-07-25 13:12:02 -040079 void histogramGPUForEach(const std::function<void(HistogramEntry)>& callback) const;
John Reck7075c792017-07-05 14:03:43 -070080
81 constexpr static int HistogramSize() {
John Reck1bcacfd2017-11-03 10:12:19 -070082 return std::tuple_size<decltype(ProfileData::mFrameCounts)>::value +
83 std::tuple_size<decltype(ProfileData::mSlowFrameCounts)>::value;
John Reck7075c792017-07-05 14:03:43 -070084 }
85
Stan Iliev7203e1f2019-07-25 13:12:02 -040086 constexpr static int GPUHistogramSize() {
87 return std::tuple_size<decltype(ProfileData::mGPUFrameCounts)>::value;
88 }
89
John Reck7075c792017-07-05 14:03:43 -070090 // Visible for testing
91 static uint32_t frameTimeForFrameCountIndex(uint32_t index);
92 static uint32_t frameTimeForSlowFrameCountIndex(uint32_t index);
Stan Iliev7203e1f2019-07-25 13:12:02 -040093 static uint32_t GPUFrameTimeForFrameCountIndex(uint32_t index);
John Reck7075c792017-07-05 14:03:43 -070094
95private:
96 // Open our guts up to unit tests
97 friend class MockProfileData;
98
John Reck1bcacfd2017-11-03 10:12:19 -070099 std::array<uint32_t, NUM_BUCKETS> mJankTypeCounts;
John Reck7075c792017-07-05 14:03:43 -0700100 // See comments on kBucket* constants for what this holds
101 std::array<uint32_t, 57> mFrameCounts;
102 // Holds a histogram of frame times in 50ms increments from 150ms to 5s
103 std::array<uint16_t, 97> mSlowFrameCounts;
Stan Iliev7203e1f2019-07-25 13:12:02 -0400104 // Holds a histogram of GPU draw times in 1ms increments. Frames longer than 25ms are placed in
105 // last bucket.
106 std::array<uint32_t, 26> mGPUFrameCounts;
John Reck7075c792017-07-05 14:03:43 -0700107
108 uint32_t mTotalFrameCount;
109 uint32_t mJankFrameCount;
Jorim Jaggi10f328c2021-01-19 00:08:02 +0100110 uint32_t mJankLegacyFrameCount;
John Reck7075c792017-07-05 14:03:43 -0700111 nsecs_t mStatStartTime;
Stan Iliev637ba5e2019-08-16 13:43:08 -0400112
113 // true if HWUI renders with Vulkan pipeline
114 RenderPipelineType mPipelineType;
John Reck7075c792017-07-05 14:03:43 -0700115};
116
117// For testing
118class MockProfileData : public ProfileData {
119public:
120 std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; }
121 std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; }
122 std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; }
123 uint32_t& editTotalFrameCount() { return mTotalFrameCount; }
124 uint32_t& editJankFrameCount() { return mJankFrameCount; }
125 nsecs_t& editStatStartTime() { return mStatStartTime; }
126};
127
128} /* namespace uirenderer */
129} /* namespace android */