From ff84a15c51b388402292412875273f39f829b74a Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Fri, 17 May 2019 18:36:19 -0700 Subject: [SurfaceFlinger] Filter out wide color modes for built-in display when necessary. OEMs can choose whether to advertize the built-in display is wide color capable regardless of whether hardware composer returns wide color modes or not. This patch makes sure those this configuration is taken into account when we return the color modes of the built-in display. Otherwise those devices will fail the Display CTS tests. BUG: 133010445 Test: Boot. Verified with Pixel 3. Change-Id: Id70c39a4d274400f2c66b0a04728524051cb5c6a --- services/surfaceflinger/SurfaceFlinger.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 820ccc5de0..dd75868443 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1049,6 +1049,7 @@ status_t SurfaceFlinger::getDisplayColorModes(const sp& displayToken, } std::vector modes; + bool isInternalDisplay = false; { ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); @@ -1058,9 +1059,20 @@ status_t SurfaceFlinger::getDisplayColorModes(const sp& displayToken, } modes = getHwComposer().getColorModes(*displayId); + isInternalDisplay = displayId == getInternalDisplayIdLocked(); } outColorModes->clear(); - std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); + + // If it's built-in display and the configuration claims it's not wide color capable, + // filter out all wide color modes. The typical reason why this happens is that the + // hardware is not good enough to support GPU composition of wide color, and thus the + // OEMs choose to disable this capability. + if (isInternalDisplay && !hasWideColorDisplay) { + std::remove_copy_if(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes), + isWideColorMode); + } else { + std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes)); + } return NO_ERROR; } @@ -1207,6 +1219,13 @@ status_t SurfaceFlinger::isWideColorDisplay(const sp& displayToken, if (!display) { return BAD_VALUE; } + + // Use hasWideColorDisplay to override built-in display. + const auto displayId = display->getId(); + if (displayId && displayId == getInternalDisplayIdLocked()) { + *outIsWideColorDisplay = hasWideColorDisplay; + return NO_ERROR; + } *outIsWideColorDisplay = display->hasWideColorGamut(); return NO_ERROR; } @@ -4746,7 +4765,7 @@ void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const { } void SurfaceFlinger::dumpWideColorInfo(std::string& result) const { - StringAppendF(&result, "Device has wide color display: %d\n", hasWideColorDisplay); + StringAppendF(&result, "Device has wide color built-in display: %d\n", hasWideColorDisplay); StringAppendF(&result, "Device uses color management: %d\n", useColorManagement); StringAppendF(&result, "DisplayColorSetting: %s\n", decodeDisplayColorSetting(mDisplayColorSetting).c_str()); -- cgit v1.2.3-59-g8ed1b