diff options
6 files changed, 56 insertions, 5 deletions
diff --git a/libs/ui/include_types/ui/HdrRenderTypeUtils.h b/libs/ui/include_types/ui/HdrRenderTypeUtils.h index b0af878cdb..70c50f07e5 100644 --- a/libs/ui/include_types/ui/HdrRenderTypeUtils.h +++ b/libs/ui/include_types/ui/HdrRenderTypeUtils.h @@ -61,4 +61,24 @@ inline HdrRenderType getHdrRenderType(ui::Dataspace dataspace, return HdrRenderType::SDR; } -} // namespace android
\ No newline at end of file +/** + * Returns the maximum headroom allowed for this content under "idealized" + * display conditions (low surround luminance, high-enough display brightness). + * + * TODO: take into account hdr metadata, but square it with the fact that some + * HLG content has CTA.861-3 metadata + */ +inline float getIdealizedMaxHeadroom(ui::Dataspace dataspace) { + const auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK; + + switch (transfer) { + case HAL_DATASPACE_TRANSFER_ST2084: + return 10000.0f / 203.0f; + case HAL_DATASPACE_TRANSFER_HLG: + return 1000.0f / 203.0f; + default: + return 1.0f; + } +} + +} // namespace android diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index f6d9a1ae6c..bb01946b2c 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -26,6 +26,7 @@ #include <ui/FloatRect.h> #include <ui/HdrRenderTypeUtils.h> #include <cstdint> +#include <limits> #include "system/graphics-base-v1.0.h" #include <com_android_graphics_libgui_flags.h> @@ -398,11 +399,22 @@ void OutputLayer::updateCompositionState( // For hdr content, treat the white point as the display brightness - HDR content should not be // boosted or dimmed. // If the layer explicitly requests to disable dimming, then don't dim either. - if (hdrRenderType == HdrRenderType::GENERIC_HDR || - getOutput().getState().displayBrightnessNits == getOutput().getState().sdrWhitePointNits || - getOutput().getState().displayBrightnessNits == 0.f || !layerFEState->dimmingEnabled) { + if (getOutput().getState().displayBrightnessNits == getOutput().getState().sdrWhitePointNits || + getOutput().getState().displayBrightnessNits <= 0.f || !layerFEState->dimmingEnabled) { state.dimmingRatio = 1.f; state.whitePointNits = getOutput().getState().displayBrightnessNits; + } else if (hdrRenderType == HdrRenderType::GENERIC_HDR) { + float deviceHeadroom = getOutput().getState().displayBrightnessNits / + getOutput().getState().sdrWhitePointNits; + float idealizedMaxHeadroom = deviceHeadroom; + + if (FlagManager::getInstance().begone_bright_hlg()) { + idealizedMaxHeadroom = + std::min(idealizedMaxHeadroom, getIdealizedMaxHeadroom(state.dataspace)); + } + + state.dimmingRatio = std::min(idealizedMaxHeadroom / deviceHeadroom, 1.0f); + state.whitePointNits = getOutput().getState().displayBrightnessNits * state.dimmingRatio; } else { float layerBrightnessNits = getOutput().getState().sdrWhitePointNits; // RANGE_EXTENDED can "self-promote" to HDR, but is still rendered for a particular diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 37b35f2f63..6499001561 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3201,7 +3201,15 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, snapshot.desiredHdrSdrRatio < 1.f ? std::numeric_limits<float>::infinity() : snapshot.desiredHdrSdrRatio; - info.mergeDesiredRatio(desiredHdrSdrRatio); + + float desiredRatio = desiredHdrSdrRatio; + if (FlagManager::getInstance().begone_bright_hlg() && + desiredHdrSdrRatio == + std::numeric_limits<float>::infinity()) { + desiredRatio = getIdealizedMaxHeadroom(snapshot.dataspace); + } + + info.mergeDesiredRatio(desiredRatio); info.numberOfHdrLayers++; const auto displayFrame = outputLayer->getState().displayFrame; const int32_t area = diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp index b56ee01422..a1b53ee738 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -160,6 +160,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(connected_display_hdr); DUMP_READ_ONLY_FLAG(deprecate_frame_tracker); DUMP_READ_ONLY_FLAG(skip_invisible_windows_in_input); + DUMP_READ_ONLY_FLAG(begone_bright_hlg); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG @@ -268,6 +269,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(display_config_error_hal, ""); FLAG_MANAGER_READ_ONLY_FLAG(connected_display_hdr, ""); FLAG_MANAGER_READ_ONLY_FLAG(deprecate_frame_tracker, ""); FLAG_MANAGER_READ_ONLY_FLAG(skip_invisible_windows_in_input, ""); +FLAG_MANAGER_READ_ONLY_FLAG(begone_bright_hlg, "debug.sf.begone_bright_hlg"); /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(refresh_rate_overlay_on_external_display, "") diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h index 9086537619..c1d88cecb2 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -98,6 +98,7 @@ public: bool connected_display_hdr() const; bool deprecate_frame_tracker() const; bool skip_invisible_windows_in_input() const; + bool begone_bright_hlg() const; protected: // overridden for unit tests diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig index d4250bcccc..1188435008 100644 --- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig @@ -35,6 +35,14 @@ flag { } # arr_surfacecontrol_setframerate_api flag { + name: "begone_bright_hlg" + namespace: "core_graphics" + description: "Caps HLG brightness relative to SDR" + bug: "362510107" + is_fixed_read_only: true +} # begone_bright_hlg + +flag { name: "ce_fence_promise" namespace: "window_surfaces" description: "Moves logic for buffer release fences into LayerFE" |