Make sdr white point do a thing
Bug: 182312559
Test: SilkFX prototype changes
Change-Id: Ieca0e4c8e2229d14aac460945702d23759d208e9
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 4c73b6e..cacad52 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -58,8 +58,7 @@
namespace android {
-static constexpr float defaultMaxMasteringLuminance = 1000.0;
-static constexpr float defaultMaxContentLuminance = 1000.0;
+static constexpr float defaultMaxLuminance = 1000.0;
BufferLayer::BufferLayer(const LayerCreationArgs& args)
: Layer(args),
@@ -206,12 +205,24 @@
layer.source.buffer.isY410BT2020 = isHdrY410();
bool hasSmpte2086 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::SMPTE2086;
bool hasCta861_3 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::CTA861_3;
- layer.source.buffer.maxMasteringLuminance = hasSmpte2086
- ? mBufferInfo.mHdrMetadata.smpte2086.maxLuminance
- : defaultMaxMasteringLuminance;
- layer.source.buffer.maxContentLuminance = hasCta861_3
- ? mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel
- : defaultMaxContentLuminance;
+ float maxLuminance = 0.f;
+ if (hasSmpte2086 && hasCta861_3) {
+ maxLuminance = std::min(mBufferInfo.mHdrMetadata.smpte2086.maxLuminance,
+ mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel);
+ } else if (hasSmpte2086) {
+ maxLuminance = mBufferInfo.mHdrMetadata.smpte2086.maxLuminance;
+ } else if (hasCta861_3) {
+ maxLuminance = mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel;
+ } else {
+ switch (layer.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) {
+ case HAL_DATASPACE_TRANSFER_ST2084:
+ case HAL_DATASPACE_TRANSFER_HLG:
+ // Behavior-match previous releases for HDR content
+ maxLuminance = defaultMaxLuminance;
+ break;
+ }
+ }
+ layer.source.buffer.maxLuminanceNits = maxLuminance;
layer.frameNumber = mCurrentFrameNumber;
layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()->getId() : 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 4976213..af58245 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -181,6 +181,9 @@
// Sets the output color mode
virtual void setColorProfile(const ColorProfile&) = 0;
+ // Sets current calibrated display brightness information
+ virtual void setDisplayBrightness(float sdrWhitePointNits, float displayBrightnessNits) = 0;
+
// Outputs a string with a state dump
virtual void dump(std::string&) const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index eeb20fc..07eaaef 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -51,6 +51,7 @@
void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
void setColorProfile(const ColorProfile&) override;
+ void setDisplayBrightness(float sdrWhitePointNits, float displayBrightnessNits) override;
void dump(std::string&) const override;
void dumpPlannerInfo(const Vector<String16>& args, std::string&) const override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index f0ef6d6..d41c2dd 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -118,6 +118,12 @@
// The earliest time to send the present command to the HAL
std::chrono::steady_clock::time_point earliestPresentTime;
+ // Current display brightness
+ float displayBrightnessNits{-1.f};
+
+ // SDR white point
+ float sdrWhitePointNits{-1.f};
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 5aa53e5..49d93ca 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -43,6 +43,7 @@
MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
+ MOCK_METHOD2(setDisplayBrightness, void(float, float));
MOCK_CONST_METHOD1(dump, void(std::string&));
MOCK_CONST_METHOD2(dumpPlannerInfo, void(const Vector<String16>&, std::string&));
diff --git a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
index 2d9f01b..27b0c80 100644
--- a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
@@ -45,8 +45,7 @@
lhs.textureTransform == rhs.textureTransform &&
lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha &&
lhs.isOpaque == rhs.isOpaque && lhs.isY410BT2020 == rhs.isY410BT2020 &&
- lhs.maxMasteringLuminance == rhs.maxMasteringLuminance &&
- lhs.maxContentLuminance == rhs.maxContentLuminance;
+ lhs.maxLuminanceNits == rhs.maxLuminanceNits;
}
inline bool equalIgnoringBuffer(const renderengine::LayerSettings& lhs,
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index c809e1a..6c2f9c5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -256,6 +256,18 @@
dirtyEntireOutput();
}
+void Output::setDisplayBrightness(float sdrWhitePointNits, float displayBrightnessNits) {
+ auto& outputState = editState();
+ if (outputState.sdrWhitePointNits == sdrWhitePointNits &&
+ outputState.displayBrightnessNits == displayBrightnessNits) {
+ // Nothing changed
+ return;
+ }
+ outputState.sdrWhitePointNits = sdrWhitePointNits;
+ outputState.displayBrightnessNits = displayBrightnessNits;
+ dirtyEntireOutput();
+}
+
void Output::dump(std::string& out) const {
using android::base::StringAppendF;
@@ -1032,8 +1044,13 @@
clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
? outputState.dataspace
: ui::Dataspace::UNKNOWN;
- clientCompositionDisplay.maxLuminance =
- mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
+
+ // If we have a valid current display brightness use that, otherwise fall back to the
+ // display's max desired
+ clientCompositionDisplay.maxLuminance = outputState.displayBrightnessNits > 0.f
+ ? outputState.displayBrightnessNits
+ : mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
+ clientCompositionDisplay.sdrWhitePointNits = outputState.sdrWhitePointNits;
// Compute the global color transform matrix.
if (!outputState.usesDeviceComposition && !getSkipColorTransform()) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2dace92..6f830aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -306,6 +306,7 @@
Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
bool SurfaceFlinger::useFrameRateApi;
+bool SurfaceFlinger::enableSdrDimming;
std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
switch(displayColorSetting) {
@@ -471,6 +472,9 @@
base::SetProperty(KERNEL_IDLE_TIMER_PROP, mKernelIdleTimerEnabled ? "true" : "false");
mRefreshRateOverlaySpinner = property_get_bool("sf.debug.show_refresh_rate_overlay_spinner", 0);
+
+ // Debug property overrides ro. property
+ enableSdrDimming = property_get_bool("debug.sf.enable_sdr_dimming", enable_sdr_dimming(false));
}
SurfaceFlinger::~SurfaceFlinger() = default;
@@ -1480,8 +1484,13 @@
}
return ftl::chain(schedule([=]() MAIN_THREAD {
- if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
- return getHwComposer().setDisplayBrightness(*displayId,
+ if (const auto display = getDisplayDeviceLocked(displayToken)) {
+ if (enableSdrDimming) {
+ display->getCompositionDisplay()
+ ->setDisplayBrightness(brightness.sdrWhitePointNits,
+ brightness.displayBrightnessNits);
+ }
+ return getHwComposer().setDisplayBrightness(display->getPhysicalId(),
brightness.displayBrightness);
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index cf1a545..8523b1a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -271,6 +271,10 @@
static constexpr SkipInitializationTag SkipInitialization;
+ // Whether or not SDR layers should be dimmed to the desired SDR white point instead of
+ // being treated as native display brightness
+ static bool enableSdrDimming;
+
// must be called before clients can connect
void init() ANDROID_API;
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index b3dca78..4a69c8f 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -321,6 +321,10 @@
return defaultValue;
}
+bool enable_sdr_dimming(bool defaultValue) {
+ return SurfaceFlingerProperties::enable_sdr_dimming().value_or(defaultValue);
+}
+
int32_t display_update_imminent_timeout_ms(int32_t defaultValue) {
auto temp = SurfaceFlingerProperties::display_update_imminent_timeout_ms();
if (temp.has_value()) {
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h
index b19d216..039d316 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.h
+++ b/services/surfaceflinger/SurfaceFlingerProperties.h
@@ -102,6 +102,8 @@
bool enable_layer_caching(bool defaultValue);
+bool enable_sdr_dimming(bool defaultValue);
+
} // namespace sysprop
} // namespace android
#endif // SURFACEFLINGERPROPERTIES_H_
diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
index ee5542d..78f8a2f 100644
--- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
+++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
@@ -463,3 +463,12 @@
access: Readonly
prop_name: "ro.surface_flinger.enable_layer_caching"
}
+
+# Enables SDR layer dimming
+prop {
+ api_name: "enable_sdr_dimming"
+ type: Boolean
+ scope: Public
+ access: Readonly
+ prop_name: "ro.surface_flinger.enable_sdr_dimming"
+}
\ No newline at end of file
diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
index 47e14f6..9c567d6 100644
--- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
+++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
@@ -53,6 +53,10 @@
prop_name: "ro.surface_flinger.protected_contents"
}
prop {
+ api_name: "enable_sdr_dimming"
+ prop_name: "ro.surface_flinger.enable_sdr_dimming"
+ }
+ prop {
api_name: "force_hwc_copy_for_virtual_displays"
prop_name: "ro.surface_flinger.force_hwc_copy_for_virtual_displays"
}