本文档基于AndroidQ,因为暂时没有Q的代码连接,代码引用连接是AndroidP.

       打开你Android手机“设置”界面,点击“显示”=>“高级”=>“颜色”,你可以看到手机生产商为你定制的显示效果选项。如果是Google原生系统的话,则一般有三个选项,如下是Pixel4的Color Modes设置界面:
 

Android Color Mode软件架构分析Android Color Mode软件架构分析_NATURAL

1. APP和Framework Java层相关代码:

    从下面Android代码看,Google在应用层定义了4个ColorMode,分别是自然色模式COLOR_MODE_NATURAL(0)、效果增强模式COLOR_MODE_BOOSTED(1)、鲜艳模式 COLOR_MODE_SATURATED(2) 、和自动调节模式COLOR_MODE_AUTOMATIC(3)。

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/com/android/internal/app/ColorDisplayController.java

 

88    /**
89     * Color mode with natural colors.
90     *
91     * @see #setColorMode(int)
92     */
93    public static final int COLOR_MODE_NATURAL = 0;
94    /**
95     * Color mode with boosted colors.
96     *
97     * @see #setColorMode(int)
98     */
99    public static final int COLOR_MODE_BOOSTED = 1;
100    /**
101     * Color mode with saturated colors.
102     *
103     * @see #setColorMode(int)
104     */
105    public static final int COLOR_MODE_SATURATED = 2;
106    /**
107     * Color mode with automatic colors.
108     *
109     * @see #setColorMode(int)
110     */
111    public static final int COLOR_MODE_AUTOMATIC = 3;

  从图1可以看出,Pixel4在设置中给出了3个ColorModes,分别是自然色、效果增强和自动调节。这个界面的colorModes选项,可以通过以下config来配置,一般放到项目本身的overlay目录。

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/res/res/values/symbols.xml#2967  

961    <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. -->
962    <integer-array name="config_availableColorModes">
963        <!-- Example:
964        <item>0</item>
965        <item>1</item>
966        <item>3</item>
967        -->

设置UI中的colorModes是怎么实现的呢?看DisplayTransformManager.java中的setColorMode函数。有两个接口很关键,它们是applySaturation()和setDisplayColor()。他们分别调用了SurfaceFlinger的transact code 1022/1023,用来设置饱和度和colorSetting,从而综合得出一个colorMode的效果。代码如下图。顺便提下,除了colorMode外,Android显示效果中的夜晚模式以及颜色反转等,是通过另外一个接口setColorTransform配置不同的matrix来实现的。

frameworks/base/services/core/java/com/android/server/display/color/DisplayTransformManager.java
 

327      public boolean setColorMode(int colorMode, float[] nightDisplayMatrix) {
328          if (colorMode == ColorDisplayManager.COLOR_MODE_NATURAL) {
329              applySaturation(COLOR_SATURATION_NATURAL);
330              setDisplayColor(DISPLAY_COLOR_MANAGED);
331          } else if (colorMode == ColorDisplayManager.COLOR_MODE_BOOSTED) {
340              applySaturation(COLOR_SATURATION_BOOSTED);
341              setDisplayColor(DISPLAY_COLOR_MANAGED);
343          } else if (colorMode == ColorDisplayManager.COLOR_MODE_SATURATED) {
344              applySaturation(COLOR_SATURATION_NATURAL);
345              setDisplayColor(DISPLAY_COLOR_UNMANAGED);
346          } else if (colorMode == ColorDisplayManager.COLOR_MODE_AUTOMATIC) {
347              applySaturation(COLOR_SATURATION_NATURAL);
348              setDisplayColor(DISPLAY_COLOR_ENHANCED);
349          } else if (colorMode >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
350                  && colorMode <= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX) {
351              applySaturation(COLOR_SATURATION_NATURAL);
352              setDisplayColor(colorMode);
353          }
354   }
 

    可以看出,除了效果增强模式COLOR_MODE_BOOSTED使用了110%(COLOR_SATURATION_BOOSTED)的饱和度,其他模式都是使用100%(COLOR_SATURATION_NATURAL )的饱和度。几个相关定义如下:

   //用来调用surfaceFlinger的transact code如下
    //SurfaceFlinger global saturation factor.
    private static final int SURFACE_FLINGER_TRANSACTION_SATURATION = 1022;
    //SurfaceFlinger display color (managed, unmanaged, etc.).
    private static final int SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR = 1023;
    private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;

    //Google饱和度初设值
    private static final float COLOR_SATURATION_NATURAL = 1.0f;
    private static final float COLOR_SATURATION_BOOSTED = 1.1f;

    //Google定义的colorSetting值,在native层会转化为renderIntent,用来区分相同colorSpace的不同底层colorMode
    private static final int DISPLAY_COLOR_MANAGED = 0;
    private static final int DISPLAY_COLOR_UNMANAGED = 1;
    private static final int DISPLAY_COLOR_ENHANCED = 2;
 

2. SurfaceFlinger相关代码

 上面我们讲了app层的代码,知道DisplayTransformManager会调用SurfaceFlinger来配置saturation和colorSetting。上层应用可以随时设置saturation和colorSetting,并记为mGlobalSaturationFactor和mDisplayColorSetting,但真正的colorMode生效是实际的layer更新时才向HAL层传递的。mGlobalSaturationFactor会更新mDrawingState.colorMatrix并通过setColorTransform()来生效。
 

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,  uint32_t flags) {
        switch (code) {
            case 1022: { // Set saturation boost
                Mutex::Autolock _l(mStateLock);
                mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f));
                updateColorMatrixLocked();
                return NO_ERROR;
            }
            case 1023: { // Set native mode
                mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32());
                invalidateHwcGeometry();
                repaintEverything();
                return NO_ERROR;
            }
        }
}

 

       当有layer需要更新时,handleMessageRefresh()会调用calculateWorkingSet(),根据当前的colorSetting、saturation(即colorMatrix)、以及topLayer的内容,来决定是否更改colorMode。请注意这里的colorMode与应用层的colorMode是不同的概念,这里的colorMode是从HAL层获取的到的本设备支持的colorMode合集(mColorModes),他是结合dataSpace、hwcColorModes和renderIntent生成的一个colorMap。

       其中dataSpace、hwcColorModes和renderIntent是定义在composer的hidl接口中的,随着Google的更新,更新的composer hidl接口中会有更多的补充定义。dataSpace的定义如下:

https://sse.am.mot.com/q_source/xref/mq-r-qsh2020/hardware/interfaces/graphics/common/1.0/types.hal#577  

@export(name="android_dataspace_t", value_prefix="HAL_DATASPACE_")
577 enum Dataspace : int32_t {
587     UNKNOWN = 0x0,
600     ARBITRARY = 0x1,
610     STANDARD_SHIFT = 16,
        ......
755     STANDARD_DCI_P3 = 10 << STANDARD_SHIFT,
765     STANDARD_ADOBE_RGB = 11 << STANDARD_SHIFT,
769     TRANSFER_SHIFT = 22,
        .......
892     RANGE_SHIFT = 27,
         ......
992     SRGB = 0x201, // deprecated, use V0_SRGB
994     V0_SRGB = STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL,
1009     V0_SCRGB = STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED,
         .......
1075     DCI_P3_LINEAR = STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL,
1087     DCI_P3 = STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL,
1096     DISPLAY_P3_LINEAR = STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL,
1105     DISPLAY_P3 = STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL,
1115     ADOBE_RGB = STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL,
1125     BT2020_LINEAR = STANDARD_BT2020 | TRANSFER_LINEAR | RANGE_FULL,
1135     BT2020 = STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL,
1144     BT2020_PQ = STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL,
1169     DEPTH = 0x1000,
1179     SENSOR = 0x1001
1180 };
 

 hwcColorModes的定义如下:

http://androidxref.com/9.0.0_r3/xref/hardware/interfaces/graphics/common/1.0/types.hal#1226

1226 @export(name="android_color_mode_t", value_prefix="HAL_COLOR_MODE_")
1227 enum ColorMode : int32_t {
1234     NATIVE = 0,
1260     STANDARD_BT601_625 = 1,
1280     STANDARD_BT601_625_UNADJUSTED = 2,
1302     STANDARD_BT601_525 = 3,
1322     STANDARD_BT601_525_UNADJUSTED = 4,
1350     STANDARD_BT709 = 5,
1365     DCI_P3 = 6,
1393     SRGB = 7,
1408     ADOBE_RGB = 8,
1430     DISPLAY_P3 = 9
1431 };
 

 RenderIntent的定义如下,其中COLORMETRIC对应managed和unmanaged colorSetting(即应用层的自然模式和鲜艳模式),ENHANCE对应应用层的增强模式。客户也可以用enhance intent来定制自己的colorMode。如果设备支持HDR的话,当播放HDR内容时,intent会更新为对应的TONE_MAP_COLORIMETRIC和TONE_MAP_ENHANCE。

http://androidxref.com/9.0.0_r3/xref/hardware/interfaces/graphics/common/1.1/types.hal#288  

251enum RenderIntent : int32_t {
259    COLORIMETRIC = 0,
269    ENHANCE = 1,
277    TONE_MAP_COLORIMETRIC = 2,
288    TONE_MAP_ENHANCE = 3,
294};
 

   handleMessageRefresh()的调用很简单,首先做一些layer合成前的准备工作,然后调用calculateWorkingSet()视情况来配置colorMode,最后进行合成。在calculateWorkingSet()中,首先通过setColorTransform(mDrawingState.colorMatrix)设置饱和度,然后看当前的colorSetting是否是management的,如果是的话则通过pickColorMode()综合考虑本设备的colorMode列表和layer的内容来确定colorMode(android_color_mode_t), targetDataspace和renderIntent三个参数,并传递给HAL层。这里为什么不是只传colorMode呢?因为在HAL层维护的本身背支持的colorMode列表不是单纯靠color Mode就能确定的,而是一个三维数组color_mode_map_ [ColorMode::XXX][render_intent][kSdrType],所以必须把colorMode和intent传下去。
 

void SurfaceFlinger::handleMessageRefresh()
2152      const bool repaintEverything = mRepaintEverything.exchange(false);
2153      preComposition();
2154      rebuildLayerStacks();
2155      calculateWorkingSet();
2156      for (const auto& [token, display] : mDisplays) {
2157          beginFrame(display);
2158          prepareFrame(display);
2159          doDebugFlashRegions(display, repaintEverything);
2160          doComposition(display, repaintEverything);
2161      }

void SurfaceFlinger::calculateWorkingSet()               
2296          if (mDrawingState.colorMatrixChanged) {  //在这里saturation通过colorMatrix告诉HWC
2297              display->setColorTransform(mDrawingState.colorMatrix);
2298          }
2299          Dataspace targetDataspace = Dataspace::UNKNOWN;
2300          if (useColorManagement) {  //只有managed的colorMode才会根据topLayer的内容来动态切换colorMode
2301              ColorMode colorMode;
2302              RenderIntent renderIntent;
2303              pickColorMode(displayDevice, &colorMode, &targetDataspace, &renderIntent);
2304              display->setColorMode(colorMode, targetDataspace, renderIntent);
2305          }
               //这里的targetDataspace是从getBestColorMode中获取的所有layer的目标layer。
               //比如当前colorMode的dataSpace(一般等于targetDataspace)是P3,但是其中有些layer的dataspace是SRGB,
               //则这些layer需要从SRGB转换到P3。这个工作在HWC或者GPU中完成。
2306          for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
2331              layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport,
2332                                     displayDevice->getSupportedPerFrameMetadata(),
2333                                     isHdrColorMode(displayState.colorMode) ? Dataspace::UNKNOWN
2334                                                                            : targetDataspace);
2335          }
 

 我们仔细来看一下pickColorMode是如何获取三个参数的。

       首先,如果color Setting是unmanaged,则固定colorMode为ColorMode::NATIVE,dataSpace为UNKNOWN,renderIntent为COLORIMETRIC,这样当参数传到HAL层后,它选择的colormode就固定为color_mode_map_ [ColorMode::NATIVE][COLORIMETRIC][kSdrType]。即不管layer的内容是上面,也不管是否HDR,统统使用固定不变的显示效果。一般native显示效果是结合设备本身的panel硬件而精调的一套显示效果参数,能够比较好的表现出屏幕硬件本身的优点。

       然后通过getBestDataspace遍历当前可见layer的dataSpace来决定bestDataspace。以最上层的layer的dataspace为结果。

       接着,依据mDisplayColorSetting来确定renderIntent;

       最后,掉用getBestColorMode()从本机支持的colorMode中找到符合前面符合前面intent和dataSpace的colorMode,并最终确定dataSpace和intent。

http://androidxref.com/9.0.0_r3/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp#1922  

1921// Pick the ColorMode / Dataspace for the display device.
1922void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& displayDevice,
1923                                   ColorMode* outMode, Dataspace* outDataSpace,
1924                                   RenderIntent* outRenderIntent) const {
1925    if (mDisplayColorSetting == DisplayColorSetting::UNMANAGED) {
1926        *outMode = ColorMode::NATIVE;
1927        *outDataSpace = Dataspace::UNKNOWN;
1928        *outRenderIntent = RenderIntent::COLORIMETRIC;
1929        return;
1930    }
        //这里遍历当前可见layer的dataSpace来决定bestDataspace.以最上层的layer的dataspace为结果。
        //没有适合的则返回bestDataSpace 是V0_SRGB.
1932    Dataspace hdrDataSpace;
1933    Dataspace bestDataSpace = getBestDataspace(displayDevice, &hdrDataSpace);
1934
1935    // respect hdrDataSpace only when there is no legacy HDR support
1936    const bool isHdr= hdrDataSpace != Dataspace::UNKNOWN &&!displayDevice->hasLegacyHdrSupport(hdrDataSpace);
1938    if (isHdr) {
1939        bestDataSpace = hdrDataSpace;
1940    }
1941    //确定renderIntent
1942    RenderIntent intent;
1943    switch (mDisplayColorSetting) {
1944        case DisplayColorSetting::MANAGED:
1945        case DisplayColorSetting::UNMANAGED:
1946            intent = isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
1947            break;
1948        case DisplayColorSetting::ENHANCED:
1949            intent = isHdr ? RenderIntent::TONE_MAP_ENHANCE : RenderIntent::ENHANCE;
1950            break;
1951        default: // vendor display color setting
1952            intent = static_cast<RenderIntent>(mDisplayColorSetting);
1953            break;
1954    }
            //这里根据bestDataSpace/intent来从本机支持的colorMode list中确定colorMode、dataSpace和intent。
1956    displayDevice->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
1957}
 

下面是getBestDataspace()如何遍历可见layer并确定的最优的dataSpace的。

1881// Returns a data space that fits all visible layers.  The returned data space
1882// can only be one of
1883//  - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
1884//  - Dataspace::DISPLAY_P3
1885// The returned HDR data space is one of
1886//  - Dataspace::UNKNOWN
1887//  - Dataspace::BT2020_HLG
1888//  - Dataspace::BT2020_PQ
1889Dataspace SurfaceFlinger::getBestDataspace(
1890    const sp<const DisplayDevice>& displayDevice, Dataspace* outHdrDataSpace) const {
1891    Dataspace bestDataSpace = Dataspace::SRGB;
1892    *outHdrDataSpace = Dataspace::UNKNOWN;
1893
1894    for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
1895        switch (layer->getDataSpace()) {
1896            case Dataspace::V0_SCRGB:
1897            case Dataspace::V0_SCRGB_LINEAR:
1898            case Dataspace::DISPLAY_P3:
1899                bestDataSpace = Dataspace::DISPLAY_P3;
1900                break;
1901            case Dataspace::BT2020_PQ:
1902            case Dataspace::BT2020_ITU_PQ:
1903                *outHdrDataSpace = Dataspace::BT2020_PQ;
1904                break;
1905            case Dataspace::BT2020_HLG:
1906            case Dataspace::BT2020_ITU_HLG:
1907                // When there's mixed PQ content and HLG content, we set the HDR
1908                // data space to be BT2020_PQ and convert HLG to PQ.
1909                if (*outHdrDataSpace == Dataspace::UNKNOWN) {
1910                    *outHdrDataSpace = Dataspace::BT2020_HLG;
1911                }
1912                break;
1913            default:
1914                break;
1915        }
1916    }
1917
1918    return bestDataSpace;
1919}

 这里补充一下,layer的dataSpace是怎么来的呢?其实,Android中layer的默认dataSpace都是Dataspace::UNKNOWN。但在AndroidQ上添加了新的接口native_window_set_buffers_data_space(window, dataSpace)来设置窗口即layer的dataSpace属性,使基于intent的自适应colorMode变为可行的。应用可以自己选择colorMode。
 


 

   当outDataSpace, outMode, outRenderIntent确定以后,这些参数在现实刷新的过程中被传递给HAL层,应用并立即生效。调用的接口是Composer::setColorMode()。

Error Composer::setColorMode(Display display, ColorMode mode,RenderIntent 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));
    }
    return unwrapRet(ret);
}
 

3. HAL层代码相关代码

       在HAL层初始化时,会从colorProfile.xml中读出本设备支持的colorModes。color Profile XML的格式如下:

<Mode ModeID="0" DisplayID="0" IsDefaultMode="0" IsAppMode="0" Name="p3" NumOfFeatures="15" WhitePoint="0" EValue="255" BValue="100" RValue="100" DynamicRange="sdr" ColorGamut="dcip3" PictureQuality="standard" RenderIntent="0" IsMerge="1">
 

   其中,ColorGamut对一个surfaceFlinger通过setColorMode传下来的mode,RenderIntent对应setColorMode传下来的renderIntent。DynamicRange是对应当前显示内容是否具备HDR属性。

      以高通平台8996为例,初始化colorModes的代码如下(连接中P的代码与我在Q上测试的代码区别比较大)。这里就是从color Profile XML中把设备支持的colorMode都读出来并存储在color_mode_map_中,注意这里只记录了mode name。

http://androidxref.com/9.0.0_r3/xref/hardware/qcom/display/msm8996/sdm/libs/hwc2/hwc_display.cpp#166  

PopulateColorModes() {
356      std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard, transfer;
357      int int_render_intent = -1;
381        auto render_intent = static_cast<RenderIntent>(int_render_intent);
382        if (color_gamut == kNative) {
383          color_mode_map_[ColorMode::NATIVE][render_intent][kSdrType] = mode_string;
384        }
386        if (color_gamut == kSrgb && dynamic_range == kSdr) {
387          color_mode_map_[ColorMode::SRGB][render_intent][kSdrType] = mode_string;
388        }
390        if (color_gamut == kDcip3 && dynamic_range == kSdr) {
391          color_mode_map_[ColorMode::DISPLAY_P3][render_intent][kSdrType] = mode_string;
392        }
393        if (color_gamut == kDcip3 && dynamic_range == kHdr) {
394          if (display_intf_->IsSupportSsppTonemap()) {
395            color_mode_map_[ColorMode::DISPLAY_P3][render_intent][kHdrType] = mode_string;
396          } else if (pic_quality == kStandard) {
397            color_mode_map_[ColorMode::BT2100_PQ][render_intent][kHdrType] = mode_string;
399            color_mode_map_[ColorMode::BT2100_HLG][render_intent][kHdrType] = mode_string;
401          }
402        } else if (color_gamut == kBt2020) {
403          if (transfer == kSt2084) {
404            color_mode_map_[ColorMode::BT2100_PQ][RenderIntent::COLORIMETRIC][kHdrType] = mode_string;
406          } else if (transfer == kHlg) {
407            color_mode_map_[ColorMode::BT2100_HLG][RenderIntent::COLORIMETRIC][kHdrType] = mode_string;
409          } else if (transfer == kSrgb) {
410            color_mode_map_[ColorMode::DISPLAY_BT2020][RenderIntent::COLORIMETRIC][kSdrType] = mode_string;
412          }
413        }
414  
415        if (color_gamut == kAdobeRgb) {
416          color_mode_map_[ColorMode::ADOBE_RGB][RenderIntent::COLORIMETRIC][kHdrType] = mode_string;
418        }
}
 

    从surfaceFlinger调下来的setColorMode会根据mode和intent来更新HAL层记录当前colorMode和Intent的全局变量current_color_mode_和current_render_intent_ 。

http://androidxref.com/9.0.0_r3/xref/hardware/interfaces/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h#200 Return<Error> QtiComposerClient::setColorMode_2_2(uint64_t display, common_V1_1::ColorMode mode, common_V1_1::RenderIntent intent) {
  auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),static_cast<int32_t>(intent));
  return static_cast<Error>(error);
}
 

hardware/qcom/display/composer/hwc_display_builtin.cpp

130  HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
132    HWC2::Error hwc_error = ValidateColorModeWithRenderIntent(mode, intent);
137    if (current_color_mode_ == mode && current_render_intent_ == intent) {
138      return HWC2::Error::None;
139    }
140  
141    auto mode_string = color_mode_map_[mode][intent][kSdrType];
142    DisplayError error = display_intf_->SetColorMode(mode_string);
147    // The mode does not have the PCC configured, restore the transform
148    RestoreColorTransform();
149    //这里更新全局变量current_color_mode_和current_render_intent_,在validate时用来确定当前colorMode。
150    current_color_mode_ = mode;
151    current_render_intent_ = intent;
155  }
 

   真正写入硬件并生效是在hwc做validate()的时候,调用ApplyCurrentColorModeWithRenderIntent()根据current_color_mode_、current_render_intent_和curr_dynamic_range_来获取mode name,然后通过SetPreferredColorModeInternal()调用colorManager的接口写入硬件。

hardware/qcom/display/composer/hwc_display_builtin.cpp

hardware/qcom/display/composer/hwc_display.cpp
 

67  HWC2::Error HWCDisplayBuiltIn::Validate(uint32_t *out_num_types, uint32_t *out_num_requests)

174  HWC2::Error HWCColorMode::ApplyCurrentColorModeWithRenderIntent(bool hdr_present) {
189    std::string mode_string = preferred_mode_[current_color_mode_][curr_dynamic_range_];
190    if (mode_string.empty()) {
191      mode_string = color_mode_map_[current_color_mode_][current_render_intent_][curr_dynamic_range_];
192      if (mode_string.empty() && hdr_present) {
193        // Use the colorimetric HDR mode, if an HDR mode with the current render intent is not present
194        mode_string = color_mode_map_[current_color_mode_][RenderIntent::COLORIMETRIC][kHdrType];
195      }
196      if (mode_string.empty() &&
197         (current_color_mode_ == ColorMode::DISPLAY_P3 || current_color_mode_ == ColorMode::DISPLAY_BT2020) &&
199         curr_dynamic_range_ == kHdrType) {
200        // fall back to display_p3/display_bt2020 SDR mode if there is no HDR mode
201        mode_string = color_mode_map_[current_color_mode_][current_render_intent_][kSdrType];
202      }
209    }
211    auto error = SetPreferredColorModeInternal(mode_string, false, NULL, NULL);
21x  }
 

4. 总结

       综上所述,Google通过saturation和displayColor两个参数来操作colorMode,上层的一个colorMode对应HAL层color_mode_map_里的多个colorMode。除了COLOR_MODE_SATURATED固定对应适配Panel硬件本身特性的native colorMode,其他都是内容自适应的。

       SurfaceFlinger在刷新每个frame前通过检测硬件支持的colorModes和当前可见layer(最上层)的dataSpace(getBestDataspace)来决定hwcColorMode、targetDataspace和intent,并传入HAL层使其生效。所有与确定后的colorMode的dataspace不同的layer,都要在HWC或者GPU中进行dataspace转换,转换到targetDataspace。Saturation则通过color Transform来完成。

Android Color Mode软件架构分析Android Color Mode软件架构分析_java_02