summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2021-12-10 13:16:06 -0800
committer Alec Mouri <alecmouri@google.com> 2022-01-05 17:22:49 -0800
commitcdf1679ca691ba0afe3c3f94fa7ab14db67ba4ac (patch)
treea5cc3e06d1af2cfdaa05fc82941cea57b8b41187 /services/surfaceflinger/SurfaceFlinger.cpp
parent7ee3882228a741ec4194f0b0682a2e01de502db8 (diff)
Synchronize brightness change with frame update for hdr layers.
When the brightness changes while hdr layers are on screen, the dimming ratio may also change based on ambient conditions, so HWC must recomposite the scene with the new brightness value. Bug: 210151839 Test: builds, boots Change-Id: I4741b28d13f4528a7b5c9045bec7a5823e802935
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp67
1 files changed, 64 insertions, 3 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 89f3bd6fbb..58f2ab6049 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1669,6 +1669,17 @@ status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayT
return NO_ERROR;
}
+bool SurfaceFlinger::hasVisibleHdrLayer(const sp<DisplayDevice>& display) {
+ bool hasHdrLayers = false;
+ mDrawingState.traverse([&,
+ compositionDisplay = display->getCompositionDisplay()](Layer* layer) {
+ hasHdrLayers |= (layer->isVisible() &&
+ compositionDisplay->includesLayer(layer->getCompositionEngineLayerFE()) &&
+ isHdrDataspace(layer->getDataSpace()));
+ });
+ return hasHdrLayers;
+}
+
status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
const gui::DisplayBrightness& brightness) {
if (!displayToken) {
@@ -1678,13 +1689,33 @@ status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
const char* const whence = __func__;
return ftl::chain(mScheduler->schedule([=]() MAIN_THREAD {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
- if (enableSdrDimming) {
+ const bool supportsDisplayBrightnessCommand =
+ getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
+ // If we support applying display brightness as a command, then we also support
+ // dimming SDR layers.
+ // TODO(b/212634488): Once AIDL composer implementations are finalized, remove
+ // the enableSdrDimming check, as dimming support will be expected for AIDL
+ // composer.
+ if (enableSdrDimming && supportsDisplayBrightnessCommand) {
display->getCompositionDisplay()
->setDisplayBrightness(brightness.sdrWhitePointNits,
brightness.displayBrightnessNits);
+ MAIN_THREAD_GUARD(display->stageBrightness(brightness.displayBrightness));
+ if (hasVisibleHdrLayer(display)) {
+ scheduleComposite(FrameHint::kNone);
+ } else {
+ scheduleCommit(FrameHint::kNone);
+ }
+ return ftl::yield<status_t>(OK);
+ } else {
+ return getHwComposer().setDisplayBrightness(
+ display->getPhysicalId(), brightness.displayBrightness,
+ Hwc2::Composer::DisplayBrightnessOptions{.applyImmediately = true,
+ .sdrDimmingEnabled =
+ enableSdrDimming});
}
- return getHwComposer().setDisplayBrightness(display->getPhysicalId(),
- brightness.displayBrightness);
+
} else {
ALOGE("%s: Invalid display token %p", whence, displayToken.get());
return ftl::yield<status_t>(NAME_NOT_FOUND);
@@ -2069,6 +2100,8 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
updateCursorAsync();
updateInputFlinger();
+ MAIN_THREAD_GUARD(persistDisplayBrightness(mustComposite));
+
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}
@@ -3101,6 +3134,34 @@ void SurfaceFlinger::updateInputFlinger() {
mInputWindowCommands.clear();
}
+void SurfaceFlinger::persistDisplayBrightness(bool needsComposite) {
+ const bool supportsDisplayBrightnessCommand = getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::DisplayBrightnessCommand);
+ if (!supportsDisplayBrightnessCommand) {
+ return;
+ }
+
+ const auto& displays = ON_MAIN_THREAD(mDisplays);
+
+ for (const auto& [_, display] : displays) {
+ if (const auto brightness = display->getStagedBrightness(); brightness) {
+ if (!needsComposite) {
+ const status_t error =
+ getHwComposer()
+ .setDisplayBrightness(display->getPhysicalId(), *brightness,
+ Hwc2::Composer::DisplayBrightnessOptions{
+ .applyImmediately = true})
+ .get();
+
+ ALOGE_IF(error != NO_ERROR,
+ "Error setting display brightness for display %s: %d (%s)",
+ display->getDebugName().c_str(), error, strerror(error));
+ }
+ display->persistBrightness(needsComposite);
+ }
+ }
+}
+
void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
std::vector<DisplayInfo>& outDisplayInfos) {
std::unordered_map<uint32_t /*layerStackId*/,