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