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

Commit 0607fbe8 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: compute color mode mappings on hotplug

Populuate DisplayDevice::mColorModes when a DisplayDevice is
created.

DisplayDevice::mColorModes is a map from any possible
Dataspace/RenderIntent to supported
Dataspace/ColorMode/RenderIntent.  This makes sure we never ask the
composer to use an unsupported Dataspace/ColorMode/RenderIntent
combination.

The map is populated on hotplug because we don't want to compute the
mapping on the fly at each frame.

Bug: 79843697
Bug: 75981986
Test: manual under sRGB, P3, HDR
Change-Id: I967d09b1e8d31ea631b202db1799a7a2a0c5ee3f
Merged-In: I967d09b1e8d31ea631b202db1799a7a2a0c5ee3f
parent 62994a47
Loading
Loading
Loading
Loading
+229 −30
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@
#undef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "DisplayDevice"
#define LOG_TAG "DisplayDevice"


#include <array>
#include <unordered_set>

#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
@@ -55,6 +58,7 @@ namespace android {
using namespace android::hardware::configstore;
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
using namespace android::hardware::configstore::V1_0;
using android::ui::ColorMode;
using android::ui::ColorMode;
using android::ui::Dataspace;
using android::ui::Hdr;
using android::ui::Hdr;
using android::ui::RenderIntent;
using android::ui::RenderIntent;


@@ -65,6 +69,147 @@ using android::ui::RenderIntent;


uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;


namespace {

// ordered list of known SDR color modes
const std::array<ColorMode, 2> sSdrColorModes = {
        ColorMode::DISPLAY_P3,
        ColorMode::SRGB,
};

// ordered list of known HDR color modes
const std::array<ColorMode, 2> sHdrColorModes = {
        ColorMode::BT2100_PQ,
        ColorMode::BT2100_HLG,
};

// ordered list of known SDR render intents
const std::array<RenderIntent, 2> sSdrRenderIntents = {
        RenderIntent::ENHANCE,
        RenderIntent::COLORIMETRIC,
};

// ordered list of known HDR render intents
const std::array<RenderIntent, 2> sHdrRenderIntents = {
        RenderIntent::TONE_MAP_ENHANCE,
        RenderIntent::TONE_MAP_COLORIMETRIC,
};

// map known color mode to dataspace
Dataspace colorModeToDataspace(ColorMode mode) {
    switch (mode) {
        case ColorMode::SRGB:
            return Dataspace::SRGB;
        case ColorMode::DISPLAY_P3:
            return Dataspace::DISPLAY_P3;
        case ColorMode::BT2100_HLG:
            return Dataspace::BT2020_HLG;
        case ColorMode::BT2100_PQ:
            return Dataspace::BT2020_PQ;
        default:
            return Dataspace::UNKNOWN;
    }
}

// Return a list of candidate color modes.
std::vector<ColorMode> getColorModeCandidates(ColorMode mode) {
    std::vector<ColorMode> candidates;

    // add mode itself
    candidates.push_back(mode);

    // check if mode is HDR
    bool isHdr = false;
    for (auto hdrMode : sHdrColorModes) {
        if (hdrMode == mode) {
            isHdr = true;
            break;
        }
    }

    // add other HDR candidates when mode is HDR
    if (isHdr) {
        for (auto hdrMode : sHdrColorModes) {
            if (hdrMode != mode) {
                candidates.push_back(hdrMode);
            }
        }
    }

    // add other SDR candidates
    for (auto sdrMode : sSdrColorModes) {
        if (sdrMode != mode) {
            candidates.push_back(sdrMode);
        }
    }

    return candidates;
}

// Return a list of candidate render intents.
std::vector<RenderIntent> getRenderIntentCandidates(RenderIntent intent) {
    std::vector<RenderIntent> candidates;

    // add intent itself
    candidates.push_back(intent);

    // check if intent is HDR
    bool isHdr = false;
    for (auto hdrIntent : sHdrRenderIntents) {
        if (hdrIntent == intent) {
            isHdr = true;
            break;
        }
    }

    // add other HDR candidates when intent is HDR
    if (isHdr) {
        for (auto hdrIntent : sHdrRenderIntents) {
            if (hdrIntent != intent) {
                candidates.push_back(hdrIntent);
            }
        }
    }

    // add COLORIMETRIC
    if (intent != RenderIntent::COLORIMETRIC) {
        candidates.push_back(RenderIntent::COLORIMETRIC);
    }

    return candidates;
}

// Return the best color mode supported by HWC.
ColorMode getHwcColorMode(
        const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
        ColorMode mode) {
    std::vector<ColorMode> candidates = getColorModeCandidates(mode);
    for (auto candidate : candidates) {
        auto iter = hwcColorModes.find(candidate);
        if (iter != hwcColorModes.end()) {
            return candidate;
        }
    }

    return ColorMode::NATIVE;
}

// Return the best render intent supported by HWC.
RenderIntent getHwcRenderIntent(const std::vector<RenderIntent>& hwcIntents, RenderIntent intent) {
    std::vector<RenderIntent> candidates = getRenderIntentCandidates(intent);
    for (auto candidate : candidates) {
        for (auto hwcIntent : hwcIntents) {
            if (candidate == hwcIntent) {
                return candidate;
            }
        }
    }

    return RenderIntent::COLORIMETRIC;
}

} // anonymous namespace

// clang-format off
// clang-format off
DisplayDevice::DisplayDevice(
DisplayDevice::DisplayDevice(
        const sp<SurfaceFlinger>& flinger,
        const sp<SurfaceFlinger>& flinger,
@@ -80,7 +225,7 @@ DisplayDevice::DisplayDevice(
        bool hasWideColorGamut,
        bool hasWideColorGamut,
        const HdrCapabilities& hdrCapabilities,
        const HdrCapabilities& hdrCapabilities,
        const int32_t supportedPerFrameMetadata,
        const int32_t supportedPerFrameMetadata,
        const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
        const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
        int initialPowerMode)
        int initialPowerMode)
    : lastCompositionHadVisibleLayers(false),
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
      mFlinger(flinger),
@@ -105,13 +250,11 @@ DisplayDevice::DisplayDevice(
      mHasHdr10(false),
      mHasHdr10(false),
      mHasHLG(false),
      mHasHLG(false),
      mHasDolbyVision(false),
      mHasDolbyVision(false),
      mSupportedPerFrameMetadata(supportedPerFrameMetadata),
      mSupportedPerFrameMetadata(supportedPerFrameMetadata)
      mHasBT2100PQColorimetric(false),
      mHasBT2100PQEnhance(false),
      mHasBT2100HLGColorimetric(false),
      mHasBT2100HLGEnhance(false)
{
{
    // clang-format on
    // clang-format on
    populateColorModes(hwcColorModes);

    std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
    std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
    for (Hdr hdrType : types) {
    for (Hdr hdrType : types) {
        switch (hdrType) {
        switch (hdrType) {
@@ -149,18 +292,6 @@ DisplayDevice::DisplayDevice(
    }
    }
    mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
    mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);


    auto iter = hdrAndRenderIntents.find(ColorMode::BT2100_PQ);
    if (iter != hdrAndRenderIntents.end()) {
        hasToneMapping(iter->second,
                       &mHasBT2100PQColorimetric, &mHasBT2100PQEnhance);
    }

    iter = hdrAndRenderIntents.find(ColorMode::BT2100_HLG);
    if (iter != hdrAndRenderIntents.end()) {
        hasToneMapping(iter->second,
                       &mHasBT2100HLGColorimetric, &mHasBT2100HLGEnhance);
    }

    // initialize the display orientation transform.
    // initialize the display orientation transform.
    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
}
@@ -545,19 +676,87 @@ void DisplayDevice::dump(String8& result) const {
    result.append(surfaceDump);
    result.append(surfaceDump);
}
}


void DisplayDevice::hasToneMapping(const std::vector<RenderIntent>& renderIntents,
// Map dataspace/intent to the best matched dataspace/colorMode/renderIntent
                                   bool* outColorimetric, bool *outEnhance) {
// supported by HWC.
    for (auto intent : renderIntents) {
void DisplayDevice::addColorMode(
        switch (intent) {
        const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
            case RenderIntent::TONE_MAP_COLORIMETRIC:
        const ColorMode mode, const RenderIntent intent) {
                *outColorimetric = true;
    // find the best color mode
                break;
    const ColorMode hwcColorMode = getHwcColorMode(hwcColorModes, mode);
            case RenderIntent::TONE_MAP_ENHANCE:

                *outEnhance = true;
    // find the best render intent
                break;
    auto iter = hwcColorModes.find(hwcColorMode);
            default:
    const auto& hwcIntents =
                break;
            iter != hwcColorModes.end() ? iter->second : std::vector<RenderIntent>();
    const RenderIntent hwcIntent = getHwcRenderIntent(hwcIntents, intent);

    const Dataspace dataspace = colorModeToDataspace(mode);
    const Dataspace hwcDataspace = colorModeToDataspace(hwcColorMode);

    ALOGV("DisplayDevice %d/%d: map (%s, %s) to (%s, %s, %s)", mType, mHwcDisplayId,
          dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
          decodeRenderIntent(intent).c_str(),
          dataspaceDetails(static_cast<android_dataspace_t>(hwcDataspace)).c_str(),
          decodeColorMode(hwcColorMode).c_str(), decodeRenderIntent(hwcIntent).c_str());

    mColorModes[getColorModeKey(dataspace, intent)] = {hwcDataspace, hwcColorMode, hwcIntent};
}

void DisplayDevice::populateColorModes(
        const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes) {
    if (!hasWideColorGamut()) {
        return;
    }

    // add known SDR combinations
    for (auto intent : sSdrRenderIntents) {
        for (auto mode : sSdrColorModes) {
            addColorMode(hwcColorModes, mode, intent);
        }
    }

    // add known HDR combinations
    for (auto intent : sHdrRenderIntents) {
        for (auto mode : sHdrColorModes) {
            addColorMode(hwcColorModes, mode, intent);
        }
    }
}
}

bool DisplayDevice::hasRenderIntent(RenderIntent intent) const {
    // assume a render intent is supported when SRGB supports it; we should
    // get rid of that assumption.
    auto iter = mColorModes.find(getColorModeKey(Dataspace::SRGB, intent));
    return iter != mColorModes.end() && iter->second.renderIntent == intent;
}

bool DisplayDevice::hasModernHdrSupport(Dataspace dataspace) const {
    if ((dataspace == Dataspace::BT2020_PQ && hasHDR10Support()) ||
        (dataspace == Dataspace::BT2020_HLG && hasHLGSupport())) {
        auto iter =
                mColorModes.find(getColorModeKey(dataspace, RenderIntent::TONE_MAP_COLORIMETRIC));
        return iter != mColorModes.end() && iter->second.dataspace == dataspace;
    }

    return false;
}

void DisplayDevice::getBestColorMode(Dataspace dataspace, RenderIntent intent,
                                     Dataspace* outDataspace, ColorMode* outMode,
                                     RenderIntent* outIntent) const {
    auto iter = mColorModes.find(getColorModeKey(dataspace, intent));
    if (iter != mColorModes.end()) {
        *outDataspace = iter->second.dataspace;
        *outMode = iter->second.colorMode;
        *outIntent = iter->second.renderIntent;
    } else {
        ALOGE("map unknown (%s)/(%s) to default color mode",
              dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
              decodeRenderIntent(intent).c_str());

        *outDataspace = Dataspace::UNKNOWN;
        *outMode = ColorMode::NATIVE;
        *outIntent = RenderIntent::COLORIMETRIC;
    }
    }
}
}


+32 −16
Original line number Original line Diff line number Diff line
@@ -91,7 +91,7 @@ public:
            bool hasWideColorGamut,
            bool hasWideColorGamut,
            const HdrCapabilities& hdrCapabilities,
            const HdrCapabilities& hdrCapabilities,
            const int32_t supportedPerFrameMetadata,
            const int32_t supportedPerFrameMetadata,
            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hdrAndRenderIntents,
            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes,
            int initialPowerMode);
            int initialPowerMode);
    // clang-format on
    // clang-format on


@@ -143,11 +143,17 @@ public:
    // machine happy without actually queueing a buffer if nothing has changed
    // machine happy without actually queueing a buffer if nothing has changed
    status_t beginFrame(bool mustRecompose) const;
    status_t beginFrame(bool mustRecompose) const;
    status_t prepareFrame(HWComposer& hwc);
    status_t prepareFrame(HWComposer& hwc);

    bool hasWideColorGamut() const { return mHasWideColorGamut; }
    bool hasWideColorGamut() const { return mHasWideColorGamut; }
    // Whether h/w composer has native support for specific HDR type.
    // Whether h/w composer has native support for specific HDR type.
    bool hasHDR10Support() const { return mHasHdr10; }
    bool hasHDR10Support() const { return mHasHdr10; }
    bool hasHLGSupport() const { return mHasHLG; }
    bool hasHLGSupport() const { return mHasHLG; }
    bool hasDolbyVisionSupport() const { return mHasDolbyVision; }
    bool hasDolbyVisionSupport() const { return mHasDolbyVision; }

    // Return true if the corresponding color mode for the HDR dataspace is
    // supported.
    bool hasModernHdrSupport(ui::Dataspace dataspace) const;

    // The returned HdrCapabilities is the combination of HDR capabilities from
    // The returned HdrCapabilities is the combination of HDR capabilities from
    // hardware composer and RenderEngine. When the DisplayDevice supports wide
    // hardware composer and RenderEngine. When the DisplayDevice supports wide
    // color gamut, RenderEngine is able to simulate HDR support in Display P3
    // color gamut, RenderEngine is able to simulate HDR support in Display P3
@@ -156,13 +162,12 @@ public:
    // respectively if hardware composer doesn't return meaningful values.
    // respectively if hardware composer doesn't return meaningful values.
    const HdrCapabilities& getHdrCapabilities() const { return mHdrCapabilities; }
    const HdrCapabilities& getHdrCapabilities() const { return mHdrCapabilities; }


    // Whether h/w composer has BT2100_PQ color mode.
    // Return true if intent is supported by the display.
    bool hasBT2100PQColorimetricSupport() const { return mHasBT2100PQColorimetric; }
    bool hasRenderIntent(ui::RenderIntent intent) const;
    bool hasBT2100PQEnhanceSupport() const { return mHasBT2100PQEnhance; }


    // Whether h/w composer has BT2100_HLG color mode.
    void getBestColorMode(ui::Dataspace dataspace, ui::RenderIntent intent,
    bool hasBT2100HLGColorimetricSupport() const { return mHasBT2100HLGColorimetric; }
                          ui::Dataspace* outDataspace, ui::ColorMode* outMode,
    bool hasBT2100HLGEnhanceSupport() const { return mHasBT2100HLGEnhance; }
                          ui::RenderIntent* outIntent) const;


    void swapBuffers(HWComposer& hwc) const;
    void swapBuffers(HWComposer& hwc) const;


@@ -214,9 +219,6 @@ public:
    void dump(String8& result) const;
    void dump(String8& result) const;


private:
private:
    void hasToneMapping(const std::vector<ui::RenderIntent>& renderIntents,
                        bool* outColorimetric, bool *outEnhance);

    /*
    /*
     *  Constants, set during initialization
     *  Constants, set during initialization
     */
     */
@@ -288,12 +290,26 @@ private:
    bool mHasDolbyVision;
    bool mHasDolbyVision;
    HdrCapabilities mHdrCapabilities;
    HdrCapabilities mHdrCapabilities;
    const int32_t mSupportedPerFrameMetadata;
    const int32_t mSupportedPerFrameMetadata;
    // Whether h/w composer has BT2100_PQ and BT2100_HLG color mode with

    // colorimetrical tone mapping or enhanced tone mapping.
    // Mappings from desired Dataspace/RenderIntent to the supported
    bool mHasBT2100PQColorimetric;
    // Dataspace/ColorMode/RenderIntent.
    bool mHasBT2100PQEnhance;
    using ColorModeKey = uint64_t;
    bool mHasBT2100HLGColorimetric;
    struct ColorModeValue {
    bool mHasBT2100HLGEnhance;
        ui::Dataspace dataspace;
        ui::ColorMode colorMode;
        ui::RenderIntent renderIntent;
    };

    static ColorModeKey getColorModeKey(ui::Dataspace dataspace, ui::RenderIntent intent) {
        return (static_cast<uint64_t>(dataspace) << 32) | static_cast<uint32_t>(intent);
    }
    void populateColorModes(
            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes);
    void addColorMode(
            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes,
            const ui::ColorMode mode, const ui::RenderIntent intent);

    std::unordered_map<ColorModeKey, ColorModeValue> mColorModes;
};
};


struct DisplayDeviceState {
struct DisplayDeviceState {
+17 −116
Original line number Original line Diff line number Diff line
@@ -1868,7 +1868,6 @@ void SurfaceFlinger::rebuildLayerStacks() {
// can only be one of
// can only be one of
//  - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
//  - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
//  - Dataspace::DISPLAY_P3
//  - Dataspace::DISPLAY_P3
//  - Dataspace::V0_SCRGB_LINEAR
// The returned HDR data space is one of
// The returned HDR data space is one of
//  - Dataspace::UNKNOWN
//  - Dataspace::UNKNOWN
//  - Dataspace::BT2020_HLG
//  - Dataspace::BT2020_HLG
@@ -1882,12 +1881,8 @@ Dataspace SurfaceFlinger::getBestDataspace(
        switch (layer->getDataSpace()) {
        switch (layer->getDataSpace()) {
            case Dataspace::V0_SCRGB:
            case Dataspace::V0_SCRGB:
            case Dataspace::V0_SCRGB_LINEAR:
            case Dataspace::V0_SCRGB_LINEAR:
                bestDataSpace = Dataspace::V0_SCRGB_LINEAR;
                break;
            case Dataspace::DISPLAY_P3:
            case Dataspace::DISPLAY_P3:
                if (bestDataSpace == Dataspace::SRGB) {
                bestDataSpace = Dataspace::DISPLAY_P3;
                bestDataSpace = Dataspace::DISPLAY_P3;
                }
                break;
                break;
            case Dataspace::BT2020_PQ:
            case Dataspace::BT2020_PQ:
            case Dataspace::BT2020_ITU_PQ:
            case Dataspace::BT2020_ITU_PQ:
@@ -1923,104 +1918,17 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice,
    Dataspace hdrDataSpace;
    Dataspace hdrDataSpace;
    Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);
    Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);


    if (hdrDataSpace == Dataspace::BT2020_PQ) {
    RenderIntent intent = mDisplayColorSetting == DisplayColorSetting::ENHANCED ?
        // Hardware composer can handle BT2100 ColorMode only when
        RenderIntent::ENHANCE : RenderIntent::COLORIMETRIC;
        // - colorimetrical tone mapping is supported, or
        // - Auto mode is turned on and enhanced tone mapping is supported.
        if (displayDevice->hasBT2100PQColorimetricSupport() ||
            (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
             displayDevice->hasBT2100PQEnhanceSupport())) {
            *outMode = ColorMode::BT2100_PQ;
            *outDataSpace = Dataspace::BT2020_PQ;
        } else if (displayDevice->hasHDR10Support()) {
            // Legacy HDR support.  HDR layers are treated as UNKNOWN layers.
            hdrDataSpace = Dataspace::UNKNOWN;
        } else {
            // Simulate PQ through RenderEngine, pick DISPLAY_P3 color mode.
            *outMode = ColorMode::DISPLAY_P3;
            *outDataSpace = Dataspace::DISPLAY_P3;
        }
    } else if (hdrDataSpace == Dataspace::BT2020_HLG) {
        if (displayDevice->hasBT2100HLGColorimetricSupport() ||
            (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
             displayDevice->hasBT2100HLGEnhanceSupport())) {
            *outMode = ColorMode::BT2100_HLG;
            *outDataSpace = Dataspace::BT2020_HLG;
        } else if (displayDevice->hasHLGSupport()) {
            // Legacy HDR support.  HDR layers are treated as UNKNOWN layers.
            hdrDataSpace = Dataspace::UNKNOWN;
        } else {
            // Simulate HLG through RenderEngine, pick DISPLAY_P3 color mode.
            *outMode = ColorMode::DISPLAY_P3;
            *outDataSpace = Dataspace::DISPLAY_P3;
        }
    }


    // At this point, there's no HDR layer.
    // respect hdrDataSpace only when there is modern HDR support
    if (hdrDataSpace == Dataspace::UNKNOWN) {
    if (hdrDataSpace != Dataspace::UNKNOWN && displayDevice->hasModernHdrSupport(hdrDataSpace)) {
        switch (bestDataSpace) {
        bestDataSpace = hdrDataSpace;
            case Dataspace::DISPLAY_P3:
        intent = mDisplayColorSetting == DisplayColorSetting::ENHANCED ?
            case Dataspace::V0_SCRGB_LINEAR:
                *outMode = ColorMode::DISPLAY_P3;
                *outDataSpace = Dataspace::DISPLAY_P3;
                break;
            default:
                *outMode = ColorMode::SRGB;
                *outDataSpace = Dataspace::SRGB;
                break;
        }
    }
    *outRenderIntent = pickRenderIntent(displayDevice, *outMode);
}

RenderIntent SurfaceFlinger::pickRenderIntent(const sp<DisplayDevice>& displayDevice,
                                              ColorMode colorMode) const {
    // Native Mode means the display is not color managed, and whichever
    // render intent is picked doesn't matter, thus return
    // RenderIntent::COLORIMETRIC as default here.
    if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
        return RenderIntent::COLORIMETRIC;
    }

    // In Auto Color Mode, we want to strech to panel color space, right now
    // only the built-in display supports it.
    if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
        mBuiltinDisplaySupportsEnhance &&
        displayDevice->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
        switch (colorMode) {
            case ColorMode::DISPLAY_P3:
            case ColorMode::SRGB:
                return RenderIntent::ENHANCE;
            // In Auto Color Mode, BT2100_PQ and BT2100_HLG will only be picked
            // when TONE_MAP_ENHANCE or TONE_MAP_COLORIMETRIC is supported.
            // If TONE_MAP_ENHANCE is not supported, fall back to TONE_MAP_COLORIMETRIC.
            case ColorMode::BT2100_PQ:
                return displayDevice->hasBT2100PQEnhanceSupport() ?
                    RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
            case ColorMode::BT2100_HLG:
                return displayDevice->hasBT2100HLGEnhanceSupport() ?
            RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
            RenderIntent::TONE_MAP_ENHANCE : RenderIntent::TONE_MAP_COLORIMETRIC;
            // This statement shouldn't be reached, switch cases will always
            // cover all possible ColorMode returned by pickColorMode.
            default:
                return RenderIntent::COLORIMETRIC;
    }
    }
    }

    // Either enhance is not supported or we are in natural mode.


    // Natural Mode means it's color managed and the color must be right,
    displayDevice->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
    // thus we pick RenderIntent::COLORIMETRIC as render intent for non-HDR
    // content and pick RenderIntent::TONE_MAP_COLORIMETRIC for HDR content.
    switch (colorMode) {
        // In Natural Color Mode, BT2100_PQ and BT2100_HLG will only be picked
        // when TONE_MAP_COLORIMETRIC is supported.
        case ColorMode::BT2100_PQ:
        case ColorMode::BT2100_HLG:
            return RenderIntent::TONE_MAP_COLORIMETRIC;
        default:
            return RenderIntent::COLORIMETRIC;
    }
}
}


void SurfaceFlinger::setUpHWComposer() {
void SurfaceFlinger::setUpHWComposer() {
@@ -2332,7 +2240,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
        const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
        const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
        const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
    bool hasWideColorGamut = false;
    bool hasWideColorGamut = false;
    std::unordered_map<ColorMode, std::vector<RenderIntent>> hdrAndRenderIntents;
    std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;


    if (hasWideColorDisplay) {
    if (hasWideColorDisplay) {
        std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
        std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
@@ -2349,18 +2257,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(


            std::vector<RenderIntent> renderIntents = getHwComposer().getRenderIntents(hwcId,
            std::vector<RenderIntent> renderIntents = getHwComposer().getRenderIntents(hwcId,
                                                                                       colorMode);
                                                                                       colorMode);
            if (state.type == DisplayDevice::DISPLAY_PRIMARY) {
            hwcColorModes.emplace(colorMode, renderIntents);
                for (auto intent : renderIntents) {
                    if (intent == RenderIntent::ENHANCE) {
                        mBuiltinDisplaySupportsEnhance = true;
                        break;
                    }
                }
            }

            if (colorMode == ColorMode::BT2100_PQ || colorMode == ColorMode::BT2100_HLG) {
                hdrAndRenderIntents.emplace(colorMode, renderIntents);
            }
        }
        }
    }
    }


@@ -2400,17 +2297,21 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
                              dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                              dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                              hasWideColorGamut, hdrCapabilities,
                              hasWideColorGamut, hdrCapabilities,
                              getHwComposer().getSupportedPerFrameMetadata(hwcId),
                              getHwComposer().getSupportedPerFrameMetadata(hwcId),
                              hdrAndRenderIntents, initialPowerMode);
                              hwcColorModes, initialPowerMode);


    if (maxFrameBufferAcquiredBuffers >= 3) {
    if (maxFrameBufferAcquiredBuffers >= 3) {
        nativeWindowSurface->preallocateBuffers();
        nativeWindowSurface->preallocateBuffers();
    }
    }


    if (hw->isPrimary() && hw->hasRenderIntent(RenderIntent::ENHANCE)) {
        mBuiltinDisplaySupportsEnhance = true;
    }

    ColorMode defaultColorMode = ColorMode::NATIVE;
    ColorMode defaultColorMode = ColorMode::NATIVE;
    Dataspace defaultDataSpace = Dataspace::UNKNOWN;
    Dataspace defaultDataSpace = Dataspace::UNKNOWN;
    if (hasWideColorGamut) {
    if (hasWideColorGamut) {
        defaultColorMode = ColorMode::SRGB;
        defaultColorMode = ColorMode::SRGB;
        defaultDataSpace = Dataspace::V0_SRGB;
        defaultDataSpace = Dataspace::SRGB;
    }
    }
    setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
    setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
                               RenderIntent::COLORIMETRIC);
                               RenderIntent::COLORIMETRIC);
+0 −2
Original line number Original line Diff line number Diff line
@@ -664,8 +664,6 @@ private:
                       ui::ColorMode* outMode,
                       ui::ColorMode* outMode,
                       ui::Dataspace* outDataSpace,
                       ui::Dataspace* outDataSpace,
                       ui::RenderIntent* outRenderIntent) const;
                       ui::RenderIntent* outRenderIntent) const;
    ui::RenderIntent pickRenderIntent(const sp<DisplayDevice>& displayDevice,
                                      ui::ColorMode colorMode) const;


    void setUpHWComposer();
    void setUpHWComposer();
    void doComposition();
    void doComposition();