1 /* 2 * Copyright 2016 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 18 #ifndef ANDROID_GUI_OCCUPANCYTRACKER_H 19 #define ANDROID_GUI_OCCUPANCYTRACKER_H 20 21 #include <binder/Parcelable.h> 22 23 #include <utils/Timers.h> 24 25 #include <deque> 26 #include <unordered_map> 27 28 namespace android { 29 30 class String8; 31 32 class OccupancyTracker 33 { 34 public: OccupancyTracker()35 OccupancyTracker() 36 : mPendingSegment(), 37 mSegmentHistory(), 38 mLastOccupancy(0), 39 mLastOccupancyChangeTime(0) {} 40 41 struct Segment : public Parcelable { SegmentSegment42 Segment() 43 : totalTime(0), 44 numFrames(0), 45 occupancyAverage(0.0f), 46 usedThirdBuffer(false) {} 47 SegmentSegment48 Segment(nsecs_t totalTime, size_t numFrames, float occupancyAverage, 49 bool usedThirdBuffer) 50 : totalTime(totalTime), 51 numFrames(numFrames), 52 occupancyAverage(occupancyAverage), 53 usedThirdBuffer(usedThirdBuffer) {} 54 55 // Parcelable interface 56 virtual status_t writeToParcel(Parcel* parcel) const override; 57 virtual status_t readFromParcel(const Parcel* parcel) override; 58 59 nsecs_t totalTime; 60 size_t numFrames; 61 62 // Average occupancy of the queue over this segment. (0.0, 1.0) implies 63 // double-buffered, (1.0, 2.0) implies triple-buffered. 64 float occupancyAverage; 65 66 // Whether a third buffer was used at all during this segment (since a 67 // segment could read as double-buffered on average, but still require a 68 // third buffer to avoid jank for some smaller portion) 69 bool usedThirdBuffer; 70 }; 71 72 void registerOccupancyChange(size_t occupancy); 73 std::vector<Segment> getSegmentHistory(bool forceFlush); 74 75 private: 76 static constexpr size_t MAX_HISTORY_SIZE = 10; 77 static constexpr nsecs_t NEW_SEGMENT_DELAY = ms2ns(100); 78 static constexpr size_t LONG_SEGMENT_THRESHOLD = 3; 79 80 struct PendingSegment { clearPendingSegment81 void clear() { 82 totalTime = 0; 83 numFrames = 0; 84 mOccupancyTimes.clear(); 85 } 86 87 nsecs_t totalTime; 88 size_t numFrames; 89 std::unordered_map<size_t, nsecs_t> mOccupancyTimes; 90 }; 91 92 void recordPendingSegment(); 93 94 PendingSegment mPendingSegment; 95 std::deque<Segment> mSegmentHistory; 96 97 size_t mLastOccupancy; 98 nsecs_t mLastOccupancyChangeTime; 99 100 }; // class OccupancyTracker 101 102 } // namespace android 103 104 #endif 105