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