diff options
-rw-r--r-- | include/android/surface_control.h | 50 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 5 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 14 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 5 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshot.cpp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/RequestedLayerState.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 15 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 13 |
10 files changed, 106 insertions, 10 deletions
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. @@ -574,6 +579,45 @@ void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* transac 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 7564c26316..1e0aacddab 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -611,6 +611,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; @@ -774,6 +778,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 83c2b7f703..4f1356bebb 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1808,6 +1808,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setExten return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesiredHdrHeadroom( + const sp<SurfaceControl>& 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<SurfaceControl>& 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 920310ea9e..0fedea7b9e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -209,7 +209,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, @@ -248,7 +248,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 88a2c342e7..288882695a 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -594,6 +594,7 @@ public: Transaction& setDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace); Transaction& setExtendedRangeBrightness(const sp<SurfaceControl>& sc, float currentBufferRatio, float desiredRatio); + Transaction& setDesiredHdrHeadroom(const sp<SurfaceControl>& sc, float desiredRatio); Transaction& setCachingHint(const sp<SurfaceControl>& sc, gui::CachingHint cachingHint); Transaction& setHdrMetadata(const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata); Transaction& setSurfaceDamageRegion(const sp<SurfaceControl>& sc, diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index 3ef9e69620..ea06cf6de6 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -381,6 +381,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 2cf4c1b7dd..cb0e2a1938 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; @@ -606,7 +606,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<IBinder> 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 d354e4bc93..5bb550834e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3111,6 +3111,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, for (auto& [compositionDisplay, listener] : hdrInfoListeners) { HdrLayerInfoReporter::HdrLayerInfo info; int32_t maxArea = 0; + auto updateInfoFn = [&](const std::shared_ptr<compositionengine::Display>& compositionDisplay, const frontend::LayerSnapshot& snapshot, const sp<LayerFE>& layerFe) { @@ -3121,7 +3122,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<float>::infinity() : snapshot.desiredHdrSdrRatio; info.mergeDesiredRatio(desiredHdrSdrRatio); @@ -5559,6 +5560,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; @@ -5744,6 +5750,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<ui::Transform::RotationFlags> transformHint = std::nullopt; frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); |