| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include "utils/Macros.h" |
| |
| #include <utils/Timers.h> |
| |
| #include <array> |
| #include <functional> |
| #include <tuple> |
| |
| namespace android { |
| namespace uirenderer { |
| |
| enum JankType { |
| kMissedVsync = 0, |
| kHighInputLatency, |
| kSlowUI, |
| kSlowSync, |
| kSlowRT, |
| |
| // must be last |
| NUM_BUCKETS, |
| }; |
| |
| // For testing |
| class MockProfileData; |
| |
| // Try to keep as small as possible, should match ASHMEM_SIZE in |
| // GraphicsStatsService.java |
| class ProfileData { |
| PREVENT_COPY_AND_ASSIGN(ProfileData); |
| |
| public: |
| ProfileData() { reset(); } |
| |
| void reset(); |
| void mergeWith(const ProfileData& other); |
| void dump(int fd) const; |
| uint32_t findPercentile(int percentile) const; |
| |
| void reportFrame(int64_t duration); |
| void reportJank() { mJankFrameCount++; } |
| void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; } |
| |
| uint32_t totalFrameCount() const { return mTotalFrameCount; } |
| uint32_t jankFrameCount() const { return mJankFrameCount; } |
| nsecs_t statsStartTime() const { return mStatStartTime; } |
| uint32_t jankTypeCount(JankType type) const { return mJankTypeCounts[static_cast<int>(type)]; } |
| |
| struct HistogramEntry { |
| uint32_t renderTimeMs; |
| uint32_t frameCount; |
| }; |
| void histogramForEach(const std::function<void(HistogramEntry)>& callback) const; |
| |
| constexpr static int HistogramSize() { |
| return std::tuple_size<decltype(ProfileData::mFrameCounts)>::value + |
| std::tuple_size<decltype(ProfileData::mSlowFrameCounts)>::value; |
| } |
| |
| // Visible for testing |
| static uint32_t frameTimeForFrameCountIndex(uint32_t index); |
| static uint32_t frameTimeForSlowFrameCountIndex(uint32_t index); |
| |
| private: |
| // Open our guts up to unit tests |
| friend class MockProfileData; |
| |
| std::array<uint32_t, NUM_BUCKETS> mJankTypeCounts; |
| // See comments on kBucket* constants for what this holds |
| std::array<uint32_t, 57> mFrameCounts; |
| // Holds a histogram of frame times in 50ms increments from 150ms to 5s |
| std::array<uint16_t, 97> mSlowFrameCounts; |
| |
| uint32_t mTotalFrameCount; |
| uint32_t mJankFrameCount; |
| nsecs_t mStatStartTime; |
| }; |
| |
| // For testing |
| class MockProfileData : public ProfileData { |
| public: |
| std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; } |
| std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; } |
| std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; } |
| uint32_t& editTotalFrameCount() { return mTotalFrameCount; } |
| uint32_t& editJankFrameCount() { return mJankFrameCount; } |
| nsecs_t& editStatStartTime() { return mStatStartTime; } |
| }; |
| |
| } /* namespace uirenderer */ |
| } /* namespace android */ |