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