Kể từ ngày 27 tháng 3 năm 2025, bạn nên sử dụng android-latest-release thay vì aosp-main để xây dựng và đóng góp cho AOSP. Để biết thêm thông tin, hãy xem phần Thay đổi đối với AOSP.
Ánh xạ độ sáng HDR theo tông màu tới phạm vi tương thích với SDR
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Android 13 giới thiệu một thư viện tĩnh do nhà cung cấp có thể định cấu hình có tên là libtonemap, xác định các thao tác ánh xạ tông màu và được chia sẻ với quy trình SurfaceFlinger và các cách triển khai Trình kết hợp phần cứng (HWC).
Tính năng này cho phép các OEM xác định và chia sẻ các thuật toán ánh xạ tông màu màn hình giữa khung và nhà cung cấp, giảm sự không khớp trong ánh xạ tông màu.
Trước Android 13, các thao tác ánh xạ tông màu dành riêng cho màn hình không được chia sẻ giữa HWC, SurfaceFlinger và các ứng dụng. Tuỳ thuộc vào đường dẫn kết xuất, đối với nội dung HDR, điều này dẫn đến sự không khớp về chất lượng hình ảnh, trong đó nội dung HDR được ánh xạ tông màu sang một không gian đầu ra theo nhiều cách. Điều này có thể nhận thấy trong các trường hợp như xoay màn hình, khi chiến lược thành phần thay đổi giữa GPU và DPU, cũng như sự khác biệt về hành vi kết xuất giữa TextureView và SurfaceView.
Trang này mô tả giao diện, thông tin tuỳ chỉnh và xác thực của thư viện libtonemap.
Giao diện đến thư viện ánh xạ tông màu
Thư viện libtonemap chứa các phương thức triển khai dựa trên CPU và các chương trình đổ bóng SkSL. SurfaceFlinger có thể cắm các chương trình này để tạo thành phần phụ trợ GPU và HWC để tạo bảng tra cứu (LUT) ánh xạ tông màu. Điểm truy cập vào libtonemap là android::tonemap::getToneMapper(). Điểm này trả về một đối tượng triển khai giao diện ToneMapper.
Giao diện ToneMapper hỗ trợ các chức năng sau:
Tạo bảng tra cứu màu ánh xạ tông màu
Giao diện ToneMapper::lookupTonemapGain là một cách triển khai CPU của chương trình đổ bóng được xác định trong libtonemap_LookupTonemapGain(). Các bài kiểm thử đơn vị trong khung này sử dụng thông tin này và các đối tác có thể sử dụng thông tin này để được hỗ trợ tạo LUT ánh xạ tông màu trong quy trình xử lý màu của họ.
libtonemap_LookupTonemapGain() nhận các giá trị màu trong không gian tuyến tính tuyệt đối, chưa được chuẩn hoá, cả trong RGB tuyến tính và trong XYZ, đồng thời trả về một số thực mô tả mức độ nhân các màu đầu vào trong không gian tuyến tính.
Tạo chương trình đổ bóng SkSL
Giao diện ToneMapper::generateTonemapGainShaderSkSL() trả về một chuỗi chương trình đổ bóng SkSL, cho trước một nguồn và không gian dữ liệu đích. Chương trình đổ bóng SkSL được cắm vào quá trình triển khai Skia cho RenderEngine, thành phần tổng hợp được tăng tốc bằng GPU cho SurfaceFlinger. Chương trình đổ bóng này cũng được cắm vào libhwui, để có thể thực hiện hiệu quả việc ánh xạ tông màu từ HDR sang SDR cho TextureView.
Vì chuỗi được tạo được nội tuyến hoá vào các chương trình đổ bóng SkSL khác mà Skia sử dụng, nên chương trình đổ bóng phải tuân thủ các quy tắc sau:
Chuỗi chương trình đổ bóng phải có một điểm nhập bằng chữ ký float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), trong đó linearRGB là giá trị của nits tuyệt đối của các pixel RGB trong không gian tuyến tính và xyz là linearRGB được chuyển đổi thành XYZ.
Mọi phương thức trợ giúp mà chuỗi chương trình đổ bóng sử dụng phải có tiền tố là chuỗi libtonemap_ để các định nghĩa chương trình đổ bóng của khung không xung đột.
Tương tự, các giá trị đồng nhất đầu vào phải có tiền tố là in_libtonemap_.
Tạo các đối tượng đồng nhất SkSL
Giao diện ToneMapper::generateShaderSkSLUniforms() sẽ trả về những nội dung sau, cho trước một siêu dữ liệu struct mô tả siêu dữ liệu từ các tiêu chuẩn HDR và điều kiện hiển thị khác nhau:
Danh sách các đối tượng đồng nhất được liên kết bằng chương trình đổ bóng SkSL.
Các giá trị đồng nhất in_libtonemap_displayMaxLuminance và in_libtonemap_inputMaxLuminance. Các giá trị này được các chương trình đổ bóng khung hình dùng khi mở rộng quy mô đầu vào thành libtonemap và chuẩn hoá đầu ra nếu có thể.
Hiện tại, quy trình tạo các thành phần đồng nhất không phụ thuộc vào không gian dữ liệu đầu vào và đầu ra.
Tuỳ chỉnh
Phương thức triển khai tham chiếu của thư viện libtonemap tạo ra kết quả chấp nhận được. Tuy nhiên, vì thuật toán ánh xạ tông màu mà thành phần GPU sử dụng có thể khác với thuật toán mà thành phần DPU sử dụng, nên việc sử dụng quy trình triển khai tham chiếu có thể gây ra hiện tượng nhấp nháy trong một số trường hợp, chẳng hạn như ảnh động xoay. Việc tuỳ chỉnh có thể giải quyết những vấn đề về chất lượng hình ảnh dành riêng cho nhà cung cấp như vậy.
Các OEM nên ghi đè việc triển khai libtonemap để xác định lớp con ToneMapper của riêng họ, được trả về theo getToneMapper().
Khi tuỳ chỉnh việc triển khai, các đối tác phải thực hiện một trong những việc sau:
Sửa đổi trực tiếp quá trình triển khai libtonemap.
Xác định thư viện tĩnh riêng, biên dịch thư viện dưới dạng độc lập và thay thế tệp .a của thư viện libtonemap bằng tệp được tạo từ thư viện tuỳ chỉnh của họ.
Các nhà cung cấp không cần sửa đổi bất kỳ mã nhân nào, nhưng nhiều nhà cung cấp phải trao đổi thông tin chi tiết về thuật toán ánh xạ tông màu DPU để triển khai đúng cách.
Xác nhận kết quả
Hãy làm theo các bước sau để xác thực việc triển khai:
Phát video HDR trên màn hình có bất kỳ tiêu chuẩn HDR nào mà hệ thống hiển thị của bạn hỗ trợ, chẳng hạn như HLG, HDR10, HDR10+ hoặc DolbyVision.
Bật/tắt thành phần GPU để đảm bảo không có hiện tượng nhấp nháy mà người dùng có thể nhận thấy.
Dùng lệnh adb sau đây để bật/tắt thành phần GPU:
adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
1 to force GPU composition>
Các vấn đề thường gặp
Các vấn đề sau có thể xảy ra với cách triển khai này:
Hiện tượng phân dải xảy ra khi đích kết xuất mà thành phần GPU sử dụng có độ chính xác thấp hơn giá trị thông thường đối với nội dung HDR. Ví dụ: hiện tượng sọc màu có thể xảy ra khi một chế độ triển khai HWC hỗ trợ các định dạng 10 bit mờ cho HDR (chẳng hạn như RGBA1010102 hoặc P010), nhưng yêu cầu thành phần GPU ghi vào định dạng 8 bit (chẳng hạn như RGBA8888) để hỗ trợ kênh alpha.
Sự thay đổi màu sắc tinh tế là do sự khác biệt về lượng tử hoá nếu DPU hoạt động ở độ chính xác khác với GPU.
Mỗi vấn đề này đều liên quan đến sự khác biệt về độ chính xác tương đối của phần cứng cơ bản. Một giải pháp thường thấy là đảm bảo có một bước làm giảm độ chính xác trong các đường dẫn có độ chính xác thấp hơn, giúp mọi khác biệt về độ chính xác ít được con người nhận thấy hơn.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-07-27 UTC."],[],[],null,["# Tone Mapping HDR Luminance to an SDR-compatible Range\n\nAndroid 13 introduces a vendor-configurable static\nlibrary called `libtonemap`, which defines tone mapping operations and is shared\nwith the SurfaceFlinger process and Hardware Composer (HWC) implementations.\nThis feature enables OEMs to define and share their display tone mapping\nalgorithms between the framework and vendors, lessening a mismatch in tone\nmapping.\n\nPrior to Android 13, display-specific tone mapping\noperations weren't shared between the HWC, SurfaceFlinger, and apps. Depending\non the rendering path, for HDR content, this led to mismatches in image quality,\nwhere the HDR content was tone mapped to an output space in different ways. This\nwas perceptible in scenarios such as screen rotation, where the composition\nstrategy changes between the GPU and the DPU, and in differences in rendering\nbehavior between TextureView and SurfaceView.\n\nThis page describes the interface, customization, and validation details of the\n`libtonemap` library.\n| **Note:** Android 16 introduces a new HDR tone mapping method called Look-up Table (LUT) for HDR video outputs instead of using `libtonemap`. LUTs primarily resolve the fragmentation issue with HDR video outputs, especially for HLG and PQ, across a diverse range of Android devices. See the AIDL API [`android.hardware.graphics.composer3.DisplayLuts`](https://cs.android.com/android/platform/superproject/+/android-latest-release:hardware/interfaces/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl) for more information.\n\nInterface to the tone mapping library\n-------------------------------------\n\nThe [`libtonemap`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/)\nlibrary contains CPU-backed implementations and SkSL shaders, which can be\nplugged in by SurfaceFlinger for GPU-backend composition and by the HWC for\ngenerating a tone mapping look-up table (LUT). The entry point to `libtonemap`\nis [`android::tonemap::getToneMapper()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/tonemap.cpp#733), which returns an object that\nimplements the [`ToneMapper`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#86) interface.\n\nThe `ToneMapper` interface supports the following capabilities:\n\n- Generate a tone-mapping LUT\n\n The interface [`ToneMapper::lookupTonemapGain`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#147) is a CPU\n implementation of the shader defined in `libtonemap_LookupTonemapGain()`. This\n is used by unit tests in the framework, and can be used by partners for\n assistance with generating a tone-mapping LUT inside their color pipeline.\n\n `libtonemap_LookupTonemapGain()` takes in color values in absolute,\n unnormalized linear space, both in linear RGB and in XYZ, and returns a float\n describing how much to multiply the input colors in linear space.\n- Generate an SkSL shader\n\n The interface [`ToneMapper::generateTonemapGainShaderSkSL()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#122) returns an\n SkSL shader string, given a source and destination dataspace. The SkSL shader is\n plugged into the Skia implementation for [`RenderEngine`](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/native/libs/renderengine/),\n the GPU-accelerated compositing component for SurfaceFlinger. The shader is also\n plugged into [`libhwui`](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/libs/hwui),\n so that HDR-to-SDR tone mapping can be performed efficiently for `TextureView`.\n Because the generated string is in-lined into other SkSL shaders used by Skia,\n the shader must adhere to the following rules:\n - The shader string must have an entry point with the `float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)` signature, where `linearRGB` is the value of the absolute nits of the RGB pixels in linear space and `xyz` is `linearRGB` converted into XYZ.\n - Any helper methods used by the shader string must be prefixed with the string `libtonemap_` so that framework shader definitions don't conflict. Similarly, input uniforms must be prefixed with `in_libtonemap_`.\n- Generate SkSL uniforms\n\n The interface [`ToneMapper::generateShaderSkSLUniforms()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#136) returns the\n following, given a metadata `struct` describing metadata from different HDR\n standards and display conditions:\n - A list of uniforms that are bound by an SkSL shader.\n\n - The uniform values `in_libtonemap_displayMaxLuminance` and\n `in_libtonemap_inputMaxLuminance`. These values are used by framework shaders\n when scaling the input into `libtonemap`, and normalizing the output as\n applicable.\n\n Currently the process of generating uniforms is agnostic to the input and\n output dataspace.\n\n### Customization\n\nThe reference implementation of the [`libtonemap`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/) library produces acceptable results. However,\nbecause the tone mapping algorithm used by GPU composition can differ from that\nused by the DPU composition, using the reference implementation can cause\nflicker in some scenarios such as the rotation animation. Customization can\nresolve such vendor-specific image quality issues.\n\nOEMs are strongly encouraged to override the implementation of `libtonemap` to\ndefine their own `ToneMapper` subclass, which is returned by `getToneMapper()`.\nWhen customizing the implementation, partners are expected to do one of the\nfollowing:\n\n- Modify the implementation of `libtonemap` directly.\n- Define their own static library, compile the library as a standalone, and replace `libtonemap` library's `.a` file with the one generated from their custom library.\n\nVendors don't need to modify any kernel code, but multiple vendors must\ncommunicate details about the DPU tone-mapping algorithms for proper\nimplementation.\n\n### Validation\n\nFollow these steps to validate your implementation:\n\n1. Play HDR videos on screen of any HDR standards that your [display system supports](https://developer.android.com/reference/android/view/Display#getHdrCapabilities()),\n such as HLG, HDR10, HDR10+, or DolbyVision.\n\n2. Toggle GPU composition to ensure that there's no user perceptible flicker.\n\n Use the following `adb` command to toggle the GPU composition: \n\n adb shell service call SurfaceFlinger 1008 i32 \u003c0 to enable HWC composition,\n 1 to force GPU composition\u003e\n\n### Common issues\n\nThe following issues can occur with this implementation:\n\n- Banding is caused when the render target used by GPU composition is of lower\n precision than the typical value for HDR content. For instance, banding can\n occur when an HWC implementation supports opaque 10-bit formats for HDR such as\n RGBA1010102 or P010, but requires that GPU composition writes to an 8-bit format\n like RGBA8888 to support alpha.\n\n- A subtle color shift is caused by quantization differences if the DPU\n operates at a different precision than the GPU.\n\nEach of these issues is related to the relative precision differences of the\nunderlying hardware. A typical workaround is to ensure that there's a dithering\nstep in the lower precision paths, making any precision differences less human\nperceptible."]]