From 59a6be3c5d547a02850bf486cfe1036f4008df83 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 29 Jan 2024 10:26:21 -0800 Subject: Introduce eCanOccludePresentation layer flag Sets a property on a layer hierarchy indicating that its visible region should be considered when computing TrustedPresentation Thresholds. This property is set on a layer and inherited by all its children. The property is then passed via windowinfos so the TrustedPresentation controller can determine which windows to use when computing the thresholds. Test: presubmit Bug: b/275574214 Change-Id: Ide384c64cb7b5a9b2b3ce293b20e2be64da8ad69 --- libs/gui/LayerState.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 38fab9cdaa..7564c26316 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -199,7 +199,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeParcelable, trustedPresentationListener); SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio); SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio); - SAFE_PARCEL(output.writeInt32, static_cast(cachingHint)) + SAFE_PARCEL(output.writeInt32, static_cast(cachingHint)); return NO_ERROR; } @@ -484,6 +484,12 @@ void layer_state_t::sanitize(int32_t permissions) { flags &= ~eLayerIsDisplayDecoration; ALOGE("Stripped attempt to set LayerIsDisplayDecoration in sanitize"); } + if ((mask & eCanOccludePresentation) && + !(permissions & Permission::ACCESS_SURFACE_FLINGER)) { + flags &= ~eCanOccludePresentation; + mask &= ~eCanOccludePresentation; + ALOGE("Stripped attempt to set eCanOccludePresentation in sanitize"); + } } if (what & layer_state_t::eInputInfoChanged) { -- cgit v1.2.3-59-g8ed1b From 1b0d4e16530a4feb99eafbfdfce2aeb39c5e23e3 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 12 Feb 2024 22:27:19 +0000 Subject: Add support for restricting HDR headroom for video This is needed for allowing apps to vote for HDR headroom restrictions for SurfaceView and SurfaceControl Bug: 323964760 Test: manually poking at test app Test: SurfaceViewTests Test: SurfaceControlTest Test: ASurfaceControlTest Change-Id: Ie886e67879525462d49fdedc535aea659d69321a --- include/android/surface_control.h | 50 ++++++++++++++++++++-- libs/gui/LayerState.cpp | 5 +++ libs/gui/SurfaceComposerClient.cpp | 14 ++++++ libs/gui/include/gui/LayerState.h | 5 ++- libs/gui/include/gui/SurfaceComposerClient.h | 1 + services/surfaceflinger/FrontEnd/LayerSnapshot.cpp | 3 ++ .../FrontEnd/RequestedLayerState.cpp | 5 ++- services/surfaceflinger/Layer.cpp | 15 +++++++ services/surfaceflinger/Layer.h | 5 ++- services/surfaceflinger/SurfaceFlinger.cpp | 13 +++++- 10 files changed, 106 insertions(+), 10 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/include/android/surface_control.h b/include/android/surface_control.h index cce2e46471..321737e226 100644 --- a/include/android/surface_control.h +++ b/include/android/surface_control.h @@ -528,9 +528,8 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio /** * Sets the desired extended range brightness for the layer. This only applies for layers whose - * dataspace has RANGE_EXTENDED set on it. - * - * Available since API level 34. + * dataspace has RANGE_EXTENDED set on it. See: ASurfaceTransaction_setDesiredHdrHeadroom, prefer + * using this API for formats that encode an HDR/SDR ratio as part of generating the buffer. * * @param surface_control The layer whose extended range brightness is being specified * @param currentBufferRatio The current hdr/sdr ratio of the current buffer as represented as @@ -564,6 +563,12 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio * determined entirely by the dataspace being used (ie, typically SDR * however PQ or HLG transfer functions will still result in HDR) * + * When called after ASurfaceTransaction_setDesiredHdrHeadroom, the + * desiredRatio will override the desiredHeadroom provided by + * ASurfaceTransaction_setDesiredHdrHeadroom. Conversely, when called before + * ASurfaceTransaction_setDesiredHdrHeadroom, the desiredHeadroom provided by + *. ASurfaceTransaction_setDesiredHdrHeadroom will override the desiredRatio. + * * Must be finite && >= 1.0f * * Available since API level 34. @@ -573,6 +578,45 @@ void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* transac float currentBufferRatio, float desiredRatio) __INTRODUCED_IN(__ANDROID_API_U__); +/** + * Sets the desired hdr headroom for the layer. See: ASurfaceTransaction_setExtendedRangeBrightness, + * prefer using this API for formats that conform to HDR standards like HLG or HDR10, that do not + * communicate a HDR/SDR ratio as part of generating the buffer. + * + * @param surface_control The layer whose desired hdr headroom is being specified + * + * @param desiredHeadroom The desired hdr/sdr ratio as represented as peakHdrBrightnessInNits / + * targetSdrWhitePointInNits. This can be used to communicate the max + * desired brightness range of the panel. The system may not be able to, or + * may choose not to, deliver the requested range. + * + * While requesting a large desired ratio will result in the most + * dynamic range, voluntarily reducing the requested range can help + * improve battery life as well as can improve quality by ensuring + * greater bit depth is allocated to the luminance range in use. + * + * Default value is 0.0f and indicates that the system will choose the best + * headroom for this surface control's content. Typically, this means that + * HLG/PQ encoded content will be displayed with some HDR headroom greater + * than 1.0. + * + * When called after ASurfaceTransaction_setExtendedRangeBrightness, the + * desiredHeadroom will override the desiredRatio provided by + * ASurfaceTransaction_setExtendedRangeBrightness. Conversely, when called + * before ASurfaceTransaction_setExtendedRangeBrightness, the desiredRatio + * provided by ASurfaceTransaction_setExtendedRangeBrightness will override + * the desiredHeadroom. + * + * Must be finite && >= 1.0f or 0.0f to indicate there is no desired + * headroom. + * + * Available since API level 35. + */ +void ASurfaceTransaction_setDesiredHdrHeadroom(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, + float desiredHeadroom) + __INTRODUCED_IN(__ANDROID_API_V__); + /** * Same as ASurfaceTransaction_setFrameRateWithChangeStrategy(transaction, surface_control, * frameRate, compatibility, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS). diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 38fab9cdaa..9d7d304afb 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -605,6 +605,10 @@ void layer_state_t::merge(const layer_state_t& other) { desiredHdrSdrRatio = other.desiredHdrSdrRatio; currentHdrSdrRatio = other.currentHdrSdrRatio; } + if (other.what & eDesiredHdrHeadroomChanged) { + what |= eDesiredHdrHeadroomChanged; + desiredHdrSdrRatio = other.desiredHdrSdrRatio; + } if (other.what & eCachingHintChanged) { what |= eCachingHintChanged; cachingHint = other.cachingHint; @@ -768,6 +772,7 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { CHECK_DIFF(diff, eDataspaceChanged, other, dataspace); CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentHdrSdrRatio, desiredHdrSdrRatio); + CHECK_DIFF(diff, eDesiredHdrHeadroomChanged, other, desiredHdrSdrRatio); CHECK_DIFF(diff, eCachingHintChanged, other, cachingHint); CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata); if (other.what & eSurfaceDamageRegionChanged && diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 8d18551b69..3a02c644bf 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1807,6 +1807,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setExten return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesiredHdrHeadroom( + const sp& sc, float desiredRatio) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eDesiredHdrHeadroomChanged; + s->desiredHdrSdrRatio = desiredRatio; + + registerSurfaceControlForCallback(sc); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCachingHint( const sp& sc, gui::CachingHint cachingHint) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 6b8e8248b8..9350c95178 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -206,7 +206,7 @@ struct layer_state_t { eBackgroundBlurRadiusChanged = 0x80'00000000, eProducerDisconnect = 0x100'00000000, eFixedTransformHintChanged = 0x200'00000000, - /* unused 0x400'00000000, */ + eDesiredHdrHeadroomChanged = 0x400'00000000, eBlurRegionsChanged = 0x800'00000000, eAutoRefreshChanged = 0x1000'00000000, eStretchChanged = 0x2000'00000000, @@ -245,7 +245,8 @@ struct layer_state_t { layer_state_t::eSidebandStreamChanged | layer_state_t::eSurfaceDamageRegionChanged | layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eTransparentRegionChanged | - layer_state_t::eExtendedRangeBrightnessChanged; + layer_state_t::eExtendedRangeBrightnessChanged | + layer_state_t::eDesiredHdrHeadroomChanged; // Content updates. static constexpr uint64_t CONTENT_CHANGES = layer_state_t::BUFFER_CHANGES | diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 14e3dd583e..7118883411 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -594,6 +594,7 @@ public: Transaction& setDataspace(const sp& sc, ui::Dataspace dataspace); Transaction& setExtendedRangeBrightness(const sp& sc, float currentBufferRatio, float desiredRatio); + Transaction& setDesiredHdrHeadroom(const sp& sc, float desiredRatio); Transaction& setCachingHint(const sp& sc, gui::CachingHint cachingHint); Transaction& setHdrMetadata(const sp& sc, const HdrMetadata& hdrMetadata); Transaction& setSurfaceDamageRegion(const sp& sc, diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index 38974a2f58..8b200a2cf8 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -380,6 +380,9 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate currentHdrSdrRatio = requested.currentHdrSdrRatio; desiredHdrSdrRatio = requested.desiredHdrSdrRatio; } + if (forceUpdate || requested.what & layer_state_t::eDesiredHdrHeadroomChanged) { + desiredHdrSdrRatio = requested.desiredHdrSdrRatio; + } if (forceUpdate || requested.what & layer_state_t::eCachingHintChanged) { cachingHint = requested.cachingHint; } diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp index 209df79f8e..b72588ab47 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -98,7 +98,7 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) z = 0; layerStack = ui::DEFAULT_LAYER_STACK; transformToDisplayInverse = false; - desiredHdrSdrRatio = 1.f; + desiredHdrSdrRatio = -1.f; currentHdrSdrRatio = 1.f; dataspaceRequested = false; hdrMetadata.validTypes = 0; @@ -603,7 +603,8 @@ bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const { layer_state_t::eShadowRadiusChanged | layer_state_t::eFixedTransformHintChanged | layer_state_t::eTrustedOverlayChanged | layer_state_t::eStretchChanged | layer_state_t::eBufferCropChanged | layer_state_t::eDestinationFrameChanged | - layer_state_t::eDimmingEnabledChanged | layer_state_t::eExtendedRangeBrightnessChanged; + layer_state_t::eDimmingEnabledChanged | layer_state_t::eExtendedRangeBrightnessChanged | + layer_state_t::eDesiredHdrHeadroomChanged; if (changedFlags & deniedChanges) { ATRACE_FORMAT_INSTANT("%s: false [has denied changes flags 0x%" PRIx64 "]", __func__, s.what & deniedChanges); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 219a8e20a4..736fec6fb2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -3395,6 +3395,14 @@ bool Layer::setExtendedRangeBrightness(float currentBufferRatio, float desiredRa return true; } +bool Layer::setDesiredHdrHeadroom(float desiredRatio) { + if (mDrawingState.desiredHdrSdrRatio == desiredRatio) return false; + mDrawingState.desiredHdrSdrRatio = desiredRatio; + mDrawingState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + bool Layer::setCachingHint(gui::CachingHint cachingHint) { if (mDrawingState.cachingHint == cachingHint) return false; mDrawingState.cachingHint = cachingHint; @@ -3991,6 +3999,13 @@ bool Layer::isSimpleBufferUpdate(const layer_state_t& s) const { } } + if (s.what & layer_state_t::eDesiredHdrHeadroomChanged) { + if (mDrawingState.desiredHdrSdrRatio != s.desiredHdrSdrRatio) { + ATRACE_FORMAT_INSTANT("%s: false [eDesiredHdrHeadroomChanged changed]", __func__); + return false; + } + } + return true; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index dfd57c65e3..0ceecec7ec 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -233,7 +233,7 @@ public: bool autoRefresh = false; bool dimmingEnabled = true; float currentHdrSdrRatio = 1.f; - float desiredHdrSdrRatio = 1.f; + float desiredHdrSdrRatio = -1.f; gui::CachingHint cachingHint = gui::CachingHint::Enabled; int64_t latchedVsyncId = 0; bool useVsyncIdForRefreshRateSelection = false; @@ -317,6 +317,7 @@ public: void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/); bool setDataspace(ui::Dataspace /*dataspace*/); bool setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio); + bool setDesiredHdrHeadroom(float desiredRatio); bool setCachingHint(gui::CachingHint cachingHint); bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/); bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/); @@ -546,7 +547,7 @@ public: sp mReleaseBufferEndpoint; bool mFrameLatencyNeeded{false}; - float mDesiredHdrSdrRatio = 1.f; + float mDesiredHdrSdrRatio = -1.f; }; BufferInfo mBufferInfo; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 7626fe73e9..1a40bc241f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3119,6 +3119,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, for (auto& [compositionDisplay, listener] : hdrInfoListeners) { HdrLayerInfoReporter::HdrLayerInfo info; int32_t maxArea = 0; + auto updateInfoFn = [&](const std::shared_ptr& compositionDisplay, const frontend::LayerSnapshot& snapshot, const sp& layerFe) { @@ -3129,7 +3130,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, compositionDisplay->getOutputLayerForLayer(layerFe); if (outputLayer) { const float desiredHdrSdrRatio = - snapshot.desiredHdrSdrRatio <= 1.f + snapshot.desiredHdrSdrRatio < 1.f ? std::numeric_limits::infinity() : snapshot.desiredHdrSdrRatio; info.mergeDesiredRatio(desiredHdrSdrRatio); @@ -5415,6 +5416,11 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime flags |= eTraversalNeeded; } } + if (what & layer_state_t::eDesiredHdrHeadroomChanged) { + if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) { + flags |= eTraversalNeeded; + } + } if (what & layer_state_t::eCachingHintChanged) { if (layer->setCachingHint(s.cachingHint)) { flags |= eTraversalNeeded; @@ -5600,6 +5606,11 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f flags |= eTraversalNeeded; } } + if (what & layer_state_t::eDesiredHdrHeadroomChanged) { + if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) { + flags |= eTraversalNeeded; + } + } if (what & layer_state_t::eBufferChanged) { std::optional transformHint = std::nullopt; frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); -- cgit v1.2.3-59-g8ed1b