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/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 200bb65..29e5a74 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -1005,12 +1005,19 @@
}
Error AidlComposer::getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) {
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
+ float* whitePointNits) {
ClientTargetProperty property;
- mReader.takeClientTargetProperty(translate<int64_t>(display), &property);
+ mReader.takeClientTargetProperty(translate<int64_t>(display), &property, whitePointNits);
*outClientTargetProperty = translate<IComposerClient::ClientTargetProperty>(property);
return Error::NONE;
}
+Error AidlComposer::setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) {
+ mWriter.setLayerWhitePointNits(translate<int64_t>(display), translate<int64_t>(layer),
+ whitePointNits);
+ return Error::NONE;
+}
+
} // namespace Hwc2
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 418a8cc..8cae25f 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -194,9 +194,10 @@
bool mandatory, const std::vector<uint8_t>& value) override;
V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override;
- Error getClientTargetProperty(
- Display display,
- IComposerClient::ClientTargetProperty* outClientTargetProperty) override;
+ Error getClientTargetProperty(Display display,
+ IComposerClient::ClientTargetProperty* outClientTargetProperty,
+ float* outClientTargetWhitePointNits) override;
+ Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
private:
// Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 3bbce7b..3cc5e5e 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -221,7 +221,11 @@
virtual V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0;
virtual Error getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) = 0;
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) = 0;
+
+ // AIDL Composer
+ virtual Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) = 0;
};
} // namespace android::Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index e21b0da..596666c 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -555,8 +555,10 @@
return static_cast<Error>(intError);
}
-Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProperty) {
- const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty);
+Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) {
+ const auto error =
+ mComposer.getClientTargetProperty(mId, outClientTargetProperty, outWhitePointNits);
return static_cast<Error>(error);
}
@@ -919,6 +921,16 @@
return static_cast<Error>(intError);
}
+// AIDL HAL
+Error Layer::setWhitePointNits(float whitePointNits) {
+ if (CC_UNLIKELY(!mDisplay)) {
+ return Error::BAD_DISPLAY;
+ }
+
+ auto intError = mComposer.setLayerWhitePointNits(mDisplay->getId(), mId, whitePointNits);
+ return static_cast<Error>(intError);
+}
+
} // namespace impl
} // namespace HWC2
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index a65efb2..5e0ba06 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -146,7 +146,7 @@
std::vector<hal::ContentType>*) const = 0;
[[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
[[clang::warn_unused_result]] virtual hal::Error getClientTargetProperty(
- hal::ClientTargetProperty* outClientTargetProperty) = 0;
+ hal::ClientTargetProperty* outClientTargetProperty, float* outWhitePointNits) = 0;
};
namespace impl {
@@ -209,7 +209,8 @@
hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>* outSupportedContentTypes) const override;
hal::Error setContentType(hal::ContentType) override;
- hal::Error getClientTargetProperty(hal::ClientTargetProperty* outClientTargetProperty) override;
+ hal::Error getClientTargetProperty(hal::ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) override;
// Other Display methods
hal::HWDisplayId getId() const override { return mId; }
@@ -288,6 +289,9 @@
// Composer HAL 2.4
[[clang::warn_unused_result]] virtual hal::Error setLayerGenericMetadata(
const std::string& name, bool mandatory, const std::vector<uint8_t>& value) = 0;
+
+ // AIDL HAL
+ [[clang::warn_unused_result]] virtual hal::Error setWhitePointNits(float whitePointNits) = 0;
};
namespace impl {
@@ -331,6 +335,9 @@
hal::Error setLayerGenericMetadata(const std::string& name, bool mandatory,
const std::vector<uint8_t>& value) override;
+ // AIDL HAL
+ hal::Error setWhitePointNits(float whitePointNits) override;
+
private:
// These are references to data owned by HWC2::Device, which will outlive
// this HWC2::Layer, so these references are guaranteed to be valid for
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 06f5df5..d851e22 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -522,11 +522,13 @@
RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
- error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
+ float clientTargetWhitePointNits;
+ error = hwcDisplay->getClientTargetProperty(&clientTargetProperty, &clientTargetWhitePointNits);
outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
std::move(layerRequests),
- std::move(clientTargetProperty)});
+ std::move(clientTargetProperty),
+ clientTargetWhitePointNits});
error = hwcDisplay->acceptChanges();
RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 0a090da..bd79977 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -79,6 +79,7 @@
DisplayRequests displayRequests;
LayerRequests layerRequests;
ClientTargetProperty clientTargetProperty;
+ float clientTargetWhitePointNits;
};
struct HWCDisplayMode {
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 6c40598..11d41c0 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -1164,8 +1164,14 @@
}
Error HidlComposer::getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) {
+ Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) {
mReader.takeClientTargetProperty(display, outClientTargetProperty);
+ *outWhitePointNits = -1.f;
+ return Error::NONE;
+}
+
+Error HidlComposer::setLayerWhitePointNits(Display, Layer, float) {
return Error::NONE;
}
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index ad253a2..18c0635 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -304,9 +304,10 @@
bool mandatory, const std::vector<uint8_t>& value) override;
V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override;
- Error getClientTargetProperty(
- Display display,
- IComposerClient::ClientTargetProperty* outClientTargetProperty) override;
+ Error getClientTargetProperty(Display display,
+ IComposerClient::ClientTargetProperty* outClientTargetProperty,
+ float* outWhitePointNits) override;
+ Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
private:
class CommandWriter : public CommandWriterBase {