1 /*
2  * Copyright (C) 2023 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 "VariableRefreshRateController.h"
20 
21 #include <android-base/logging.h>
22 #include <processgroup/sched_policy.h>
23 #include <sync/sync.h>
24 #include <utils/Trace.h>
25 
26 #include "ExynosHWCHelper.h"
27 #include "drmmode.h"
28 
29 #include <chrono>
30 #include <tuple>
31 
32 #include "RefreshRateCalculator/RefreshRateCalculatorFactory.h"
33 #include "display/DisplayContextProviderFactory.h"
34 #include "interface/Panel_def.h"
35 
36 namespace android::hardware::graphics::composer {
37 
38 namespace {
39 
40 using android::hardware::graphics::composer::VrrControllerEventType;
41 
42 }
43 
getOperationSpeedModeWrapper(void * host)44 static OperationSpeedMode getOperationSpeedModeWrapper(void* host) {
45     VariableRefreshRateController* controller =
46             reinterpret_cast<VariableRefreshRateController*>(host);
47     return controller->getOperationSpeedMode();
48 }
49 
getBrightnessModeWrapper(void * host)50 static BrightnessMode getBrightnessModeWrapper(void* host) {
51     VariableRefreshRateController* controller =
52             reinterpret_cast<VariableRefreshRateController*>(host);
53     return controller->getBrightnessMode();
54 }
55 
getBrightnessNitsWrapper(void * host)56 static int getBrightnessNitsWrapper(void* host) {
57     VariableRefreshRateController* controller =
58             reinterpret_cast<VariableRefreshRateController*>(host);
59     return controller->getBrightnessNits();
60 }
61 
getDisplayFileNodePathWrapper(void * host)62 static const char* getDisplayFileNodePathWrapper(void* host) {
63     VariableRefreshRateController* controller =
64             reinterpret_cast<VariableRefreshRateController*>(host);
65     return controller->getDisplayFileNodePath();
66 }
67 
getEstimateVideoFrameRateWrapper(void * host)68 static int getEstimateVideoFrameRateWrapper(void* host) {
69     VariableRefreshRateController* controller =
70             reinterpret_cast<VariableRefreshRateController*>(host);
71     return controller->getEstimatedVideoFrameRate();
72 }
73 
getAmbientLightSensorOutputWrapper(void * host)74 static int getAmbientLightSensorOutputWrapper(void* host) {
75     VariableRefreshRateController* controller =
76             reinterpret_cast<VariableRefreshRateController*>(host);
77     return controller->getAmbientLightSensorOutput();
78 }
79 
isProximityThrottlingEnabledWrapper(void * host)80 static bool isProximityThrottlingEnabledWrapper(void* host) {
81     VariableRefreshRateController* controller =
82             reinterpret_cast<VariableRefreshRateController*>(host);
83     return controller->isProximityThrottlingEnabled();
84 }
85 
CreateInstance(ExynosDisplay * display,const std::string & panelName)86 auto VariableRefreshRateController::CreateInstance(ExynosDisplay* display,
87                                                    const std::string& panelName)
88         -> std::shared_ptr<VariableRefreshRateController> {
89     if (!display) {
90         LOG(ERROR)
91                 << "VrrController: create VariableRefreshRateController without display handler.";
92         return nullptr;
93     }
94     auto controller = std::shared_ptr<VariableRefreshRateController>(
95             new VariableRefreshRateController(display, panelName));
96     std::thread thread = std::thread(&VariableRefreshRateController::threadBody, controller.get());
97     std::string threadName = "VrrCtrl_";
98     threadName += display->mIndex == 0 ? "Primary" : "Second";
99     int error = pthread_setname_np(thread.native_handle(), threadName.c_str());
100     if (error != 0) {
101         LOG(WARNING) << "VrrController: Unable to set thread name, error = " << strerror(error);
102     }
103     thread.detach();
104 
105     return controller;
106 }
107 
VariableRefreshRateController(ExynosDisplay * display,const std::string & panelName)108 VariableRefreshRateController::VariableRefreshRateController(ExynosDisplay* display,
109                                                              const std::string& panelName)
110       : mDisplay(display), mPanelName(panelName) {
111     mState = VrrControllerState::kDisable;
112     std::string displayFileNodePath = mDisplay->getPanelSysfsPath();
113     if (displayFileNodePath.empty()) {
114         LOG(WARNING) << "VrrController: Cannot find file node of display: "
115                      << mDisplay->mDisplayName;
116     } else {
117         auto& fileNodeManager =
118                 android::hardware::graphics::composer::FileNodeManager::getInstance();
119         mFileNode = fileNodeManager.getFileNode(displayFileNodePath);
120         auto content = mFileNode->readString(kRefreshControlNodeName);
121         if (!(content.has_value()) ||
122             (content.value().compare(0, kRefreshControlNodeEnabled.length(),
123                                      kRefreshControlNodeEnabled))) {
124             LOG(ERROR) << "VrrController: RefreshControlNode is not enabled";
125         }
126     }
127 
128     // Initialize DisplayContextProviderInterface.
129     mDisplayContextProviderInterface.getOperationSpeedMode = (&getOperationSpeedModeWrapper);
130     mDisplayContextProviderInterface.getBrightnessMode = (&getBrightnessModeWrapper);
131     mDisplayContextProviderInterface.getBrightnessNits = (&getBrightnessNitsWrapper);
132     mDisplayContextProviderInterface.getDisplayFileNodePath = (&getDisplayFileNodePathWrapper);
133     mDisplayContextProviderInterface.getEstimatedVideoFrameRate =
134             (&getEstimateVideoFrameRateWrapper);
135     mDisplayContextProviderInterface.getAmbientLightSensorOutput =
136             (&getAmbientLightSensorOutputWrapper);
137     mDisplayContextProviderInterface.isProximityThrottlingEnabled =
138             (&isProximityThrottlingEnabledWrapper);
139 
140     // Flow to build refresh rate calculator.
141     RefreshRateCalculatorFactory refreshRateCalculatorFactory;
142     std::vector<std::shared_ptr<RefreshRateCalculator>> Calculators;
143 
144     Calculators.emplace_back(std::move(
145             refreshRateCalculatorFactory
146                     .BuildRefreshRateCalculator(&mEventQueue, RefreshRateCalculatorType::kAod)));
147     Calculators.emplace_back(
148             std::move(refreshRateCalculatorFactory
149                               .BuildRefreshRateCalculator(&mEventQueue,
150                                                           RefreshRateCalculatorType::kExitIdle)));
151     // videoFrameRateCalculator will be shared with display context provider.
152     auto videoFrameRateCalculator =
153             refreshRateCalculatorFactory
154                     .BuildRefreshRateCalculator(&mEventQueue,
155                                                 RefreshRateCalculatorType::kVideoPlayback);
156     Calculators.emplace_back(videoFrameRateCalculator);
157 
158     PeriodRefreshRateCalculatorParameters peridParams;
159     peridParams.mConfidencePercentage = 0;
160     Calculators.emplace_back(std::move(
161             refreshRateCalculatorFactory.BuildRefreshRateCalculator(&mEventQueue, peridParams)));
162 
163     mRefreshRateCalculator =
164             refreshRateCalculatorFactory.BuildRefreshRateCalculator(std::move(Calculators));
165     mRefreshRateCalculator->registerRefreshRateChangeCallback(
166             std::bind(&VariableRefreshRateController::onRefreshRateChanged, this,
167                       std::placeholders::_1));
168 
169     mPowerModeListeners.push_back(mRefreshRateCalculator.get());
170 
171     std::string fullPath = displayFileNodePath + kFrameRateNodeName;
172     int fd = open(fullPath.c_str(), O_WRONLY, 0);
173     if (fd >= 0) {
174         mFrameRateReporter =
175                 refreshRateCalculatorFactory
176                         .BuildRefreshRateCalculator(&mEventQueue,
177                                                     RefreshRateCalculatorType::kInstant);
178         mFrameRateReporter->registerRefreshRateChangeCallback(
179                 std::bind(&VariableRefreshRateController::onFrameRateChangedForDBI, this,
180                           std::placeholders::_1));
181     }
182 
183     DisplayContextProviderFactory displayContextProviderFactory(mDisplay, this, &mEventQueue);
184     mDisplayContextProvider =
185             displayContextProviderFactory
186                     .buildDisplayContextProvider(DisplayContextProviderType::kExynos,
187                                                  std::move(videoFrameRateCalculator));
188 
189     mPresentTimeoutEventHandlerLoader.reset(
190             new ExternalEventHandlerLoader(std::string(kVendorDisplayPanelLibrary).c_str(),
191                                            &mDisplayContextProviderInterface, this,
192                                            mPanelName.c_str()));
193     mPresentTimeoutEventHandler = mPresentTimeoutEventHandlerLoader->getEventHandler();
194 
195     mVariableRefreshRateStatistic =
196             std::make_shared<VariableRefreshRateStatistic>(mDisplayContextProvider.get(),
197                                                            &mEventQueue, kMaxFrameRate,
198                                                            kMaxTefrequency,
199                                                            (1 * std::nano::den /*1 second*/));
200     mPowerModeListeners.push_back(mVariableRefreshRateStatistic.get());
201 
202     mResidencyWatcher =
203             ndk::SharedRefBase::make<DisplayStateResidencyWatcher>(mDisplayContextProvider,
204                                                                    mVariableRefreshRateStatistic);
205 }
206 
~VariableRefreshRateController()207 VariableRefreshRateController::~VariableRefreshRateController() {
208     stopThread(true);
209 
210     const std::lock_guard<std::mutex> lock(mMutex);
211     if (mLastPresentFence.has_value()) {
212         if (close(mLastPresentFence.value())) {
213             LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
214         }
215         mLastPresentFence = std::nullopt;
216     }
217 };
218 
notifyExpectedPresent(int64_t timestamp,int32_t frameIntervalNs)219 int VariableRefreshRateController::notifyExpectedPresent(int64_t timestamp,
220                                                          int32_t frameIntervalNs) {
221     ATRACE_CALL();
222     {
223         const std::lock_guard<std::mutex> lock(mMutex);
224         mRecord.mNextExpectedPresentTime = {mVrrActiveConfig, timestamp, frameIntervalNs};
225         // Post kNotifyExpectedPresentConfig event.
226         postEvent(VrrControllerEventType::kNotifyExpectedPresentConfig, getSteadyClockTimeNs());
227     }
228     mCondition.notify_all();
229     return 0;
230 }
231 
reset()232 void VariableRefreshRateController::reset() {
233     ATRACE_CALL();
234 
235     const std::lock_guard<std::mutex> lock(mMutex);
236     mEventQueue.mPriorityQueue = std::priority_queue<VrrControllerEvent>();
237     mRecord.clear();
238     dropEventLocked();
239     if (mLastPresentFence.has_value()) {
240         if (close(mLastPresentFence.value())) {
241             LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
242         }
243         mLastPresentFence = std::nullopt;
244     }
245 }
246 
setActiveVrrConfiguration(hwc2_config_t config)247 void VariableRefreshRateController::setActiveVrrConfiguration(hwc2_config_t config) {
248     LOG(INFO) << "VrrController: Set active Vrr configuration = " << config
249               << ", power mode = " << mPowerMode;
250     ATRACE_CALL();
251     {
252         const std::lock_guard<std::mutex> lock(mMutex);
253         if (mVrrConfigs.count(config) == 0) {
254             LOG(ERROR) << "VrrController: Set an undefined active configuration";
255             return;
256         }
257         const auto oldMaxFrameRate =
258                 durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
259         mVrrActiveConfig = config;
260         if (mFrameRateReporter) {
261             mFrameRateReporter->onPresent(getSteadyClockTimeNs(), 0);
262         }
263         // If the minimum refresh rate is active and the maximum refresh rate timeout is set,
264         // also we are stay at the maximum refresh rate, any change in the active configuration
265         // needs to reconfigure the maximum refresh rate according to the newly activated
266         // configuration.
267         if (mMinimumRefreshRatePresentStates >= kAtMaximumRefreshRate) {
268             if (isMinimumRefreshRateActive() && (mMaximumRefreshRateTimeoutNs > 0)) {
269                 uint32_t command = getCurrentRefreshControlStateLocked();
270                 auto newMaxFrameRate = durationNsToFreq(mVrrConfigs[config].minFrameIntervalNs);
271                 setBitField(command, newMaxFrameRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
272                             kPanelRefreshCtrlMinimumRefreshRateMask);
273                 if (!mFileNode->WriteUint32(composer::kRefreshControlNodeName, command)) {
274                     LOG(WARNING) << "VrrController: write file node error, command = " << command;
275                 }
276                 onRefreshRateChangedInternal(newMaxFrameRate);
277                 LOG(INFO) << "VrrController: update maximum refresh rate from " << oldMaxFrameRate
278                           << " to " << newMaxFrameRate;
279             } else {
280                 LOG(ERROR) << "VrrController: MinimumRefreshRatePresentState cannot be "
281                            << mMinimumRefreshRatePresentStates
282                            << " when minimum refresh rate = " << mMinimumRefreshRate
283                            << " , mMaximumRefreshRateTimeoutNs = " << mMaximumRefreshRateTimeoutNs;
284             }
285         }
286         if (mVariableRefreshRateStatistic) {
287             mVariableRefreshRateStatistic
288                     ->setActiveVrrConfiguration(config,
289                                                 durationNsToFreq(mVrrConfigs[mVrrActiveConfig]
290                                                                          .vsyncPeriodNs));
291         }
292         reportRefreshRateIndicator();
293         if (mState == VrrControllerState::kDisable) {
294             return;
295         }
296         mState = VrrControllerState::kRendering;
297         dropEventLocked(VrrControllerEventType::kSystemRenderingTimeout);
298 
299         if (mVrrConfigs[mVrrActiveConfig].isFullySupported) {
300             postEvent(VrrControllerEventType::kSystemRenderingTimeout,
301                       getSteadyClockTimeNs() +
302                               mVrrConfigs[mVrrActiveConfig].notifyExpectedPresentConfig->TimeoutNs);
303         }
304         if (mRefreshRateCalculator) {
305             mRefreshRateCalculator
306                     ->setVrrConfigAttributes(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
307                                              mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
308         }
309         if (mFrameRateReporter) {
310             mFrameRateReporter
311                     ->setVrrConfigAttributes(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
312                                              mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
313         }
314     }
315     mCondition.notify_all();
316 }
317 
setEnable(bool isEnabled)318 void VariableRefreshRateController::setEnable(bool isEnabled) {
319     ATRACE_CALL();
320     {
321         const std::lock_guard<std::mutex> lock(mMutex);
322         if (mEnabled == isEnabled) {
323             return;
324         }
325         mEnabled = isEnabled;
326         if (mEnabled == false) {
327             dropEventLocked();
328         }
329     }
330     mCondition.notify_all();
331 }
332 
preSetPowerMode(int32_t powerMode)333 void VariableRefreshRateController::preSetPowerMode(int32_t powerMode) {
334     ATRACE_CALL();
335     LOG(INFO) << "VrrController: preSet power mode to " << powerMode << ", from " << mPowerMode;
336     {
337         const std::lock_guard<std::mutex> lock(mMutex);
338         if (mPowerMode == powerMode) {
339             return;
340         }
341         switch (powerMode) {
342             case HWC_POWER_MODE_DOZE:
343             case HWC_POWER_MODE_DOZE_SUSPEND: {
344                 uint32_t command = getCurrentRefreshControlStateLocked();
345                 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
346                 if (!mFileNode->WriteUint32(kRefreshControlNodeName, command)) {
347                     LOG(ERROR) << "VrrController: write file node error, command = " << command;
348                 }
349                 dropEventLocked(VrrControllerEventType::kVendorRenderingTimeout);
350                 return;
351             }
352             case HWC_POWER_MODE_OFF:
353             case HWC_POWER_MODE_NORMAL: {
354                 return;
355             }
356             default: {
357                 LOG(ERROR) << "VrrController: Unknown power mode = " << powerMode;
358                 return;
359             }
360         }
361     }
362 }
363 
postSetPowerMode(int32_t powerMode)364 void VariableRefreshRateController::postSetPowerMode(int32_t powerMode) {
365     ATRACE_CALL();
366     LOG(INFO) << "VrrController: postSet power mode to " << powerMode << ", from " << mPowerMode;
367     {
368         const std::lock_guard<std::mutex> lock(mMutex);
369         if (mPowerMode == powerMode) {
370             return;
371         }
372         switch (powerMode) {
373             case HWC_POWER_MODE_OFF:
374             case HWC_POWER_MODE_DOZE:
375             case HWC_POWER_MODE_DOZE_SUSPEND: {
376                 mState = VrrControllerState::kDisable;
377                 dropEventLocked(VrrControllerEventType::kGeneralEventMask);
378                 break;
379             }
380             case HWC_POWER_MODE_NORMAL: {
381                 // We should transition from either HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE, or
382                 // HWC_POWER_MODE_DOZE_SUSPEND. At this point, there should be no pending events
383                 // posted.
384                 if (!mEventQueue.mPriorityQueue.empty()) {
385                     LOG(WARNING) << "VrrController: there should be no pending event when resume "
386                                     "from power mode = "
387                                  << mPowerMode << " to power mode = " << powerMode;
388                     LOG(INFO) << dumpEventQueueLocked();
389                 }
390                 mState = VrrControllerState::kRendering;
391                 const auto& vrrConfig = mVrrConfigs[mVrrActiveConfig];
392                 if (vrrConfig.isFullySupported) {
393                     postEvent(VrrControllerEventType::kSystemRenderingTimeout,
394                               getSteadyClockTimeNs() +
395                                       vrrConfig.notifyExpectedPresentConfig->TimeoutNs);
396                 }
397                 break;
398             }
399             default: {
400                 LOG(ERROR) << "VrrController: Unknown power mode = " << powerMode;
401                 return;
402             }
403         }
404         if (!mPowerModeListeners.empty()) {
405             for (const auto& listener : mPowerModeListeners) {
406                 listener->onPowerStateChange(mPowerMode, powerMode);
407             }
408         }
409         mPowerMode = powerMode;
410     }
411     mCondition.notify_all();
412 }
413 
setVrrConfigurations(std::unordered_map<hwc2_config_t,VrrConfig_t> configs)414 void VariableRefreshRateController::setVrrConfigurations(
415         std::unordered_map<hwc2_config_t, VrrConfig_t> configs) {
416     ATRACE_CALL();
417 
418     std::unordered_map<hwc2_config_t, std::vector<int>> validRefreshRates;
419     for (const auto& [id, config] : configs) {
420         LOG(INFO) << "VrrController: set Vrr configuration id = " << id;
421         if (config.isFullySupported) {
422             if (!config.notifyExpectedPresentConfig.has_value()) {
423                 LOG(ERROR) << "VrrController: full vrr config should have "
424                               "notifyExpectedPresentConfig.";
425                 return;
426             }
427         }
428         validRefreshRates[id] = generateValidRefreshRates(config);
429     }
430 
431     const std::lock_guard<std::mutex> lock(mMutex);
432     mVrrConfigs = std::move(configs);
433     mValidRefreshRates = std::move(validRefreshRates);
434 }
435 
getAmbientLightSensorOutput() const436 int VariableRefreshRateController::getAmbientLightSensorOutput() const {
437     return mDisplayContextProvider->getAmbientLightSensorOutput();
438 }
439 
getBrightnessMode() const440 BrightnessMode VariableRefreshRateController::getBrightnessMode() const {
441     return mDisplayContextProvider->getBrightnessMode();
442 }
443 
getBrightnessNits() const444 int VariableRefreshRateController::getBrightnessNits() const {
445     return mDisplayContextProvider->getBrightnessNits();
446 }
447 
getDisplayFileNodePath() const448 const char* VariableRefreshRateController::getDisplayFileNodePath() const {
449     return mDisplayContextProvider->getDisplayFileNodePath();
450 }
451 
getEstimatedVideoFrameRate() const452 int VariableRefreshRateController::getEstimatedVideoFrameRate() const {
453     return mDisplayContextProvider->getEstimatedVideoFrameRate();
454 }
455 
getOperationSpeedMode() const456 OperationSpeedMode VariableRefreshRateController::getOperationSpeedMode() const {
457     return mDisplayContextProvider->getOperationSpeedMode();
458 }
459 
isProximityThrottlingEnabled() const460 bool VariableRefreshRateController::isProximityThrottlingEnabled() const {
461     return mDisplayContextProvider->isProximityThrottlingEnabled();
462 }
463 
setPresentTimeoutParameters(int timeoutNs,const std::vector<std::pair<uint32_t,uint32_t>> & settings)464 void VariableRefreshRateController::setPresentTimeoutParameters(
465         int timeoutNs, const std::vector<std::pair<uint32_t, uint32_t>>& settings) {
466     const std::lock_guard<std::mutex> lock(mMutex);
467 
468     if (!mPresentTimeoutEventHandler) {
469         return;
470     }
471     if ((timeoutNs >= 0) && (!settings.empty())) {
472         auto functor = mPresentTimeoutEventHandler->getHandleFunction();
473         mVendorPresentTimeoutOverride = std::make_optional<PresentTimeoutSettings>();
474         mVendorPresentTimeoutOverride.value().mTimeoutNs = timeoutNs;
475         mVendorPresentTimeoutOverride.value().mFunctor = std::move(functor);
476         for (const auto& setting : settings) {
477             mVendorPresentTimeoutOverride.value().mSchedule.emplace_back(setting);
478         }
479     } else {
480         mVendorPresentTimeoutOverride = std::nullopt;
481     }
482 }
483 
setPresentTimeoutController(uint32_t controllerType)484 void VariableRefreshRateController::setPresentTimeoutController(uint32_t controllerType) {
485     const std::lock_guard<std::mutex> lock(mMutex);
486 
487     PresentTimeoutControllerType newControllerType =
488             static_cast<PresentTimeoutControllerType>(controllerType);
489     if (newControllerType != mPresentTimeoutController) {
490         if (mPresentTimeoutController == PresentTimeoutControllerType::kSoftware) {
491             dropEventLocked(VrrControllerEventType::kVendorRenderingTimeout);
492         }
493         mPresentTimeoutController = newControllerType;
494         uint32_t command = getCurrentRefreshControlStateLocked();
495         if (newControllerType == PresentTimeoutControllerType::kHardware) {
496             setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
497         } else {
498             clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
499         }
500         if (!mFileNode->WriteUint32(composer::kRefreshControlNodeName, command)) {
501             LOG(ERROR) << "VrrController: write file node error, command = " << command;
502         }
503     }
504 }
505 
setFixedRefreshRateRange(uint32_t minimumRefreshRate,uint64_t minLockTimeForPeakRefreshRate)506 int VariableRefreshRateController::setFixedRefreshRateRange(
507         uint32_t minimumRefreshRate, uint64_t minLockTimeForPeakRefreshRate) {
508     const std::lock_guard<std::mutex> lock(mMutex);
509 
510     // If the new setting is equivalent to the old setting.
511     if ((minimumRefreshRate) <= 1 && (mMinimumRefreshRate <= 1)) {
512         // When |mMinimumRefreshRate| is 0 or 1, it is normal mode; there's no need to compare
513         // |mMaximumRefreshRateTimeoutNs|.
514         return NO_ERROR;
515     } else {
516         if ((minimumRefreshRate == mMinimumRefreshRate) &&
517             (mMaximumRefreshRateTimeoutNs == minLockTimeForPeakRefreshRate)) {
518             return NO_ERROR;
519         }
520     }
521     uint32_t command = getCurrentRefreshControlStateLocked();
522     mMinimumRefreshRate = minimumRefreshRate;
523     mMaximumRefreshRateTimeoutNs = minLockTimeForPeakRefreshRate;
524     dropEventLocked(VrrControllerEventType::kMinLockTimeForPeakRefreshRate);
525     if (isMinimumRefreshRateActive()) {
526         dropEventLocked(VrrControllerEventType::kVendorRenderingTimeout);
527         // Delegate timeout management to hardware.
528         setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
529         // Configure panel to maintain the minimum refresh rate.
530         setBitField(command, minimumRefreshRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
531                     kPanelRefreshCtrlMinimumRefreshRateMask);
532         // TODO(b/333204544): ensure the correct refresh rate is set when calling
533         // setFixedRefreshRate().
534         // Inform Statistics to stay at the minimum refresh rate change.
535         if (mVariableRefreshRateStatistic) {
536             mVariableRefreshRateStatistic->setFixedRefreshRate(mMinimumRefreshRate);
537         }
538         mMinimumRefreshRatePresentStates = kAtMinimumRefreshRate;
539         if (mMaximumRefreshRateTimeoutNs > 0) {
540             // Set up peak refresh rate timeout event accordingly.
541             mMinimumRefreshRateTimeoutEvent =
542                     std::make_optional<TimedEvent>("MinimumRefreshRateTimeout");
543             mMinimumRefreshRateTimeoutEvent->mFunctor = [this]() -> int {
544                 if (mMinimumRefreshRatePresentStates == kAtMaximumRefreshRate) {
545                     mMinimumRefreshRatePresentStates = kTransitionToMinimumRefreshRate;
546                     mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
547                     auto delayNs =
548                             (std::nano::den / mMinimumRefreshRate) + kMillisecondToNanoSecond;
549                     mMinimumRefreshRateTimeoutEvent->mWhenNs = getSteadyClockTimeNs() + delayNs;
550                     postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
551                               mMinimumRefreshRateTimeoutEvent.value());
552                     return 1;
553                 } else {
554                     if (mMinimumRefreshRatePresentStates != kTransitionToMinimumRefreshRate) {
555                         LOG(ERROR) << "VrrController: expect mMinimumRefreshRatePresentStates is "
556                                       "kTransitionToMinimumRefreshRate, but it is "
557                                    << mMinimumRefreshRatePresentStates;
558                         return -1;
559                     }
560                     mMinimumRefreshRatePresentStates = kAtMinimumRefreshRate;
561                     // TODO(b/333204544): ensure the correct refresh rate is set when calling
562                     // setFixedRefreshRate().
563                     if (mVariableRefreshRateStatistic) {
564                         mVariableRefreshRateStatistic->setFixedRefreshRate(mMinimumRefreshRate);
565                     }
566                     uint32_t command = getCurrentRefreshControlStateLocked();
567                     setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
568                     setBitField(command, mMinimumRefreshRate,
569                                 kPanelRefreshCtrlMinimumRefreshRateOffset,
570                                 kPanelRefreshCtrlMinimumRefreshRateMask);
571                     onRefreshRateChangedInternal(mMinimumRefreshRate);
572                     return mFileNode->WriteUint32(composer::kRefreshControlNodeName, command);
573                 }
574             };
575         }
576         if (!mFileNode->WriteUint32(composer::kRefreshControlNodeName, command)) {
577             return -1;
578         }
579         // Report refresh rate change.
580         onRefreshRateChangedInternal(mMinimumRefreshRate);
581     } else {
582         clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
583         // Configure panel with the minimum refresh rate = 1.
584         setBitField(command, 1, kPanelRefreshCtrlMinimumRefreshRateOffset,
585                     kPanelRefreshCtrlMinimumRefreshRateMask);
586         // Inform Statistics about the minimum refresh rate change.
587         if (!mFileNode->WriteUint32(composer::kRefreshControlNodeName, command)) {
588             return -1;
589         }
590         // TODO(b/333204544): ensure the correct refresh rate is set when calling
591         // setFixedRefreshRate().
592         if (mVariableRefreshRateStatistic) {
593             mVariableRefreshRateStatistic->setFixedRefreshRate(0);
594         }
595         mMaximumRefreshRateTimeoutNs = 0;
596         onRefreshRateChangedInternal(1);
597         mMinimumRefreshRateTimeoutEvent = std::nullopt;
598         mMinimumRefreshRatePresentStates = kMinRefreshRateUnset;
599     }
600     return 1;
601 }
602 
stopThread(bool exit)603 void VariableRefreshRateController::stopThread(bool exit) {
604     ATRACE_CALL();
605     {
606         const std::lock_guard<std::mutex> lock(mMutex);
607         mThreadExit = exit;
608         mEnabled = false;
609         mState = VrrControllerState::kDisable;
610     }
611     mCondition.notify_all();
612 }
613 
onPresent(int fence)614 void VariableRefreshRateController::onPresent(int fence) {
615     if (fence < 0) {
616         return;
617     }
618     ATRACE_CALL();
619     {
620         const std::lock_guard<std::mutex> lock(mMutex);
621         if (!mRecord.mPendingCurrentPresentTime.has_value()) {
622             LOG(WARNING) << "VrrController: VrrController: Present without expected present time "
623                             "information";
624             return;
625         } else {
626             if (mRefreshRateCalculator) {
627                 mRefreshRateCalculator->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime,
628                                                   getPresentFrameFlag());
629             }
630             if (mFrameRateReporter) {
631                 mFrameRateReporter->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime, 0);
632             }
633             if (mVariableRefreshRateStatistic) {
634                 mVariableRefreshRateStatistic
635                         ->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime,
636                                     getPresentFrameFlag());
637             }
638             mRecord.mPresentHistory.next() = mRecord.mPendingCurrentPresentTime.value();
639         }
640         if (mState == VrrControllerState::kDisable) {
641             return;
642         } else if (mState == VrrControllerState::kHibernate) {
643             LOG(WARNING) << "VrrController: Present during hibernation without prior notification "
644                             "via notifyExpectedPresent.";
645             mState = VrrControllerState::kRendering;
646             dropEventLocked(VrrControllerEventType::kHibernateTimeout);
647         }
648 
649         if ((mMaximumRefreshRateTimeoutNs > 0) && (mMinimumRefreshRate > 1)) {
650             auto maxFrameRate = durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
651             // If the target minimum refresh rate equals the maxFrameRate, there's no need to
652             // promote the refresh rate to maxFrameRate during presentation.
653             // E.g. in low-light conditions, with |maxFrameRate| and |mMinimumRefreshRate| both at
654             // 120, no refresh rate promotion is needed.
655             if (maxFrameRate != mMinimumRefreshRate) {
656                 if (mMinimumRefreshRatePresentStates == kAtMinimumRefreshRate) {
657                     uint32_t command = getCurrentRefreshControlStateLocked();
658                     // Delegate timeout management to hardware.
659                     setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
660                     // Configure panel to maintain the minimum refresh rate.
661                     setBitField(command, maxFrameRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
662                                 kPanelRefreshCtrlMinimumRefreshRateMask);
663                     if (!mFileNode->WriteUint32(composer::kRefreshControlNodeName, command)) {
664                         LOG(WARNING)
665                                 << "VrrController: write file node error, command = " << command;
666                         return;
667                     }
668                     mMinimumRefreshRatePresentStates = kAtMaximumRefreshRate;
669                     onRefreshRateChangedInternal(maxFrameRate);
670                     mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
671                     mMinimumRefreshRateTimeoutEvent->mWhenNs =
672                             mRecord.mPendingCurrentPresentTime.value().mTime +
673                             mMaximumRefreshRateTimeoutNs;
674                     postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
675                               mMinimumRefreshRateTimeoutEvent.value());
676                 } else if (mMinimumRefreshRatePresentStates == kTransitionToMinimumRefreshRate) {
677                     dropEventLocked(VrrControllerEventType::kMinLockTimeForPeakRefreshRate);
678                     mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
679                     auto delayNs =
680                             (std::nano::den / mMinimumRefreshRate) + kMillisecondToNanoSecond;
681                     mMinimumRefreshRateTimeoutEvent->mWhenNs =
682                             mRecord.mPendingCurrentPresentTime.value().mTime + delayNs;
683                     postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
684                               mMinimumRefreshRateTimeoutEvent.value());
685                 } else {
686                     if (mMinimumRefreshRatePresentStates != kAtMaximumRefreshRate) {
687                         LOG(ERROR) << "VrrController: wrong state when setting min refresh rate: "
688                                    << mMinimumRefreshRatePresentStates;
689                     }
690                 }
691             }
692             return;
693         }
694     }
695 
696     // Prior to pushing the most recent fence update, verify the release timestamps of all preceding
697     // fences.
698     // TODO(b/309873055): delegate the task of executing updateVsyncHistory to the Vrr controller's
699     // loop thread in order to reduce the workload of calling thread.
700     updateVsyncHistory();
701     int dupFence = dup(fence);
702     if (dupFence < 0) {
703         LOG(ERROR) << "VrrController: duplicate fence file failed." << errno;
704     }
705 
706     {
707         const std::lock_guard<std::mutex> lock(mMutex);
708         if (mLastPresentFence.has_value()) {
709             LOG(WARNING) << "VrrController: last present fence remains open.";
710         }
711         mLastPresentFence = dupFence;
712         // Drop the out of date timeout.
713         dropEventLocked(VrrControllerEventType::kSystemRenderingTimeout);
714         cancelPresentTimeoutHandlingLocked();
715         // Post next rendering timeout.
716         int64_t timeoutNs;
717         if (mVrrConfigs[mVrrActiveConfig].isFullySupported) {
718             timeoutNs = getSteadyClockTimeNs() +
719                     mVrrConfigs[mVrrActiveConfig].notifyExpectedPresentConfig->TimeoutNs;
720         } else {
721             timeoutNs = kDefaultSystemPresentTimeoutNs;
722         }
723         postEvent(VrrControllerEventType::kSystemRenderingTimeout,
724                   getSteadyClockTimeNs() + timeoutNs);
725         if (shouldHandleVendorRenderingTimeout()) {
726             auto presentTimeoutNs = mVendorPresentTimeoutOverride
727                     ? mVendorPresentTimeoutOverride.value().mTimeoutNs
728                     : mPresentTimeoutEventHandler->getPresentTimeoutNs();
729             // If |presentTimeoutNs| == 0, we don't need to handle the present timeout. Otherwise,
730             // post the next frame insertion event
731             if (presentTimeoutNs) {
732                 // Convert the relative time clock from now to the absolute steady time clock.
733                 presentTimeoutNs = getSteadyClockTimeNs() + presentTimeoutNs;
734                 postEvent(VrrControllerEventType::kVendorRenderingTimeout, presentTimeoutNs);
735             }
736         }
737         mRecord.mPendingCurrentPresentTime = std::nullopt;
738     }
739     mCondition.notify_all();
740 }
741 
setExpectedPresentTime(int64_t timestampNanos,int frameIntervalNs)742 void VariableRefreshRateController::setExpectedPresentTime(int64_t timestampNanos,
743                                                            int frameIntervalNs) {
744     ATRACE_CALL();
745 
746     const std::lock_guard<std::mutex> lock(mMutex);
747     mRecord.mPendingCurrentPresentTime = {mVrrActiveConfig, timestampNanos, frameIntervalNs};
748 }
749 
onVsync(int64_t timestampNanos,int32_t __unused vsyncPeriodNanos)750 void VariableRefreshRateController::onVsync(int64_t timestampNanos,
751                                             int32_t __unused vsyncPeriodNanos) {
752     const std::lock_guard<std::mutex> lock(mMutex);
753     mRecord.mVsyncHistory
754             .next() = {.mType = VariableRefreshRateController::VsyncEvent::Type::kVblank,
755                        .mTime = timestampNanos};
756 }
757 
cancelPresentTimeoutHandlingLocked()758 void VariableRefreshRateController::cancelPresentTimeoutHandlingLocked() {
759     dropEventLocked(VrrControllerEventType::kVendorRenderingTimeout);
760     dropEventLocked(VrrControllerEventType::kHandleVendorRenderingTimeout);
761 }
762 
dropEventLocked()763 void VariableRefreshRateController::dropEventLocked() {
764     mEventQueue.mPriorityQueue = std::priority_queue<VrrControllerEvent>();
765 }
766 
dropEventLocked(VrrControllerEventType eventType)767 void VariableRefreshRateController::dropEventLocked(VrrControllerEventType eventType) {
768     std::priority_queue<VrrControllerEvent> q;
769     auto target = static_cast<int>(eventType);
770     while (!mEventQueue.mPriorityQueue.empty()) {
771         const auto& it = mEventQueue.mPriorityQueue.top();
772         if ((static_cast<int>(it.mEventType) & target) != target) {
773             q.push(it);
774         }
775         mEventQueue.mPriorityQueue.pop();
776     }
777     mEventQueue.mPriorityQueue = std::move(q);
778 }
779 
dumpEventQueueLocked()780 std::string VariableRefreshRateController::dumpEventQueueLocked() {
781     std::string content;
782     if (mEventQueue.mPriorityQueue.empty()) {
783         return content;
784     }
785 
786     std::priority_queue<VrrControllerEvent> q;
787     while (!mEventQueue.mPriorityQueue.empty()) {
788         const auto& it = mEventQueue.mPriorityQueue.top();
789         content += "VrrController: event = ";
790         content += it.toString();
791         content += "\n";
792         q.push(it);
793         mEventQueue.mPriorityQueue.pop();
794     }
795     mEventQueue.mPriorityQueue = std::move(q);
796     return content;
797 }
798 
getCurrentRefreshControlStateLocked() const799 uint32_t VariableRefreshRateController::getCurrentRefreshControlStateLocked() const {
800     return (mFileNode->getLastWrittenValue(kRefreshControlNodeName) &
801             kPanelRefreshCtrlStateBitsMask);
802 }
803 
getLastFenceSignalTimeUnlocked(int fd)804 int64_t VariableRefreshRateController::getLastFenceSignalTimeUnlocked(int fd) {
805     if (fd == -1) {
806         return SIGNAL_TIME_INVALID;
807     }
808     struct sync_file_info* finfo = sync_file_info(fd);
809     if (finfo == nullptr) {
810         LOG(ERROR) << "VrrController: sync_file_info returned NULL for fd " << fd;
811         return SIGNAL_TIME_INVALID;
812     }
813     if (finfo->status != 1) {
814         const auto status = finfo->status;
815         if (status < 0) {
816             LOG(ERROR) << "VrrController: sync_file_info contains an error: " << status;
817         }
818         sync_file_info_free(finfo);
819         return status < 0 ? SIGNAL_TIME_INVALID : SIGNAL_TIME_PENDING;
820     }
821     uint64_t timestamp = 0;
822     struct sync_fence_info* pinfo = sync_get_fence_info(finfo);
823     if (finfo->num_fences != 1) {
824         LOG(WARNING) << "VrrController:: there is more than one fence in the file descriptor = "
825                      << fd;
826     }
827     for (size_t i = 0; i < finfo->num_fences; i++) {
828         if (pinfo[i].timestamp_ns > timestamp) {
829             timestamp = pinfo[i].timestamp_ns;
830         }
831     }
832     sync_file_info_free(finfo);
833     return timestamp;
834 }
835 
getNextEventTimeLocked() const836 int64_t VariableRefreshRateController::getNextEventTimeLocked() const {
837     if (mEventQueue.mPriorityQueue.empty()) {
838         LOG(WARNING) << "VrrController: event queue should NOT be empty.";
839         return -1;
840     }
841     const auto& event = mEventQueue.mPriorityQueue.top();
842     return event.mWhenNs;
843 }
844 
getStateName(VrrControllerState state) const845 std::string VariableRefreshRateController::getStateName(VrrControllerState state) const {
846     switch (state) {
847         case VrrControllerState::kDisable:
848             return "Disable";
849         case VrrControllerState::kRendering:
850             return "Rendering";
851         case VrrControllerState::kHibernate:
852             return "Hibernate";
853         default:
854             return "Unknown";
855     }
856 }
857 
handleCadenceChange()858 void VariableRefreshRateController::handleCadenceChange() {
859     ATRACE_CALL();
860     if (!mRecord.mNextExpectedPresentTime.has_value()) {
861         LOG(WARNING) << "VrrController: cadence change occurs without the expected present timing "
862                         "information.";
863         return;
864     }
865     // TODO(b/305311056): handle frame rate change.
866     mRecord.mNextExpectedPresentTime = std::nullopt;
867 }
868 
handleResume()869 void VariableRefreshRateController::handleResume() {
870     ATRACE_CALL();
871     if (!mRecord.mNextExpectedPresentTime.has_value()) {
872         LOG(WARNING)
873                 << "VrrController: resume occurs without the expected present timing information.";
874         return;
875     }
876     // TODO(b/305311281): handle panel resume.
877     mRecord.mNextExpectedPresentTime = std::nullopt;
878 }
879 
handleHibernate()880 void VariableRefreshRateController::handleHibernate() {
881     ATRACE_CALL();
882     if (mFrameRateReporter) {
883         mFrameRateReporter->reset();
884     }
885     // TODO(b/305311206): handle entering panel hibernate.
886     postEvent(VrrControllerEventType::kHibernateTimeout,
887               getSteadyClockTimeNs() + kDefaultWakeUpTimeInPowerSaving);
888 }
889 
handleStayHibernate()890 void VariableRefreshRateController::handleStayHibernate() {
891     ATRACE_CALL();
892     // TODO(b/305311698): handle keeping panel hibernate.
893     postEvent(VrrControllerEventType::kHibernateTimeout,
894               getSteadyClockTimeNs() + kDefaultWakeUpTimeInPowerSaving);
895 }
896 
handlePresentTimeout(const VrrControllerEvent & event)897 void VariableRefreshRateController::handlePresentTimeout(const VrrControllerEvent& event) {
898     ATRACE_CALL();
899 
900     if (mState == VrrControllerState::kDisable) {
901         cancelPresentTimeoutHandlingLocked();
902         return;
903     }
904     uint32_t command = mFileNode->getLastWrittenValue(composer::kRefreshControlNodeName);
905     clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
906     setBitField(command, 1, kPanelRefreshCtrlFrameInsertionFrameCountOffset,
907                 kPanelRefreshCtrlFrameInsertionFrameCountMask);
908     mFileNode->WriteUint32(composer::kRefreshControlNodeName, command);
909     if (mFrameRateReporter) {
910         mFrameRateReporter->onPresent(getSteadyClockTimeNs(), 0);
911     }
912 }
913 
onFrameRateChangedForDBI(int refreshRate)914 void VariableRefreshRateController::onFrameRateChangedForDBI(int refreshRate) {
915     // By default, if the refresh rate calculator cannot lock onto a specific frame rate, it may
916     // return -1 to reflect this. To avoid reporting a negative frame frequency, return 1 instead in
917     // this case.
918     auto maxFrameRate = durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
919     refreshRate = std::max(1, refreshRate);
920     refreshRate = std::min(maxFrameRate, refreshRate);
921     mFileNode->WriteUint32(kFrameRateNodeName, refreshRate);
922 }
923 
onRefreshRateChanged(int refreshRate)924 void VariableRefreshRateController::onRefreshRateChanged(int refreshRate) {
925     if (mMinimumRefreshRate > 1) {
926         // If the minimum refresh rate has been set, the refresh rate remains fixed at a specific
927         // value.
928         return;
929     }
930     onRefreshRateChangedInternal(refreshRate);
931 }
932 
onRefreshRateChangedInternal(int refreshRate)933 void VariableRefreshRateController::onRefreshRateChangedInternal(int refreshRate) {
934     if (!(mDisplay) || !(mDisplay->mDevice)) {
935         LOG(ERROR) << "VrrController: absence of a device or display.";
936         return;
937     }
938     refreshRate =
939             refreshRate == kDefaultInvalidRefreshRate ? kDefaultMinimumRefreshRate : refreshRate;
940     refreshRate = convertToValidRefreshRate(refreshRate);
941     if (mLastRefreshRate == refreshRate) {
942         return;
943     }
944     mLastRefreshRate = refreshRate;
945     for (const auto& listener : mRefreshRateChangeListeners) {
946         if (listener) listener->onRefreshRateChange(refreshRate);
947     }
948     reportRefreshRateIndicator();
949 }
950 
reportRefreshRateIndicator()951 void VariableRefreshRateController::reportRefreshRateIndicator() {
952     if (mRefreshRateCalculatorEnabled) {
953         if (!mDisplay->mDevice->isVrrApiSupported()) {
954             // For legacy API, vsyncPeriodNanos is utilized to denote the refresh rate,
955             // refreshPeriodNanos is disregarded.
956             mDisplay->mDevice->onRefreshRateChangedDebug(mDisplay->mDisplayId,
957                                                          freqToDurationNs(mLastRefreshRate));
958         } else {
959             mDisplay->mDevice
960                     ->onRefreshRateChangedDebug(mDisplay->mDisplayId,
961                                                 mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
962                                                 freqToDurationNs(mLastRefreshRate));
963         }
964     }
965 }
966 
generateValidRefreshRates(const VrrConfig_t & config) const967 std::vector<int> VariableRefreshRateController::generateValidRefreshRates(
968         const VrrConfig_t& config) const {
969     std::vector<int> refreshRates;
970     int teFrequency = durationNsToFreq(config.vsyncPeriodNs);
971     int minVsyncNum = roundDivide(config.minFrameIntervalNs, config.vsyncPeriodNs);
972     for (int vsyncNum = minVsyncNum; vsyncNum <= teFrequency; vsyncNum++) {
973         refreshRates.push_back(roundDivide(teFrequency, vsyncNum));
974     }
975     std::set<int> uniqueRefreshRates(refreshRates.begin(), refreshRates.end());
976     refreshRates.assign(uniqueRefreshRates.begin(), uniqueRefreshRates.end());
977     return refreshRates;
978 }
979 
convertToValidRefreshRate(int refreshRate)980 int VariableRefreshRateController::convertToValidRefreshRate(int refreshRate) {
981     const auto& validRefreshRates = mValidRefreshRates[mVrrActiveConfig];
982     auto it = std::lower_bound(validRefreshRates.begin(), validRefreshRates.end(), refreshRate);
983     if (it != validRefreshRates.end()) {
984         return *it;
985     }
986     LOG(ERROR) << "Could not match to any valid refresh rate: " << refreshRate;
987     return durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
988 }
989 
shouldHandleVendorRenderingTimeout() const990 bool VariableRefreshRateController::shouldHandleVendorRenderingTimeout() const {
991     return (mPresentTimeoutController == PresentTimeoutControllerType::kSoftware) &&
992             ((!mVendorPresentTimeoutOverride) ||
993              (mVendorPresentTimeoutOverride.value().mSchedule.size() > 0)) &&
994             (mPowerMode == HWC_POWER_MODE_NORMAL);
995 }
996 
threadBody()997 void VariableRefreshRateController::threadBody() {
998     struct sched_param param = {.sched_priority = sched_get_priority_max(SCHED_FIFO)};
999     if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
1000         LOG(ERROR) << "VrrController: fail to set scheduler to SCHED_FIFO.";
1001         return;
1002     }
1003     for (;;) {
1004         bool stateChanged = false;
1005         {
1006             std::unique_lock<std::mutex> lock(mMutex);
1007             if (mThreadExit) break;
1008             if (!mEnabled) mCondition.wait(lock);
1009             if (!mEnabled) continue;
1010 
1011             if (mEventQueue.mPriorityQueue.empty()) {
1012                 mCondition.wait(lock);
1013             }
1014             int64_t whenNs = getNextEventTimeLocked();
1015             int64_t nowNs = getSteadyClockTimeNs();
1016             if (whenNs > nowNs) {
1017                 int64_t delayNs = whenNs - nowNs;
1018                 auto res = mCondition.wait_for(lock, std::chrono::nanoseconds(delayNs));
1019                 if (res != std::cv_status::timeout) {
1020                     continue;
1021                 }
1022             }
1023 
1024             if (mEventQueue.mPriorityQueue.empty()) {
1025                 continue;
1026             }
1027 
1028             auto event = mEventQueue.mPriorityQueue.top();
1029             if (event.mWhenNs > getSteadyClockTimeNs()) {
1030                 continue;
1031             }
1032             mEventQueue.mPriorityQueue.pop();
1033             if (static_cast<int>(event.mEventType) &
1034                 static_cast<int>(VrrControllerEventType::kCallbackEventMask)) {
1035                 handleCallbackEventLocked(event);
1036                 continue;
1037             }
1038             if (mState == VrrControllerState::kRendering) {
1039                 if (event.mEventType == VrrControllerEventType::kHibernateTimeout) {
1040                     LOG(ERROR) << "VrrController: receiving a hibernate timeout event while in the "
1041                                   "rendering state.";
1042                 }
1043                 switch (event.mEventType) {
1044                     case VrrControllerEventType::kSystemRenderingTimeout: {
1045                         handleHibernate();
1046                         mState = VrrControllerState::kHibernate;
1047                         stateChanged = true;
1048                         break;
1049                     }
1050                     case VrrControllerEventType::kNotifyExpectedPresentConfig: {
1051                         handleCadenceChange();
1052                         break;
1053                     }
1054                     case VrrControllerEventType::kVendorRenderingTimeout: {
1055                         if (mPresentTimeoutEventHandler) {
1056                             // Verify whether a present timeout override exists, and if so, execute
1057                             // it first.
1058                             if (mVendorPresentTimeoutOverride) {
1059                                 const auto& params = mVendorPresentTimeoutOverride.value();
1060                                 TimedEvent timedEvent("VendorPresentTimeoutOverride");
1061                                 timedEvent.mIsRelativeTime = true;
1062                                 timedEvent.mFunctor = params.mFunctor;
1063                                 int64_t whenFromNowNs = 0;
1064                                 for (int i = 0; i < params.mSchedule.size(); ++i) {
1065                                     uint32_t intervalNs = params.mSchedule[i].second;
1066                                     for (int j = 0; j < params.mSchedule[i].first; ++j) {
1067                                         timedEvent.mWhenNs = whenFromNowNs;
1068                                         postEvent(VrrControllerEventType::
1069                                                           kHandleVendorRenderingTimeout,
1070                                                   timedEvent);
1071                                         whenFromNowNs += intervalNs;
1072                                     }
1073                                 }
1074                             } else {
1075                                 auto handleEvents = mPresentTimeoutEventHandler->getHandleEvents();
1076                                 if (!handleEvents.empty()) {
1077                                     for (auto& event : handleEvents) {
1078                                         postEvent(VrrControllerEventType::
1079                                                           kHandleVendorRenderingTimeout,
1080                                                   event);
1081                                     }
1082                                 }
1083                             }
1084                         }
1085                         break;
1086                     }
1087                     case VrrControllerEventType::kHandleVendorRenderingTimeout: {
1088                         handlePresentTimeout(event);
1089                         if (event.mFunctor) {
1090                             event.mFunctor();
1091                         }
1092                         break;
1093                     }
1094                     default: {
1095                         break;
1096                     }
1097                 }
1098             } else {
1099                 if (event.mEventType == VrrControllerEventType::kSystemRenderingTimeout) {
1100                     LOG(ERROR) << "VrrController: receiving a rendering timeout event while in the "
1101                                   "hibernate state.";
1102                 }
1103                 if (mState != VrrControllerState::kHibernate) {
1104                     LOG(ERROR) << "VrrController: expecting to be in hibernate, but instead in "
1105                                   "state = "
1106                                << getStateName(mState);
1107                 }
1108                 switch (event.mEventType) {
1109                     case VrrControllerEventType::kHibernateTimeout: {
1110                         handleStayHibernate();
1111                         break;
1112                     }
1113                     case VrrControllerEventType::kNotifyExpectedPresentConfig: {
1114                         handleResume();
1115                         mState = VrrControllerState::kRendering;
1116                         stateChanged = true;
1117                         break;
1118                     }
1119                     default: {
1120                         break;
1121                     }
1122                 }
1123             }
1124         }
1125         // TODO(b/309873055): implement a handler to serialize all outer function calls to the same
1126         // thread owned by the VRR controller.
1127         if (stateChanged) {
1128             updateVsyncHistory();
1129         }
1130     }
1131 }
1132 
postEvent(VrrControllerEventType type,int64_t when)1133 void VariableRefreshRateController::postEvent(VrrControllerEventType type, int64_t when) {
1134     VrrControllerEvent event;
1135     event.mEventType = type;
1136     event.mWhenNs = when;
1137     mEventQueue.mPriorityQueue.emplace(event);
1138 }
1139 
postEvent(VrrControllerEventType type,TimedEvent & timedEvent)1140 void VariableRefreshRateController::postEvent(VrrControllerEventType type, TimedEvent& timedEvent) {
1141     VrrControllerEvent event;
1142     event.mEventType = type;
1143     event.mWhenNs = timedEvent.mIsRelativeTime ? (getSteadyClockTimeNs() + timedEvent.mWhenNs)
1144                                                : timedEvent.mWhenNs;
1145     event.mFunctor = std::move(timedEvent.mFunctor);
1146     mEventQueue.mPriorityQueue.emplace(event);
1147 }
1148 
updateVsyncHistory()1149 void VariableRefreshRateController::updateVsyncHistory() {
1150     int fence = -1;
1151 
1152     {
1153         const std::lock_guard<std::mutex> lock(mMutex);
1154         if (!mLastPresentFence.has_value()) {
1155             return;
1156         }
1157         fence = mLastPresentFence.value();
1158         mLastPresentFence = std::nullopt;
1159     }
1160 
1161     // Execute the following logic unlocked to enhance performance.
1162     int64_t lastSignalTime = getLastFenceSignalTimeUnlocked(fence);
1163     if (close(fence)) {
1164         LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
1165         return;
1166     } else if (lastSignalTime == SIGNAL_TIME_PENDING || lastSignalTime == SIGNAL_TIME_INVALID) {
1167         return;
1168     }
1169 
1170     {
1171         // Acquire the mutex again to store the vsync record.
1172         const std::lock_guard<std::mutex> lock(mMutex);
1173         mRecord.mVsyncHistory
1174                 .next() = {.mType = VariableRefreshRateController::VsyncEvent::Type::kReleaseFence,
1175                            .mTime = lastSignalTime};
1176     }
1177 }
1178 
1179 } // namespace android::hardware::graphics::composer
1180