diff options
author | 2023-09-06 02:10:05 +0000 | |
---|---|---|
committer | 2023-12-06 00:16:02 +0000 | |
commit | f97df4d8a6e4ef1364244b0e9adefc08c3f95c06 (patch) | |
tree | bd5a54efeda611d597c67dca073abe995b928feb | |
parent | d6a6f38c2449d059e9ba2f90668b95145f6237b8 (diff) |
Support fp16 in sf
* Make sure we don't dim SDR in renderengine, and instead map HDR to the
correct relative luminance above 1.0
* Plumb the HDR/SDR ratio into HWC
Bug: 236745178
Test: builds
Change-Id: I325972a01280d287189d38dd6c5bf7f2d4b776bb
36 files changed, 268 insertions, 82 deletions
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp index e316190499..ae2f2dbbf5 100644 --- a/services/surfaceflinger/CompositionEngine/Android.bp +++ b/services/surfaceflinger/CompositionEngine/Android.bp @@ -37,6 +37,7 @@ cc_defaults { "libSurfaceFlingerProp", "libui", "libutils", + "server_configurable_flags", ], static_libs: [ "liblayers_proto", @@ -60,13 +61,8 @@ cc_defaults { ], } -cc_library { - name: "libcompositionengine", - defaults: ["libcompositionengine_defaults"], - static_libs: [ - "libsurfaceflinger_common", - "libsurfaceflingerflags", - ], +filegroup { + name: "libcompositionengine_sources", srcs: [ "src/planner/CachedSet.cpp", "src/planner/Flattener.cpp", @@ -89,6 +85,18 @@ cc_library { "src/OutputLayerCompositionState.cpp", "src/RenderSurface.cpp", ], +} + +cc_library { + name: "libcompositionengine", + defaults: ["libcompositionengine_defaults"], + static_libs: [ + "libsurfaceflinger_common", + "libsurfaceflingerflags", + ], + srcs: [ + ":libcompositionengine_sources", + ], local_include_dirs: ["include"], export_include_dirs: ["include"], shared_libs: [ @@ -133,6 +141,7 @@ cc_test { ], defaults: ["libcompositionengine_defaults"], srcs: [ + ":libcompositionengine_sources", "tests/planner/CachedSetTest.cpp", "tests/planner/FlattenerTest.cpp", "tests/planner/LayerStateTest.cpp", @@ -151,7 +160,6 @@ cc_test { "tests/RenderSurfaceTest.cpp", ], static_libs: [ - "libcompositionengine", "libcompositionengine_mocks", "libgui_mocks", "librenderengine_mocks", diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h index ca86f4c604..643b458067 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h @@ -60,7 +60,7 @@ public: // // advanceFrame must be followed by a call to onFrameCommitted before // advanceFrame may be called again. - virtual status_t advanceFrame() = 0; + virtual status_t advanceFrame(float hdrSdrRatio) = 0; // onFrameCommitted is called after the frame has been committed to the // hardware composer. The surface collects the release fence for this diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h index 585467456c..02cea0d1ce 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h @@ -86,7 +86,7 @@ public: // Queues the drawn buffer for consumption by HWC. readyFence is the fence // which will fire when the buffer is ready for consumption. - virtual void queueBuffer(base::unique_fd readyFence) = 0; + virtual void queueBuffer(base::unique_fd readyFence, float hdrSdrRatio) = 0; // Called after the HWC calls are made to present the display virtual void onPresentDisplayCompleted() = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h index ec6a4e9c63..911d67b5ed 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h @@ -137,7 +137,8 @@ protected: void applyCompositionStrategy(const std::optional<DeviceRequestedChanges>&) override{}; bool getSkipColorTransform() const override; compositionengine::Output::FrameFences presentFrame() override; - virtual renderengine::DisplaySettings generateClientCompositionDisplaySettings() const; + virtual renderengine::DisplaySettings generateClientCompositionDisplaySettings( + const std::shared_ptr<renderengine::ExternalTexture>& buffer) const; std::vector<LayerFE::LayerSettings> generateClientCompositionRequests( bool supportsProtectedContent, ui::Dataspace outputDataspace, std::vector<LayerFE*>& outLayerFEs) override; @@ -168,6 +169,7 @@ private: compositionengine::Output::ColorProfile pickColorProfile( const compositionengine::CompositionRefreshArgs&) const; void updateHwcAsyncWorker(); + float getHdrSdrRatio(const std::shared_ptr<renderengine::ExternalTexture>& buffer) const; std::string mName; std::string mNamePlusId; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h index 1c14a43920..202145ed6c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h @@ -60,7 +60,7 @@ public: void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override; std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer( base::unique_fd* bufferFence) override; - void queueBuffer(base::unique_fd readyFence) override; + void queueBuffer(base::unique_fd readyFence, float hdrSdrRatio) override; void onPresentDisplayCompleted() override; bool supportsCompositionStrategyPrediction() const override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h index 168e433da2..08d8ff756f 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h @@ -30,7 +30,7 @@ public: MOCK_METHOD1(beginFrame, status_t(bool mustRecompose)); MOCK_METHOD1(prepareFrame, status_t(CompositionType compositionType)); - MOCK_METHOD0(advanceFrame, status_t()); + MOCK_METHOD((status_t), advanceFrame, (float), (override)); MOCK_METHOD0(onFrameCommitted, void()); MOCK_CONST_METHOD1(dumpAsString, void(String8& result)); MOCK_METHOD1(resizeBuffers, void(const ui::Size&)); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h index af8d4bcb0b..c35fd3fbf6 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h @@ -40,7 +40,7 @@ public: MOCK_METHOD1(beginFrame, status_t(bool mustRecompose)); MOCK_METHOD2(prepareFrame, void(bool, bool)); MOCK_METHOD1(dequeueBuffer, std::shared_ptr<renderengine::ExternalTexture>(base::unique_fd*)); - MOCK_METHOD1(queueBuffer, void(base::unique_fd)); + MOCK_METHOD(void, queueBuffer, (base::unique_fd, float), (override)); MOCK_METHOD0(onPresentDisplayCompleted, void()); MOCK_CONST_METHOD1(dump, void(std::string& result)); MOCK_CONST_METHOD0(supportsCompositionStrategyPrediction, bool()); diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index c399224491..09c7c9933a 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -1176,7 +1176,7 @@ void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& updateProtectedContentState(); dequeueRenderBuffer(&bufferFence, &buffer); static_cast<void>(composeSurfaces(dirtyRegion, buffer, bufferFence)); - mRenderSurface->queueBuffer(base::unique_fd()); + mRenderSurface->queueBuffer(base::unique_fd(), getHdrSdrRatio(buffer)); } } @@ -1224,7 +1224,7 @@ void Output::finishFrame(GpuCompositionResult&& result) { std::make_unique<FenceTime>(sp<Fence>::make(dup(optReadyFence->get())))); } // swap buffers (presentation) - mRenderSurface->queueBuffer(std::move(*optReadyFence)); + mRenderSurface->queueBuffer(std::move(*optReadyFence), getHdrSdrRatio(buffer)); } void Output::updateProtectedContentState() { @@ -1298,7 +1298,7 @@ std::optional<base::unique_fd> Output::composeSurfaces( ALOGV("hasClientComposition"); renderengine::DisplaySettings clientCompositionDisplay = - generateClientCompositionDisplaySettings(); + generateClientCompositionDisplaySettings(tex); // Generate the client composition requests for the layers on this output. auto& renderEngine = getCompositionEngine().getRenderEngine(); @@ -1379,7 +1379,8 @@ std::optional<base::unique_fd> Output::composeSurfaces( return base::unique_fd(fence->dup()); } -renderengine::DisplaySettings Output::generateClientCompositionDisplaySettings() const { +renderengine::DisplaySettings Output::generateClientCompositionDisplaySettings( + const std::shared_ptr<renderengine::ExternalTexture>& buffer) const { const auto& outputState = getState(); renderengine::DisplaySettings clientCompositionDisplay; @@ -1399,8 +1400,10 @@ renderengine::DisplaySettings Output::generateClientCompositionDisplaySettings() : mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance(); clientCompositionDisplay.maxLuminance = mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance(); - clientCompositionDisplay.targetLuminanceNits = - outputState.clientTargetBrightness * outputState.displayBrightnessNits; + + float hdrSdrRatioMultiplier = 1.0f / getHdrSdrRatio(buffer); + clientCompositionDisplay.targetLuminanceNits = outputState.clientTargetBrightness * + outputState.displayBrightnessNits * hdrSdrRatioMultiplier; clientCompositionDisplay.dimmingStage = outputState.clientTargetDimmingStage; clientCompositionDisplay.renderIntent = static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>( @@ -1715,5 +1718,25 @@ bool Output::mustRecompose() const { return mMustRecompose; } +float Output::getHdrSdrRatio(const std::shared_ptr<renderengine::ExternalTexture>& buffer) const { + if (buffer == nullptr) { + return 1.0f; + } + + if (!FlagManager::getInstance().fp16_client_target()) { + return 1.0f; + } + + if (getState().displayBrightnessNits < 0.0f || getState().sdrWhitePointNits <= 0.0f || + buffer->getPixelFormat() != PIXEL_FORMAT_RGBA_FP16 || + (static_cast<int32_t>(getState().dataspace) & + static_cast<int32_t>(ui::Dataspace::RANGE_MASK)) != + static_cast<int32_t>(ui::Dataspace::RANGE_EXTENDED)) { + return 1.0f; + } + + return getState().displayBrightnessNits / getState().sdrWhitePointNits; +} + } // namespace impl } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp index 0fe55db05c..c0b23d97d4 100644 --- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp +++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp @@ -198,7 +198,7 @@ std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer( return mTexture; } -void RenderSurface::queueBuffer(base::unique_fd readyFence) { +void RenderSurface::queueBuffer(base::unique_fd readyFence, float hdrSdrRatio) { auto& state = mDisplay.getState(); if (state.usesClientComposition || state.flipClientTarget) { @@ -241,7 +241,7 @@ void RenderSurface::queueBuffer(base::unique_fd readyFence) { } } - status_t result = mDisplaySurface->advanceFrame(); + status_t result = mDisplaySurface->advanceFrame(hdrSdrRatio); if (result != NO_ERROR) { ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplay.getName().c_str(), result); } diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 4a778d49ac..a95a5c62fd 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -936,7 +936,7 @@ TEST_F(DisplayFinishFrameTest, doesNotSkipCompositionIfNotDirtyOnHwcDisplay) { mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect no calls to queueBuffer if composition was skipped. - EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1); + EXPECT_CALL(*renderSurface, queueBuffer(_, _)).Times(1); // Expect a call to signal no expensive rendering since there is no client composition. EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)); @@ -957,7 +957,7 @@ TEST_F(DisplayFinishFrameTest, skipsCompositionIfNotDirty) { gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect no calls to queueBuffer if composition was skipped. - EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0); + EXPECT_CALL(*renderSurface, queueBuffer(_, _)).Times(0); EXPECT_CALL(*renderSurface, beginFrame(false)); gpuDisplay->editState().isEnabled = true; @@ -978,7 +978,7 @@ TEST_F(DisplayFinishFrameTest, skipsCompositionIfEmpty) { gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect no calls to queueBuffer if composition was skipped. - EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0); + EXPECT_CALL(*renderSurface, queueBuffer(_, _)).Times(0); EXPECT_CALL(*renderSurface, beginFrame(false)); gpuDisplay->editState().isEnabled = true; @@ -999,7 +999,7 @@ TEST_F(DisplayFinishFrameTest, performsCompositionIfDirtyAndNotEmpty) { gpuDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface)); // We expect a single call to queueBuffer when composition is not skipped. - EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1); + EXPECT_CALL(*renderSurface, queueBuffer(_, _)).Times(1); EXPECT_CALL(*renderSurface, beginFrame(true)); gpuDisplay->editState().isEnabled = true; diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index b2491d894c..8b736be5e9 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -57,9 +57,10 @@ public: MOCK_METHOD(status_t, getDeviceCompositionChanges, (HalDisplayId, bool, std::optional<std::chrono::steady_clock::time_point>, nsecs_t, Fps, std::optional<android::HWComposer::DeviceRequestedChanges>*)); - MOCK_METHOD5(setClientTarget, - status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&, - ui::Dataspace)); + MOCK_METHOD(status_t, setClientTarget, + (HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&, ui::Dataspace, + float), + (override)); MOCK_METHOD2(presentAndGetReleaseFences, status_t(HalDisplayId, std::optional<std::chrono::steady_clock::time_point>)); MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode)); diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 5006e7d94a..bf7ed87443 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -15,6 +15,7 @@ */ #include <android-base/stringprintf.h> +#include <com_android_graphics_surfaceflinger_flags.h> #include <compositionengine/LayerFECompositionState.h> #include <compositionengine/impl/Output.h> #include <compositionengine/impl/OutputCompositionState.h> @@ -37,6 +38,8 @@ #include <cstdint> #include <variant> +#include <common/FlagManager.h> +#include <common/test/FlagUtils.h> #include "CallOrderStateMachineHelper.h" #include "MockHWC2.h" #include "RegionMatcher.h" @@ -44,6 +47,8 @@ namespace android::compositionengine { namespace { +using namespace com::android::graphics::surfaceflinger; + using testing::_; using testing::ByMove; using testing::ByRef; @@ -2961,7 +2966,7 @@ TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty EXPECT_CALL(mOutput, updateProtectedContentState()); EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)); EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), _, _)); - EXPECT_CALL(*mRenderSurface, queueBuffer(_)); + EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f)); EXPECT_CALL(mOutput, presentFrameAndReleaseLayers()); EXPECT_CALL(mOutput, prepareFrame()); @@ -2990,11 +2995,15 @@ struct OutputFinishFrameTest : public testing::Test { mOutput.setDisplayColorProfileForTest( std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile)); mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface)); + EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine)); + EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine)); } StrictMock<OutputPartialMock> mOutput; mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>(); mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>(); + StrictMock<mock::CompositionEngine> mCompositionEngine; + StrictMock<renderengine::mock::RenderEngine> mRenderEngine; }; TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) { @@ -3022,7 +3031,34 @@ TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) { EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)).WillOnce(Return(true)); EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _)) .WillOnce(Return(ByMove(base::unique_fd()))); - EXPECT_CALL(*mRenderSurface, queueBuffer(_)); + EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f)); + + impl::GpuCompositionResult result; + mOutput.finishFrame(std::move(result)); +} + +TEST_F(OutputFinishFrameTest, queuesBufferWithHdrSdrRatio) { + SET_FLAG_FOR_TEST(flags::fp16_client_target, true); + mOutput.mState.isEnabled = true; + + InSequence seq; + auto texture = std::make_shared< + renderengine::impl:: + ExternalTexture>(sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_FP16, + GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_SW_READ_OFTEN), + mRenderEngine, + renderengine::impl::ExternalTexture::Usage::READABLE | + renderengine::impl::ExternalTexture::Usage::WRITEABLE); + mOutput.mState.displayBrightnessNits = 400.f; + mOutput.mState.sdrWhitePointNits = 200.f; + mOutput.mState.dataspace = ui::Dataspace::V0_SCRGB; + EXPECT_CALL(mOutput, updateProtectedContentState()); + EXPECT_CALL(mOutput, dequeueRenderBuffer(_, _)) + .WillOnce(DoAll(SetArgPointee<1>(texture), Return(true))); + EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _, _)) + .WillOnce(Return(ByMove(base::unique_fd()))); + EXPECT_CALL(*mRenderSurface, queueBuffer(_, 2.f)); impl::GpuCompositionResult result; mOutput.finishFrame(std::move(result)); @@ -3032,7 +3068,7 @@ TEST_F(OutputFinishFrameTest, predictionSucceeded) { mOutput.mState.isEnabled = true; mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS; InSequence seq; - EXPECT_CALL(*mRenderSurface, queueBuffer(_)); + EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f)); impl::GpuCompositionResult result; mOutput.finishFrame(std::move(result)); @@ -3054,7 +3090,7 @@ TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) { composeSurfaces(RegionEq(Region::INVALID_REGION), result.buffer, Eq(ByRef(result.fence)))) .WillOnce(Return(ByMove(base::unique_fd()))); - EXPECT_CALL(*mRenderSurface, queueBuffer(_)); + EXPECT_CALL(*mRenderSurface, queueBuffer(_, 1.f)); mOutput.finishFrame(std::move(result)); } @@ -3324,6 +3360,7 @@ struct OutputComposeSurfacesTest : public testing::Test { static constexpr float kDefaultAvgLuminance = 0.7f; static constexpr float kDefaultMinLuminance = 0.1f; static constexpr float kDisplayLuminance = 400.f; + static constexpr float kWhitePointLuminance = 300.f; static constexpr float kClientTargetLuminanceNits = 200.f; static constexpr float kClientTargetBrightness = 0.5f; @@ -3634,7 +3671,7 @@ struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComp OutputComposeSurfacesTest_UsesExpectedDisplaySettings() { EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false)); EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false)); - EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _)) + EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _)) .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{})); EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)) .WillRepeatedly(Return()); @@ -3661,6 +3698,14 @@ struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComp : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> { auto withDisplayBrightnessNits(float nits) { getInstance()->mOutput.mState.displayBrightnessNits = nits; + return nextState<OutputWithSdrWhitePointNits>(); + } + }; + + struct OutputWithSdrWhitePointNits + : public CallOrderStateMachineHelper<TestType, OutputWithSdrWhitePointNits> { + auto withSdrWhitePointNits(float nits) { + getInstance()->mOutput.mState.sdrWhitePointNits = nits; return nextState<OutputWithDimmingStage>(); } }; @@ -3690,6 +3735,35 @@ struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComp // May be called zero or one times. EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform()) .WillRepeatedly(Return(skip)); + return nextState<PixelFormatState>(); + } + }; + + struct PixelFormatState : public CallOrderStateMachineHelper<TestType, PixelFormatState> { + auto withPixelFormat(std::optional<PixelFormat> format) { + // May be called zero or one times. + if (format) { + auto outputBuffer = std::make_shared< + renderengine::impl:: + ExternalTexture>(sp<GraphicBuffer>:: + make(1u, 1u, *format, + GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_SW_READ_OFTEN), + getInstance()->mRenderEngine, + renderengine::impl::ExternalTexture::Usage:: + READABLE | + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + EXPECT_CALL(*getInstance()->mRenderSurface, dequeueBuffer(_)) + .WillRepeatedly(Return(outputBuffer)); + } + return nextState<DataspaceState>(); + } + }; + + struct DataspaceState : public CallOrderStateMachineHelper<TestType, DataspaceState> { + auto withDataspace(ui::Dataspace dataspace) { + getInstance()->mOutput.mState.dataspace = dataspace; return nextState<ExpectDisplaySettingsState>(); } }; @@ -3711,10 +3785,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposi verify().ifMixedCompositionIs(true) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3738,10 +3815,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, verify().ifMixedCompositionIs(true) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3765,11 +3845,14 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, verify().ifMixedCompositionIs(true) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage( aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3793,9 +3876,12 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, verify().ifMixedCompositionIs(true) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent(aidl::android::hardware::graphics::composer3::RenderIntent::ENHANCE) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3818,10 +3904,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComp verify().ifMixedCompositionIs(true) .andIfUsesHdr(false) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3844,10 +3933,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientCo verify().ifMixedCompositionIs(false) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3870,10 +3962,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClien verify().ifMixedCompositionIs(false) .andIfUsesHdr(false) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(false) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3897,10 +3992,13 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, verify().ifMixedCompositionIs(false) .andIfUsesHdr(true) .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) .withRenderIntent( aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) .andIfSkipColorTransform(true) + .withPixelFormat(std::nullopt) + .withDataspace(kDefaultOutputDataspace) .thenExpectDisplaySettingsUsed( {.physicalDisplay = kDefaultOutputDestinationClip, .clip = kDefaultOutputViewport, @@ -3919,6 +4017,38 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, .expectAFenceWasReturned(); } +TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, + usesExpectedDisplaySettingsWithFp16Buffer) { + SET_FLAG_FOR_TEST(flags::fp16_client_target, true); + ALOGE("alecmouri: %d", flags::fp16_client_target()); + verify().ifMixedCompositionIs(false) + .andIfUsesHdr(true) + .withDisplayBrightnessNits(kDisplayLuminance) + .withSdrWhitePointNits(kWhitePointLuminance) + .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR) + .withRenderIntent( + aidl::android::hardware::graphics::composer3::RenderIntent::COLORIMETRIC) + .andIfSkipColorTransform(true) + .withPixelFormat(PIXEL_FORMAT_RGBA_FP16) + .withDataspace(ui::Dataspace::V0_SCRGB) + .thenExpectDisplaySettingsUsed( + {.physicalDisplay = kDefaultOutputDestinationClip, + .clip = kDefaultOutputViewport, + .maxLuminance = kDefaultMaxLuminance, + .currentLuminanceNits = kDisplayLuminance, + .outputDataspace = ui::Dataspace::V0_SCRGB, + .colorTransform = kDefaultColorTransformMat, + .deviceHandlesColorTransform = true, + .orientation = kDefaultOutputOrientationFlags, + .targetLuminanceNits = kClientTargetLuminanceNits * 0.75f, + .dimmingStage = + aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR, + .renderIntent = aidl::android::hardware::graphics::composer3::RenderIntent:: + COLORIMETRIC}) + .execute() + .expectAFenceWasReturned(); +} + struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest { struct Layer { Layer() { diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp index 83937a679e..edfaa26c92 100644 --- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp @@ -263,9 +263,9 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) { state.flipClientTarget = false; EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); - EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1); - mSurface.queueBuffer(base::unique_fd()); + mSurface.queueBuffer(base::unique_fd(), 0.5f); EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get()); } @@ -283,9 +283,9 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) { EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1); - mSurface.queueBuffer(base::unique_fd()); + mSurface.queueBuffer(base::unique_fd(), 0.5f); EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); } @@ -303,9 +303,9 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) { EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1); - mSurface.queueBuffer(base::unique_fd()); + mSurface.queueBuffer(base::unique_fd(), 0.5f); EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); } @@ -323,9 +323,9 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferY DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR))); EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1); - mSurface.queueBuffer(base::unique_fd()); + mSurface.queueBuffer(base::unique_fd(), 0.5f); EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); } @@ -345,9 +345,9 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirt EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true)); EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); - EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*mDisplaySurface, advanceFrame(0.5f)).Times(1); - mSurface.queueBuffer(base::unique_fd()); + mSurface.queueBuffer(base::unique_fd(), 0.5f); EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); } diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp index 369021995c..c25f9ddd12 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp @@ -666,7 +666,8 @@ Error AidlComposer::setActiveConfig(Display display, Config config) { Error AidlComposer::setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, - const std::vector<IComposerClient::Rect>& damage) { + const std::vector<IComposerClient::Rect>& damage, + float hdrSdrRatio) { const native_handle_t* handle = nullptr; if (target.get()) { handle = target->getNativeBuffer()->handle; @@ -679,7 +680,7 @@ Error AidlComposer::setClientTarget(Display display, uint32_t slot, const sp<Gra .setClientTarget(translate<int64_t>(display), slot, handle, acquireFence, translate<aidl::android::hardware::graphics::common::Dataspace>( dataspace), - translate<AidlRect>(damage)); + translate<AidlRect>(damage), hdrSdrRatio); } else { error = Error::BAD_DISPLAY; } diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h index 1635a16ec8..51ac1f5e6a 100644 --- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h @@ -124,7 +124,8 @@ public: */ Error setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, - const std::vector<IComposerClient::Rect>& damage) override; + const std::vector<IComposerClient::Rect>& damage, + float hdrSdrRatio) override; Error setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) override; Error setColorTransform(Display display, const float* matrix) override; Error setOutputBuffer(Display display, const native_handle_t* buffer, diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 082717a65b..1a24222af3 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -163,7 +163,8 @@ public: */ virtual Error setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, - const std::vector<IComposerClient::Rect>& damage) = 0; + const std::vector<IComposerClient::Rect>& damage, + float hdrSdrRatio) = 0; virtual Error setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) = 0; virtual Error setColorTransform(Display display, const float* matrix) = 0; virtual Error setOutputBuffer(Display display, const native_handle_t* buffer, diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index ce602a8ad9..c77cdd4432 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -91,7 +91,7 @@ status_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) { return NO_ERROR; } -status_t FramebufferSurface::advanceFrame() { +status_t FramebufferSurface::advanceFrame(float hdrSdrRatio) { Mutex::Autolock lock(mMutex); BufferItem item; @@ -131,7 +131,7 @@ status_t FramebufferSurface::advanceFrame() { hwcBuffer = mCurrentBuffer; // HWC hasn't previously seen this buffer in this slot } status_t result = mHwc.setClientTarget(mDisplayId, mCurrentBufferSlot, mCurrentFence, hwcBuffer, - mDataspace); + mDataspace, hdrSdrRatio); if (result != NO_ERROR) { ALOGE("error posting framebuffer: %s (%d)", strerror(-result), result); return result; diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index 0b863daf47..2728cf637e 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -46,7 +46,7 @@ public: virtual status_t beginFrame(bool mustRecompose); virtual status_t prepareFrame(CompositionType compositionType); - virtual status_t advanceFrame(); + virtual status_t advanceFrame(float hdrSdrRatio); virtual void onFrameCommitted(); virtual void dumpAsString(String8& result) const; diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index bc763b2e55..24a9e22a2b 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -446,12 +446,13 @@ Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId, } Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, - const sp<Fence>& acquireFence, Dataspace dataspace) -{ + const sp<Fence>& acquireFence, Dataspace dataspace, + float hdrSdrRatio) { // TODO: Properly encode client target surface damage int32_t fenceFd = acquireFence->dup(); - auto intError = mComposer.setClientTarget(mId, slot, target, - fenceFd, dataspace, std::vector<Hwc2::IComposerClient::Rect>()); + auto intError = + mComposer.setClientTarget(mId, slot, target, fenceFd, dataspace, + std::vector<Hwc2::IComposerClient::Rect>(), hdrSdrRatio); return static_cast<Error>(intError); } diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 29fe38008d..f907061774 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -141,7 +141,8 @@ public: [[nodiscard]] virtual hal::Error present(android::sp<android::Fence>* outPresentFence) = 0; [[nodiscard]] virtual hal::Error setClientTarget( uint32_t slot, const android::sp<android::GraphicBuffer>& target, - const android::sp<android::Fence>& acquireFence, hal::Dataspace dataspace) = 0; + const android::sp<android::Fence>& acquireFence, hal::Dataspace dataspace, + float hdrSdrRatio) = 0; [[nodiscard]] virtual hal::Error setColorMode(hal::ColorMode mode, hal::RenderIntent renderIntent) = 0; [[nodiscard]] virtual hal::Error setColorTransform(const android::mat4& matrix) = 0; @@ -229,7 +230,7 @@ public: hal::Error present(android::sp<android::Fence>* outPresentFence) override; hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target, const android::sp<android::Fence>& acquireFence, - hal::Dataspace dataspace) override; + hal::Dataspace dataspace, float hdrSdrRatio) override; hal::Error setColorMode(hal::ColorMode, hal::RenderIntent) override; hal::Error setColorTransform(const android::mat4& matrix) override; hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>&, diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 10df216b02..6b67865bdb 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -485,12 +485,12 @@ void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target, - ui::Dataspace dataspace) { + ui::Dataspace dataspace, float hdrSdrRatio) { RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str()); auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; - auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace); + auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace, hdrSdrRatio); RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); return NO_ERROR; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 5846c07f87..af62731a41 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -151,7 +151,8 @@ public: std::optional<DeviceRequestedChanges>* outChanges) = 0; virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, - const sp<GraphicBuffer>& target, ui::Dataspace) = 0; + const sp<GraphicBuffer>& target, ui::Dataspace, + float hdrSdrRatio) = 0; // Present layers to the display and read releaseFences. virtual status_t presentAndGetReleaseFences( @@ -352,7 +353,8 @@ public: std::optional<DeviceRequestedChanges>* outChanges) override; status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, - const sp<GraphicBuffer>& target, ui::Dataspace) override; + const sp<GraphicBuffer>& target, ui::Dataspace, + float hdrSdrRatio) override; // Present layers to the display and read releaseFences. status_t presentAndGetReleaseFences( diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp index ed52b9583c..5f1d5f8164 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp @@ -608,7 +608,8 @@ Error HidlComposer::setActiveConfig(Display display, Config config) { Error HidlComposer::setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, - const std::vector<IComposerClient::Rect>& damage) { + const std::vector<IComposerClient::Rect>& damage, + float /*hdrSdrRatio*/) { mWriter.selectDisplay(display); const native_handle_t* handle = nullptr; diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h index 5c19b47b00..c768d2758d 100644 --- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h @@ -226,7 +226,8 @@ public: */ Error setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, - const std::vector<IComposerClient::Rect>& damage) override; + const std::vector<IComposerClient::Rect>& damage, + float hdrSdrRatio) override; Error setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) override; Error setColorTransform(Display display, const float* matrix) override; Error setOutputBuffer(Display display, const native_handle_t* buffer, diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index d62075ec65..4b5a68cefa 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -175,7 +175,7 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { return NO_ERROR; } -status_t VirtualDisplaySurface::advanceFrame() { +status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) { if (GpuVirtualDisplayId::tryCast(mDisplayId)) { return NO_ERROR; } @@ -223,7 +223,7 @@ status_t VirtualDisplaySurface::advanceFrame() { } // TODO: Correctly propagate the dataspace from GL composition result = mHwc.setClientTarget(*halDisplayId, mFbProducerSlot, mFbFence, hwcBuffer, - ui::Dataspace::UNKNOWN); + ui::Dataspace::UNKNOWN, hdrSdrRatio); } return result; diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index be06e2bb10..90426f729a 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -84,7 +84,7 @@ public: // virtual status_t beginFrame(bool mustRecompose); virtual status_t prepareFrame(CompositionType); - virtual status_t advanceFrame(); + virtual status_t advanceFrame(float hdrSdrRatio); virtual void onFrameCommitted(); virtual void dumpAsString(String8& result) const; virtual void resizeBuffers(const ui::Size&) override; diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index a4a5ce2b46..dd03366bcc 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -75,10 +75,10 @@ void ScreenCaptureOutput::updateColorProfile(const compositionengine::Compositio outputState.renderIntent = mColorProfile.renderIntent; } -renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisplaySettings() - const { +renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisplaySettings( + const std::shared_ptr<renderengine::ExternalTexture>& buffer) const { auto clientCompositionDisplay = - compositionengine::impl::Output::generateClientCompositionDisplaySettings(); + compositionengine::impl::Output::generateClientCompositionDisplaySettings(buffer); clientCompositionDisplay.clip = mRenderArea.getSourceCrop(); auto renderIntent = static_cast<ui::RenderIntent>(clientCompositionDisplay.renderIntent); diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h index 1c16308e15..069f458bdb 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -59,7 +59,8 @@ public: protected: bool getSkipColorTransform() const override { return false; } - renderengine::DisplaySettings generateClientCompositionDisplaySettings() const override; + renderengine::DisplaySettings generateClientCompositionDisplaySettings( + const std::shared_ptr<renderengine::ExternalTexture>& buffer) const override; private: const RenderArea& mRenderArea; diff --git a/services/surfaceflinger/ScreenCaptureRenderSurface.h b/services/surfaceflinger/ScreenCaptureRenderSurface.h index 20973003d5..50ba9bff3f 100644 --- a/services/surfaceflinger/ScreenCaptureRenderSurface.h +++ b/services/surfaceflinger/ScreenCaptureRenderSurface.h @@ -37,7 +37,7 @@ public: return mBuffer; } - void queueBuffer(base::unique_fd readyFence) override { + void queueBuffer(base::unique_fd readyFence, float) override { mRenderFence = sp<Fence>::make(readyFence.release()); } diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index 2d7482862a..adb497462d 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -125,6 +125,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved); DUMP_READ_ONLY_FLAG(enable_fro_dependent_features); DUMP_READ_ONLY_FLAG(display_protected); + DUMP_READ_ONLY_FLAG(fp16_client_target); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG @@ -199,6 +200,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved, "debug.sf.cache_source_crop_only_moved") FLAG_MANAGER_READ_ONLY_FLAG(enable_fro_dependent_features, "") FLAG_MANAGER_READ_ONLY_FLAG(display_protected, "") +FLAG_MANAGER_READ_ONLY_FLAG(fp16_client_target, "debug.sf.fp16_client_target") /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "") diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index e0f620465c..cdab461a58 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -64,6 +64,7 @@ public: bool cache_if_source_crop_layer_only_moved() const; bool enable_fro_dependent_features() const; bool display_protected() const; + bool fp16_client_target() const; protected: // overridden for unit tests diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp index afb5f5c630..68237c8dd6 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp +++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp @@ -286,7 +286,7 @@ void DisplayHardwareFuzzer::invokeAidlComposer() { composer.setClientTarget(display, mFdp.ConsumeIntegral<uint32_t>(), sp<GraphicBuffer>(), mFdp.ConsumeIntegral<int32_t>(), mFdp.PickValueInArray(kDataspaces), - {}); + {}, mFdp.ConsumeFloatingPoint<float>()); composer.setColorMode(display, mFdp.PickValueInArray(kColormodes), mFdp.PickValueInArray(kRenderIntents)); @@ -494,7 +494,7 @@ void DisplayHardwareFuzzer::invokeFrameBufferSurface() { surface->beginFrame(mFdp.ConsumeBool()); surface->prepareFrame(mFdp.PickValueInArray(kCompositionTypes)); - surface->advanceFrame(); + surface->advanceFrame(mFdp.ConsumeFloatingPoint<float>()); surface->onFrameCommitted(); String8 result = String8(mFdp.ConsumeRandomLengthString().c_str()); surface->dumpAsString(result); @@ -530,7 +530,7 @@ void DisplayHardwareFuzzer::invokeVirtualDisplaySurface() { surface->prepareFrame(mFdp.PickValueInArray(kCompositionTypes)); surface->resizeBuffers(getFuzzedSize()); surface->getClientTargetAcquireFence(); - surface->advanceFrame(); + surface->advanceFrame(mFdp.ConsumeFloatingPoint<float>()); surface->onFrameCommitted(); String8 result = String8(mFdp.ConsumeRandomLengthString().c_str()); surface->dumpAsString(result); @@ -561,7 +561,8 @@ void DisplayHardwareFuzzer::invokeComposer() { getDeviceCompositionChanges(halDisplayID); mHwc.setClientTarget(halDisplayID, mFdp.ConsumeIntegral<uint32_t>(), Fence::NO_FENCE, - sp<GraphicBuffer>::make(), mFdp.PickValueInArray(kDataspaces)); + sp<GraphicBuffer>::make(), mFdp.PickValueInArray(kDataspaces), + mFdp.ConsumeFloatingPoint<float>()); mHwc.presentAndGetReleaseFences(halDisplayID, std::chrono::steady_clock::now()); diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig index 620ac26cfd..fabd73846e 100644 --- a/services/surfaceflinger/surfaceflinger_flags.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags.aconfig @@ -90,7 +90,6 @@ flag { namespace: "core_graphics" description: "Whether to use the closest known refresh rate to determine the fps consistency." bug: "299201319" - is_fixed_read_only: true } flag { @@ -115,3 +114,11 @@ flag { bug: "301647974" is_fixed_read_only: true } + +flag { + name: "fp16_client_target" + namespace: "core_graphics" + description: "Controls whether we render to fp16 client targets" + bug: "236745178" + is_fixed_read_only: true +} diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 0b9a0309be..beb2147c98 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -315,7 +315,7 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mComposer, getReleaseFences(HWC_DISPLAY, _, _)).Times(1); EXPECT_CALL(*test->mDisplaySurface, onFrameCommitted()).Times(1); - EXPECT_CALL(*test->mDisplaySurface, advanceFrame()).Times(1); + EXPECT_CALL(*test->mDisplaySurface, advanceFrame(_)).Times(1); Case::CompositionType::setupHwcSetCallExpectations(test); Case::CompositionType::setupHwcGetCallExpectations(test); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 3b74f0ab4a..d649679ac8 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -86,9 +86,10 @@ public: MOCK_METHOD3(getReleaseFences, Error(Display, std::vector<Layer>*, std::vector<int>*)); MOCK_METHOD2(presentDisplay, Error(Display, int*)); MOCK_METHOD2(setActiveConfig, Error(Display, Config)); - MOCK_METHOD6(setClientTarget, - Error(Display, uint32_t, const sp<GraphicBuffer>&, int, Dataspace, - const std::vector<IComposerClient::Rect>&)); + MOCK_METHOD(Error, setClientTarget, + (Display, uint32_t, const sp<GraphicBuffer>&, int, Dataspace, + const std::vector<IComposerClient::Rect>&, float), + (override)); MOCK_METHOD3(setColorMode, Error(Display, ColorMode, RenderIntent)); MOCK_METHOD2(setColorTransform, Error(Display, const float*)); MOCK_METHOD3(setOutputBuffer, Error(Display, const native_handle_t*, int)); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h index a7ddb6df58..7413235c19 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h @@ -66,8 +66,8 @@ public: ((std::unordered_map<Layer *, android::sp<android::Fence>> *)), (const, override)); MOCK_METHOD(hal::Error, present, (android::sp<android::Fence> *), (override)); MOCK_METHOD(hal::Error, setClientTarget, - (uint32_t, const android::sp<android::GraphicBuffer> &, - const android::sp<android::Fence> &, hal::Dataspace), + (uint32_t, const android::sp<android::GraphicBuffer>&, + const android::sp<android::Fence>&, hal::Dataspace, float), (override)); MOCK_METHOD(hal::Error, setColorMode, (hal::ColorMode, hal::RenderIntent), (override)); MOCK_METHOD(hal::Error, setColorTransform, (const android::mat4 &), (override)); |