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 "Properties.h" 20 #include "utils/Macros.h" 21 22 #include <utils/Timers.h> 23 24 #include <array> 25 #include <functional> 26 #include <tuple> 27 28 namespace android { 29 namespace uirenderer { 30 31 enum JankType { 32 kMissedVsync = 0, 33 kHighInputLatency, 34 kSlowUI, 35 kSlowSync, 36 kSlowRT, 37 kMissedDeadline, 38 kMissedDeadlineLegacy, 39 40 // must be last 41 NUM_BUCKETS, 42 }; 43 44 // For testing 45 class MockProfileData; 46 47 // Try to keep as small as possible, should match ASHMEM_SIZE in 48 // GraphicsStatsService.java 49 class ProfileData { 50 PREVENT_COPY_AND_ASSIGN(ProfileData); 51 52 public: ProfileData()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; 59 uint32_t findGPUPercentile(int percentile) const; 60 61 void reportFrame(int64_t duration); 62 void reportGPUFrame(int64_t duration); reportJank()63 void reportJank() { mJankFrameCount++; } reportJankLegacy()64 void reportJankLegacy() { mJankLegacyFrameCount++; } reportJankType(JankType type)65 void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; } 66 totalFrameCount()67 uint32_t totalFrameCount() const { return mTotalFrameCount; } jankFrameCount()68 uint32_t jankFrameCount() const { return mJankFrameCount; } jankLegacyFrameCount()69 uint32_t jankLegacyFrameCount() const { return mJankLegacyFrameCount; } statsStartTime()70 nsecs_t statsStartTime() const { return mStatStartTime; } jankTypeCount(JankType type)71 uint32_t jankTypeCount(JankType type) const { return mJankTypeCounts[static_cast<int>(type)]; } pipelineType()72 RenderPipelineType pipelineType() const { return mPipelineType; } 73 74 struct HistogramEntry { 75 uint32_t renderTimeMs; 76 uint32_t frameCount; 77 }; 78 void histogramForEach(const std::function<void(HistogramEntry)>& callback) const; 79 void histogramGPUForEach(const std::function<void(HistogramEntry)>& callback) const; 80 HistogramSize()81 constexpr static int HistogramSize() { 82 return std::tuple_size<decltype(ProfileData::mFrameCounts)>::value + 83 std::tuple_size<decltype(ProfileData::mSlowFrameCounts)>::value; 84 } 85 GPUHistogramSize()86 constexpr static int GPUHistogramSize() { 87 return std::tuple_size<decltype(ProfileData::mGPUFrameCounts)>::value; 88 } 89 90 // Visible for testing 91 static uint32_t frameTimeForFrameCountIndex(uint32_t index); 92 static uint32_t frameTimeForSlowFrameCountIndex(uint32_t index); 93 static uint32_t GPUFrameTimeForFrameCountIndex(uint32_t index); 94 95 private: 96 // Open our guts up to unit tests 97 friend class MockProfileData; 98 99 std::array<uint32_t, NUM_BUCKETS> mJankTypeCounts; 100 // 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; 104 // 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; 107 108 uint32_t mTotalFrameCount; 109 uint32_t mJankFrameCount; 110 uint32_t mJankLegacyFrameCount; 111 nsecs_t mStatStartTime; 112 113 // true if HWUI renders with Vulkan pipeline 114 RenderPipelineType mPipelineType; 115 }; 116 117 // For testing 118 class MockProfileData : public ProfileData { 119 public: editJankTypeCounts()120 std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; } editFrameCounts()121 std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; } editSlowFrameCounts()122 std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; } editTotalFrameCount()123 uint32_t& editTotalFrameCount() { return mTotalFrameCount; } editJankFrameCount()124 uint32_t& editJankFrameCount() { return mJankFrameCount; } editStatStartTime()125 nsecs_t& editStatStartTime() { return mStatStartTime; } 126 }; 127 128 } /* namespace uirenderer */ 129 } /* namespace android */ 130