• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <compositionengine/CompositionEngine.h>
28 #include <compositionengine/Display.h>
29 #include <compositionengine/DisplayColorProfile.h>
30 #include <compositionengine/DisplayColorProfileCreationArgs.h>
31 #include <compositionengine/DisplayCreationArgs.h>
32 #include <compositionengine/DisplaySurface.h>
33 #include <compositionengine/ProjectionSpace.h>
34 #include <compositionengine/RenderSurface.h>
35 #include <compositionengine/RenderSurfaceCreationArgs.h>
36 #include <compositionengine/impl/OutputCompositionState.h>
37 #include <configstore/Utils.h>
38 #include <ftl/concat.h>
39 #include <log/log.h>
40 #include <system/window.h>
41 
42 #include "DisplayDevice.h"
43 #include "FrontEnd/DisplayInfo.h"
44 #include "HdrSdrRatioOverlay.h"
45 #include "Layer.h"
46 #include "RefreshRateOverlay.h"
47 #include "SurfaceFlinger.h"
48 
49 namespace android {
50 
51 namespace hal = hardware::graphics::composer::hal;
52 
DisplayDeviceCreationArgs(const sp<SurfaceFlinger> & flinger,HWComposer & hwComposer,const wp<IBinder> & displayToken,std::shared_ptr<compositionengine::Display> compositionDisplay)53 DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
54         const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
55         std::shared_ptr<compositionengine::Display> compositionDisplay)
56       : flinger(flinger),
57         hwComposer(hwComposer),
58         displayToken(displayToken),
59         compositionDisplay(compositionDisplay) {}
60 
DisplayDevice(DisplayDeviceCreationArgs & args)61 DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
62       : mFlinger(args.flinger),
63         mHwComposer(args.hwComposer),
64         mDisplayToken(args.displayToken),
65         mSequenceId(args.sequenceId),
66         mCompositionDisplay{args.compositionDisplay},
67         mPhysicalOrientation(args.physicalOrientation),
68         mPowerMode(ftl::Concat("PowerMode ", getId().value).c_str(), args.initialPowerMode),
69         mIsPrimary(args.isPrimary),
70         mRequestedRefreshRate(args.requestedRefreshRate),
71         mRefreshRateSelector(std::move(args.refreshRateSelector)) {
72     mCompositionDisplay->editState().isSecure = args.isSecure;
73     mCompositionDisplay->editState().isProtected = args.isProtected;
74     mCompositionDisplay->createRenderSurface(
75             compositionengine::RenderSurfaceCreationArgsBuilder()
76                     .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
77                     .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get()))
78                     .setNativeWindow(std::move(args.nativeWindow))
79                     .setDisplaySurface(std::move(args.displaySurface))
80                     .setMaxTextureCacheSize(
81                             static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers))
82                     .build());
83 
84     if (!mFlinger->mDisableClientCompositionCache &&
85         SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
86         mCompositionDisplay->createClientCompositionCache(
87                 static_cast<uint32_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers));
88     }
89 
90     mCompositionDisplay->setPredictCompositionStrategy(mFlinger->mPredictCompositionStrategy);
91     mCompositionDisplay->setTreat170mAsSrgb(mFlinger->mTreat170mAsSrgb);
92     mCompositionDisplay->createDisplayColorProfile(
93             compositionengine::DisplayColorProfileCreationArgsBuilder()
94                     .setHasWideColorGamut(args.hasWideColorGamut)
95                     .setHdrCapabilities(std::move(args.hdrCapabilities))
96                     .setSupportedPerFrameMetadata(args.supportedPerFrameMetadata)
97                     .setHwcColorModes(std::move(args.hwcColorModes))
98                     .Build());
99 
100     if (!mCompositionDisplay->isValid()) {
101         ALOGE("Composition Display did not validate!");
102     }
103 
104     mCompositionDisplay->getRenderSurface()->initialize();
105 
106     setPowerMode(args.initialPowerMode);
107 
108     // initialize the display orientation transform.
109     setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
110 }
111 
112 DisplayDevice::~DisplayDevice() = default;
113 
disconnect()114 void DisplayDevice::disconnect() {
115     mCompositionDisplay->disconnect();
116 }
117 
getWidth() const118 int DisplayDevice::getWidth() const {
119     return mCompositionDisplay->getState().displaySpace.getBounds().width;
120 }
121 
getHeight() const122 int DisplayDevice::getHeight() const {
123     return mCompositionDisplay->getState().displaySpace.getBounds().height;
124 }
125 
setDisplayName(const std::string & displayName)126 void DisplayDevice::setDisplayName(const std::string& displayName) {
127     if (!displayName.empty()) {
128         // never override the name with an empty name
129         mDisplayName = displayName;
130         mCompositionDisplay->setName(displayName);
131     }
132 }
133 
getFrontEndInfo() const134 auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo {
135     gui::DisplayInfo info;
136     info.displayId = ui::LogicalDisplayId{static_cast<int32_t>(getLayerStack().id)};
137 
138     // The physical orientation is set when the orientation of the display panel is
139     // different than the default orientation of the device. Other services like
140     // InputFlinger do not know about this, so we do not need to expose the physical
141     // orientation of the panel outside of SurfaceFlinger.
142     const ui::Rotation inversePhysicalOrientation = ui::ROTATION_0 - mPhysicalOrientation;
143     auto width = getWidth();
144     auto height = getHeight();
145     if (inversePhysicalOrientation == ui::ROTATION_90 ||
146         inversePhysicalOrientation == ui::ROTATION_270) {
147         std::swap(width, height);
148     }
149     const ui::Transform undoPhysicalOrientation(ui::Transform::toRotationFlags(
150                                                         inversePhysicalOrientation),
151                                                 width, height);
152     const auto& displayTransform = undoPhysicalOrientation * getTransform();
153     // Send the inverse display transform to input so it can convert display coordinates to
154     // logical display.
155     info.transform = displayTransform.inverse();
156 
157     info.logicalWidth = getLayerStackSpaceRect().width();
158     info.logicalHeight = getLayerStackSpaceRect().height();
159 
160     return {.info = info,
161             .transform = displayTransform,
162             .receivesInput = receivesInput(),
163             .isSecure = isSecure(),
164             .isPrimary = isPrimary(),
165             .isVirtual = isVirtual(),
166             .rotationFlags = ui::Transform::toRotationFlags(mOrientation),
167             .transformHint = getTransformHint()};
168 }
169 
setPowerMode(hal::PowerMode mode)170 void DisplayDevice::setPowerMode(hal::PowerMode mode) {
171     // TODO(b/241285876): Skip this for virtual displays.
172     if (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON) {
173         if (mStagedBrightness && mBrightness != mStagedBrightness) {
174             getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
175             mBrightness = *mStagedBrightness;
176         }
177         mStagedBrightness = std::nullopt;
178         getCompositionDisplay()->applyDisplayBrightness(true);
179     }
180 
181     mPowerMode = mode;
182 
183     getCompositionDisplay()->setCompositionEnabled(isPoweredOn());
184 }
185 
tracePowerMode()186 void DisplayDevice::tracePowerMode() {
187     // Assign the same value for tracing.
188     mPowerMode = mPowerMode.get();
189 }
190 
enableLayerCaching(bool enable)191 void DisplayDevice::enableLayerCaching(bool enable) {
192     getCompositionDisplay()->setLayerCachingEnabled(enable);
193 }
194 
getPowerMode() const195 hal::PowerMode DisplayDevice::getPowerMode() const {
196     return mPowerMode;
197 }
198 
isPoweredOn() const199 bool DisplayDevice::isPoweredOn() const {
200     return mPowerMode != hal::PowerMode::OFF;
201 }
202 
getVsyncPeriodFromHWC() const203 nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
204     const auto physicalId = getPhysicalId();
205     if (!mHwComposer.isConnected(physicalId)) {
206         return 0;
207     }
208 
209     if (const auto vsyncPeriodOpt = mHwComposer.getDisplayVsyncPeriod(physicalId).value_opt()) {
210         return *vsyncPeriodOpt;
211     }
212 
213     return refreshRateSelector().getActiveMode().modePtr->getVsyncRate().getPeriodNsecs();
214 }
215 
getCompositionDataSpace() const216 ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
217     return mCompositionDisplay->getState().dataspace;
218 }
219 
setLayerFilter(ui::LayerFilter filter)220 void DisplayDevice::setLayerFilter(ui::LayerFilter filter) {
221     mCompositionDisplay->setLayerFilter(filter);
222     if (mRefreshRateOverlay) {
223         mRefreshRateOverlay->setLayerStack(filter.layerStack);
224     }
225     if (mHdrSdrRatioOverlay) {
226         mHdrSdrRatioOverlay->setLayerStack(filter.layerStack);
227     }
228 }
229 
setFlags(uint32_t flags)230 void DisplayDevice::setFlags(uint32_t flags) {
231     mFlags = flags;
232 }
233 
setDisplaySize(int width,int height)234 void DisplayDevice::setDisplaySize(int width, int height) {
235     LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
236     const auto size = ui::Size(width, height);
237     mCompositionDisplay->setDisplaySize(size);
238     if (mRefreshRateOverlay) {
239         mRefreshRateOverlay->setViewport(size);
240     }
241     if (mHdrSdrRatioOverlay) {
242         mHdrSdrRatioOverlay->setViewport(size);
243     }
244 }
245 
setProjection(ui::Rotation orientation,Rect layerStackSpaceRect,Rect orientedDisplaySpaceRect)246 void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
247                                   Rect orientedDisplaySpaceRect) {
248     mIsOrientationChanged = mOrientation != orientation;
249     mOrientation = orientation;
250 
251     // We need to take care of display rotation for globalTransform for case if the panel is not
252     // installed aligned with device orientation.
253     const auto transformOrientation = orientation + mPhysicalOrientation;
254 
255     const auto& state = getCompositionDisplay()->getState();
256 
257     // If the layer stack and destination frames have never been set, then configure them to be the
258     // same as the physical device, taking into account the total transform.
259     if (!orientedDisplaySpaceRect.isValid()) {
260         ui::Size bounds = state.displaySpace.getBounds();
261         bounds.rotate(transformOrientation);
262         orientedDisplaySpaceRect = Rect(bounds);
263     }
264     if (layerStackSpaceRect.isEmpty()) {
265         ui::Size bounds = state.framebufferSpace.getBounds();
266         bounds.rotate(transformOrientation);
267         layerStackSpaceRect = Rect(bounds);
268     }
269     getCompositionDisplay()->setProjection(transformOrientation, layerStackSpaceRect,
270                                            orientedDisplaySpaceRect);
271 }
272 
stageBrightness(float brightness)273 void DisplayDevice::stageBrightness(float brightness) {
274     mStagedBrightness = brightness;
275 }
276 
persistBrightness(bool needsComposite)277 void DisplayDevice::persistBrightness(bool needsComposite) {
278     if (mStagedBrightness && mBrightness != mStagedBrightness) {
279         if (needsComposite) {
280             getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
281         }
282         mBrightness = *mStagedBrightness;
283     }
284     mStagedBrightness = std::nullopt;
285 }
286 
getStagedBrightness() const287 std::optional<float> DisplayDevice::getStagedBrightness() const {
288     return mStagedBrightness;
289 }
290 
dump(utils::Dumper & dumper) const291 void DisplayDevice::dump(utils::Dumper& dumper) const {
292     using namespace std::string_view_literals;
293 
294     dumper.dump("name"sv, '"' + mDisplayName + '"');
295     dumper.dump("powerMode"sv, mPowerMode);
296 
297     if (mRefreshRateSelector) {
298         mRefreshRateSelector->dump(dumper);
299     }
300 }
301 
hasRenderIntent(ui::RenderIntent intent) const302 bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const {
303     return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
304 }
305 
getId() const306 DisplayId DisplayDevice::getId() const {
307     return mCompositionDisplay->getId();
308 }
309 
isSecure() const310 bool DisplayDevice::isSecure() const {
311     return mCompositionDisplay->isSecure();
312 }
313 
setSecure(bool secure)314 void DisplayDevice::setSecure(bool secure) {
315     mCompositionDisplay->setSecure(secure);
316 }
317 
getBounds() const318 const Rect DisplayDevice::getBounds() const {
319     return mCompositionDisplay->getState().displaySpace.getBoundsAsRect();
320 }
321 
getUndefinedRegion() const322 const Region& DisplayDevice::getUndefinedRegion() const {
323     return mCompositionDisplay->getState().undefinedRegion;
324 }
325 
getLayerStack() const326 ui::LayerStack DisplayDevice::getLayerStack() const {
327     return mCompositionDisplay->getState().layerFilter.layerStack;
328 }
329 
getTransformHint() const330 ui::Transform::RotationFlags DisplayDevice::getTransformHint() const {
331     return mCompositionDisplay->getTransformHint();
332 }
333 
getTransform() const334 const ui::Transform& DisplayDevice::getTransform() const {
335     return mCompositionDisplay->getState().transform;
336 }
337 
getLayerStackSpaceRect() const338 const Rect& DisplayDevice::getLayerStackSpaceRect() const {
339     return mCompositionDisplay->getState().layerStackSpace.getContent();
340 }
341 
getOrientedDisplaySpaceRect() const342 const Rect& DisplayDevice::getOrientedDisplaySpaceRect() const {
343     return mCompositionDisplay->getState().orientedDisplaySpace.getContent();
344 }
345 
hasWideColorGamut() const346 bool DisplayDevice::hasWideColorGamut() const {
347     return mCompositionDisplay->getDisplayColorProfile()->hasWideColorGamut();
348 }
349 
hasHDR10PlusSupport() const350 bool DisplayDevice::hasHDR10PlusSupport() const {
351     return mCompositionDisplay->getDisplayColorProfile()->hasHDR10PlusSupport();
352 }
353 
hasHDR10Support() const354 bool DisplayDevice::hasHDR10Support() const {
355     return mCompositionDisplay->getDisplayColorProfile()->hasHDR10Support();
356 }
357 
hasHLGSupport() const358 bool DisplayDevice::hasHLGSupport() const {
359     return mCompositionDisplay->getDisplayColorProfile()->hasHLGSupport();
360 }
361 
hasDolbyVisionSupport() const362 bool DisplayDevice::hasDolbyVisionSupport() const {
363     return mCompositionDisplay->getDisplayColorProfile()->hasDolbyVisionSupport();
364 }
365 
getSupportedPerFrameMetadata() const366 int DisplayDevice::getSupportedPerFrameMetadata() const {
367     return mCompositionDisplay->getDisplayColorProfile()->getSupportedPerFrameMetadata();
368 }
369 
overrideHdrTypes(const std::vector<ui::Hdr> & hdrTypes)370 void DisplayDevice::overrideHdrTypes(const std::vector<ui::Hdr>& hdrTypes) {
371     mOverrideHdrTypes = hdrTypes;
372 }
373 
getHdrCapabilities() const374 HdrCapabilities DisplayDevice::getHdrCapabilities() const {
375     const HdrCapabilities& capabilities =
376             mCompositionDisplay->getDisplayColorProfile()->getHdrCapabilities();
377     std::vector<ui::Hdr> hdrTypes = capabilities.getSupportedHdrTypes();
378     if (!mOverrideHdrTypes.empty()) {
379         hdrTypes = mOverrideHdrTypes;
380     }
381     return HdrCapabilities(hdrTypes, capabilities.getDesiredMaxLuminance(),
382                            capabilities.getDesiredMaxAverageLuminance(),
383                            capabilities.getDesiredMinLuminance());
384 }
385 
enableHdrSdrRatioOverlay(bool enable)386 void DisplayDevice::enableHdrSdrRatioOverlay(bool enable) {
387     if (!enable) {
388         mHdrSdrRatioOverlay.reset();
389         return;
390     }
391 
392     mHdrSdrRatioOverlay = HdrSdrRatioOverlay::create();
393     if (mHdrSdrRatioOverlay) {
394         mHdrSdrRatioOverlay->setLayerStack(getLayerStack());
395         mHdrSdrRatioOverlay->setViewport(getSize());
396         updateHdrSdrRatioOverlayRatio(mHdrSdrRatio);
397     }
398 }
399 
updateHdrSdrRatioOverlayRatio(float currentHdrSdrRatio)400 void DisplayDevice::updateHdrSdrRatioOverlayRatio(float currentHdrSdrRatio) {
401     ATRACE_CALL();
402     mHdrSdrRatio = currentHdrSdrRatio;
403     if (mHdrSdrRatioOverlay) {
404         mHdrSdrRatioOverlay->changeHdrSdrRatio(currentHdrSdrRatio);
405     }
406 }
407 
enableRefreshRateOverlay(bool enable,bool setByHwc,Fps refreshRate,Fps renderFps,bool showSpinner,bool showRenderRate,bool showInMiddle)408 void DisplayDevice::enableRefreshRateOverlay(bool enable, bool setByHwc, Fps refreshRate,
409                                              Fps renderFps, bool showSpinner, bool showRenderRate,
410                                              bool showInMiddle) {
411     if (!enable) {
412         mRefreshRateOverlay.reset();
413         return;
414     }
415 
416     ftl::Flags<RefreshRateOverlay::Features> features;
417     if (showSpinner) {
418         features |= RefreshRateOverlay::Features::Spinner;
419     }
420 
421     if (showRenderRate) {
422         features |= RefreshRateOverlay::Features::RenderRate;
423     }
424 
425     if (showInMiddle) {
426         features |= RefreshRateOverlay::Features::ShowInMiddle;
427     }
428 
429     if (setByHwc) {
430         features |= RefreshRateOverlay::Features::SetByHwc;
431     }
432 
433     const auto fpsRange = mRefreshRateSelector->getSupportedRefreshRateRange();
434     mRefreshRateOverlay = RefreshRateOverlay::create(fpsRange, features);
435     if (mRefreshRateOverlay) {
436         mRefreshRateOverlay->setLayerStack(getLayerStack());
437         mRefreshRateOverlay->setViewport(getSize());
438         updateRefreshRateOverlayRate(refreshRate, renderFps, setByHwc);
439     }
440 }
441 
updateRefreshRateOverlayRate(Fps refreshRate,Fps renderFps,bool setByHwc)442 void DisplayDevice::updateRefreshRateOverlayRate(Fps refreshRate, Fps renderFps, bool setByHwc) {
443     ATRACE_CALL();
444     if (mRefreshRateOverlay) {
445         if (!mRefreshRateOverlay->isSetByHwc() || setByHwc) {
446             if (mRefreshRateSelector->isVrrDevice() && !mRefreshRateOverlay->isSetByHwc()) {
447                 refreshRate = renderFps;
448             }
449             mRefreshRateOverlay->changeRefreshRate(refreshRate, renderFps);
450         } else {
451             mRefreshRateOverlay->changeRenderRate(renderFps);
452         }
453     }
454 }
455 
onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,bool timerExpired)456 bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
457                                          bool timerExpired) {
458     if (mRefreshRateSelector && mRefreshRateOverlay) {
459         const auto newMode =
460                 mRefreshRateSelector->onKernelTimerChanged(desiredModeId, timerExpired);
461         if (newMode) {
462             updateRefreshRateOverlayRate(newMode->modePtr->getVsyncRate(), newMode->fps);
463             return true;
464         }
465     }
466 
467     return false;
468 }
469 
onVrrIdle(bool idle)470 void DisplayDevice::onVrrIdle(bool idle) {
471     if (mRefreshRateOverlay) {
472         mRefreshRateOverlay->onVrrIdle(idle);
473     }
474 }
475 
animateOverlay()476 void DisplayDevice::animateOverlay() {
477     if (mRefreshRateOverlay) {
478         mRefreshRateOverlay->animate();
479     }
480     if (mHdrSdrRatioOverlay) {
481         // hdr sdr ratio is designed to be on the top right of the screen,
482         // therefore, we need to re-calculate the display's width and height
483         if (mIsOrientationChanged) {
484             auto width = getWidth();
485             auto height = getHeight();
486             if (mOrientation == ui::ROTATION_90 || mOrientation == ui::ROTATION_270) {
487                 std::swap(width, height);
488             }
489             mHdrSdrRatioOverlay->setViewport({width, height});
490         }
491         mHdrSdrRatioOverlay->animate();
492     }
493 }
494 
adjustRefreshRate(Fps pacesetterDisplayRefreshRate)495 void DisplayDevice::adjustRefreshRate(Fps pacesetterDisplayRefreshRate) {
496     using fps_approx_ops::operator<=;
497     if (mRequestedRefreshRate <= 0_Hz) {
498         return;
499     }
500 
501     using fps_approx_ops::operator>;
502     if (mRequestedRefreshRate > pacesetterDisplayRefreshRate) {
503         mAdjustedRefreshRate = pacesetterDisplayRefreshRate;
504         return;
505     }
506 
507     unsigned divisor = static_cast<unsigned>(
508             std::floor(pacesetterDisplayRefreshRate.getValue() / mRequestedRefreshRate.getValue()));
509     if (divisor == 0) {
510         mAdjustedRefreshRate = 0_Hz;
511         return;
512     }
513 
514     mAdjustedRefreshRate = pacesetterDisplayRefreshRate / divisor;
515 }
516 
517 std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
518 
519 }  // namespace android
520 
521 // TODO(b/129481165): remove the #pragma below and fix conversion issues
522 #pragma clang diagnostic pop // ignored "-Wconversion"
523