颜色管理

Android 8.1 及更高版本新增了对颜色管理功能的支持,此功能可用于在采用不同显示技术的设备间提供一致的体验。在 Android 上运行的应用可以访问广色域屏幕的所有功能,以便充分利用显示设备。

之前的 Android 版本不支持颜色管理功能,而是依赖于内容和显示屏之间的兼容性(这个目标通常需要借助电视行业的帮助才能实现)。不过,最新的显示技术可让不能按预期显示现有内容的显示屏具有更广的色域。搭载 Android 8.1 及更高版本时,采用广色域显示屏(例如有机发光二极管有源阵列或 AMOLED 及某些 LCD)的设备能够从应用中查看到广色域内容。

确定设备支持情况

搭载 Android 8.1 或更高版本且采用广色域显示屏的设备应支持颜色管理(广色域)。启用此功能前,请确保设备满足以下要求:

  • 设备显示屏符合硬件要求,其中包括可支持 Display-P3 颜色空间的性能良好的显示屏。如果显示屏不符合此要求,请勿启用颜色管理。为了降低 CPU 和 GPU 影响,有必要在显示通道中支持扩展的 sRGB 和 HDR10。
  • 设备支持出厂校准流程,该流程可生成校准数据(存储在设备上)来调整显示行为中的制造差异。校准数据至少应允许显示屏准确显示 sRGB 内容以及 D65 和 D73 白点。

如果满足以上要求,就可以为设备启用颜色管理功能。

实现颜色管理

如需实现颜色管理功能,请先更新 Hardware Composer 2 (HWC2) 驱动程序,以了解颜色模式并将这些模式应用到硬件。具体而言,HWC2 制作程序必须使用 HWCDisplay::GetColorModes 报告 Display-P3 和 sRGB 颜色模式。

接下来,启用必需的 OpenGL 扩展程序和库支持,以将 OpenGL 颜色空间转换为 HAL 数据空间。必需的 OpenGL 扩展包括:

  • EGL_EXT_pixel_format_float。允许应用使用 16 位浮点颜色组件创建可呈现的 EGLSurface。优先级:高(建议将这项作为宽色域感知应用的默认像素格式)。需要驱动程序支持。
  • EGL_KHR_gl_colorspace。对于需要使用 sRGB 格式默认帧缓冲区来轻松实现显示设备的 sRGB 渲染的应用,此扩展程序允许创建将由支持该功能的 OpenGL 上下文采用 sRGB 格式进行渲染的 EGLSurface。需要驱动程序支持 sRGB 行为。

Android 还提供以下可选的扩展程序:

  • EGL_EXT_colorspace_scrgb_linear。该扩展程序可提供一个新的颜色空间选项 scRGB,供应用在创建 EGLSurface 时选择。scRGB 颜色空间可定义与 sRGB 具有相同白点和颜色基准(以便与 sRGB 向后兼容)的线性显示引用空间。该扩展程序应该不需要驱动程序支持,而且可以在 Android EGL 封装容器中实现。为了正常发挥作用,此扩展程序需支持 16 位浮点 (FP16)。
  • EGL_EXT_gl_colorspace_display_p3EGL_EXT_gl_colorspace_display_p3_linear。对于需要使用 Display-P3 格式默认帧缓冲区来轻松实现显示设备的 sRGB 渲染的应用,此扩展程序允许创建将由支持该功能的 OpenGL 上下文采用 Display-P3 格式进行渲染的 EGLSurface。此扩展可以在 EGL 驱动程序封装容器中实现。
  • VK_EXT_swapchain_colorspace (Vulkan)。可让应用通过它们正在使用的颜色空间来标记交换链。包括一些常见颜色空间,例如 DCI-P3、Display-P3、AdobeRGB、BT2020。

自定义

您可以通过添加对各种颜色标准(例如 DCI-P3、AdobeRGB、Rec709 和 Rec2020)的支持,实现对颜色管理功能的自定义。其他自定义项包括:

  • 针对显示通道中颜色转换的硬件支持。在硬件中支持多种颜色转换。
  • 支持在多个图层上进行独立的颜色转换(例如,某些图层可能是 sRGB,其他图层则是扩展的 sRGB,每个图层都有自己的颜色管道)。如果有多个颜色空间可见,需要将某些颜色空间转换为显示屏的颜色空间。理想情况下,此转换最好由显示引擎提供(否则 Android 必须执行 GPU 合成)。

测试

如需测试颜色管理,请使用 opengl/tests 中的以下资源:

  • gl2_basic,一种请求 Display-P3 颜色空间的简单 OpenGL 演示。
  • EGL_test,测试必要的扩展和配置支持(10:10:10:2 和 FP16)。
  • test_wide_color,创建 surface 的方式与 SurfaceFlinger 相同(例如配置、颜色空间和像素格式)。

参考实现

如需查看参考实现,请参阅 frameworks/native。对于头文件,请参阅: