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 "ExitIdleRefreshRateCalculator.h"
20 
21 #include <algorithm>
22 
23 namespace android::hardware::graphics::composer {
24 
ExitIdleRefreshRateCalculator(EventQueue * eventQueue)25 ExitIdleRefreshRateCalculator::ExitIdleRefreshRateCalculator(EventQueue* eventQueue)
26       : ExitIdleRefreshRateCalculator(eventQueue, ExitIdleRefreshRateCalculatorParameters()) {}
27 
ExitIdleRefreshRateCalculator(EventQueue * eventQueue,const ExitIdleRefreshRateCalculatorParameters & params)28 ExitIdleRefreshRateCalculator::ExitIdleRefreshRateCalculator(
29         EventQueue* eventQueue, const ExitIdleRefreshRateCalculatorParameters& params)
30       : mEventQueue(eventQueue), mParams(params) {
31     mName = "RefreshRateCalculator-ExitIdle";
32     mTimeoutEvent.mEventType = VrrControllerEventType::kExitIdleRefreshRateCalculatorUpdate;
33     mTimeoutEvent.mFunctor =
34             std::move(std::bind(&ExitIdleRefreshRateCalculator::invalidateRefreshRate, this));
35 }
36 
getRefreshRate() const37 int ExitIdleRefreshRateCalculator::getRefreshRate() const {
38     return mLastRefreshRate;
39 }
40 
onPowerStateChange(int from,int to)41 void ExitIdleRefreshRateCalculator::onPowerStateChange(int from, int to) {
42     if (to != HWC_POWER_MODE_NORMAL) {
43         setEnabled(false);
44     } else {
45         if (from == HWC_POWER_MODE_NORMAL) {
46             ALOGE("Disregard power state change notification by staying current power state.");
47             return;
48         }
49         setEnabled(true);
50     }
51 }
52 
onPresentInternal(int64_t presentTimeNs,int flag)53 void ExitIdleRefreshRateCalculator::onPresentInternal(int64_t presentTimeNs, int flag) {
54     if (hasPresentFrameFlag(flag, PresentFrameFlag::kPresentingWhenDoze)) {
55         return;
56     }
57     if ((mLastPresentTimeNs == kDefaultInvalidPresentTimeNs) ||
58         (presentTimeNs > mLastPresentTimeNs + mParams.mIdleCriteriaTimeNs)) {
59         setNewRefreshRate(mMaxFrameRate);
60 
61         mTimeoutEvent.mWhenNs = presentTimeNs + mParams.mMaxValidTimeNs;
62         mEventQueue->mPriorityQueue.emplace(mTimeoutEvent);
63     }
64     mLastPresentTimeNs = presentTimeNs;
65 }
66 
reset()67 void ExitIdleRefreshRateCalculator::reset() {
68     mLastPresentTimeNs = kDefaultInvalidPresentTimeNs;
69     setNewRefreshRate(kDefaultInvalidRefreshRate);
70 }
71 
setEnabled(bool isEnabled)72 void ExitIdleRefreshRateCalculator::setEnabled(bool isEnabled) {
73     if (!isEnabled) {
74         mEventQueue->dropEvent(VrrControllerEventType::kExitIdleRefreshRateCalculatorUpdate);
75     } else {
76         reset();
77     }
78 }
79 
setNewRefreshRate(int newRefreshRate)80 void ExitIdleRefreshRateCalculator::setNewRefreshRate(int newRefreshRate) {
81     if (newRefreshRate != mLastRefreshRate) {
82         mLastRefreshRate = newRefreshRate;
83         ATRACE_INT(mName.c_str(), newRefreshRate);
84         if (mRefreshRateChangeCallback) {
85             mRefreshRateChangeCallback(newRefreshRate);
86         }
87     }
88 }
89 
invalidateRefreshRate()90 int ExitIdleRefreshRateCalculator::invalidateRefreshRate() {
91     setNewRefreshRate(kDefaultInvalidRefreshRate);
92     return NO_ERROR;
93 }
94 
95 } // namespace android::hardware::graphics::composer
96