Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8face53a authored by Alec Mouri's avatar Alec Mouri
Browse files

Limit HLG to 4.926x SDR

HLG is universally too bright on basically every single platform that
supports HDR. Fix this for Android.

Bug: 362510107
Flag: com.android.graphics.surfaceflinger.flags.begone_bright_hlg
Test: HLG playback
Change-Id: I5d464c016be62b11f6a3cc1ab228e14d198afb15
parent 4fabc011
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -61,4 +61,24 @@ inline HdrRenderType getHdrRenderType(ui::Dataspace dataspace,
    return HdrRenderType::SDR;
}

/**
 * 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
+15 −3
Original line number Diff line number Diff line
@@ -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
+9 −1
Original line number Diff line number Diff line
@@ -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 =
+2 −0
Original line number Diff line number Diff line
@@ -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, "")
+1 −0
Original line number Diff line number Diff line
@@ -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
Loading