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, ¶m) != 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