diff options
author | 2018-10-09 16:05:09 -0700 | |
---|---|---|
committer | 2018-10-22 09:40:35 -0700 | |
commit | 9758ae05d7dfc7c02d0b4086b1343fae4ccd8470 (patch) | |
tree | 37afa10bc513311e472cfc5def0005dbdfbbcd8d | |
parent | 5a3a23129dce1396714af584cb1d45900da7bcef (diff) |
Support DISPLAY_P3 dataspace to BT2020 in SF
Adding support to fallback to ColorMode BT2020 with
SRGB when P3 layers are present when external display supports BT2020 with SRGB
transfer function. (Before fallback was to BT709_sRGB)
Bug: 115335239
Test: ./libsurfaceflinger_unittest --gtest_filter=GetBestColorModeTest.*
Change-Id: Iec7154d411cb3dcc4fd1158199bc45207799bb27
-rw-r--r-- | libs/ui/Android.bp | 4 | ||||
-rw-r--r-- | libs/ui/DebugUtils.cpp | 3 | ||||
-rw-r--r-- | libs/ui/include/ui/GraphicTypes.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/Android.bp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.cpp | 64 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp | 88 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 12 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h | 4 |
11 files changed, 169 insertions, 32 deletions
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 7b35409943..0a0c8ca014 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -78,7 +78,7 @@ cc_library_shared { shared_libs: [ "android.hardware.graphics.allocator@2.0", - "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.configstore@1.0", @@ -97,7 +97,7 @@ cc_library_shared { ], export_shared_lib_headers: [ - "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", ], static_libs: [ diff --git a/libs/ui/DebugUtils.cpp b/libs/ui/DebugUtils.cpp index 61df02d41d..ee06d930d8 100644 --- a/libs/ui/DebugUtils.cpp +++ b/libs/ui/DebugUtils.cpp @@ -234,6 +234,9 @@ std::string decodeColorMode(ColorMode colorMode) { case ColorMode::BT2020: return std::string("ColorMode::BT2020"); + case ColorMode::DISPLAY_BT2020: + return std::string("ColorMode::DISPLAY_BT2020"); + case ColorMode::BT2100_PQ: return std::string("ColorMode::BT2100_PQ"); diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h index 0fa819dce8..1d53ac8550 100644 --- a/libs/ui/include/ui/GraphicTypes.h +++ b/libs/ui/include/ui/GraphicTypes.h @@ -17,6 +17,7 @@ #pragma once #include <android/hardware/graphics/common/1.1/types.h> +#include <android/hardware/graphics/common/1.2/types.h> #include <system/graphics.h> // android::ui::* in this header file will alias different types as @@ -25,10 +26,10 @@ namespace android { namespace ui { using android::hardware::graphics::common::V1_0::Hdr; -using android::hardware::graphics::common::V1_1::ColorMode; -using android::hardware::graphics::common::V1_1::Dataspace; using android::hardware::graphics::common::V1_1::PixelFormat; using android::hardware::graphics::common::V1_1::RenderIntent; +using android::hardware::graphics::common::V1_2::ColorMode; +using android::hardware::graphics::common::V1_2::Dataspace; } // namespace ui } // namespace android diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 339f83b5f0..16003a258c 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -30,6 +30,7 @@ cc_defaults { "android.hardware.configstore@1.1", "android.hardware.configstore@1.2", "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.common@1.2", "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", @@ -79,6 +80,7 @@ cc_defaults { ], export_shared_lib_headers: [ "android.hardware.graphics.allocator@2.0", + "android.hardware.graphics.common@1.2", "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 60cad02e87..6f645df73f 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -37,8 +37,8 @@ #include <ui/DebugUtils.h> #include <ui/DisplayInfo.h> #include <ui/PixelFormat.h> -#include <utils/RefBase.h> #include <utils/Log.h> +#include <utils/RefBase.h> #include "DisplayHardware/DisplaySurface.h" #include "DisplayHardware/HWComposer.h" @@ -66,7 +66,8 @@ uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0; namespace { // ordered list of known SDR color modes -const std::array<ColorMode, 2> sSdrColorModes = { +const std::array<ColorMode, 3> sSdrColorModes = { + ColorMode::DISPLAY_BT2020, ColorMode::DISPLAY_P3, ColorMode::SRGB, }; @@ -96,6 +97,8 @@ Dataspace colorModeToDataspace(ColorMode mode) { return Dataspace::SRGB; case ColorMode::DISPLAY_P3: return Dataspace::DISPLAY_P3; + case ColorMode::DISPLAY_BT2020: + return Dataspace::DISPLAY_BT2020; case ColorMode::BT2100_HLG: return Dataspace::BT2020_HLG; case ColorMode::BT2100_PQ: diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 163b26cd36..f0bccaabf1 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -354,16 +354,26 @@ Error Composer::getColorModes(Display display, { Error error = kDefaultError; - if (mClient_2_2) { - mClient_2_2->getColorModes_2_2(display, - [&](const auto& tmpError, const auto& tmpModes) { - error = tmpError; - if (error != Error::NONE) { - return; - } + if (mClient_2_3) { + mClient_2_3->getColorModes_2_3(display, [&](const auto& tmpError, const auto& tmpModes) { + error = tmpError; + if (error != Error::NONE) { + return; + } - *outModes = tmpModes; - }); + *outModes = tmpModes; + }); + } else if (mClient_2_2) { + mClient_2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) { + error = tmpError; + if (error != Error::NONE) { + return; + } + + for (types::V1_1::ColorMode colorMode : tmpModes) { + outModes->push_back(static_cast<ColorMode>(colorMode)); + } + }); } else { mClient->getColorModes(display, [&](const auto& tmpError, const auto& tmpModes) { @@ -555,8 +565,11 @@ Error Composer::setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) { hardware::Return<Error> ret(kDefaultError); - if (mClient_2_2) { - ret = mClient_2_2->setColorMode_2_2(display, mode, renderIntent); + if (mClient_2_3) { + ret = mClient_2_3->setColorMode_2_3(display, mode, renderIntent); + } else if (mClient_2_2) { + ret = mClient_2_2->setColorMode_2_2(display, static_cast<types::V1_1::ColorMode>(mode), + renderIntent); } else { ret = mClient->setColorMode(display, static_cast<types::V1_0::ColorMode>(mode)); @@ -934,15 +947,22 @@ Error Composer::getRenderIntents(Display display, ColorMode colorMode, } Error error = kDefaultError; - mClient_2_2->getRenderIntents(display, colorMode, - [&](const auto& tmpError, const auto& tmpKeys) { + + auto getRenderIntentsLambda = [&](const auto& tmpError, const auto& tmpKeys) { error = tmpError; if (error != Error::NONE) { return; } *outRenderIntents = tmpKeys; - }); + }; + + if (mClient_2_3) { + mClient_2_3->getRenderIntents_2_3(display, colorMode, getRenderIntentsLambda); + } else { + mClient_2_2->getRenderIntents(display, static_cast<types::V1_1::ColorMode>(colorMode), + getRenderIntentsLambda); + } return error; } @@ -955,14 +975,14 @@ Error Composer::getDataspaceSaturationMatrix(Dataspace dataspace, mat4* outMatri } Error error = kDefaultError; - mClient_2_2->getDataspaceSaturationMatrix(dataspace, [&](const auto& tmpError, const auto& tmpMatrix) { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outMatrix = mat4(tmpMatrix.data()); - }); + mClient_2_2->getDataspaceSaturationMatrix(static_cast<types::V1_1::Dataspace>(dataspace), + [&](const auto& tmpError, const auto& tmpMatrix) { + error = tmpError; + if (error != Error::NONE) { + return; + } + *outMatrix = mat4(tmpMatrix.data()); + }); return error; } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 94be6e93a9..4188352a76 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -49,10 +49,10 @@ using types::V1_0::ColorTransform; using types::V1_0::Hdr; using types::V1_0::Transform; -using types::V1_1::ColorMode; -using types::V1_1::Dataspace; using types::V1_1::PixelFormat; using types::V1_1::RenderIntent; +using types::V1_2::ColorMode; +using types::V1_2::Dataspace; using V2_1::Config; using V2_1::Display; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f0723e897b..bd28978bb2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -124,6 +124,7 @@ bool isWideColorMode(const ColorMode colorMode) { case ColorMode::ADOBE_RGB: case ColorMode::DCI_P3: case ColorMode::BT2020: + case ColorMode::DISPLAY_BT2020: case ColorMode::BT2100_PQ: case ColorMode::BT2100_HLG: return true; @@ -2008,6 +2009,7 @@ void SurfaceFlinger::rebuildLayerStacks() { // can only be one of // - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced) // - Dataspace::DISPLAY_P3 +// - Dataspace::DISPLAY_BT2020 // The returned HDR data space is one of // - Dataspace::UNKNOWN // - Dataspace::BT2020_HLG @@ -2021,6 +2023,12 @@ Dataspace SurfaceFlinger::getBestDataspace(const sp<const DisplayDevice>& displa switch (layer->getDataSpace()) { case Dataspace::V0_SCRGB: case Dataspace::V0_SCRGB_LINEAR: + case Dataspace::BT2020: + case Dataspace::BT2020_ITU: + case Dataspace::BT2020_LINEAR: + case Dataspace::DISPLAY_BT2020: + bestDataSpace = Dataspace::DISPLAY_BT2020; + break; case Dataspace::DISPLAY_P3: bestDataSpace = Dataspace::DISPLAY_P3; break; diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index b474e42260..d32627a7d3 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -22,6 +22,7 @@ #include <log/log.h> +#include <ui/DebugUtils.h> #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockDisplaySurface.h" @@ -997,6 +998,93 @@ TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) { } /* ------------------------------------------------------------------------ + * DisplayDevice::GetBestColorMode + */ +class GetBestColorModeTest : public DisplayTransactionTest { +public: + GetBestColorModeTest() + : DisplayTransactionTest(), + mInjector(FakeDisplayDeviceInjector(mFlinger, DisplayDevice::DISPLAY_PRIMARY, 0)) {} + + void setHasWideColorGamut(bool hasWideColorGamut) { mHasWideColorGamut = hasWideColorGamut; } + + void addHwcColorModesMapping(ui::ColorMode colorMode, + std::vector<ui::RenderIntent> renderIntents) { + mHwcColorModes[colorMode] = renderIntents; + } + + void setInputDataspace(ui::Dataspace dataspace) { mInputDataspace = dataspace; } + + void setInputRenderIntent(ui::RenderIntent renderIntent) { mInputRenderIntent = renderIntent; } + + void getBestColorMode() { + mInjector.setHwcColorModes(mHwcColorModes); + mInjector.setHasWideColorGamut(mHasWideColorGamut); + auto displayDevice = mInjector.inject(); + + displayDevice->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace, + &mOutColorMode, &mOutRenderIntent); + } + + ui::Dataspace mOutDataspace; + ui::ColorMode mOutColorMode; + ui::RenderIntent mOutRenderIntent; + +private: + ui::Dataspace mInputDataspace; + ui::RenderIntent mInputRenderIntent; + bool mHasWideColorGamut = false; + std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> mHwcColorModes; + FakeDisplayDeviceInjector mInjector; +}; + +TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeSRGB) { + addHwcColorModesMapping(ui::ColorMode::SRGB, + std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC)); + setInputDataspace(ui::Dataspace::DISPLAY_P3); + setInputRenderIntent(ui::RenderIntent::COLORIMETRIC); + setHasWideColorGamut(true); + + getBestColorMode(); + + ASSERT_EQ(ui::Dataspace::SRGB, mOutDataspace); + ASSERT_EQ(ui::ColorMode::SRGB, mOutColorMode); + ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent); +} + +TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDisplayP3) { + addHwcColorModesMapping(ui::ColorMode::DISPLAY_P3, + std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC)); + addHwcColorModesMapping(ui::ColorMode::SRGB, + std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC)); + addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020, + std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC)); + setInputDataspace(ui::Dataspace::DISPLAY_P3); + setInputRenderIntent(ui::RenderIntent::COLORIMETRIC); + setHasWideColorGamut(true); + + getBestColorMode(); + + ASSERT_EQ(ui::Dataspace::DISPLAY_P3, mOutDataspace); + ASSERT_EQ(ui::ColorMode::DISPLAY_P3, mOutColorMode); + ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent); +} + +TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDISPLAY_BT2020) { + addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020, + std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC)); + setInputDataspace(ui::Dataspace::DISPLAY_P3); + setInputRenderIntent(ui::RenderIntent::COLORIMETRIC); + setHasWideColorGamut(true); + + getBestColorMode(); + + ASSERT_EQ(ui::Dataspace::DISPLAY_BT2020, mOutDataspace); + ASSERT_EQ(ui::ColorMode::DISPLAY_BT2020, mOutColorMode); + ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent); +} + +/* ------------------------------------------------------------------------ * SurfaceFlinger::setupNewDisplayDeviceInternal */ diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 2046439889..62afde9b0f 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -369,6 +369,18 @@ public: return *this; } + auto& setHwcColorModes( + const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> + hwcColorModes) { + mCreationArgs.hwcColorModes = hwcColorModes; + return *this; + } + + auto& setHasWideColorGamut(bool hasWideColorGamut) { + mCreationArgs.hasWideColorGamut = hasWideColorGamut; + return *this; + } + sp<DisplayDevice> inject() { DisplayDeviceState state; state.type = mCreationArgs.type; diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index ecf3181695..c0395c01ce 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -30,10 +30,10 @@ namespace mock { using android::hardware::graphics::common::V1_0::ColorTransform; using android::hardware::graphics::common::V1_0::Hdr; using android::hardware::graphics::common::V1_0::Transform; -using android::hardware::graphics::common::V1_1::ColorMode; -using android::hardware::graphics::common::V1_1::Dataspace; using android::hardware::graphics::common::V1_1::PixelFormat; using android::hardware::graphics::common::V1_1::RenderIntent; +using android::hardware::graphics::common::V1_2::ColorMode; +using android::hardware::graphics::common::V1_2::Dataspace; using android::hardware::graphics::composer::V2_1::Config; using android::hardware::graphics::composer::V2_1::Display; |