1 /*
2 * Copyright (C) 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 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18
19 #include "VideoFrameRateCalculator.h"
20
21 #include <numeric>
22
23 #include "../Utils.h"
24
25 namespace android::hardware::graphics::composer {
26
VideoFrameRateCalculator(EventQueue * eventQueue,const VideoFrameRateCalculatorParameters & params)27 VideoFrameRateCalculator::VideoFrameRateCalculator(EventQueue* eventQueue,
28 const VideoFrameRateCalculatorParameters& params)
29 : mEventQueue(eventQueue), mParams(params) {
30 mName = "RefreshRateCalculator-Video";
31
32 mParams.mMaxInterestedFrameRate = std::min(mMaxFrameRate, mParams.mMaxInterestedFrameRate);
33 mParams.mMinInterestedFrameRate = std::max(1, mParams.mMinInterestedFrameRate);
34
35 mRefreshRateCalculator =
36 std::make_unique<PeriodRefreshRateCalculator>(mEventQueue, params.mPeriodParams);
37 mRefreshRateCalculator->setName("RefreshRateCalculator-Period-Worker");
38 mRefreshRateCalculator->registerRefreshRateChangeCallback(
39 std::bind(&VideoFrameRateCalculator::onReportRefreshRate, this, std::placeholders::_1));
40 }
41
getRefreshRate() const42 int VideoFrameRateCalculator::getRefreshRate() const {
43 if ((mLastVideoFrameRate >= mParams.mMinInterestedFrameRate) &&
44 (mLastVideoFrameRate <= mParams.mMaxInterestedFrameRate)) {
45 return mLastVideoFrameRate;
46 }
47 return kDefaultInvalidRefreshRate;
48 }
49
onPowerStateChange(int from,int to)50 void VideoFrameRateCalculator::onPowerStateChange(int from, int to) {
51 if (to != HWC_POWER_MODE_NORMAL) {
52 setEnabled(false);
53 } else {
54 if (from == HWC_POWER_MODE_NORMAL) {
55 ALOGE("Disregard power state change notification by staying current power state.");
56 return;
57 }
58 setEnabled(true);
59 }
60 }
61
onPresentInternal(int64_t presentTimeNs,int flag)62 void VideoFrameRateCalculator::onPresentInternal(int64_t presentTimeNs, int flag) {
63 if (hasPresentFrameFlag(flag, PresentFrameFlag::kPresentingWhenDoze)) {
64 return;
65 }
66 if (hasPresentFrameFlag(flag, PresentFrameFlag::kIsYuv)) {
67 mRefreshRateCalculator->onPresentInternal(presentTimeNs, flag);
68 } else {
69 reset();
70 }
71 }
72
reset()73 void VideoFrameRateCalculator::reset() {
74 setNewRefreshRate(kDefaultInvalidRefreshRate);
75 mLastPeriodFrameRate = kDefaultInvalidRefreshRate;
76 mLastPeriodFrameRateRuns = 0;
77 mHistory.clear();
78 }
79
setEnabled(bool isEnabled)80 void VideoFrameRateCalculator::setEnabled(bool isEnabled) {
81 mRefreshRateCalculator->setEnabled(isEnabled);
82 }
83
setVrrConfigAttributes(int64_t vsyncPeriodNs,int64_t minFrameIntervalNs)84 void VideoFrameRateCalculator::setVrrConfigAttributes(int64_t vsyncPeriodNs,
85 int64_t minFrameIntervalNs) {
86 RefreshRateCalculator::setVrrConfigAttributes(vsyncPeriodNs, minFrameIntervalNs);
87
88 mRefreshRateCalculator->setVrrConfigAttributes(vsyncPeriodNs, minFrameIntervalNs);
89 }
90
onReportRefreshRate(int refreshRate)91 int VideoFrameRateCalculator::onReportRefreshRate(int refreshRate) {
92 if ((mLastPeriodFrameRate != kDefaultInvalidRefreshRate) &&
93 (std::abs(mLastPeriodFrameRate - refreshRate) <= mParams.mDelta) &&
94 (mLastPeriodFrameRate >= mParams.mMinInterestedFrameRate) &&
95 (mLastPeriodFrameRate <= mParams.mMaxInterestedFrameRate)) {
96 ++mLastPeriodFrameRateRuns;
97 mHistory.push_back(refreshRate);
98 while (mHistory.size() > mParams.mWindowSize) {
99 mHistory.pop_front();
100 }
101 if (mLastPeriodFrameRateRuns >= mParams.mMinStableRuns) {
102 int sum = std::accumulate(std::begin(mHistory), std::end(mHistory), 0);
103 mLastPeriodFrameRate = std::round(sum / static_cast<float>(mHistory.size()));
104 setNewRefreshRate(mLastPeriodFrameRate);
105 }
106 } else {
107 mLastPeriodFrameRate = refreshRate;
108 mLastPeriodFrameRateRuns = 1;
109 setNewRefreshRate(kDefaultInvalidRefreshRate);
110 mHistory.clear();
111 mHistory.push_back(refreshRate);
112 }
113 return NO_ERROR;
114 }
115
setNewRefreshRate(int newRefreshRate)116 void VideoFrameRateCalculator::setNewRefreshRate(int newRefreshRate) {
117 if (newRefreshRate != mLastVideoFrameRate) {
118 mLastVideoFrameRate = newRefreshRate;
119 ATRACE_INT(mName.c_str(), newRefreshRate);
120 if (mRefreshRateChangeCallback) {
121 if ((mLastVideoFrameRate >= mParams.mMinInterestedFrameRate) &&
122 (mLastVideoFrameRate <= mParams.mMaxInterestedFrameRate)) {
123 mRefreshRateChangeCallback(mLastVideoFrameRate);
124 }
125 }
126 }
127 }
128
129 } // namespace android::hardware::graphics::composer
130