summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2023-09-06 02:10:05 +0000
committer Alec Mouri <alecmouri@google.com> 2023-12-06 00:16:02 +0000
commitf97df4d8a6e4ef1364244b0e9adefc08c3f95c06 (patch)
treebd5a54efeda611d597c67dca073abe995b928feb
parentd6a6f38c2449d059e9ba2f90668b95145f6237b8 (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
-rw-r--r--services/surfaceflinger/CompositionEngine/Android.bp24
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h4
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/DisplaySurface.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp35
-rw-r--r--services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp4
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp8
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h7
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp140
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp20
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp5
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.h2
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.cpp9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h5
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h6
-rw-r--r--services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp3
-rw-r--r--services/surfaceflinger/DisplayHardware/HidlComposerHal.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h2
-rw-r--r--services/surfaceflinger/ScreenCaptureOutput.cpp6
-rw-r--r--services/surfaceflinger/ScreenCaptureOutput.h3
-rw-r--r--services/surfaceflinger/ScreenCaptureRenderSurface.h2
-rw-r--r--services/surfaceflinger/common/FlagManager.cpp2
-rw-r--r--services/surfaceflinger/common/include/common/FlagManager.h1
-rw-r--r--services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp9
-rw-r--r--services/surfaceflinger/surfaceflinger_flags.aconfig9
-rw-r--r--services/surfaceflinger/tests/unittests/CompositionTest.cpp2
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h7
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h4
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));