2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
21 // #define LOG_NDEBUG 0
23 #define LOG_TAG "DisplayDevice"
25 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
27 #include <android-base/stringprintf.h>
28 #include <compositionengine/CompositionEngine.h>
29 #include <compositionengine/Display.h>
30 #include <compositionengine/DisplayColorProfile.h>
31 #include <compositionengine/DisplayColorProfileCreationArgs.h>
32 #include <compositionengine/DisplayCreationArgs.h>
33 #include <compositionengine/DisplaySurface.h>
34 #include <compositionengine/ProjectionSpace.h>
35 #include <compositionengine/RenderSurface.h>
36 #include <compositionengine/RenderSurfaceCreationArgs.h>
37 #include <compositionengine/impl/OutputCompositionState.h>
38 #include <configstore/Utils.h>
40 #include <system/window.h>
41 #include <ui/GraphicTypes.h>
48 #include "DisplayDevice.h"
50 #include "RefreshRateOverlay.h"
51 #include "SurfaceFlinger.h"
53 // Duplicate enum values here, this avoids making SurfaceFlinger module
54 // depend on drm_gralloc, which is obsolete and will eventually go away.
57 GRALLOC_MODULE_PERFORM_ENTER_VT = 0x80000005,
58 GRALLOC_MODULE_PERFORM_LEAVE_VT = 0x80000006,
64 namespace hal = hardware::graphics::composer::hal;
66 using android::base::StringAppendF;
68 #ifdef CONSOLE_MANAGER
69 class ConsoleManagerThread : public Thread {
71 ConsoleManagerThread(const sp<SurfaceFlinger>&, const wp<IBinder>&);
72 virtual ~ConsoleManagerThread();
74 status_t releaseScreen() const;
77 sp<SurfaceFlinger> mFlinger;
78 wp<IBinder> mDisplayToken;
82 virtual void onFirstRef();
83 virtual status_t readyToRun();
84 virtual void requestExit();
85 virtual bool threadLoop();
86 static void sigHandler(int sig);
87 static pid_t sSignalCatcherPid;
90 ConsoleManagerThread::ConsoleManagerThread(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& token)
91 : Thread(false), mFlinger(flinger), mDisplayToken(token), consoleFd(-1)
93 sSignalCatcherPid = 0;
95 // create a new console
96 char const * const ttydev = "/dev/tty0";
97 int fd = open(ttydev, O_RDWR | O_SYNC);
99 ALOGE("Can't open %s, errno=%d (%s)", ttydev, errno, strerror(errno));
103 ALOGD("Open /dev/tty0 OK");
105 // to make sure that we are in text mode
106 int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
108 ALOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
109 fd, res, strerror(errno));
112 // get the current console
114 res = ioctl(fd, VT_GETSTATE, &vs);
116 ALOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
117 fd, res, strerror(errno));
122 // switch to console 7 (which is what X normaly uses)
124 res = ioctl(fd, VT_ACTIVATE, ANDROID_VT);
125 } while(res < 0 && errno == EINTR);
127 ALOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for vt %d",
128 fd, errno, strerror(errno), ANDROID_VT);
134 res = ioctl(fd, VT_WAITACTIVE, ANDROID_VT);
135 } while (res < 0 && errno == EINTR);
137 ALOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for vt %d",
138 fd, res, errno, strerror(errno), ANDROID_VT);
143 // open the new console
145 fd = open(ttydev, O_RDWR | O_SYNC);
147 ALOGE("Can't open new console %s", ttydev);
152 /* disable console line buffer, echo, ... */
153 struct termios ttyarg;
154 ioctl(fd, TCGETS , &ttyarg);
157 ioctl(fd, TCSETS , &ttyarg);
159 // set up signals so we're notified when the console changes
160 // we can't use SIGUSR1 because it's used by the java-vm
161 vm.mode = VT_PROCESS;
164 vm.acqsig = SIGUNUSED;
167 struct sigaction act;
168 sigemptyset(&act.sa_mask);
169 act.sa_handler = sigHandler;
171 sigaction(vm.relsig, &act, NULL);
173 sigemptyset(&act.sa_mask);
174 act.sa_handler = sigHandler;
176 sigaction(vm.acqsig, &act, NULL);
180 sigaddset(&mask, vm.relsig);
181 sigaddset(&mask, vm.acqsig);
182 sigprocmask(SIG_BLOCK, &mask, NULL);
184 // switch to graphic mode
185 res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
187 "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
189 prev_vt_num = vs.v_active;
193 ConsoleManagerThread::~ConsoleManagerThread()
195 if (consoleFd >= 0) {
198 ioctl(fd, KDSETMODE, (void*)KD_TEXT);
200 res = ioctl(fd, VT_ACTIVATE, prev_vt_num);
201 } while(res < 0 && errno == EINTR);
203 res = ioctl(fd, VT_WAITACTIVE, prev_vt_num);
204 } while(res < 0 && errno == EINTR);
206 char const * const ttydev = "/dev/tty0";
207 fd = open(ttydev, O_RDWR | O_SYNC);
208 ioctl(fd, VT_DISALLOCATE, 0);
213 status_t ConsoleManagerThread::releaseScreen() const
215 int err = ioctl(consoleFd, VT_RELDISP, (void*)1);
216 ALOGE_IF(err < 0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
217 consoleFd, errno, strerror(errno));
218 return (err < 0) ? (-errno) : status_t(NO_ERROR);
221 void ConsoleManagerThread::onFirstRef()
223 run("ConsoleManagerThread", PRIORITY_URGENT_DISPLAY);
226 status_t ConsoleManagerThread::readyToRun()
228 if (consoleFd >= 0) {
229 sSignalCatcherPid = gettid();
233 sigaddset(&mask, vm.relsig);
234 sigaddset(&mask, vm.acqsig);
235 sigprocmask(SIG_BLOCK, &mask, NULL);
237 int res = ioctl(consoleFd, VT_SETMODE, &vm);
239 ALOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
240 consoleFd, errno, strerror(errno));
247 void ConsoleManagerThread::requestExit()
249 Thread::requestExit();
250 if (sSignalCatcherPid != 0) {
251 // wake the thread up
252 kill(sSignalCatcherPid, SIGINT);
257 bool ConsoleManagerThread::threadLoop()
261 sigaddset(&mask, vm.relsig);
262 sigaddset(&mask, vm.acqsig);
265 sigwait(&mask, &sig);
267 hw_module_t const* mod;
268 gralloc_module_t const* gr = NULL;
269 status_t err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
271 gr = reinterpret_cast<gralloc_module_t const*>(mod);
276 if (sig == vm.relsig) {
278 gr->perform(gr, GRALLOC_MODULE_PERFORM_LEAVE_VT);
279 mFlinger->screenReleased(mDisplayToken.promote());
280 } else if (sig == vm.acqsig) {
281 mFlinger->screenAcquired(mDisplayToken.promote());
283 gr->perform(gr, GRALLOC_MODULE_PERFORM_ENTER_VT);
289 void ConsoleManagerThread::sigHandler(int sig)
291 // resend the signal to our signal catcher thread
292 ALOGW("received signal %d in thread %d, resending to %d",
293 sig, gettid(), sSignalCatcherPid);
295 // we absolutely need the delays below because without them
296 // our main thread never gets a chance to handle the signal.
298 kill(sSignalCatcherPid, sig);
302 pid_t ConsoleManagerThread::sSignalCatcherPid;
305 ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
307 DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
308 const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
309 std::shared_ptr<compositionengine::Display> compositionDisplay)
311 hwComposer(hwComposer),
312 displayToken(displayToken),
313 compositionDisplay(compositionDisplay) {}
315 DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
316 : mFlinger(args.flinger),
317 mHwComposer(args.hwComposer),
318 mDisplayToken(args.displayToken),
319 mSequenceId(args.sequenceId),
320 mConnectionType(args.connectionType),
321 mCompositionDisplay{args.compositionDisplay},
322 mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())),
323 mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())),
324 mPhysicalOrientation(args.physicalOrientation),
325 mSupportedModes(std::move(args.supportedModes)),
326 #ifdef CONSOLE_MANAGER
327 mConsoleManagerThread(0),
329 mIsPrimary(args.isPrimary),
330 mRefreshRateConfigs(std::move(args.refreshRateConfigs)) {
331 mCompositionDisplay->editState().isSecure = args.isSecure;
332 mCompositionDisplay->createRenderSurface(
333 compositionengine::RenderSurfaceCreationArgsBuilder()
334 .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
335 .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get()))
336 .setNativeWindow(std::move(args.nativeWindow))
337 .setDisplaySurface(std::move(args.displaySurface))
338 .setMaxTextureCacheSize(
339 static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers))
342 if (!mFlinger->mDisableClientCompositionCache &&
343 SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
344 mCompositionDisplay->createClientCompositionCache(
345 static_cast<uint32_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers));
348 mCompositionDisplay->createDisplayColorProfile(
349 compositionengine::DisplayColorProfileCreationArgs{args.hasWideColorGamut,
350 std::move(args.hdrCapabilities),
351 args.supportedPerFrameMetadata,
352 args.hwcColorModes});
354 if (!mCompositionDisplay->isValid()) {
355 ALOGE("Composition Display did not validate!");
358 mCompositionDisplay->getRenderSurface()->initialize();
360 setPowerMode(args.initialPowerMode);
362 // initialize the display orientation transform.
363 setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
366 #ifdef CONSOLE_MANAGER
367 DisplayDevice::~DisplayDevice() {
368 if (mConsoleManagerThread != 0) {
369 mConsoleManagerThread->requestExitAndWait();
370 ALOGD("ConsoleManagerThread: destroy primary DisplayDevice");
374 DisplayDevice::~DisplayDevice() = default;
377 void DisplayDevice::disconnect() {
378 mCompositionDisplay->disconnect();
381 int DisplayDevice::getWidth() const {
382 return mCompositionDisplay->getState().displaySpace.bounds.getWidth();
385 int DisplayDevice::getHeight() const {
386 return mCompositionDisplay->getState().displaySpace.bounds.getHeight();
389 void DisplayDevice::setDisplayName(const std::string& displayName) {
390 if (!displayName.empty()) {
391 // never override the name with an empty name
392 mDisplayName = displayName;
393 mCompositionDisplay->setName(displayName);
397 void DisplayDevice::setDeviceProductInfo(std::optional<DeviceProductInfo> info) {
398 mDeviceProductInfo = std::move(info);
401 uint32_t DisplayDevice::getPageFlipCount() const {
402 return mCompositionDisplay->getRenderSurface()->getPageFlipCount();
405 // ----------------------------------------------------------------------------
406 void DisplayDevice::setPowerMode(hal::PowerMode mode) {
408 getCompositionDisplay()->setCompositionEnabled(mPowerMode != hal::PowerMode::OFF);
409 #ifdef CONSOLE_MANAGER
410 if (mode != hal::PowerMode::ON && mConsoleManagerThread != 0) {
411 mConsoleManagerThread->releaseScreen();
416 void DisplayDevice::enableLayerCaching(bool enable) {
417 getCompositionDisplay()->setLayerCachingEnabled(enable);
420 hal::PowerMode DisplayDevice::getPowerMode() const {
424 bool DisplayDevice::isPoweredOn() const {
425 return mPowerMode != hal::PowerMode::OFF;
428 void DisplayDevice::setActiveMode(DisplayModeId id) {
429 const auto mode = getMode(id);
430 LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported.");
431 ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue());
433 if (mRefreshRateConfigs) {
434 mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
436 if (mRefreshRateOverlay) {
437 mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
441 status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info,
442 const hal::VsyncPeriodChangeConstraints& constraints,
443 hal::VsyncPeriodChangeTimeline* outTimeline) {
444 if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) {
445 ALOGE("Trying to initiate a mode change to invalid mode %s on display %s",
446 info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null",
447 to_string(getId()).c_str());
450 mUpcomingActiveMode = info;
451 ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue());
452 return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(),
453 constraints, outTimeline);
456 const DisplayModePtr& DisplayDevice::getActiveMode() const {
460 const DisplayModes& DisplayDevice::getSupportedModes() const {
461 return mSupportedModes;
464 DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
465 const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
466 [&](DisplayModePtr mode) { return mode->getId() == modeId; });
467 if (it != mSupportedModes.end()) {
473 nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
474 const auto physicalId = getPhysicalId();
475 if (!mHwComposer.isConnected(physicalId)) {
480 const auto status = mHwComposer.getDisplayVsyncPeriod(physicalId, &vsyncPeriod);
481 if (status == NO_ERROR) {
485 return getActiveMode()->getFps().getPeriodNsecs();
488 nsecs_t DisplayDevice::getRefreshTimestamp() const {
489 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
490 const auto vsyncPeriodNanos = getVsyncPeriodFromHWC();
491 return now - ((now - mLastHwVsync) % vsyncPeriodNanos);
494 void DisplayDevice::onVsync(nsecs_t timestamp) {
495 mLastHwVsync = timestamp;
498 ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
499 return mCompositionDisplay->getState().dataspace;
502 void DisplayDevice::setLayerStack(ui::LayerStack stack) {
503 mCompositionDisplay->setLayerStackFilter(stack, isInternal());
504 if (mRefreshRateOverlay) {
505 mRefreshRateOverlay->setLayerStack(stack);
509 void DisplayDevice::setFlags(uint32_t flags) {
513 void DisplayDevice::setDisplaySize(int width, int height) {
514 LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
515 const auto size = ui::Size(width, height);
516 mCompositionDisplay->setDisplaySize(size);
517 if (mRefreshRateOverlay) {
518 mRefreshRateOverlay->setViewport(size);
522 void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
523 Rect orientedDisplaySpaceRect) {
524 mOrientation = orientation;
527 sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation);
528 #ifdef CONSOLE_MANAGER
529 mConsoleManagerThread = new ConsoleManagerThread(mFlinger, mDisplayToken);
533 if (!orientedDisplaySpaceRect.isValid()) {
534 // The destination frame can be invalid if it has never been set,
535 // in that case we assume the whole display size.
536 orientedDisplaySpaceRect = getCompositionDisplay()->getState().displaySpace.bounds;
539 if (layerStackSpaceRect.isEmpty()) {
540 // The layerStackSpaceRect can be invalid if it has never been set, in that case
541 // we assume the whole framebuffer size.
542 layerStackSpaceRect = getCompositionDisplay()->getState().framebufferSpace.bounds;
543 if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
544 std::swap(layerStackSpaceRect.right, layerStackSpaceRect.bottom);
548 // We need to take care of display rotation for globalTransform for case if the panel is not
549 // installed aligned with device orientation.
550 const auto transformOrientation = orientation + mPhysicalOrientation;
551 getCompositionDisplay()->setProjection(transformOrientation, layerStackSpaceRect,
552 orientedDisplaySpaceRect);
555 ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() {
556 return sPrimaryDisplayRotationFlags;
559 std::string DisplayDevice::getDebugName() const {
560 const char* type = "virtual";
561 if (mConnectionType) {
562 type = isInternal() ? "internal" : "external";
565 return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
566 isPrimary() ? ", primary" : "", mDisplayName.c_str());
569 void DisplayDevice::dump(std::string& result) const {
570 StringAppendF(&result, "+ %s\n", getDebugName().c_str());
571 StringAppendF(&result, " powerMode=%s (%d)\n", to_string(mPowerMode).c_str(),
572 static_cast<int32_t>(mPowerMode));
573 const auto activeMode = getActiveMode();
574 StringAppendF(&result, " activeMode=%s\n",
575 activeMode ? to_string(*activeMode).c_str() : "none");
577 result.append(" supportedModes=\n");
579 for (const auto& mode : mSupportedModes) {
581 result.append(to_string(*mode));
584 StringAppendF(&result, " deviceProductInfo=");
585 if (mDeviceProductInfo) {
586 mDeviceProductInfo->dump(result);
591 getCompositionDisplay()->dump(result);
593 if (mRefreshRateConfigs) {
594 mRefreshRateConfigs->dump(result);
598 bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const {
599 return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
602 DisplayId DisplayDevice::getId() const {
603 return mCompositionDisplay->getId();
606 bool DisplayDevice::isSecure() const {
607 return mCompositionDisplay->isSecure();
610 const Rect& DisplayDevice::getBounds() const {
611 return mCompositionDisplay->getState().displaySpace.bounds;
614 const Region& DisplayDevice::getUndefinedRegion() const {
615 return mCompositionDisplay->getState().undefinedRegion;
618 bool DisplayDevice::needsFiltering() const {
619 return mCompositionDisplay->getState().needsFiltering;
622 ui::LayerStack DisplayDevice::getLayerStack() const {
623 return mCompositionDisplay->getState().layerStackId;
626 ui::Transform::RotationFlags DisplayDevice::getTransformHint() const {
627 return mCompositionDisplay->getTransformHint();
630 const ui::Transform& DisplayDevice::getTransform() const {
631 return mCompositionDisplay->getState().transform;
634 const Rect& DisplayDevice::getLayerStackSpaceRect() const {
635 return mCompositionDisplay->getState().layerStackSpace.content;
638 const Rect& DisplayDevice::getOrientedDisplaySpaceRect() const {
639 return mCompositionDisplay->getState().orientedDisplaySpace.content;
642 bool DisplayDevice::hasWideColorGamut() const {
643 return mCompositionDisplay->getDisplayColorProfile()->hasWideColorGamut();
646 bool DisplayDevice::hasHDR10PlusSupport() const {
647 return mCompositionDisplay->getDisplayColorProfile()->hasHDR10PlusSupport();
650 bool DisplayDevice::hasHDR10Support() const {
651 return mCompositionDisplay->getDisplayColorProfile()->hasHDR10Support();
654 bool DisplayDevice::hasHLGSupport() const {
655 return mCompositionDisplay->getDisplayColorProfile()->hasHLGSupport();
658 bool DisplayDevice::hasDolbyVisionSupport() const {
659 return mCompositionDisplay->getDisplayColorProfile()->hasDolbyVisionSupport();
662 int DisplayDevice::getSupportedPerFrameMetadata() const {
663 return mCompositionDisplay->getDisplayColorProfile()->getSupportedPerFrameMetadata();
666 void DisplayDevice::overrideHdrTypes(const std::vector<ui::Hdr>& hdrTypes) {
667 mOverrideHdrTypes = hdrTypes;
670 HdrCapabilities DisplayDevice::getHdrCapabilities() const {
671 const HdrCapabilities& capabilities =
672 mCompositionDisplay->getDisplayColorProfile()->getHdrCapabilities();
673 std::vector<ui::Hdr> hdrTypes = capabilities.getSupportedHdrTypes();
674 if (!mOverrideHdrTypes.empty()) {
675 hdrTypes = mOverrideHdrTypes;
677 return HdrCapabilities(hdrTypes, capabilities.getDesiredMaxLuminance(),
678 capabilities.getDesiredMaxAverageLuminance(),
679 capabilities.getDesiredMinLuminance());
682 void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
684 mRefreshRateOverlay.reset();
688 const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange();
689 mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(),
690 highFps.getIntValue(), showSpinnner);
691 mRefreshRateOverlay->setLayerStack(getLayerStack());
692 mRefreshRateOverlay->setViewport(getSize());
693 mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
696 bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
698 if (mRefreshRateConfigs && mRefreshRateOverlay) {
699 const auto newRefreshRate =
700 mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
701 if (newRefreshRate) {
702 mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
710 void DisplayDevice::onInvalidate() {
711 if (mRefreshRateOverlay) {
712 mRefreshRateOverlay->onInvalidate();
716 bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) {
719 LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided");
720 LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch");
722 ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str());
724 std::scoped_lock lock(mActiveModeLock);
725 if (mDesiredActiveModeChanged) {
726 // If a mode change is pending, just cache the latest request in mDesiredActiveMode
727 const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event;
728 mDesiredActiveMode = info;
729 mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig;
733 // Check if we are already at the desired mode
734 if (getActiveMode()->getId() == info.mode->getId()) {
738 // Initiate a mode change.
739 mDesiredActiveModeChanged = true;
740 mDesiredActiveMode = info;
744 std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const {
745 std::scoped_lock lock(mActiveModeLock);
746 if (mDesiredActiveModeChanged) return mDesiredActiveMode;
750 void DisplayDevice::clearDesiredActiveModeState() {
751 std::scoped_lock lock(mActiveModeLock);
752 mDesiredActiveMode.event = Scheduler::ModeEvent::None;
753 mDesiredActiveModeChanged = false;
756 std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
758 } // namespace android
760 // TODO(b/129481165): remove the #pragma below and fix conversion issues
761 #pragma clang diagnostic pop // ignored "-Wconversion"