Home | History | Annotate | Download | only in gui
      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 
     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) {}
     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
    105