• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include "utils/Macros.h"
20 
21 #include <utils/Timers.h>
22 
23 #include <array>
24 #include <functional>
25 #include <tuple>
26 
27 namespace android {
28 namespace uirenderer {
29 
30 enum JankType {
31     kMissedVsync = 0,
32     kHighInputLatency,
33     kSlowUI,
34     kSlowSync,
35     kSlowRT,
36 
37     // must be last
38     NUM_BUCKETS,
39 };
40 
41 // For testing
42 class MockProfileData;
43 
44 // Try to keep as small as possible, should match ASHMEM_SIZE in
45 // GraphicsStatsService.java
46 class ProfileData {
47     PREVENT_COPY_AND_ASSIGN(ProfileData);
48 
49 public:
ProfileData()50     ProfileData() { reset(); }
51 
52     void reset();
53     void mergeWith(const ProfileData& other);
54     void dump(int fd) const;
55     uint32_t findPercentile(int percentile) const;
56 
57     void reportFrame(int64_t duration);
reportJank()58     void reportJank() { mJankFrameCount++; }
reportJankType(JankType type)59     void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; }
60 
totalFrameCount()61     uint32_t totalFrameCount() const { return mTotalFrameCount; }
jankFrameCount()62     uint32_t jankFrameCount() const { return mJankFrameCount; }
statsStartTime()63     nsecs_t statsStartTime() const { return mStatStartTime; }
jankTypeCount(JankType type)64     uint32_t jankTypeCount(JankType type) const { return mJankTypeCounts[static_cast<int>(type)]; }
65 
66     struct HistogramEntry {
67         uint32_t renderTimeMs;
68         uint32_t frameCount;
69     };
70     void histogramForEach(const std::function<void(HistogramEntry)>& callback) const;
71 
HistogramSize()72     constexpr static int HistogramSize() {
73         return std::tuple_size<decltype(ProfileData::mFrameCounts)>::value
74                 + std::tuple_size<decltype(ProfileData::mSlowFrameCounts)>::value;
75     }
76 
77     // Visible for testing
78     static uint32_t frameTimeForFrameCountIndex(uint32_t index);
79     static uint32_t frameTimeForSlowFrameCountIndex(uint32_t index);
80 
81 private:
82     // Open our guts up to unit tests
83     friend class MockProfileData;
84 
85     std::array <uint32_t, NUM_BUCKETS> mJankTypeCounts;
86     // See comments on kBucket* constants for what this holds
87     std::array<uint32_t, 57> mFrameCounts;
88     // Holds a histogram of frame times in 50ms increments from 150ms to 5s
89     std::array<uint16_t, 97> mSlowFrameCounts;
90 
91     uint32_t mTotalFrameCount;
92     uint32_t mJankFrameCount;
93     nsecs_t mStatStartTime;
94 };
95 
96 // For testing
97 class MockProfileData : public ProfileData {
98 public:
editJankTypeCounts()99     std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; }
editFrameCounts()100     std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; }
editSlowFrameCounts()101     std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; }
editTotalFrameCount()102     uint32_t& editTotalFrameCount() { return mTotalFrameCount; }
editJankFrameCount()103     uint32_t& editJankFrameCount() { return mJankFrameCount; }
editStatStartTime()104     nsecs_t& editStatStartTime() { return mStatStartTime; }
105 };
106 
107 } /* namespace uirenderer */
108 } /* namespace android */
109 
110