1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2016 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker 18*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_GUI_OCCUPANCYTRACKER_H 19*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_GUI_OCCUPANCYTRACKER_H 20*38e8c45fSAndroid Build Coastguard Worker 21*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcelable.h> 22*38e8c45fSAndroid Build Coastguard Worker 23*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h> 24*38e8c45fSAndroid Build Coastguard Worker 25*38e8c45fSAndroid Build Coastguard Worker #include <deque> 26*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map> 27*38e8c45fSAndroid Build Coastguard Worker 28*38e8c45fSAndroid Build Coastguard Worker namespace android { 29*38e8c45fSAndroid Build Coastguard Worker 30*38e8c45fSAndroid Build Coastguard Worker class String8; 31*38e8c45fSAndroid Build Coastguard Worker 32*38e8c45fSAndroid Build Coastguard Worker class OccupancyTracker 33*38e8c45fSAndroid Build Coastguard Worker { 34*38e8c45fSAndroid Build Coastguard Worker public: OccupancyTracker()35*38e8c45fSAndroid Build Coastguard Worker OccupancyTracker() 36*38e8c45fSAndroid Build Coastguard Worker : mPendingSegment(), 37*38e8c45fSAndroid Build Coastguard Worker mSegmentHistory(), 38*38e8c45fSAndroid Build Coastguard Worker mLastOccupancy(0), 39*38e8c45fSAndroid Build Coastguard Worker mLastOccupancyChangeTime(0) {} 40*38e8c45fSAndroid Build Coastguard Worker 41*38e8c45fSAndroid Build Coastguard Worker struct Segment : public Parcelable { SegmentSegment42*38e8c45fSAndroid Build Coastguard Worker Segment() 43*38e8c45fSAndroid Build Coastguard Worker : totalTime(0), 44*38e8c45fSAndroid Build Coastguard Worker numFrames(0), 45*38e8c45fSAndroid Build Coastguard Worker occupancyAverage(0.0f), 46*38e8c45fSAndroid Build Coastguard Worker usedThirdBuffer(false) {} 47*38e8c45fSAndroid Build Coastguard Worker SegmentSegment48*38e8c45fSAndroid Build Coastguard Worker Segment(nsecs_t _totalTime, size_t _numFrames, float _occupancyAverage, 49*38e8c45fSAndroid Build Coastguard Worker bool _usedThirdBuffer) 50*38e8c45fSAndroid Build Coastguard Worker : totalTime(_totalTime), 51*38e8c45fSAndroid Build Coastguard Worker numFrames(_numFrames), 52*38e8c45fSAndroid Build Coastguard Worker occupancyAverage(_occupancyAverage), 53*38e8c45fSAndroid Build Coastguard Worker usedThirdBuffer(_usedThirdBuffer) {} 54*38e8c45fSAndroid Build Coastguard Worker 55*38e8c45fSAndroid Build Coastguard Worker // Parcelable interface 56*38e8c45fSAndroid Build Coastguard Worker virtual status_t writeToParcel(Parcel* parcel) const override; 57*38e8c45fSAndroid Build Coastguard Worker virtual status_t readFromParcel(const Parcel* parcel) override; 58*38e8c45fSAndroid Build Coastguard Worker 59*38e8c45fSAndroid Build Coastguard Worker nsecs_t totalTime; 60*38e8c45fSAndroid Build Coastguard Worker size_t numFrames; 61*38e8c45fSAndroid Build Coastguard Worker 62*38e8c45fSAndroid Build Coastguard Worker // Average occupancy of the queue over this segment. (0.0, 1.0) implies 63*38e8c45fSAndroid Build Coastguard Worker // double-buffered, (1.0, 2.0) implies triple-buffered. 64*38e8c45fSAndroid Build Coastguard Worker float occupancyAverage; 65*38e8c45fSAndroid Build Coastguard Worker 66*38e8c45fSAndroid Build Coastguard Worker // Whether a third buffer was used at all during this segment (since a 67*38e8c45fSAndroid Build Coastguard Worker // segment could read as double-buffered on average, but still require a 68*38e8c45fSAndroid Build Coastguard Worker // third buffer to avoid jank for some smaller portion) 69*38e8c45fSAndroid Build Coastguard Worker bool usedThirdBuffer; 70*38e8c45fSAndroid Build Coastguard Worker }; 71*38e8c45fSAndroid Build Coastguard Worker 72*38e8c45fSAndroid Build Coastguard Worker void registerOccupancyChange(size_t occupancy); 73*38e8c45fSAndroid Build Coastguard Worker std::vector<Segment> getSegmentHistory(bool forceFlush); 74*38e8c45fSAndroid Build Coastguard Worker 75*38e8c45fSAndroid Build Coastguard Worker private: 76*38e8c45fSAndroid Build Coastguard Worker static constexpr size_t MAX_HISTORY_SIZE = 10; 77*38e8c45fSAndroid Build Coastguard Worker static constexpr nsecs_t NEW_SEGMENT_DELAY = ms2ns(100); 78*38e8c45fSAndroid Build Coastguard Worker static constexpr size_t LONG_SEGMENT_THRESHOLD = 3; 79*38e8c45fSAndroid Build Coastguard Worker 80*38e8c45fSAndroid Build Coastguard Worker struct PendingSegment { clearPendingSegment81*38e8c45fSAndroid Build Coastguard Worker void clear() { 82*38e8c45fSAndroid Build Coastguard Worker totalTime = 0; 83*38e8c45fSAndroid Build Coastguard Worker numFrames = 0; 84*38e8c45fSAndroid Build Coastguard Worker mOccupancyTimes.clear(); 85*38e8c45fSAndroid Build Coastguard Worker } 86*38e8c45fSAndroid Build Coastguard Worker 87*38e8c45fSAndroid Build Coastguard Worker nsecs_t totalTime; 88*38e8c45fSAndroid Build Coastguard Worker size_t numFrames; 89*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<size_t, nsecs_t> mOccupancyTimes; 90*38e8c45fSAndroid Build Coastguard Worker }; 91*38e8c45fSAndroid Build Coastguard Worker 92*38e8c45fSAndroid Build Coastguard Worker void recordPendingSegment(); 93*38e8c45fSAndroid Build Coastguard Worker 94*38e8c45fSAndroid Build Coastguard Worker PendingSegment mPendingSegment; 95*38e8c45fSAndroid Build Coastguard Worker std::deque<Segment> mSegmentHistory; 96*38e8c45fSAndroid Build Coastguard Worker 97*38e8c45fSAndroid Build Coastguard Worker size_t mLastOccupancy; 98*38e8c45fSAndroid Build Coastguard Worker nsecs_t mLastOccupancyChangeTime; 99*38e8c45fSAndroid Build Coastguard Worker 100*38e8c45fSAndroid Build Coastguard Worker }; // class OccupancyTracker 101*38e8c45fSAndroid Build Coastguard Worker 102*38e8c45fSAndroid Build Coastguard Worker } // namespace android 103*38e8c45fSAndroid Build Coastguard Worker 104*38e8c45fSAndroid Build Coastguard Worker #endif 105