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), mPendingVendorRenderingTimeoutTasks(this) {
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 if (mFileNode->getFileHandler(kFrameRateNodeName) >= 0) {
172 mFrameRateReporter =
173 refreshRateCalculatorFactory
174 .BuildRefreshRateCalculator(&mEventQueue,
175 RefreshRateCalculatorType::kInstant);
176 mFrameRateReporter->registerRefreshRateChangeCallback(
177 std::bind(&VariableRefreshRateController::onFrameRateChangedForDBI, this,
178 std::placeholders::_1));
179 }
180
181 DisplayContextProviderFactory displayContextProviderFactory(mDisplay, this, &mEventQueue);
182 mDisplayContextProvider =
183 displayContextProviderFactory
184 .buildDisplayContextProvider(DisplayContextProviderType::kExynos,
185 std::move(videoFrameRateCalculator));
186
187 mPresentTimeoutEventHandlerLoader.reset(
188 new ExternalEventHandlerLoader(std::string(kVendorDisplayPanelLibrary).c_str(),
189 &mDisplayContextProviderInterface, this,
190 mPanelName.c_str()));
191 mPresentTimeoutEventHandler = mPresentTimeoutEventHandlerLoader->getEventHandler();
192
193 mVariableRefreshRateStatistic =
194 std::make_shared<VariableRefreshRateStatistic>(mDisplayContextProvider.get(),
195 &mEventQueue, kMaxFrameRate,
196 kMaxTefrequency,
197 (1 * std::nano::den /*1 second*/));
198 mPowerModeListeners.push_back(mVariableRefreshRateStatistic.get());
199
200 mResidencyWatcher =
201 ndk::SharedRefBase::make<DisplayStateResidencyWatcher>(mDisplayContextProvider,
202 mVariableRefreshRateStatistic);
203 }
204
~VariableRefreshRateController()205 VariableRefreshRateController::~VariableRefreshRateController() {
206 stopThread(true);
207
208 const std::lock_guard<std::mutex> lock(mMutex);
209 if (mLastPresentFence.has_value()) {
210 if (close(mLastPresentFence.value())) {
211 LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
212 }
213 mLastPresentFence = std::nullopt;
214 }
215 };
216
notifyExpectedPresent(int64_t timestamp,int32_t frameIntervalNs)217 int VariableRefreshRateController::notifyExpectedPresent(int64_t timestamp,
218 int32_t frameIntervalNs) {
219 ATRACE_CALL();
220 {
221 const std::lock_guard<std::mutex> lock(mMutex);
222 mRecord.mNextExpectedPresentTime = {mVrrActiveConfig, timestamp, frameIntervalNs};
223 // Post kNotifyExpectedPresentConfig event.
224 postEvent(VrrControllerEventType::kNotifyExpectedPresentConfig, getSteadyClockTimeNs());
225 }
226
227 if (mFileNode == nullptr) {
228 LOG(WARNING) << "VrrController: Cannot find file node of display: "
229 << mDisplay->mDisplayName;
230 } else {
231 if (!mFileNode->writeValue("expected_present_time_ns", timestamp)) {
232 std::string displayFileNodePath = mDisplay->getPanelSysfsPath();
233 ALOGE("%s(): write command to file node %s%s failed.", __func__,
234 displayFileNodePath.c_str(), "expect_present_time");
235 }
236
237 if (!mFileNode->writeValue("frame_interval_ns", frameIntervalNs)) {
238 std::string displayFileNodePath = mDisplay->getPanelSysfsPath();
239 ALOGE("%s(): write command to file node %s%s failed.", __func__,
240 displayFileNodePath.c_str(), "frame_interval");
241 }
242 }
243
244 mCondition.notify_all();
245 return 0;
246 }
247
reset()248 void VariableRefreshRateController::reset() {
249 ATRACE_CALL();
250
251 const std::lock_guard<std::mutex> lock(mMutex);
252 mEventQueue.mPriorityQueue = std::priority_queue<VrrControllerEvent>();
253 mRecord.clear();
254 dropEventLocked();
255 if (mLastPresentFence.has_value()) {
256 if (close(mLastPresentFence.value())) {
257 LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
258 }
259 mLastPresentFence = std::nullopt;
260 }
261 }
262
setActiveVrrConfiguration(hwc2_config_t config)263 void VariableRefreshRateController::setActiveVrrConfiguration(hwc2_config_t config) {
264 LOG(INFO) << "VrrController: Set active Vrr configuration = " << config
265 << ", power mode = " << mPowerMode;
266 ATRACE_CALL();
267 {
268 const std::lock_guard<std::mutex> lock(mMutex);
269 if (mVrrConfigs.count(config) == 0) {
270 LOG(ERROR) << "VrrController: Set an undefined active configuration";
271 return;
272 }
273 if (mFileNode &&
274 mFileNode->writeValue("expected_present_time_ns", mLastExpectedPresentTimeNs)) {
275 ATRACE_NAME("WriteExpectedPresentTime");
276 } else {
277 std::string displayFileNodePath = mDisplay->getPanelSysfsPath();
278 ALOGE("%s(): write command to file node %s%s failed.", __func__,
279 displayFileNodePath.c_str(), "expected_present_time_ns");
280 }
281 if (mFrameRateReporter) {
282 mFrameRateReporter->onPresent(getSteadyClockTimeNs(), 0);
283 }
284 const auto oldMaxFrameRate =
285 durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
286 mVrrActiveConfig = config;
287 if ((mPendingMinimumRefreshRateRequest) &&
288 (durationNsToFreq(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs) ==
289 durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs))) {
290 LOG(INFO) << "The configuration is ready to set minimum refresh rate = "
291 << mMinimumRefreshRate;
292 ATRACE_NAME("pending_minimum refresh_rate_with_target_config");
293 if (mLastExpectedPresentTimeNs > getSteadyClockTimeNs()) {
294 // An upcoming presentation requires aligning the minimum refresh rate configuration
295 // with the presentation cadence. Additionally, we can optimize by combining the
296 // minimum refresh rate adjustment with the upcoming presentation to directly
297 // transition to the maximum refresh rate state.
298 auto aheadOfTimeNs =
299 std::min((static_cast<int64_t>(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs /
300 2)),
301 (2 * kMillisecondToNanoSecond) /*200 ms*/);
302 auto scheduledTimeNs = (mLastExpectedPresentTimeNs - aheadOfTimeNs);
303 if (getSteadyClockTimeNs() > scheduledTimeNs) {
304 scheduledTimeNs += mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs;
305 }
306 createMinimumRefreshRateTimeoutEventLocked();
307 postEvent(VrrControllerEventType::kMinimumRefreshRateAlignWithPresent,
308 scheduledTimeNs);
309 } else {
310 mMinimumRefreshRate = mPendingMinimumRefreshRateRequest.value();
311 setFixedRefreshRateRangeWorker();
312 mPendingMinimumRefreshRateRequest = std::nullopt;
313 }
314 }
315 // If the minimum refresh rate is active and the maximum refresh rate timeout is set,
316 // also we are stay at the maximum refresh rate, any change in the active configuration
317 // needs to reconfigure the maximum refresh rate according to the newly activated
318 // configuration.
319 else if (mMinimumRefreshRatePresentState >= kAtMaximumRefreshRate) {
320 if (isMinimumRefreshRateActive() && (mMaximumRefreshRateTimeoutNs > 0)) {
321 uint32_t command = getCurrentRefreshControlStateLocked();
322 auto newMaxFrameRate = durationNsToFreq(mVrrConfigs[config].minFrameIntervalNs);
323 setBitField(command, newMaxFrameRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
324 kPanelRefreshCtrlMinimumRefreshRateMask);
325 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
326 LOG(WARNING) << "VrrController: write file node error, command = " << command;
327 }
328 ATRACE_INT(kMinimumRefreshRateConfiguredTraceName, newMaxFrameRate);
329 onRefreshRateChangedInternal(newMaxFrameRate);
330 LOG(INFO) << "VrrController: update maximum refresh rate from " << oldMaxFrameRate
331 << " to " << newMaxFrameRate;
332 } else {
333 LOG(ERROR) << "VrrController: MinimumRefreshRatePresentState cannot be "
334 << mMinimumRefreshRatePresentState
335 << " when minimum refresh rate = " << mMinimumRefreshRate
336 << " , mMaximumRefreshRateTimeoutNs = " << mMaximumRefreshRateTimeoutNs;
337 }
338 }
339 if (mVariableRefreshRateStatistic) {
340 mVariableRefreshRateStatistic
341 ->setActiveVrrConfiguration(config,
342 durationNsToFreq(mVrrConfigs[mVrrActiveConfig]
343 .vsyncPeriodNs));
344 }
345 reportRefreshRateIndicator();
346 if (mState == VrrControllerState::kDisable) {
347 return;
348 }
349 mState = VrrControllerState::kRendering;
350 dropEventLocked(VrrControllerEventType::kSystemRenderingTimeout);
351
352 if (mVrrConfigs[mVrrActiveConfig].isFullySupported) {
353 postEvent(VrrControllerEventType::kSystemRenderingTimeout,
354 getSteadyClockTimeNs() +
355 mVrrConfigs[mVrrActiveConfig].notifyExpectedPresentConfig->TimeoutNs);
356 }
357 if (mRefreshRateCalculator) {
358 mRefreshRateCalculator
359 ->setVrrConfigAttributes(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
360 mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
361 }
362 if (mFrameRateReporter) {
363 mFrameRateReporter
364 ->setVrrConfigAttributes(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
365 mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
366 }
367 }
368 mCondition.notify_all();
369 }
370
setEnable(bool isEnabled)371 void VariableRefreshRateController::setEnable(bool isEnabled) {
372 ATRACE_CALL();
373 {
374 const std::lock_guard<std::mutex> lock(mMutex);
375 if (mEnabled == isEnabled) {
376 return;
377 }
378 mEnabled = isEnabled;
379 if (mEnabled == false) {
380 dropEventLocked();
381 }
382 }
383 mCondition.notify_all();
384 }
385
preSetPowerMode(int32_t powerMode)386 void VariableRefreshRateController::preSetPowerMode(int32_t powerMode) {
387 ATRACE_CALL();
388 LOG(INFO) << "VrrController: preSet power mode to " << powerMode << ", from " << mPowerMode;
389 {
390 const std::lock_guard<std::mutex> lock(mMutex);
391 if (mPowerMode == powerMode) {
392 return;
393 }
394 switch (powerMode) {
395 case HWC_POWER_MODE_DOZE:
396 case HWC_POWER_MODE_DOZE_SUSPEND: {
397 uint32_t command = getCurrentRefreshControlStateLocked();
398 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
399 mPresentTimeoutController = PresentTimeoutControllerType::kHardware;
400 if (!mFileNode->writeValue(kRefreshControlNodeName, command)) {
401 LOG(ERROR) << "VrrController: write file node error, command = " << command;
402 }
403 cancelPresentTimeoutHandlingLocked();
404 return;
405 }
406 case HWC_POWER_MODE_OFF: {
407 return;
408 }
409 case HWC_POWER_MODE_NORMAL: {
410 mPresentTimeoutController = mDefaultPresentTimeoutController;
411 return;
412 }
413 default: {
414 LOG(ERROR) << "VrrController: Unknown power mode = " << powerMode;
415 return;
416 }
417 }
418 }
419 }
420
postSetPowerMode(int32_t powerMode)421 void VariableRefreshRateController::postSetPowerMode(int32_t powerMode) {
422 ATRACE_CALL();
423 LOG(INFO) << "VrrController: postSet power mode to " << powerMode << ", from " << mPowerMode;
424 {
425 const std::lock_guard<std::mutex> lock(mMutex);
426 if (mPowerMode == powerMode) {
427 return;
428 }
429 switch (powerMode) {
430 case HWC_POWER_MODE_OFF:
431 case HWC_POWER_MODE_DOZE:
432 case HWC_POWER_MODE_DOZE_SUSPEND: {
433 mState = VrrControllerState::kDisable;
434 dropEventLocked(VrrControllerEventType::kGeneralEventMask);
435 break;
436 }
437 case HWC_POWER_MODE_NORMAL: {
438 // We should transition from either HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE, or
439 // HWC_POWER_MODE_DOZE_SUSPEND. At this point, there should be no pending events
440 // posted.
441 if (!mEventQueue.mPriorityQueue.empty()) {
442 LOG(WARNING) << "VrrController: there should be no pending event when resume "
443 "from power mode = "
444 << mPowerMode << " to power mode = " << powerMode;
445 LOG(INFO) << dumpEventQueueLocked();
446 }
447 mState = VrrControllerState::kRendering;
448 const auto& vrrConfig = mVrrConfigs[mVrrActiveConfig];
449 if (vrrConfig.isFullySupported) {
450 postEvent(VrrControllerEventType::kSystemRenderingTimeout,
451 getSteadyClockTimeNs() +
452 vrrConfig.notifyExpectedPresentConfig->TimeoutNs);
453 }
454 break;
455 }
456 default: {
457 LOG(ERROR) << "VrrController: Unknown power mode = " << powerMode;
458 return;
459 }
460 }
461 if (!mPowerModeListeners.empty()) {
462 for (const auto& listener : mPowerModeListeners) {
463 listener->onPowerStateChange(mPowerMode, powerMode);
464 }
465 }
466 mPowerMode = powerMode;
467 }
468 mCondition.notify_all();
469 }
470
setVrrConfigurations(std::unordered_map<hwc2_config_t,VrrConfig_t> configs)471 void VariableRefreshRateController::setVrrConfigurations(
472 std::unordered_map<hwc2_config_t, VrrConfig_t> configs) {
473 ATRACE_CALL();
474
475 std::unordered_map<hwc2_config_t, std::vector<int>> validRefreshRates;
476 for (const auto& [id, config] : configs) {
477 LOG(INFO) << "VrrController: set Vrr configuration id = " << id;
478 if (config.isFullySupported) {
479 if (!config.notifyExpectedPresentConfig.has_value()) {
480 LOG(ERROR) << "VrrController: full vrr config should have "
481 "notifyExpectedPresentConfig.";
482 return;
483 }
484 }
485 validRefreshRates[id] = generateValidRefreshRates(config);
486 }
487
488 const std::lock_guard<std::mutex> lock(mMutex);
489 mVrrConfigs = std::move(configs);
490 mValidRefreshRates = std::move(validRefreshRates);
491 }
492
getAmbientLightSensorOutput() const493 int VariableRefreshRateController::getAmbientLightSensorOutput() const {
494 return mDisplayContextProvider->getAmbientLightSensorOutput();
495 }
496
getBrightnessMode() const497 BrightnessMode VariableRefreshRateController::getBrightnessMode() const {
498 return mDisplayContextProvider->getBrightnessMode();
499 }
500
getBrightnessNits() const501 int VariableRefreshRateController::getBrightnessNits() const {
502 return mDisplayContextProvider->getBrightnessNits();
503 }
504
getDisplayFileNodePath() const505 const char* VariableRefreshRateController::getDisplayFileNodePath() const {
506 return mDisplayContextProvider->getDisplayFileNodePath();
507 }
508
getEstimatedVideoFrameRate() const509 int VariableRefreshRateController::getEstimatedVideoFrameRate() const {
510 return mDisplayContextProvider->getEstimatedVideoFrameRate();
511 }
512
getOperationSpeedMode() const513 OperationSpeedMode VariableRefreshRateController::getOperationSpeedMode() const {
514 return mDisplayContextProvider->getOperationSpeedMode();
515 }
516
isProximityThrottlingEnabled() const517 bool VariableRefreshRateController::isProximityThrottlingEnabled() const {
518 return mDisplayContextProvider->isProximityThrottlingEnabled();
519 }
520
setPresentTimeoutParameters(int timeoutNs,const std::vector<std::pair<uint32_t,uint32_t>> & settings)521 void VariableRefreshRateController::setPresentTimeoutParameters(
522 int timeoutNs, const std::vector<std::pair<uint32_t, uint32_t>>& settings) {
523 const std::lock_guard<std::mutex> lock(mMutex);
524
525 if (!mPresentTimeoutEventHandler) {
526 return;
527 }
528 if ((timeoutNs >= 0) && (!settings.empty())) {
529 auto functor = mPresentTimeoutEventHandler->getHandleFunction();
530 mVendorPresentTimeoutOverride = std::make_optional<PresentTimeoutSettings>();
531 mVendorPresentTimeoutOverride.value().mTimeoutNs = timeoutNs;
532 mVendorPresentTimeoutOverride.value().mFunctor = std::move(functor);
533 for (const auto& setting : settings) {
534 mVendorPresentTimeoutOverride.value().mSchedule.emplace_back(setting);
535 }
536 } else {
537 mVendorPresentTimeoutOverride = std::nullopt;
538 }
539 }
540
setPresentTimeoutController(uint32_t controllerType)541 void VariableRefreshRateController::setPresentTimeoutController(uint32_t controllerType) {
542 const std::lock_guard<std::mutex> lock(mMutex);
543
544 if (mPowerMode != HWC_POWER_MODE_NORMAL) {
545 LOG(WARNING) << "VrrController: Please change the present timeout controller only when the "
546 "power mode is on.";
547 return;
548 }
549
550 PresentTimeoutControllerType newDefaultControllerType =
551 static_cast<PresentTimeoutControllerType>(controllerType);
552 if (newDefaultControllerType != mDefaultPresentTimeoutController) {
553 mDefaultPresentTimeoutController = newDefaultControllerType;
554 PresentTimeoutControllerType oldControllerType = mPresentTimeoutController;
555 if (mDefaultPresentTimeoutController == PresentTimeoutControllerType::kHardware) {
556 mPresentTimeoutController = PresentTimeoutControllerType::kHardware;
557 } else {
558 // When change |mDefaultPresentTimeoutController| from |kHardware| to |kSoftware|,
559 // only change |mPresentTimeoutController| if the minimum refresh rate has not been set.
560 // Otherwise, retain the current |mPresentTimeoutController| until the conditions are
561 // met.
562 if (!(isMinimumRefreshRateActive())) {
563 mPresentTimeoutController = PresentTimeoutControllerType::kSoftware;
564 }
565 }
566 if (oldControllerType == mPresentTimeoutController) return;
567 uint32_t command = getCurrentRefreshControlStateLocked();
568 if (mPresentTimeoutController == PresentTimeoutControllerType::kHardware) {
569 cancelPresentTimeoutHandlingLocked();
570 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
571 } else {
572 clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
573 }
574 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
575 LOG(ERROR) << "VrrController: write file node error, command = " << command;
576 }
577 }
578 }
579
setFixedRefreshRateRange(uint32_t minimumRefreshRate,uint64_t minLockTimeForPeakRefreshRate)580 int VariableRefreshRateController::setFixedRefreshRateRange(
581 uint32_t minimumRefreshRate, uint64_t minLockTimeForPeakRefreshRate) {
582 ATRACE_CALL();
583 ATRACE_INT(kMinimumRefreshRateRequestTraceName, minimumRefreshRate);
584 const std::lock_guard<std::mutex> lock(mMutex);
585 // Discontinue handling fixed refresh rate range settings after power-off, as we will
586 // immediately configure it again.
587 if (mPowerMode == HWC_POWER_MODE_OFF) {
588 return NO_ERROR;
589 }
590 if (minimumRefreshRate == 0) {
591 minimumRefreshRate = 1;
592 }
593 mMaximumRefreshRateTimeoutNs = minLockTimeForPeakRefreshRate;
594
595 if ((mPendingMinimumRefreshRateRequest) &&
596 (mPendingMinimumRefreshRateRequest.value() == minimumRefreshRate)) {
597 return NO_ERROR;
598 }
599
600 mPendingMinimumRefreshRateRequest = std::nullopt;
601 dropEventLocked(VrrControllerEventType::kMinimumRefreshRateControlEventMask);
602 if (minimumRefreshRate == mMinimumRefreshRate) {
603 return NO_ERROR;
604 }
605
606 if ((minimumRefreshRate == 1) ||
607 (durationNsToFreq(mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs) ==
608 durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs))) {
609 mMinimumRefreshRate = minimumRefreshRate;
610 return setFixedRefreshRateRangeWorker();
611 } else {
612 LOG(INFO) << "Set the minimum refresh rate to " << mMinimumRefreshRate
613 << " but wait until the configuration is ready before applying.";
614 mPendingMinimumRefreshRateRequest = minimumRefreshRate;
615 postEvent(VrrControllerEventType::kMinimumRefreshRateWaitForConfigTimeout,
616 getSteadyClockTimeNs() + kWaitForConfigTimeoutNs);
617 return NO_ERROR;
618 }
619 }
620
setFixedRefreshRateRangeWorker()621 int VariableRefreshRateController::setFixedRefreshRateRangeWorker() {
622 uint32_t command = getCurrentRefreshControlStateLocked();
623 if (isMinimumRefreshRateActive()) {
624 cancelPresentTimeoutHandlingLocked();
625 // Delegate timeout management to hardware.
626 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
627 // Configure panel to maintain the minimum refresh rate.
628 setBitField(command, mMinimumRefreshRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
629 kPanelRefreshCtrlMinimumRefreshRateMask);
630 // TODO(b/333204544): ensure the correct refresh rate is set when calling
631 // setFixedRefreshRate().
632 // Inform Statistics to stay at the minimum refresh rate change.
633 if (mVariableRefreshRateStatistic) {
634 mVariableRefreshRateStatistic->setFixedRefreshRate(mMinimumRefreshRate);
635 }
636 mMinimumRefreshRatePresentState = kAtMinimumRefreshRate;
637 createMinimumRefreshRateTimeoutEventLocked();
638 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
639 return -1;
640 }
641 mPresentTimeoutController = PresentTimeoutControllerType::kHardware;
642 // Report refresh rate change.
643 onRefreshRateChangedInternal(mMinimumRefreshRate);
644 } else {
645 // If the minimum refresh rate is 1, check |mDefaultPresentTimeoutController|.
646 // Only disable auto mode if |mDefaultPresentTimeoutController| is |kSoftware|.
647 mPresentTimeoutController = mDefaultPresentTimeoutController;
648 if (mPresentTimeoutController == PresentTimeoutControllerType::kSoftware) {
649 clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
650 // Configure panel with the minimum refresh rate = 1.
651 setBitField(command, 1, kPanelRefreshCtrlMinimumRefreshRateOffset,
652 kPanelRefreshCtrlMinimumRefreshRateMask);
653 // Inform Statistics about the minimum refresh rate change.
654 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
655 return -1;
656 }
657 }
658 // TODO(b/333204544): ensure the correct refresh rate is set when calling
659 // setFixedRefreshRate().
660 if (mVariableRefreshRateStatistic) {
661 mVariableRefreshRateStatistic->setFixedRefreshRate(0);
662 }
663 mMaximumRefreshRateTimeoutNs = 0;
664 onRefreshRateChangedInternal(1);
665 mMinimumRefreshRateTimeoutEvent = std::nullopt;
666 mMinimumRefreshRatePresentState = kMinRefreshRateUnset;
667 }
668 command = getCurrentRefreshControlStateLocked();
669 ATRACE_INT(kMinimumRefreshRateConfiguredTraceName,
670 ((command & kPanelRefreshCtrlMinimumRefreshRateMask) >>
671 kPanelRefreshCtrlFrameInsertionFrameCountBits));
672 return 1;
673 }
674
stopThread(bool exit)675 void VariableRefreshRateController::stopThread(bool exit) {
676 ATRACE_CALL();
677 {
678 const std::lock_guard<std::mutex> lock(mMutex);
679 mThreadExit = exit;
680 mEnabled = false;
681 mState = VrrControllerState::kDisable;
682 }
683 mCondition.notify_all();
684 }
685
onPresent(int fence)686 void VariableRefreshRateController::onPresent(int fence) {
687 if (fence < 0) {
688 return;
689 }
690 ATRACE_CALL();
691 {
692 const std::lock_guard<std::mutex> lock(mMutex);
693 if (!mRecord.mPendingCurrentPresentTime.has_value()) {
694 LOG(WARNING) << "VrrController: VrrController: Present without expected present time "
695 "information";
696 return;
697 } else {
698 if (mRefreshRateCalculator) {
699 mRefreshRateCalculator->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime,
700 getPresentFrameFlag());
701 }
702 if (mFrameRateReporter) {
703 mFrameRateReporter->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime, 0);
704 }
705 if (mVariableRefreshRateStatistic) {
706 mVariableRefreshRateStatistic
707 ->onPresent(mRecord.mPendingCurrentPresentTime.value().mTime,
708 getPresentFrameFlag());
709 }
710 mRecord.mPresentHistory.next() = mRecord.mPendingCurrentPresentTime.value();
711 }
712 if (mState == VrrControllerState::kDisable) {
713 return;
714 } else if (mState == VrrControllerState::kHibernate) {
715 LOG(WARNING) << "VrrController: Present during hibernation without prior notification "
716 "via notifyExpectedPresent.";
717 mState = VrrControllerState::kRendering;
718 dropEventLocked(VrrControllerEventType::kHibernateTimeout);
719 }
720
721 if ((mMaximumRefreshRateTimeoutNs > 0) && (mMinimumRefreshRate > 1) &&
722 (!mPendingMinimumRefreshRateRequest)) {
723 auto maxFrameRate = durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
724 // If the target minimum refresh rate equals the maxFrameRate, there's no need to
725 // promote the refresh rate to maxFrameRate during presentation.
726 // E.g. in low-light conditions, with |maxFrameRate| and |mMinimumRefreshRate| both at
727 // 120, no refresh rate promotion is needed.
728 if (maxFrameRate != mMinimumRefreshRate) {
729 if (mMinimumRefreshRatePresentState == kAtMinimumRefreshRate) {
730 if (mPresentTimeoutController != PresentTimeoutControllerType::kHardware) {
731 LOG(WARNING)
732 << "VrrController: incorrect type of present timeout controller.";
733 }
734 uint32_t command = getCurrentRefreshControlStateLocked();
735 // Delegate timeout management to hardware.
736 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
737 // Configure panel to maintain the minimum refresh rate.
738 setBitField(command, maxFrameRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
739 kPanelRefreshCtrlMinimumRefreshRateMask);
740 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
741 LOG(WARNING)
742 << "VrrController: write file node error, command = " << command;
743 return;
744 }
745 ATRACE_INT(kMinimumRefreshRateConfiguredTraceName, maxFrameRate);
746 mMinimumRefreshRatePresentState = kAtMaximumRefreshRate;
747 onRefreshRateChangedInternal(maxFrameRate);
748 mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
749 mMinimumRefreshRateTimeoutEvent->mWhenNs =
750 mRecord.mPendingCurrentPresentTime.value().mTime +
751 mMaximumRefreshRateTimeoutNs;
752 postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
753 mMinimumRefreshRateTimeoutEvent.value());
754 } else if (mMinimumRefreshRatePresentState == kTransitionToMinimumRefreshRate) {
755 dropEventLocked(VrrControllerEventType::kMinLockTimeForPeakRefreshRate);
756 mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
757 auto delayNs =
758 (std::nano::den / mMinimumRefreshRate) + kMillisecondToNanoSecond;
759 mMinimumRefreshRateTimeoutEvent->mWhenNs =
760 mRecord.mPendingCurrentPresentTime.value().mTime + delayNs;
761 postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
762 mMinimumRefreshRateTimeoutEvent.value());
763 } else {
764 if (mMinimumRefreshRatePresentState != kAtMaximumRefreshRate) {
765 LOG(ERROR) << "VrrController: wrong state when setting min refresh rate: "
766 << mMinimumRefreshRatePresentState;
767 }
768 }
769 }
770 return;
771 }
772 }
773
774 // Prior to pushing the most recent fence update, verify the release timestamps of all preceding
775 // fences.
776 // TODO(b/309873055): delegate the task of executing updateVsyncHistory to the Vrr controller's
777 // loop thread in order to reduce the workload of calling thread.
778 updateVsyncHistory();
779 int dupFence = dup(fence);
780 if (dupFence < 0) {
781 LOG(ERROR) << "VrrController: duplicate fence file failed." << errno;
782 }
783
784 {
785 const std::lock_guard<std::mutex> lock(mMutex);
786 if (mLastPresentFence.has_value()) {
787 LOG(WARNING) << "VrrController: last present fence remains open.";
788 }
789 mLastPresentFence = dupFence;
790 // Post next rendering timeout.
791 int64_t timeoutNs;
792 if (mVrrConfigs[mVrrActiveConfig].isFullySupported) {
793 timeoutNs = getSteadyClockTimeNs() +
794 mVrrConfigs[mVrrActiveConfig].notifyExpectedPresentConfig->TimeoutNs;
795 } else {
796 timeoutNs = kDefaultSystemPresentTimeoutNs;
797 }
798 postEvent(VrrControllerEventType::kSystemRenderingTimeout,
799 getSteadyClockTimeNs() + timeoutNs);
800 if (shouldHandleVendorRenderingTimeout()) {
801 // Post next frame insertion event.
802 int64_t firstTimeOutNs;
803 if (mVendorPresentTimeoutOverride) {
804 firstTimeOutNs = mVendorPresentTimeoutOverride.value().mTimeoutNs;
805 } else {
806 firstTimeOutNs = mPresentTimeoutEventHandler->getPresentTimeoutNs();
807 }
808 mPendingVendorRenderingTimeoutTasks.baseTimeNs += firstTimeOutNs;
809 firstTimeOutNs -= kDefaultAheadOfTimeNs;
810 if (firstTimeOutNs >= 0) {
811 auto vendorPresentTimeoutNs =
812 mRecord.mPendingCurrentPresentTime.value().mTime + firstTimeOutNs;
813 postEvent(VrrControllerEventType::kVendorRenderingTimeoutInit,
814 vendorPresentTimeoutNs);
815 } else {
816 LOG(ERROR) << "VrrController: the first vendor present timeout is negative";
817 }
818 }
819 mRecord.mPendingCurrentPresentTime = std::nullopt;
820 }
821 mCondition.notify_all();
822 }
823
setExpectedPresentTime(int64_t timestampNanos,int frameIntervalNs)824 void VariableRefreshRateController::setExpectedPresentTime(int64_t timestampNanos,
825 int frameIntervalNs) {
826 ATRACE_CALL();
827
828 const std::lock_guard<std::mutex> lock(mMutex);
829 mLastExpectedPresentTimeNs = timestampNanos;
830 // Drop the out of date timeout.
831 dropEventLocked(VrrControllerEventType::kSystemRenderingTimeout);
832 cancelPresentTimeoutHandlingLocked();
833 mPendingVendorRenderingTimeoutTasks.baseTimeNs = timestampNanos;
834 mRecord.mPendingCurrentPresentTime = {mVrrActiveConfig, timestampNanos, frameIntervalNs};
835 }
836
onVsync(int64_t timestampNanos,int32_t __unused vsyncPeriodNanos)837 void VariableRefreshRateController::onVsync(int64_t timestampNanos,
838 int32_t __unused vsyncPeriodNanos) {
839 const std::lock_guard<std::mutex> lock(mMutex);
840 mRecord.mVsyncHistory
841 .next() = {.mType = VariableRefreshRateController::VsyncEvent::Type::kVblank,
842 .mTime = timestampNanos};
843 }
844
cancelPresentTimeoutHandlingLocked()845 void VariableRefreshRateController::cancelPresentTimeoutHandlingLocked() {
846 dropEventLocked(VrrControllerEventType::kVendorRenderingTimeoutInit);
847 dropEventLocked(VrrControllerEventType::kVendorRenderingTimeoutPost);
848 mPendingVendorRenderingTimeoutTasks.reset();
849 }
850
createMinimumRefreshRateTimeoutEventLocked()851 void VariableRefreshRateController::createMinimumRefreshRateTimeoutEventLocked() {
852 // Set up peak refresh rate timeout event accordingly.
853 mMinimumRefreshRateTimeoutEvent = std::make_optional<TimedEvent>("MinimumRefreshRateTimeout");
854 mMinimumRefreshRateTimeoutEvent->mFunctor = [this]() -> int {
855 if (mMinimumRefreshRatePresentState == kAtMaximumRefreshRate) {
856 mMinimumRefreshRatePresentState = kTransitionToMinimumRefreshRate;
857 mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
858 auto delayNs = (std::nano::den / mMinimumRefreshRate) + kMillisecondToNanoSecond;
859 mMinimumRefreshRateTimeoutEvent->mWhenNs = getSteadyClockTimeNs() + delayNs;
860 postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
861 mMinimumRefreshRateTimeoutEvent.value());
862 return 1;
863 } else {
864 if (mMinimumRefreshRatePresentState != kTransitionToMinimumRefreshRate) {
865 LOG(ERROR) << "VrrController: expect mMinimumRefreshRatePresentState is "
866 "kTransitionToMinimumRefreshRate, but it is "
867 << mMinimumRefreshRatePresentState;
868 return -1;
869 }
870 mMinimumRefreshRatePresentState = kAtMinimumRefreshRate;
871 // TODO(b/333204544): ensure the correct refresh rate is set when calling
872 // setFixedRefreshRate().
873 if (mVariableRefreshRateStatistic) {
874 mVariableRefreshRateStatistic->setFixedRefreshRate(mMinimumRefreshRate);
875 }
876 if (mPresentTimeoutController != PresentTimeoutControllerType::kHardware) {
877 LOG(WARNING) << "VrrController: incorrect type of present timeout controller.";
878 }
879 uint32_t command = getCurrentRefreshControlStateLocked();
880 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
881 setBitField(command, mMinimumRefreshRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
882 kPanelRefreshCtrlMinimumRefreshRateMask);
883 onRefreshRateChangedInternal(mMinimumRefreshRate);
884 auto res = mFileNode->writeValue(composer::kRefreshControlNodeName, command);
885 ATRACE_INT(kMinimumRefreshRateConfiguredTraceName, mMinimumRefreshRate);
886 return res;
887 }
888 };
889 }
890
dropEventLocked()891 void VariableRefreshRateController::dropEventLocked() {
892 mEventQueue.mPriorityQueue = std::priority_queue<VrrControllerEvent>();
893 }
894
dropEventLocked(VrrControllerEventType eventType)895 void VariableRefreshRateController::dropEventLocked(VrrControllerEventType eventType) {
896 std::priority_queue<VrrControllerEvent> q;
897 auto target = static_cast<int>(eventType);
898 while (!mEventQueue.mPriorityQueue.empty()) {
899 const auto& it = mEventQueue.mPriorityQueue.top();
900 if ((static_cast<int>(it.mEventType) & target) != target) {
901 q.push(it);
902 }
903 mEventQueue.mPriorityQueue.pop();
904 }
905 mEventQueue.mPriorityQueue = std::move(q);
906 }
907
dumpEventQueueLocked()908 std::string VariableRefreshRateController::dumpEventQueueLocked() {
909 std::string content;
910 if (mEventQueue.mPriorityQueue.empty()) {
911 return content;
912 }
913
914 std::priority_queue<VrrControllerEvent> q;
915 while (!mEventQueue.mPriorityQueue.empty()) {
916 const auto& it = mEventQueue.mPriorityQueue.top();
917 content += "VrrController: event = ";
918 content += it.toString();
919 content += "\n";
920 q.push(it);
921 mEventQueue.mPriorityQueue.pop();
922 }
923 mEventQueue.mPriorityQueue = std::move(q);
924 return content;
925 }
926
dump(String8 & result,const std::vector<std::string> & args)927 void VariableRefreshRateController::dump(String8& result, const std::vector<std::string>& args) {
928 result.appendFormat("\nVariableRefreshRateStatistic: \n");
929 if (mDisplay) {
930 result.appendFormat("[%s] ", mDisplay->mDisplayName.c_str());
931 }
932 result.appendFormat("Physical Refresh Rate = %i \n", mLastRefreshRate);
933 mVariableRefreshRateStatistic->dump(result, args);
934 }
935
getCurrentRefreshControlStateLocked() const936 uint32_t VariableRefreshRateController::getCurrentRefreshControlStateLocked() const {
937 uint32_t state = 0;
938 return (mFileNode->getLastWrittenValue(kRefreshControlNodeName, state) == NO_ERROR)
939 ? (state & kPanelRefreshCtrlStateBitsMask)
940 : 0;
941 }
942
getLastFenceSignalTimeUnlocked(int fd)943 int64_t VariableRefreshRateController::getLastFenceSignalTimeUnlocked(int fd) {
944 if (fd == -1) {
945 return SIGNAL_TIME_INVALID;
946 }
947 struct sync_file_info* finfo = sync_file_info(fd);
948 if (finfo == nullptr) {
949 LOG(ERROR) << "VrrController: sync_file_info returned NULL for fd " << fd;
950 return SIGNAL_TIME_INVALID;
951 }
952 if (finfo->status != 1) {
953 const auto status = finfo->status;
954 if (status < 0) {
955 LOG(ERROR) << "VrrController: sync_file_info contains an error: " << status;
956 }
957 sync_file_info_free(finfo);
958 return status < 0 ? SIGNAL_TIME_INVALID : SIGNAL_TIME_PENDING;
959 }
960 uint64_t timestamp = 0;
961 struct sync_fence_info* pinfo = sync_get_fence_info(finfo);
962 if (finfo->num_fences != 1) {
963 LOG(WARNING) << "VrrController:: there is more than one fence in the file descriptor = "
964 << fd;
965 }
966 for (size_t i = 0; i < finfo->num_fences; i++) {
967 if (pinfo[i].timestamp_ns > timestamp) {
968 timestamp = pinfo[i].timestamp_ns;
969 }
970 }
971 sync_file_info_free(finfo);
972 return timestamp;
973 }
974
getNextEventTimeLocked() const975 int64_t VariableRefreshRateController::getNextEventTimeLocked() const {
976 if (mEventQueue.mPriorityQueue.empty()) {
977 LOG(WARNING) << "VrrController: event queue should NOT be empty.";
978 return -1;
979 }
980 const auto& event = mEventQueue.mPriorityQueue.top();
981 return event.mWhenNs;
982 }
983
getStateName(VrrControllerState state) const984 std::string VariableRefreshRateController::getStateName(VrrControllerState state) const {
985 switch (state) {
986 case VrrControllerState::kDisable:
987 return "Disable";
988 case VrrControllerState::kRendering:
989 return "Rendering";
990 case VrrControllerState::kHibernate:
991 return "Hibernate";
992 default:
993 return "Unknown";
994 }
995 }
996
handleCadenceChange()997 void VariableRefreshRateController::handleCadenceChange() {
998 ATRACE_CALL();
999 if (!mRecord.mNextExpectedPresentTime.has_value()) {
1000 LOG(WARNING) << "VrrController: cadence change occurs without the expected present timing "
1001 "information.";
1002 return;
1003 }
1004 // TODO(b/305311056): handle frame rate change.
1005 mRecord.mNextExpectedPresentTime = std::nullopt;
1006 }
1007
handleResume()1008 void VariableRefreshRateController::handleResume() {
1009 ATRACE_CALL();
1010 if (!mRecord.mNextExpectedPresentTime.has_value()) {
1011 LOG(WARNING)
1012 << "VrrController: resume occurs without the expected present timing information.";
1013 return;
1014 }
1015 // TODO(b/305311281): handle panel resume.
1016 mRecord.mNextExpectedPresentTime = std::nullopt;
1017 }
1018
handleHibernate()1019 void VariableRefreshRateController::handleHibernate() {
1020 ATRACE_CALL();
1021 if (mFrameRateReporter) {
1022 mFrameRateReporter->reset();
1023 }
1024 // TODO(b/305311206): handle entering panel hibernate.
1025 postEvent(VrrControllerEventType::kHibernateTimeout,
1026 getSteadyClockTimeNs() + kDefaultWakeUpTimeInPowerSaving);
1027 }
1028
handleStayHibernate()1029 void VariableRefreshRateController::handleStayHibernate() {
1030 ATRACE_CALL();
1031 // TODO(b/305311698): handle keeping panel hibernate.
1032 postEvent(VrrControllerEventType::kHibernateTimeout,
1033 getSteadyClockTimeNs() + kDefaultWakeUpTimeInPowerSaving);
1034 }
1035
handlePresentTimeout()1036 void VariableRefreshRateController::handlePresentTimeout() {
1037 ATRACE_CALL();
1038
1039 if (mState == VrrControllerState::kDisable) {
1040 cancelPresentTimeoutHandlingLocked();
1041 return;
1042 }
1043
1044 // During doze, the present timeout controller switches to |kHardware|.
1045 // This remains until |handlePresentTimeout| is first called here where the controller type is
1046 // reset back to |mDefaultPresentTimeoutController|(|kSoftware|).
1047 if (mDefaultPresentTimeoutController != PresentTimeoutControllerType::kSoftware) {
1048 LOG(WARNING) << "VrrController: incorrect type of default present timeout controller.";
1049 }
1050 uint32_t command = 0;
1051 if (mFileNode->getLastWrittenValue(composer::kRefreshControlNodeName, command) == NO_ERROR) {
1052 clearBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
1053 setBitField(command, 1, kPanelRefreshCtrlFrameInsertionFrameCountOffset,
1054 kPanelRefreshCtrlFrameInsertionFrameCountMask);
1055 mFileNode->writeValue(composer::kRefreshControlNodeName, command);
1056 if (mPresentTimeoutController != PresentTimeoutControllerType::kSoftware) {
1057 mPresentTimeoutController = PresentTimeoutControllerType::kSoftware;
1058 }
1059 } else {
1060 LOG(ERROR) << "VrrController: no last wrttien value for kRefreshControlNodeName";
1061 }
1062 if (mFrameRateReporter) {
1063 mFrameRateReporter->onPresent(getSteadyClockTimeNs(), 0);
1064 }
1065 if (mVariableRefreshRateStatistic) {
1066 mVariableRefreshRateStatistic
1067 ->onNonPresentRefresh(getSteadyClockTimeNs(),
1068 RefreshSource::kRefreshSourceFrameInsertion);
1069 }
1070 mPendingVendorRenderingTimeoutTasks.scheduleNextTask();
1071 }
1072
onFrameRateChangedForDBI(int refreshRate)1073 void VariableRefreshRateController::onFrameRateChangedForDBI(int refreshRate) {
1074 // By default, if the refresh rate calculator cannot lock onto a specific frame rate, it may
1075 // return -1 to reflect this. To avoid reporting a negative frame frequency, return 1 instead in
1076 // this case.
1077 auto maxFrameRate = durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
1078 refreshRate = std::max(1, refreshRate);
1079 mFrameRate = std::min(maxFrameRate, refreshRate);
1080 postEvent(VrrControllerEventType::kUpdateDbiFrameRate, getSteadyClockTimeNs());
1081 }
1082
onRefreshRateChanged(int refreshRate)1083 void VariableRefreshRateController::onRefreshRateChanged(int refreshRate) {
1084 if (mMinimumRefreshRate > 1) {
1085 // If the minimum refresh rate has been set, the refresh rate remains fixed at a specific
1086 // value.
1087 return;
1088 }
1089 onRefreshRateChangedInternal(refreshRate);
1090 }
1091
onRefreshRateChangedInternal(int refreshRate)1092 void VariableRefreshRateController::onRefreshRateChangedInternal(int refreshRate) {
1093 if (!(mDisplay) || !(mDisplay->mDevice)) {
1094 LOG(ERROR) << "VrrController: absence of a device or display.";
1095 return;
1096 }
1097 refreshRate =
1098 refreshRate == kDefaultInvalidRefreshRate ? kDefaultMinimumRefreshRate : refreshRate;
1099 refreshRate = convertToValidRefreshRate(refreshRate);
1100 if (mLastRefreshRate == refreshRate) {
1101 return;
1102 }
1103 mLastRefreshRate = refreshRate;
1104 for (const auto& listener : mRefreshRateChangeListeners) {
1105 if (listener) listener->onRefreshRateChange(refreshRate);
1106 }
1107 reportRefreshRateIndicator();
1108 }
1109
reportRefreshRateIndicator()1110 void VariableRefreshRateController::reportRefreshRateIndicator() {
1111 if (mRefreshRateCalculatorEnabled) {
1112 if (!mDisplay->mDevice->isVrrApiSupported()) {
1113 // For legacy API, vsyncPeriodNanos is utilized to denote the refresh rate,
1114 // refreshPeriodNanos is disregarded.
1115 mDisplay->mDevice->onRefreshRateChangedDebug(mDisplay->mDisplayId,
1116 freqToDurationNs(mLastRefreshRate));
1117 } else {
1118 mDisplay->mDevice
1119 ->onRefreshRateChangedDebug(mDisplay->mDisplayId,
1120 mVrrConfigs[mVrrActiveConfig].vsyncPeriodNs,
1121 freqToDurationNs(mLastRefreshRate));
1122 }
1123 }
1124 }
1125
generateValidRefreshRates(const VrrConfig_t & config) const1126 std::vector<int> VariableRefreshRateController::generateValidRefreshRates(
1127 const VrrConfig_t& config) const {
1128 std::vector<int> refreshRates;
1129 int teFrequency = durationNsToFreq(config.vsyncPeriodNs);
1130 int minVsyncNum = roundDivide(config.minFrameIntervalNs, config.vsyncPeriodNs);
1131 for (int vsyncNum = minVsyncNum; vsyncNum <= teFrequency; vsyncNum++) {
1132 refreshRates.push_back(roundDivide(teFrequency, vsyncNum));
1133 }
1134 std::set<int> uniqueRefreshRates(refreshRates.begin(), refreshRates.end());
1135 refreshRates.assign(uniqueRefreshRates.begin(), uniqueRefreshRates.end());
1136 return refreshRates;
1137 }
1138
convertToValidRefreshRate(int refreshRate)1139 int VariableRefreshRateController::convertToValidRefreshRate(int refreshRate) {
1140 const auto& validRefreshRates = mValidRefreshRates[mVrrActiveConfig];
1141 auto it = std::lower_bound(validRefreshRates.begin(), validRefreshRates.end(), refreshRate);
1142 if (it != validRefreshRates.end()) {
1143 return *it;
1144 }
1145 LOG(ERROR) << "Could not match to any valid refresh rate: " << refreshRate;
1146 return durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
1147 }
1148
shouldHandleVendorRenderingTimeout() const1149 bool VariableRefreshRateController::shouldHandleVendorRenderingTimeout() const {
1150 // We skip the check |mPresentTimeoutController| == |kSoftware| here because, even if it's set
1151 // to |kHardware| when resuming from doze, we still allow vendor rendering timeouts. Once this
1152 // timeout occurs, |mPresentTimeoutController| will be reset to
1153 // |mDefaultPresentTimeoutController| (which should be |kSoftware|).
1154 return (mPresentTimeoutController == PresentTimeoutControllerType::kSoftware) &&
1155 ((!mVendorPresentTimeoutOverride) ||
1156 (mVendorPresentTimeoutOverride.value().mSchedule.size() > 0)) &&
1157 (mPowerMode == HWC_POWER_MODE_NORMAL);
1158 }
1159
threadBody()1160 void VariableRefreshRateController::threadBody() {
1161 struct sched_param param = {.sched_priority = sched_get_priority_min(SCHED_FIFO)};
1162 if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
1163 LOG(ERROR) << "VrrController: fail to set scheduler to SCHED_FIFO.";
1164 return;
1165 }
1166 for (;;) {
1167 bool stateChanged = false;
1168 uint32_t frameRate = 0;
1169 {
1170 std::unique_lock<std::mutex> lock(mMutex);
1171 if (mThreadExit) break;
1172 if (!mEnabled) mCondition.wait(lock);
1173 if (!mEnabled) continue;
1174
1175 if (mEventQueue.mPriorityQueue.empty()) {
1176 mCondition.wait(lock);
1177 }
1178 int64_t whenNs = getNextEventTimeLocked();
1179 int64_t nowNs = getSteadyClockTimeNs();
1180 if (whenNs > nowNs) {
1181 int64_t delayNs = whenNs - nowNs;
1182 auto res = mCondition.wait_for(lock, std::chrono::nanoseconds(delayNs));
1183 if (res != std::cv_status::timeout) {
1184 continue;
1185 }
1186 }
1187
1188 if (mEventQueue.mPriorityQueue.empty()) {
1189 continue;
1190 }
1191
1192 auto event = mEventQueue.mPriorityQueue.top();
1193 if (event.mWhenNs > getSteadyClockTimeNs()) {
1194 continue;
1195 }
1196 mEventQueue.mPriorityQueue.pop();
1197 if (static_cast<int>(event.mEventType) &
1198 static_cast<int>(VrrControllerEventType::kCallbackEventMask)) {
1199 handleCallbackEventLocked(event);
1200 continue;
1201 }
1202 if (event.mEventType == VrrControllerEventType::kUpdateDbiFrameRate) {
1203 frameRate = mFrameRate;
1204 }
1205 if (event.mEventType == VrrControllerEventType::kMinimumRefreshRateAlignWithPresent) {
1206 if (mPendingMinimumRefreshRateRequest) {
1207 mMinimumRefreshRate = mPendingMinimumRefreshRateRequest.value();
1208 mPendingMinimumRefreshRateRequest = std::nullopt;
1209 auto maxFrameRate =
1210 durationNsToFreq(mVrrConfigs[mVrrActiveConfig].minFrameIntervalNs);
1211 uint32_t command = getCurrentRefreshControlStateLocked();
1212 // Delegate timeout management to hardware.
1213 setBit(command, kPanelRefreshCtrlFrameInsertionAutoModeOffset);
1214 // Configure panel to maintain the minimum refresh rate.
1215 setBitField(command, maxFrameRate, kPanelRefreshCtrlMinimumRefreshRateOffset,
1216 kPanelRefreshCtrlMinimumRefreshRateMask);
1217 if (!mFileNode->writeValue(composer::kRefreshControlNodeName, command)) {
1218 LOG(WARNING)
1219 << "VrrController: write file node error, command = " << command;
1220 return;
1221 }
1222 ATRACE_INT(kMinimumRefreshRateConfiguredTraceName, maxFrameRate);
1223 mMinimumRefreshRatePresentState = kAtMaximumRefreshRate;
1224 // Even though we transition directly to the maximum refresh rate, we still
1225 // report the refresh rate change for |mMinimumRefreshRate| to maintain
1226 // consistency. It will soon ovewrite by |maxFrameRate| below.
1227 onRefreshRateChangedInternal(mMinimumRefreshRate);
1228 onRefreshRateChangedInternal(maxFrameRate);
1229 mMinimumRefreshRateTimeoutEvent->mIsRelativeTime = false;
1230 mMinimumRefreshRateTimeoutEvent->mWhenNs =
1231 getSteadyClockTimeNs() + mMaximumRefreshRateTimeoutNs;
1232 postEvent(VrrControllerEventType::kMinLockTimeForPeakRefreshRate,
1233 mMinimumRefreshRateTimeoutEvent.value());
1234 }
1235 continue;
1236 }
1237 if (event.mEventType ==
1238 VrrControllerEventType::kMinimumRefreshRateWaitForConfigTimeout) {
1239 LOG(ERROR) << "Set minimum refresh rate to " << mMinimumRefreshRate
1240 << " but wait for config timeout.";
1241 mPendingMinimumRefreshRateRequest = std::nullopt;
1242 continue;
1243 }
1244 if (mState == VrrControllerState::kRendering) {
1245 if (event.mEventType == VrrControllerEventType::kHibernateTimeout) {
1246 LOG(ERROR) << "VrrController: receiving a hibernate timeout event while in the "
1247 "rendering state.";
1248 }
1249 switch (event.mEventType) {
1250 case VrrControllerEventType::kSystemRenderingTimeout: {
1251 handleHibernate();
1252 mState = VrrControllerState::kHibernate;
1253 stateChanged = true;
1254 break;
1255 }
1256 case VrrControllerEventType::kNotifyExpectedPresentConfig: {
1257 handleCadenceChange();
1258 break;
1259 }
1260 case VrrControllerEventType::kVendorRenderingTimeoutInit: {
1261 if (mPresentTimeoutEventHandler) {
1262 size_t numberOfIntervals = 0;
1263 // Verify whether a present timeout override exists, and if so, execute
1264 // it first.
1265 if (mVendorPresentTimeoutOverride) {
1266 const auto& params = mVendorPresentTimeoutOverride.value();
1267 int64_t whenFromNowNs = 0;
1268 for (int i = 0; i < params.mSchedule.size(); ++i) {
1269 numberOfIntervals += params.mSchedule[i].first;
1270 }
1271 if (numberOfIntervals > 0) {
1272 mPendingVendorRenderingTimeoutTasks.reserveSpace(
1273 numberOfIntervals);
1274 for (int i = 0; i < params.mSchedule.size(); ++i) {
1275 uint32_t intervalNs = params.mSchedule[i].second;
1276 for (int j = 0; j < params.mSchedule[i].first; ++j) {
1277 mPendingVendorRenderingTimeoutTasks.addTask(
1278 whenFromNowNs);
1279 whenFromNowNs += intervalNs;
1280 }
1281 }
1282 }
1283 } else {
1284 auto handleEvents = mPresentTimeoutEventHandler->getHandleEvents();
1285 if (!handleEvents.empty()) {
1286 numberOfIntervals = handleEvents.size();
1287 mPendingVendorRenderingTimeoutTasks.reserveSpace(
1288 numberOfIntervals);
1289 for (int i = 0; i < handleEvents.size(); ++i) {
1290 mPendingVendorRenderingTimeoutTasks.addTask(
1291 handleEvents[i].mWhenNs);
1292 }
1293 }
1294 }
1295 if (numberOfIntervals > 0) {
1296 // Start from 1 since we will execute the first task immediately
1297 // below.
1298 mPendingVendorRenderingTimeoutTasks.nextTaskIndex = 1;
1299 handlePresentTimeout();
1300 }
1301 }
1302 break;
1303 }
1304 case VrrControllerEventType::kVendorRenderingTimeoutPost: {
1305 handlePresentTimeout();
1306 if (event.mFunctor) {
1307 event.mFunctor();
1308 }
1309 break;
1310 }
1311 default: {
1312 break;
1313 }
1314 }
1315 } else {
1316 if (event.mEventType == VrrControllerEventType::kSystemRenderingTimeout) {
1317 LOG(ERROR) << "VrrController: receiving a rendering timeout event while in the "
1318 "hibernate state.";
1319 }
1320 if (mState != VrrControllerState::kHibernate) {
1321 LOG(ERROR) << "VrrController: expecting to be in hibernate, but instead in "
1322 "state = "
1323 << getStateName(mState);
1324 }
1325 switch (event.mEventType) {
1326 case VrrControllerEventType::kHibernateTimeout: {
1327 handleStayHibernate();
1328 break;
1329 }
1330 case VrrControllerEventType::kNotifyExpectedPresentConfig: {
1331 handleResume();
1332 mState = VrrControllerState::kRendering;
1333 stateChanged = true;
1334 break;
1335 }
1336 default: {
1337 break;
1338 }
1339 }
1340 }
1341 }
1342 // TODO(b/309873055): implement a handler to serialize all outer function calls to the same
1343 // thread owned by the VRR controller.
1344 if (stateChanged) {
1345 updateVsyncHistory();
1346 }
1347 // Write pending values without holding mutex shared with HWC main thread.
1348 if (frameRate) {
1349 if (!mFileNode->writeValue(kFrameRateNodeName, frameRate)) {
1350 LOG(ERROR) << "VrrController: write to node = " << kFrameRateNodeName
1351 << " failed, value = " << frameRate;
1352 }
1353 ATRACE_INT("frameRate", frameRate);
1354 }
1355 }
1356 }
1357
postEvent(VrrControllerEventType type,int64_t when)1358 void VariableRefreshRateController::postEvent(VrrControllerEventType type, int64_t when) {
1359 VrrControllerEvent event;
1360 event.mEventType = type;
1361 event.mWhenNs = when;
1362 mEventQueue.mPriorityQueue.emplace(event);
1363 }
1364
postEvent(VrrControllerEventType type,TimedEvent & timedEvent)1365 void VariableRefreshRateController::postEvent(VrrControllerEventType type, TimedEvent& timedEvent) {
1366 VrrControllerEvent event;
1367 event.mEventType = type;
1368 event.mWhenNs = timedEvent.mIsRelativeTime ? (getSteadyClockTimeNs() + timedEvent.mWhenNs)
1369 : timedEvent.mWhenNs;
1370 event.mFunctor = std::move(timedEvent.mFunctor);
1371 mEventQueue.mPriorityQueue.emplace(event);
1372 }
1373
updateVsyncHistory()1374 void VariableRefreshRateController::updateVsyncHistory() {
1375 int fence = -1;
1376
1377 {
1378 const std::lock_guard<std::mutex> lock(mMutex);
1379 if (!mLastPresentFence.has_value()) {
1380 return;
1381 }
1382 fence = mLastPresentFence.value();
1383 mLastPresentFence = std::nullopt;
1384 }
1385
1386 // Execute the following logic unlocked to enhance performance.
1387 int64_t lastSignalTime = getLastFenceSignalTimeUnlocked(fence);
1388 if (close(fence)) {
1389 LOG(ERROR) << "VrrController: close fence file failed, errno = " << errno;
1390 return;
1391 } else if (lastSignalTime == SIGNAL_TIME_PENDING || lastSignalTime == SIGNAL_TIME_INVALID) {
1392 return;
1393 }
1394
1395 {
1396 // Acquire the mutex again to store the vsync record.
1397 const std::lock_guard<std::mutex> lock(mMutex);
1398 mRecord.mVsyncHistory
1399 .next() = {.mType = VariableRefreshRateController::VsyncEvent::Type::kReleaseFence,
1400 .mTime = lastSignalTime};
1401 }
1402 }
1403
1404 } // namespace android::hardware::graphics::composer
1405