1 /*
2  * Copyright 2024 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 #pragma once
18 
19 namespace aidl {
20 namespace google {
21 namespace hardware {
22 namespace power {
23 namespace impl {
24 namespace pixel {
25 
26 /**
27  * Put jank frames into buckets. The "jank" evaluation is reusing the session records jank
28  * evaluation logic while here only counts the frames over 17ms. Though the current jank
29  * evaluation is not exactly right for every frame at the moment, it can still provide a
30  * a good sense of session's jank status. When we have more precise timeline from platform side
31  * the jank evaluation logic could be updated.
32  */
33 struct FrameBuckets {
34   public:
35     int64_t totalNumOfFrames{0};      // This includes jank frames and normal frames.
36     int64_t numOfFrames17to25ms{0};   // Jank frames over 1 120Hz Vsync interval(8.333ms)
37     int64_t numOfFrames25to34ms{0};   // Jank frames over 2 120Hz Vsync interval(16.667ms)
38     int64_t numOfFrames34to67ms{0};   // Jank frames over 3 to 6 120Hz Vsync intervals.
39     int64_t numOfFrames67to100ms{0};  // Jank frames between 10 Hz and 15 Hz
40     int64_t numOfFramesOver100ms{0};  // Jank frames below 10 Hz.
41 
toStringFrameBuckets42     std::string toString() const {
43         std::stringstream ss;
44         ss << "JankFramesInBuckets: ";
45         if (totalNumOfFrames <= 0) {
46             ss << "0%-0%-0%-0%-0%-0";
47             return ss.str();
48         }
49 
50         ss << (numOfFrames17to25ms * 10000 / totalNumOfFrames / 100.0) << "%";
51         if (numOfFrames17to25ms > 0) {
52             ss << "(" << numOfFrames17to25ms << ")";
53         }
54 
55         appendSingleBucketStr(numOfFrames25to34ms, totalNumOfFrames, ss);
56         appendSingleBucketStr(numOfFrames34to67ms, totalNumOfFrames, ss);
57         appendSingleBucketStr(numOfFrames67to100ms, totalNumOfFrames, ss);
58         appendSingleBucketStr(numOfFramesOver100ms, totalNumOfFrames, ss);
59 
60         ss << "-" << totalNumOfFrames;
61         return ss.str();
62     }
63 
addUpNewFramesFrameBuckets64     void addUpNewFrames(const FrameBuckets &newFrames) {
65         totalNumOfFrames += newFrames.totalNumOfFrames;
66         numOfFrames17to25ms += newFrames.numOfFrames17to25ms;
67         numOfFrames25to34ms += newFrames.numOfFrames25to34ms;
68         numOfFrames34to67ms += newFrames.numOfFrames34to67ms;
69         numOfFrames67to100ms += newFrames.numOfFrames67to100ms;
70         numOfFramesOver100ms += newFrames.numOfFramesOver100ms;
71     }
72 
73   private:
appendSingleBucketStrFrameBuckets74     void appendSingleBucketStr(int64_t singleBucketFrames, int64_t totalFrames,
75                                std::stringstream &ss) const {
76         ss << "-" << (singleBucketFrames * 10000 / totalFrames / 100.0) << "%";
77         if (singleBucketFrames > 0) {
78             ss << "(" << singleBucketFrames << ")";
79         }
80     }
81 };
82 
83 }  // namespace pixel
84 }  // namespace impl
85 }  // namespace power
86 }  // namespace hardware
87 }  // namespace google
88 }  // namespace aidl
89