| Dan Stoza | e77c766 | 2016-05-13 11:37:28 -0700 | [diff] [blame] | 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: | 
|  | 35 | OccupancyTracker() | 
|  | 36 | : mPendingSegment(), | 
|  | 37 | mSegmentHistory(), | 
|  | 38 | mLastOccupancy(0), | 
|  | 39 | mLastOccupancyChangeTime(0) {} | 
|  | 40 |  | 
|  | 41 | struct Segment : public Parcelable { | 
|  | 42 | Segment() | 
|  | 43 | : totalTime(0), | 
|  | 44 | numFrames(0), | 
|  | 45 | occupancyAverage(0.0f), | 
|  | 46 | usedThirdBuffer(false) {} | 
|  | 47 |  | 
| Colin Cross | 859dcdc | 2016-09-30 16:32:19 -0700 | [diff] [blame] | 48 | Segment(nsecs_t _totalTime, size_t _numFrames, float _occupancyAverage, | 
|  | 49 | bool _usedThirdBuffer) | 
|  | 50 | : totalTime(_totalTime), | 
|  | 51 | numFrames(_numFrames), | 
|  | 52 | occupancyAverage(_occupancyAverage), | 
|  | 53 | usedThirdBuffer(_usedThirdBuffer) {} | 
| Dan Stoza | e77c766 | 2016-05-13 11:37:28 -0700 | [diff] [blame] | 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 { | 
|  | 81 | 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 |