OSDN Git Service

SurfaceFlinger: enable console management
[android-x86/frameworks-native.git] / services / surfaceflinger / DisplayDevice.cpp
1 /*
2  * Copyright (C) 2007 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20
21 // #define LOG_NDEBUG 0
22 #undef LOG_TAG
23 #define LOG_TAG "DisplayDevice"
24
25 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
26
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>
39 #include <log/log.h>
40 #include <system/window.h>
41 #include <ui/GraphicTypes.h>
42
43 #include <fcntl.h>
44 #include <termios.h>
45 #include <linux/kd.h>
46 #include <linux/vt.h>
47
48 #include "DisplayDevice.h"
49 #include "Layer.h"
50 #include "RefreshRateOverlay.h"
51 #include "SurfaceFlinger.h"
52
53 // Duplicate enum values here, this avoids making SurfaceFlinger module
54 // depend on drm_gralloc, which is obsolete and will eventually go away.
55
56 enum {
57     GRALLOC_MODULE_PERFORM_ENTER_VT                  = 0x80000005,
58     GRALLOC_MODULE_PERFORM_LEAVE_VT                  = 0x80000006,
59 };
60
61
62 namespace android {
63
64 namespace hal = hardware::graphics::composer::hal;
65
66 using android::base::StringAppendF;
67
68 #ifdef CONSOLE_MANAGER
69 class ConsoleManagerThread : public Thread {
70 public:
71             ConsoleManagerThread(const sp<SurfaceFlinger>&, const wp<IBinder>&);
72     virtual ~ConsoleManagerThread();
73
74     status_t releaseScreen() const;
75
76 private:
77     sp<SurfaceFlinger> mFlinger;
78     wp<IBinder> mDisplayToken;
79     int consoleFd;
80     long prev_vt_num;
81     vt_mode vm;
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;
88 };
89
90 ConsoleManagerThread::ConsoleManagerThread(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& token)
91     : Thread(false), mFlinger(flinger), mDisplayToken(token), consoleFd(-1)
92 {
93     sSignalCatcherPid = 0;
94
95     // create a new console
96     char const * const ttydev = "/dev/tty0";
97     int fd = open(ttydev, O_RDWR | O_SYNC);
98     if (fd < 0) {
99         ALOGE("Can't open %s, errno=%d (%s)", ttydev, errno, strerror(errno));
100         consoleFd = -errno;
101         return;
102     }
103     ALOGD("Open /dev/tty0 OK");
104
105     // to make sure that we are in text mode
106     int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
107     if (res < 0) {
108         ALOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
109                 fd, res, strerror(errno));
110     }
111
112     // get the current console
113     struct vt_stat vs;
114     res = ioctl(fd, VT_GETSTATE, &vs);
115     if (res < 0) {
116         ALOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
117                 fd, res, strerror(errno));
118         consoleFd = -errno;
119         return;
120     }
121
122     // switch to console 7 (which is what X normaly uses)
123     do {
124         res = ioctl(fd, VT_ACTIVATE, ANDROID_VT);
125     } while(res < 0 && errno == EINTR);
126     if (res < 0) {
127         ALOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for vt %d",
128                 fd, errno, strerror(errno), ANDROID_VT);
129         consoleFd = -errno;
130         return;
131     }
132
133     do {
134         res = ioctl(fd, VT_WAITACTIVE, ANDROID_VT);
135     } while (res < 0 && errno == EINTR);
136     if (res < 0) {
137         ALOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for vt %d",
138                 fd, res, errno, strerror(errno), ANDROID_VT);
139         consoleFd = -errno;
140         return;
141     }
142
143     // open the new console
144     close(fd);
145     fd = open(ttydev, O_RDWR | O_SYNC);
146     if (fd < 0) {
147         ALOGE("Can't open new console %s", ttydev);
148         consoleFd = -errno;
149         return;
150     }
151
152     /* disable console line buffer, echo, ... */
153     struct termios ttyarg;
154     ioctl(fd, TCGETS , &ttyarg);
155     ttyarg.c_iflag = 0;
156     ttyarg.c_lflag = 0;
157     ioctl(fd, TCSETS , &ttyarg);
158
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;
162     vm.waitv = 0;
163     vm.relsig = SIGUSR2;
164     vm.acqsig = SIGUNUSED;
165     vm.frsig = 0;
166
167     struct sigaction act;
168     sigemptyset(&act.sa_mask);
169     act.sa_handler = sigHandler;
170     act.sa_flags = 0;
171     sigaction(vm.relsig, &act, NULL);
172
173     sigemptyset(&act.sa_mask);
174     act.sa_handler = sigHandler;
175     act.sa_flags = 0;
176     sigaction(vm.acqsig, &act, NULL);
177
178     sigset_t mask;
179     sigemptyset(&mask);
180     sigaddset(&mask, vm.relsig);
181     sigaddset(&mask, vm.acqsig);
182     sigprocmask(SIG_BLOCK, &mask, NULL);
183
184     // switch to graphic mode
185     res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
186     ALOGW_IF(res < 0,
187             "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
188
189     prev_vt_num = vs.v_active;
190     consoleFd = fd;
191 }
192
193 ConsoleManagerThread::~ConsoleManagerThread()
194 {
195     if (consoleFd >= 0) {
196         int fd = consoleFd;
197         int res;
198         ioctl(fd, KDSETMODE, (void*)KD_TEXT);
199         do {
200             res = ioctl(fd, VT_ACTIVATE, prev_vt_num);
201         } while(res < 0 && errno == EINTR);
202         do {
203             res = ioctl(fd, VT_WAITACTIVE, prev_vt_num);
204         } while(res < 0 && errno == EINTR);
205         close(fd);
206         char const * const ttydev = "/dev/tty0";
207         fd = open(ttydev, O_RDWR | O_SYNC);
208         ioctl(fd, VT_DISALLOCATE, 0);
209         close(fd);
210     }
211 }
212
213 status_t ConsoleManagerThread::releaseScreen() const
214 {
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);
219 }
220
221 void ConsoleManagerThread::onFirstRef()
222 {
223     run("ConsoleManagerThread", PRIORITY_URGENT_DISPLAY);
224 }
225
226 status_t ConsoleManagerThread::readyToRun()
227 {
228     if (consoleFd >= 0) {
229         sSignalCatcherPid = gettid();
230
231         sigset_t mask;
232         sigemptyset(&mask);
233         sigaddset(&mask, vm.relsig);
234         sigaddset(&mask, vm.acqsig);
235         sigprocmask(SIG_BLOCK, &mask, NULL);
236
237         int res = ioctl(consoleFd, VT_SETMODE, &vm);
238         if (res < 0) {
239             ALOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
240                     consoleFd, errno, strerror(errno));
241         }
242         return NO_ERROR;
243     }
244     return consoleFd;
245 }
246
247 void ConsoleManagerThread::requestExit()
248 {
249     Thread::requestExit();
250     if (sSignalCatcherPid != 0) {
251         // wake the thread up
252         kill(sSignalCatcherPid, SIGINT);
253         // wait for it...
254     }
255 }
256
257 bool ConsoleManagerThread::threadLoop()
258 {
259     sigset_t mask;
260     sigemptyset(&mask);
261     sigaddset(&mask, vm.relsig);
262     sigaddset(&mask, vm.acqsig);
263
264     int sig = 0;
265     sigwait(&mask, &sig);
266
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);
270     if (!err) {
271         gr = reinterpret_cast<gralloc_module_t const*>(mod);
272         if (!gr->perform)
273             gr = NULL;
274     }
275
276     if (sig == vm.relsig) {
277         if (gr)
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());
282         if (gr)
283             gr->perform(gr, GRALLOC_MODULE_PERFORM_ENTER_VT);
284     }
285
286     return true;
287 }
288
289 void ConsoleManagerThread::sigHandler(int sig)
290 {
291     // resend the signal to our signal catcher thread
292     ALOGW("received signal %d in thread %d, resending to %d",
293             sig, gettid(), sSignalCatcherPid);
294
295     // we absolutely need the delays below because without them
296     // our main thread never gets a chance to handle the signal.
297     usleep(10000);
298     kill(sSignalCatcherPid, sig);
299     usleep(10000);
300 }
301
302 pid_t ConsoleManagerThread::sSignalCatcherPid;
303 #endif
304
305 ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
306
307 DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
308         const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
309         std::shared_ptr<compositionengine::Display> compositionDisplay)
310       : flinger(flinger),
311         hwComposer(hwComposer),
312         displayToken(displayToken),
313         compositionDisplay(compositionDisplay) {}
314
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),
328 #endif
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))
340                     .build());
341
342     if (!mFlinger->mDisableClientCompositionCache &&
343         SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
344         mCompositionDisplay->createClientCompositionCache(
345                 static_cast<uint32_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers));
346     }
347
348     mCompositionDisplay->createDisplayColorProfile(
349             compositionengine::DisplayColorProfileCreationArgs{args.hasWideColorGamut,
350                                                                std::move(args.hdrCapabilities),
351                                                                args.supportedPerFrameMetadata,
352                                                                args.hwcColorModes});
353
354     if (!mCompositionDisplay->isValid()) {
355         ALOGE("Composition Display did not validate!");
356     }
357
358     mCompositionDisplay->getRenderSurface()->initialize();
359
360     setPowerMode(args.initialPowerMode);
361
362     // initialize the display orientation transform.
363     setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
364 }
365
366 #ifdef CONSOLE_MANAGER
367 DisplayDevice::~DisplayDevice() {
368     if (mConsoleManagerThread != 0) {
369         mConsoleManagerThread->requestExitAndWait();
370         ALOGD("ConsoleManagerThread: destroy primary DisplayDevice");
371     }
372 }
373 #else
374 DisplayDevice::~DisplayDevice() = default;
375 #endif
376
377 void DisplayDevice::disconnect() {
378     mCompositionDisplay->disconnect();
379 }
380
381 int DisplayDevice::getWidth() const {
382     return mCompositionDisplay->getState().displaySpace.bounds.getWidth();
383 }
384
385 int DisplayDevice::getHeight() const {
386     return mCompositionDisplay->getState().displaySpace.bounds.getHeight();
387 }
388
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);
394     }
395 }
396
397 void DisplayDevice::setDeviceProductInfo(std::optional<DeviceProductInfo> info) {
398     mDeviceProductInfo = std::move(info);
399 }
400
401 uint32_t DisplayDevice::getPageFlipCount() const {
402     return mCompositionDisplay->getRenderSurface()->getPageFlipCount();
403 }
404
405 // ----------------------------------------------------------------------------
406 void DisplayDevice::setPowerMode(hal::PowerMode mode) {
407     mPowerMode = mode;
408     getCompositionDisplay()->setCompositionEnabled(mPowerMode != hal::PowerMode::OFF);
409 #ifdef CONSOLE_MANAGER
410     if (mode != hal::PowerMode::ON && mConsoleManagerThread != 0) {
411         mConsoleManagerThread->releaseScreen();
412     }
413 #endif
414 }
415
416 void DisplayDevice::enableLayerCaching(bool enable) {
417     getCompositionDisplay()->setLayerCachingEnabled(enable);
418 }
419
420 hal::PowerMode DisplayDevice::getPowerMode() const {
421     return mPowerMode;
422 }
423
424 bool DisplayDevice::isPoweredOn() const {
425     return mPowerMode != hal::PowerMode::OFF;
426 }
427
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());
432     mActiveMode = mode;
433     if (mRefreshRateConfigs) {
434         mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
435     }
436     if (mRefreshRateOverlay) {
437         mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
438     }
439 }
440
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());
448         return BAD_VALUE;
449     }
450     mUpcomingActiveMode = info;
451     ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue());
452     return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(),
453                                                     constraints, outTimeline);
454 }
455
456 const DisplayModePtr& DisplayDevice::getActiveMode() const {
457     return mActiveMode;
458 }
459
460 const DisplayModes& DisplayDevice::getSupportedModes() const {
461     return mSupportedModes;
462 }
463
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()) {
468         return *it;
469     }
470     return nullptr;
471 }
472
473 nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
474     const auto physicalId = getPhysicalId();
475     if (!mHwComposer.isConnected(physicalId)) {
476         return 0;
477     }
478
479     nsecs_t vsyncPeriod;
480     const auto status = mHwComposer.getDisplayVsyncPeriod(physicalId, &vsyncPeriod);
481     if (status == NO_ERROR) {
482         return vsyncPeriod;
483     }
484
485     return getActiveMode()->getFps().getPeriodNsecs();
486 }
487
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);
492 }
493
494 void DisplayDevice::onVsync(nsecs_t timestamp) {
495     mLastHwVsync = timestamp;
496 }
497
498 ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
499     return mCompositionDisplay->getState().dataspace;
500 }
501
502 void DisplayDevice::setLayerStack(ui::LayerStack stack) {
503     mCompositionDisplay->setLayerStackFilter(stack, isInternal());
504     if (mRefreshRateOverlay) {
505         mRefreshRateOverlay->setLayerStack(stack);
506     }
507 }
508
509 void DisplayDevice::setFlags(uint32_t flags) {
510     mFlags = flags;
511 }
512
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);
519     }
520 }
521
522 void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
523                                   Rect orientedDisplaySpaceRect) {
524     mOrientation = orientation;
525
526     if (isPrimary()) {
527         sPrimaryDisplayRotationFlags = ui::Transform::toRotationFlags(orientation);
528 #ifdef CONSOLE_MANAGER
529         mConsoleManagerThread = new ConsoleManagerThread(mFlinger, mDisplayToken);
530 #endif
531     }
532
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;
537     }
538
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);
545         }
546     }
547
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);
553 }
554
555 ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() {
556     return sPrimaryDisplayRotationFlags;
557 }
558
559 std::string DisplayDevice::getDebugName() const {
560     const char* type = "virtual";
561     if (mConnectionType) {
562         type = isInternal() ? "internal" : "external";
563     }
564
565     return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
566                               isPrimary() ? ", primary" : "", mDisplayName.c_str());
567 }
568
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");
576
577     result.append("   supportedModes=\n");
578
579     for (const auto& mode : mSupportedModes) {
580         result.append("     ");
581         result.append(to_string(*mode));
582         result.append("\n");
583     }
584     StringAppendF(&result, "   deviceProductInfo=");
585     if (mDeviceProductInfo) {
586         mDeviceProductInfo->dump(result);
587     } else {
588         result.append("{}");
589     }
590     result.append("\n");
591     getCompositionDisplay()->dump(result);
592
593     if (mRefreshRateConfigs) {
594         mRefreshRateConfigs->dump(result);
595     }
596 }
597
598 bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const {
599     return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
600 }
601
602 DisplayId DisplayDevice::getId() const {
603     return mCompositionDisplay->getId();
604 }
605
606 bool DisplayDevice::isSecure() const {
607     return mCompositionDisplay->isSecure();
608 }
609
610 const Rect& DisplayDevice::getBounds() const {
611     return mCompositionDisplay->getState().displaySpace.bounds;
612 }
613
614 const Region& DisplayDevice::getUndefinedRegion() const {
615     return mCompositionDisplay->getState().undefinedRegion;
616 }
617
618 bool DisplayDevice::needsFiltering() const {
619     return mCompositionDisplay->getState().needsFiltering;
620 }
621
622 ui::LayerStack DisplayDevice::getLayerStack() const {
623     return mCompositionDisplay->getState().layerStackId;
624 }
625
626 ui::Transform::RotationFlags DisplayDevice::getTransformHint() const {
627     return mCompositionDisplay->getTransformHint();
628 }
629
630 const ui::Transform& DisplayDevice::getTransform() const {
631     return mCompositionDisplay->getState().transform;
632 }
633
634 const Rect& DisplayDevice::getLayerStackSpaceRect() const {
635     return mCompositionDisplay->getState().layerStackSpace.content;
636 }
637
638 const Rect& DisplayDevice::getOrientedDisplaySpaceRect() const {
639     return mCompositionDisplay->getState().orientedDisplaySpace.content;
640 }
641
642 bool DisplayDevice::hasWideColorGamut() const {
643     return mCompositionDisplay->getDisplayColorProfile()->hasWideColorGamut();
644 }
645
646 bool DisplayDevice::hasHDR10PlusSupport() const {
647     return mCompositionDisplay->getDisplayColorProfile()->hasHDR10PlusSupport();
648 }
649
650 bool DisplayDevice::hasHDR10Support() const {
651     return mCompositionDisplay->getDisplayColorProfile()->hasHDR10Support();
652 }
653
654 bool DisplayDevice::hasHLGSupport() const {
655     return mCompositionDisplay->getDisplayColorProfile()->hasHLGSupport();
656 }
657
658 bool DisplayDevice::hasDolbyVisionSupport() const {
659     return mCompositionDisplay->getDisplayColorProfile()->hasDolbyVisionSupport();
660 }
661
662 int DisplayDevice::getSupportedPerFrameMetadata() const {
663     return mCompositionDisplay->getDisplayColorProfile()->getSupportedPerFrameMetadata();
664 }
665
666 void DisplayDevice::overrideHdrTypes(const std::vector<ui::Hdr>& hdrTypes) {
667     mOverrideHdrTypes = hdrTypes;
668 }
669
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;
676     }
677     return HdrCapabilities(hdrTypes, capabilities.getDesiredMaxLuminance(),
678                            capabilities.getDesiredMaxAverageLuminance(),
679                            capabilities.getDesiredMinLuminance());
680 }
681
682 void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
683     if (!enable) {
684         mRefreshRateOverlay.reset();
685         return;
686     }
687
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());
694 }
695
696 bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
697                                          bool timerExpired) {
698     if (mRefreshRateConfigs && mRefreshRateOverlay) {
699         const auto newRefreshRate =
700                 mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
701         if (newRefreshRate) {
702             mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
703             return true;
704         }
705     }
706
707     return false;
708 }
709
710 void DisplayDevice::onInvalidate() {
711     if (mRefreshRateOverlay) {
712         mRefreshRateOverlay->onInvalidate();
713     }
714 }
715
716 bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) {
717     ATRACE_CALL();
718
719     LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided");
720     LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch");
721
722     ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str());
723
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;
730         return false;
731     }
732
733     // Check if we are already at the desired mode
734     if (getActiveMode()->getId() == info.mode->getId()) {
735         return false;
736     }
737
738     // Initiate a mode change.
739     mDesiredActiveModeChanged = true;
740     mDesiredActiveMode = info;
741     return true;
742 }
743
744 std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const {
745     std::scoped_lock lock(mActiveModeLock);
746     if (mDesiredActiveModeChanged) return mDesiredActiveMode;
747     return std::nullopt;
748 }
749
750 void DisplayDevice::clearDesiredActiveModeState() {
751     std::scoped_lock lock(mActiveModeLock);
752     mDesiredActiveMode.event = Scheduler::ModeEvent::None;
753     mDesiredActiveModeChanged = false;
754 }
755
756 std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
757
758 }  // namespace android
759
760 // TODO(b/129481165): remove the #pragma below and fix conversion issues
761 #pragma clang diagnostic pop // ignored "-Wconversion"