本文档基于AndroidQ,因为暂时没有Q的代码连接,代码引用连接是AndroidP.
打开你Android手机“设置”界面,点击“显示”=>“高级”=>“颜色”,你可以看到手机生产商为你定制的显示效果选项。如果是Google原生系统的话,则一般有三个选项,如下是Pixel4的Color Modes设置界面:
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来完成。
文件转载: