End-to-end plumbing for dimming SDR layers
Model here is:
* HDR luminance is set to the current display brightness
* SDR luminance is set to the current SDR white point reported by
DisplayManager
Ideally we use scene-referred white points instead, so:
* PQ is always 10k nits
* HLG is always 1k nits
* Everything else is 150-200 nits
So relative dimming thresholds are fixed. But right now this is visually
less jarring (otherwise youtube UI will suddenly dim when autoplaying
HDR video).
Bug: 200310158
Test: Verified that plumbing sdr white point is sent to renderengine
Test: librenderengine_test
Test: libcompositionengine_test
Test: DataspaceUtils_test
Change-Id: I5bcea7941935c43e57cd5434e1ec69b41d31f2b4
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index ac243c0..e77e155 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -134,6 +134,9 @@
// Configure layer settings for using blurs
BlurSetting blurSetting;
+
+ // Requested white point of the layer in nits
+ const float whitePointNits;
};
// A superset of LayerSettings required by RenderEngine to compose a layer
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index b407267..3571e11 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -76,7 +76,7 @@
virtual void applyChangedTypesToLayers(const ChangedTypes&);
virtual void applyDisplayRequests(const DisplayRequests&);
virtual void applyLayerRequestsToLayers(const LayerRequests&);
- virtual void applyClientTargetRequests(const ClientTargetProperty&);
+ virtual void applyClientTargetRequests(const ClientTargetProperty&, float whitePointNits);
// Internal
virtual void setConfiguration(const compositionengine::DisplayCreationArgs&);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 44f754f..c5b6443 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -127,6 +127,9 @@
// SDR white point
float sdrWhitePointNits{-1.f};
+ // White point of the client target
+ float clientTargetWhitePointNits{-1.f};
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 7564c54..627b80b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -146,6 +146,10 @@
// Timestamp for when the layer is queued for client composition
nsecs_t clientCompositionTimestamp{0};
+
+ // White point of the layer, in nits.
+ static constexpr float kDefaultWhitePointNits = 200.f;
+ float whitePointNits = kDefaultWhitePointNits;
};
} // namespace compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 02fa49f..4603e6b 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -237,7 +237,8 @@
applyChangedTypesToLayers(changes->changedTypes);
applyDisplayRequests(changes->displayRequests);
applyLayerRequestsToLayers(changes->layerRequests);
- applyClientTargetRequests(changes->clientTargetProperty);
+ applyClientTargetRequests(changes->clientTargetProperty,
+ changes->clientTargetWhitePointNits);
}
// Determine what type of composition we are doing from the final state
@@ -309,12 +310,14 @@
}
}
-void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty) {
+void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty,
+ float whitePointNits) {
if (clientTargetProperty.dataspace == ui::Dataspace::UNKNOWN) {
return;
}
editState().dataspace = clientTargetProperty.dataspace;
+ editState().clientTargetWhitePointNits = whitePointNits;
getRenderSurface()->setBufferDataspace(clientTargetProperty.dataspace);
getRenderSurface()->setBufferPixelFormat(clientTargetProperty.pixelFormat);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 6800004..d503153 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1057,7 +1057,7 @@
clientCompositionDisplay.maxLuminance = outputState.displayBrightnessNits > 0.f
? outputState.displayBrightnessNits
: mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
- clientCompositionDisplay.sdrWhitePointNits = outputState.sdrWhitePointNits;
+ clientCompositionDisplay.targetLuminanceNits = outputState.clientTargetWhitePointNits;
// Compute the global color transform matrix.
if (!outputState.usesDeviceComposition && !getSkipColorTransform()) {
@@ -1217,7 +1217,8 @@
.dataspace = outputDataspace,
.realContentIsVisible = realContentIsVisible,
.clearContent = !clientComposition,
- .blurSetting = blurSetting};
+ .blurSetting = blurSetting,
+ .whitePointNits = layerState.whitePointNits};
results = layerFE.prepareClientCompositionList(targetSettings);
if (realContentIsVisible && !results.empty()) {
layer->editState().clientCompositionTimestamp = systemTime();
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index cf76183..b010d9f 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -24,6 +24,9 @@
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <cstdint>
+#include "system/graphics-base-v1.0.h"
+
+#include <ui/DataspaceUtils.h>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -317,6 +320,14 @@
? outputState.targetDataspace
: layerFEState->dataspace;
+ // For hdr content, treat the white point as the display brightness - HDR content should not be
+ // boosted or dimmed.
+ if (isHdrDataspace(state.dataspace)) {
+ state.whitePointNits = getOutput().getState().displayBrightnessNits;
+ } else {
+ state.whitePointNits = getOutput().getState().sdrWhitePointNits;
+ }
+
// These are evaluated every frame as they can potentially change at any
// time.
if (layerFEState->forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
@@ -479,6 +490,16 @@
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(), dataspace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
+
+ // Don't dim cached layers
+ const auto whitePointNits = outputDependentState.overrideInfo.buffer
+ ? getOutput().getState().displayBrightnessNits
+ : outputDependentState.whitePointNits;
+
+ if (auto error = hwcLayer->setWhitePointNits(whitePointNits); error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set white point %f: %s (%d)", getLayerFE().getDebugName(),
+ whitePointNits, to_string(error).c_str(), static_cast<int32_t>(error));
+ }
}
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index ff96d94..2203f22 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -170,6 +170,7 @@
.clip = viewport,
.outputDataspace = outputDataspace,
.orientation = orientation,
+ .targetLuminanceNits = outputState.displayBrightnessNits,
};
LayerFE::ClientCompositionTargetSettings targetSettings{
@@ -182,6 +183,7 @@
.realContentIsVisible = true,
.clearContent = false,
.blurSetting = LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ .whitePointNits = outputState.displayBrightnessNits,
};
std::vector<renderengine::LayerSettings> layerSettings;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index ed235b8..568efce 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -596,6 +596,7 @@
hal::DisplayRequest::FLIP_CLIENT_TARGET,
{{nullptr, hal::LayerRequest::CLEAR_CLIENT_TARGET}},
{hal::PixelFormat::RGBA_8888, hal::Dataspace::UNKNOWN},
+ -1.f,
};
// Since two calls are made to anyLayersRequireClientComposition with different return
@@ -788,15 +789,18 @@
.dataspace = hal::Dataspace::STANDARD_BT470M,
};
+ static constexpr float kWhitePointNits = 800.f;
+
mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
EXPECT_CALL(*renderSurface, setBufferPixelFormat(clientTargetProperty.pixelFormat));
EXPECT_CALL(*renderSurface, setBufferDataspace(clientTargetProperty.dataspace));
- mDisplay->applyClientTargetRequests(clientTargetProperty);
+ mDisplay->applyClientTargetRequests(clientTargetProperty, kWhitePointNits);
auto& state = mDisplay->getState();
EXPECT_EQ(clientTargetProperty.dataspace, state.dataspace);
+ EXPECT_EQ(kWhitePointNits, state.clientTargetWhitePointNits);
}
/*
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
index 9518659..9e08f9e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
@@ -71,6 +71,7 @@
MOCK_METHOD1(setColorTransform, Error(const android::mat4&));
MOCK_METHOD3(setLayerGenericMetadata,
Error(const std::string&, bool, const std::vector<uint8_t>&));
+ MOCK_METHOD1(setWhitePointNits, Error(float));
};
} // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index fd584fd..207c31e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -652,6 +652,22 @@
EXPECT_EQ(ui::Dataspace::V0_SCRGB, mOutputLayer.getState().dataspace);
}
+TEST_F(OutputLayerUpdateCompositionStateTest, setsWhitePointNitsCorrectly) {
+ mOutputState.sdrWhitePointNits = 200.f;
+ mOutputState.displayBrightnessNits = 800.f;
+
+ mLayerFEState.dataspace = ui::Dataspace::DISPLAY_P3;
+ mLayerFEState.isColorspaceAgnostic = false;
+ mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
+ EXPECT_EQ(mOutputState.sdrWhitePointNits, mOutputLayer.getState().whitePointNits);
+
+ mLayerFEState.dataspace = ui::Dataspace::BT2020_ITU_PQ;
+ mLayerFEState.isColorspaceAgnostic = false;
+ mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
+
+ EXPECT_EQ(mOutputState.displayBrightnessNits, mOutputLayer.getState().whitePointNits);
+}
+
TEST_F(OutputLayerUpdateCompositionStateTest, doesNotRecomputeGeometryIfNotRequested) {
mOutputLayer.editState().forceClientComposition = false;
@@ -728,6 +744,8 @@
static constexpr int kOverrideHwcSlot = impl::HwcBufferCache::FLATTENER_CACHING_SLOT;
static constexpr bool kLayerGenericMetadata1Mandatory = true;
static constexpr bool kLayerGenericMetadata2Mandatory = true;
+ static constexpr float kWhitePointNits = 200.f;
+ static constexpr float kDisplayBrightnessNits = 400.f;
static const half4 kColor;
static const Rect kDisplayFrame;
@@ -758,6 +776,7 @@
outputLayerState.bufferTransform = static_cast<Hwc2::Transform>(kBufferTransform);
outputLayerState.outputSpaceVisibleRegion = kOutputSpaceVisibleRegion;
outputLayerState.dataspace = kDataspace;
+ outputLayerState.whitePointNits = kWhitePointNits;
mLayerFEState.blendMode = kBlendMode;
mLayerFEState.alpha = kAlpha;
@@ -770,6 +789,8 @@
mLayerFEState.bufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
mLayerFEState.acquireFence = kFence;
+ mOutputState.displayBrightnessNits = kDisplayBrightnessNits;
+
EXPECT_CALL(mOutput, getDisplayColorProfile())
.WillRepeatedly(Return(&mDisplayColorProfile));
EXPECT_CALL(mDisplayColorProfile, getSupportedPerFrameMetadata())
@@ -818,9 +839,11 @@
void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None,
ui::Dataspace dataspace = kDataspace,
const Region& visibleRegion = kOutputSpaceVisibleRegion,
- const Region& surfaceDamage = kSurfaceDamage) {
+ const Region& surfaceDamage = kSurfaceDamage,
+ float whitePointNits = kWhitePointNits) {
EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(visibleRegion))).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setDataspace(dataspace)).WillOnce(Return(kError));
+ EXPECT_CALL(*mHwcLayer, setWhitePointNits(whitePointNits)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
.WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
? hal::Error::UNSUPPORTED
@@ -1084,7 +1107,7 @@
expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
kOverrideBlendMode, kSkipAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
- kOverrideSurfaceDamage);
+ kOverrideSurfaceDamage, kDisplayBrightnessNits);
expectSetHdrMetadataAndBufferCalls();
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
@@ -1100,7 +1123,7 @@
expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
kOverrideBlendMode, kSkipAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
- kOverrideSurfaceDamage);
+ kOverrideSurfaceDamage, kDisplayBrightnessNits);
expectSetHdrMetadataAndBufferCalls();
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
@@ -1116,7 +1139,7 @@
expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
kOverrideBlendMode, kOverrideAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
- kOverrideSurfaceDamage);
+ kOverrideSurfaceDamage, kDisplayBrightnessNits);
expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
@@ -1132,7 +1155,7 @@
expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideSourceCrop, kOverrideBufferTransform,
kOverrideBlendMode, kOverrideAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
- kOverrideSurfaceDamage);
+ kOverrideSurfaceDamage, kDisplayBrightnessNits);
expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillRepeatedly(Return(false));
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index cf63ef5..6d96260 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3023,6 +3023,7 @@
mOutput.mState.usesDeviceComposition = false;
mOutput.mState.reusedClientComposition = false;
mOutput.mState.flipClientTarget = false;
+ mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
@@ -3057,6 +3058,7 @@
static constexpr float kDefaultMaxLuminance = 0.9f;
static constexpr float kDefaultAvgLuminance = 0.7f;
static constexpr float kDefaultMinLuminance = 0.1f;
+ static constexpr float kClientTargetLuminanceNits = 200.f;
static const Rect kDefaultOutputFrame;
static const Rect kDefaultOutputViewport;
@@ -3424,7 +3426,8 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags,
+ kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3435,7 +3438,8 @@
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags,
+ kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3444,10 +3448,10 @@
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(true)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
- kDefaultMaxLuminance, kDefaultOutputDataspace,
- kDefaultColorTransformMat,
- kDefaultOutputOrientationFlags})
+ .thenExpectDisplaySettingsUsed(
+ {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
+ kDefaultOutputDataspace, kDefaultColorTransformMat,
+ kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3456,10 +3460,10 @@
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(false)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
- kDefaultMaxLuminance, kDefaultOutputDataspace,
- kDefaultColorTransformMat,
- kDefaultOutputOrientationFlags})
+ .thenExpectDisplaySettingsUsed(
+ {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
+ kDefaultOutputDataspace, kDefaultColorTransformMat,
+ kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3471,7 +3475,8 @@
.andIfSkipColorTransform(true)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
- kDefaultOutputOrientationFlags})
+ kDefaultOutputOrientationFlags,
+ kClientTargetLuminanceNits})
.execute()
.expectAFenceWasReturned();
}
@@ -3729,6 +3734,8 @@
mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
}
+ static constexpr float kLayerWhitePointNits = 200.f;
+
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
StrictMock<OutputPartialMock> mOutput;
@@ -3768,6 +3775,7 @@
static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
+ static constexpr float kLayerWhitePointNits = 200.f;
static const Rect kDisplayFrame;
static const Rect kDisplayViewport;
@@ -3930,14 +3938,15 @@
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
- false, /* needs filtering */
- false, /* secure */
- false, /* supports protected content */
+ false, /* needs filtering */
+ false, /* secure */
+ false, /* supports protected content */
kDisplayViewport,
kDisplayDataspace,
false /* realContentIsVisible */,
true /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -3949,6 +3958,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
@@ -3988,6 +3998,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(Rect(0, 0, 30, 30)),
@@ -3999,6 +4010,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(Rect(0, 0, 40, 201)),
@@ -4010,6 +4022,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
@@ -4039,6 +4052,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4050,6 +4064,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4061,6 +4076,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
@@ -4090,7 +4106,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
-
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4102,6 +4118,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4113,6 +4130,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
@@ -4141,6 +4159,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4152,6 +4171,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4163,6 +4183,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
@@ -4179,7 +4200,6 @@
TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
protectedContentSupportUsedToGenerateRequests) {
-
compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
Region(kDisplayFrame),
false, /* needs filtering */
@@ -4190,6 +4210,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
Region(kDisplayFrame),
@@ -4201,6 +4222,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
Region(kDisplayFrame),
@@ -4212,6 +4234,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
@@ -4379,6 +4402,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
@@ -4396,6 +4420,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
@@ -4428,6 +4453,7 @@
false /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
LayerFE::LayerSettings mShadowSettings;
@@ -4472,6 +4498,7 @@
true /* realContentIsVisible */,
false /* clearContent */,
compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
+ kLayerWhitePointNits,
};
EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index 42b3d97..d5a117a 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -55,13 +55,21 @@
}
MATCHER_P(ClientCompositionTargetSettingsSecureEq, expectedSecureSetting, "") {
- *result_listener << "ClientCompositionTargetSettings' SecureSettings aren't equal \n";
+ *result_listener << "ClientCompositionTargetSettings' isSecure bits aren't equal \n";
*result_listener << "expected " << expectedSecureSetting << "\n";
*result_listener << "actual " << arg.isSecure << "\n";
return expectedSecureSetting == arg.isSecure;
}
+MATCHER_P(ClientCompositionTargetSettingsWhitePointEq, expectedWhitePoint, "") {
+ *result_listener << "ClientCompositionTargetSettings' white points aren't equal \n";
+ *result_listener << "expected " << expectedWhitePoint << "\n";
+ *result_listener << "actual " << arg.whitePointNits << "\n";
+
+ return expectedWhitePoint == arg.whitePointNits;
+}
+
static const ui::Size kOutputSize = ui::Size(1, 1);
class CachedSetTest : public testing::Test {
@@ -431,6 +439,54 @@
cachedSet.append(CachedSet(layer3));
}
+TEST_F(CachedSetTest, renderWhitePoint) {
+ // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
+ CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
+ sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
+ CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
+ sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
+
+ CachedSet cachedSet(layer1);
+ cachedSet.append(CachedSet(layer2));
+
+ std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
+ clientCompList1.push_back({});
+
+ std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
+ clientCompList2.push_back({});
+
+ mOutputState.displayBrightnessNits = 400.f;
+
+ const auto drawLayers =
+ [&](const renderengine::DisplaySettings& displaySettings,
+ const std::vector<renderengine::LayerSettings>&,
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
+ EXPECT_EQ(mOutputState.displayBrightnessNits, displaySettings.targetLuminanceNits);
+ return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
+ };
+
+ EXPECT_CALL(*layerFE1,
+ prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
+ mOutputState.displayBrightnessNits)))
+ .WillOnce(Return(clientCompList1));
+ EXPECT_CALL(*layerFE2,
+ prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
+ mOutputState.displayBrightnessNits)))
+ .WillOnce(Return(clientCompList2));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
+ mOutputState.isSecure = true;
+ cachedSet.render(mRenderEngine, mTexturePool, mOutputState);
+ expectReadyBuffer(cachedSet);
+
+ EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
+ EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());
+
+ // Now check that appending a new cached set properly cleans up RenderEngine resources.
+ CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
+ cachedSet.append(CachedSet(layer3));
+}
+
TEST_F(CachedSetTest, rendersWithOffsetFramebufferContent) {
// Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();