From 9ebb7a721aecc1da1ee3f45846010fd3945e8e22 Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Tue, 27 Jun 2023 17:01:50 -0700 Subject: Update HDCP for external displays So the secure flag of Display object in Display Manager (DM) can be set correctly. HWC calls the onSync method as a workaround, to notify SurfaceFlinger (SF) about hdcp changes, SF in turn sends an event to DM, DM will then fetch and update display info. Bug: 280818362 Test: manual Change-Id: I29ce0337865b51c0fc7bf7c2d7fdd4cd6d66ef46 --- libs/gui/SurfaceComposerClient.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 8b6f2023dc..8d18551b69 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -3117,7 +3117,6 @@ status_t SurfaceComposerClient::removeWindowInfosListener( ->removeWindowInfosListener(windowInfosListener, ComposerServiceAIDL::getComposerService()); } - // ---------------------------------------------------------------------------- status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs, -- cgit v1.2.3-59-g8ed1b From f6fb445b73f0c84f92f74c799effac08e18c4c1c Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Tue, 23 Jan 2024 21:10:30 +0000 Subject: Add captureLayersSync function This captureLayers function in SurfaceFlinger will wait on the requested binder thread for the screenshot composition to complete before returning the buffer to the client. This is different than the existing captureLayers method since the other request is oneway and invokes the screen capture callback on a different binder thread. This is needed because there are places in system server that request screenshots while holding a lock and then wait synchronously on the results. While waiting on the buffer and holding the lock, additional two way binder calls can be made into system server that are waiting to acquire the same lock. If there are enough requests, we may run out of binder threads and then the screen capture result can't be posted back to system server because it needs a free binder thread. This will result in a deadlock because the lock that the screenshot request is holding can never be unlocked without a free binder thread. Binder threads will never be freed up because they are waiting to acquire the lock. The async screencapture code is still useful for cases where there's no global lock being held while waiting on results or the results is posted to another thread. Test: Screenshots Bug: 321263247 Change-Id: I259173a59f488995e13af8f7dd2ca98c3bbf8639 --- libs/gui/SurfaceComposerClient.cpp | 13 +++++++++++-- libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 11 +++++++++++ libs/gui/fuzzer/libgui_fuzzer_utils.h | 2 ++ libs/gui/include/gui/SurfaceComposerClient.h | 3 ++- libs/gui/tests/Surface_test.cpp | 4 ++++ services/surfaceflinger/SurfaceFlinger.cpp | 13 +++++++++++++ services/surfaceflinger/SurfaceFlinger.h | 2 ++ 7 files changed, 45 insertions(+), 3 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 8d18551b69..83c2b7f703 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -56,6 +56,7 @@ #include #include +#include #include #include @@ -3138,11 +3139,19 @@ status_t ScreenshotClient::captureDisplay(DisplayId displayId, const gui::Captur } status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs, - const sp& captureListener) { + const sp& captureListener, + bool sync) { sp s(ComposerServiceAIDL::getComposerService()); if (s == nullptr) return NO_INIT; - binder::Status status = s->captureLayers(captureArgs, captureListener); + binder::Status status; + if (sync) { + gui::ScreenCaptureResults captureResults; + status = s->captureLayersSync(captureArgs, &captureResults); + captureListener->onScreenCaptureCompleted(captureResults); + } else { + status = s->captureLayers(captureArgs, captureListener); + } return statusTFromBinderStatus(status); } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index e3122bc300..51e01930d3 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -46,6 +46,7 @@ import android.gui.LayerCaptureArgs; import android.gui.LayerDebugInfo; import android.gui.OverlayProperties; import android.gui.PullAtomData; +import android.gui.ScreenCaptureResults; import android.gui.ARect; import android.gui.SchedulingPolicy; import android.gui.StalledTransactionInfo; @@ -242,6 +243,16 @@ interface ISurfaceComposer { oneway void captureDisplayById(long displayId, in CaptureArgs args, IScreenCaptureListener listener); + /** + * Capture a subtree of the layer hierarchy, potentially ignoring the root node. + * This requires READ_FRAME_BUFFER permission. This function will fail if there + * is a secure window on screen. This is a blocking call and will return the + * ScreenCaptureResults, including the captured buffer. Because this is blocking, the + * caller doesn't care about the fence and the binder thread in SurfaceFlinger will wait + * on the fence to fire before returning the results. + */ + ScreenCaptureResults captureLayersSync(in LayerCaptureArgs args); + /** * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * This requires READ_FRAME_BUFFER permission. This function will fail if there diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h index c952ba2e10..2bdbd43233 100644 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h @@ -104,6 +104,8 @@ public: (int64_t, const gui::CaptureArgs&, const sp&), (override)); MOCK_METHOD(binder::Status, captureLayers, (const LayerCaptureArgs&, const sp&), (override)); + MOCK_METHOD(binder::Status, captureLayersSync, + (const LayerCaptureArgs&, gui::ScreenCaptureResults*), (override)); MOCK_METHOD(binder::Status, clearAnimationFrameStats, (), (override)); MOCK_METHOD(binder::Status, getAnimationFrameStats, (gui::FrameStats*), (override)); MOCK_METHOD(binder::Status, overrideHdrTypes, (const sp&, const std::vector&), diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 14e3dd583e..88a2c342e7 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -849,7 +849,8 @@ public: static status_t captureDisplay(const DisplayCaptureArgs&, const sp&); static status_t captureDisplay(DisplayId, const gui::CaptureArgs&, const sp&); - static status_t captureLayers(const LayerCaptureArgs&, const sp&); + static status_t captureLayers(const LayerCaptureArgs&, const sp&, + bool sync); [[deprecated]] static status_t captureDisplay(DisplayId id, const sp& listener) { diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index c6ea317949..577d2394c6 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -791,6 +791,10 @@ public: return binder::Status::ok(); } + binder::Status captureLayersSync(const LayerCaptureArgs&, ScreenCaptureResults*) override { + return binder::Status::ok(); + } + binder::Status captureLayers(const LayerCaptureArgs&, const sp&) override { return binder::Status::ok(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fe5b159051..178828a5f6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -116,6 +116,7 @@ #include #include #include +#include #include #include "BackgroundExecutor.h" #include "Client.h" @@ -7842,6 +7843,12 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args kAllowProtected, kGrayscale, captureListener); } +ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { + sp captureListener = sp::make(); + captureLayers(args, captureListener); + return captureListener->waitForResults(); +} + void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, const sp& captureListener) { ATRACE_CALL(); @@ -9686,6 +9693,12 @@ binder::Status SurfaceComposerAIDL::captureDisplayById( return binderStatusFromStatusT(NO_ERROR); } +binder::Status SurfaceComposerAIDL::captureLayersSync(const LayerCaptureArgs& args, + ScreenCaptureResults* outResults) { + *outResults = mFlinger->captureLayersSync(args); + return binderStatusFromStatusT(NO_ERROR); +} + binder::Status SurfaceComposerAIDL::captureLayers( const LayerCaptureArgs& args, const sp& captureListener) { mFlinger->captureLayers(args, captureListener); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 6ae05d604a..24a1a108ce 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -560,6 +560,7 @@ private: void captureDisplay(const DisplayCaptureArgs&, const sp&); void captureDisplay(DisplayId, const CaptureArgs&, const sp&); + ScreenCaptureResults captureLayersSync(const LayerCaptureArgs&); void captureLayers(const LayerCaptureArgs&, const sp&); status_t getDisplayStats(const sp& displayToken, DisplayStatInfo* stats); @@ -1546,6 +1547,7 @@ public: const sp&) override; binder::Status captureLayers(const LayerCaptureArgs&, const sp&) override; + binder::Status captureLayersSync(const LayerCaptureArgs&, ScreenCaptureResults* results); // TODO(b/239076119): Remove deprecated AIDL. [[deprecated]] binder::Status clearAnimationFrameStats() override { -- 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/SurfaceComposerClient.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