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