Home | History | Annotate | Download | only in hwui
      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:
     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);
     58     void reportJank() { mJankFrameCount++; }
     59     void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; }
     60 
     61     uint32_t totalFrameCount() const { return mTotalFrameCount; }
     62     uint32_t jankFrameCount() const { return mJankFrameCount; }
     63     nsecs_t statsStartTime() const { return mStatStartTime; }
     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 
     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:
     99     std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; }
    100     std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; }
    101     std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; }
    102     uint32_t& editTotalFrameCount() { return mTotalFrameCount; }
    103     uint32_t& editJankFrameCount() { return mJankFrameCount; }
    104     nsecs_t& editStatStartTime() { return mStatStartTime; }
    105 };
    106 
    107 } /* namespace uirenderer */
    108 } /* namespace android */
    109 
    110