Od 27 marca 2025 r. zalecamy używanie android-latest-release zamiast aosp-main do kompilowania i wspołtworzenia AOSP. Więcej informacji znajdziesz w artykule o zmianach w AOSP.
Mapowanie tonów w zakresie luminancji HDR do zakresu zgodnego z SDR
Zadbaj o dobrą organizację dzięki kolekcji
Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
Android 13 wprowadza statyczną bibliotekę konfigurowaną przez dostawcę o nazwie libtonemap, która definiuje operacje mapowania odcieni i jest udostępniana procesowi SurfaceFlinger oraz implementacjom kompozytora sprzętowego (HWC).
Ta funkcja umożliwia producentom OEM definiowanie i udostępnianie algorytmów mapowania odcieni wyświetlacza między platformą a dostawcami, co zmniejsza rozbieżności w mapowaniu odcieni.
Przed Androidem 13 operacje mapowania odcieni specyficzne dla wyświetlacza nie były udostępniane między HWC, SurfaceFlinger i aplikacjami. W zależności od ścieżki renderowania w przypadku treści HDR powodowało to rozbieżności w jakości obrazu, ponieważ treści HDR były mapowane tonalnie do przestrzeni wyjściowej na różne sposoby. Było to widoczne w scenariuszach takich jak obracanie ekranu, w których strategia kompozycji zmienia się między procesorem graficznym a procesorem DPU, oraz w różnicach w zachowaniu renderowania między elementami TextureView i SurfaceView.
Na tej stronie znajdziesz opis interfejsu, dostosowywania i szczegółów weryfikacji biblioteki
libtonemap.
.
Interfejs biblioteki mapowania tonalnego
Biblioteka libtonemap zawiera implementacje oparte na procesorze i shadery SkSL, które mogą być podłączane przez SurfaceFlinger do kompozycji opartej na GPU i przez HWC do generowania tabeli LUT mapowania odcieni. Punktem wejścia do libtonemap jest android::tonemap::getToneMapper(), który zwraca obiekt implementujący interfejs ToneMapper.
Interfejs ToneMapper obsługuje te funkcje:
Generowanie tabeli LUT mapowania tonalnego
Interfejs ToneMapper::lookupTonemapGain to implementacja procesora shaderów zdefiniowanego w libtonemap_LookupTonemapGain(). Jest on używany przez testy jednostkowe w ramach platformy i może być używany przez partnerów do generowania tabeli LUT mapowania odcieni w ich potoku kolorów.
libtonemap_LookupTonemapGain() przyjmuje wartości kolorów w bezwzględnej, nieznormalizowanej przestrzeni liniowej, zarówno w liniowej przestrzeni RGB, jak i XYZ, i zwraca liczbę zmiennoprzecinkową opisującą, przez jaką wartość należy pomnożyć kolory wejściowe w przestrzeni liniowej.
Generowanie shadera SkSL
Interfejs ToneMapper::generateTonemapGainShaderSkSL() zwraca ciąg cieniowania SkSL na podstawie źródłowej i docelowej przestrzeni danych. Shader SkSL jest podłączony do implementacji Skia dla RenderEngine, komponentu komponowania z akceleracją GPU dla SurfaceFlingera. Shader jest też podłączony do libhwui, dzięki czemu można wydajnie przeprowadzać mapowanie tonów z HDR na SDR w przypadku TextureView.
Wygenerowany ciąg znaków jest wstawiany do innych shaderów SkSL używanych przez Skia, dlatego shader musi być zgodny z tymi regułami:
Ciąg cieniowania musi mieć punkt wejścia o sygnaturze float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), gdzie linearRGB to wartość bezwzględnych nitów pikseli RGB w przestrzeni liniowej, a xyz to wartość linearRGB przekonwertowana na XYZ.
Wszystkie metody pomocnicze używane przez ciąg cieniowania muszą mieć prefiks libtonemap_, aby definicje cieniowania platformy nie powodowały konfliktów.
Podobnie zmienne uniform w shaderze wejściowym muszą mieć przedrostek in_libtonemap_.
Generowanie zmiennych uniform w języku SkSL
Interfejs ToneMapper::generateShaderSkSLUniforms() zwraca te informacje, gdy otrzyma metadane struct opisujące metadane z różnych standardów HDR i warunków wyświetlania:
Lista zmiennych uniform, które są powiązane z shaderem SkSL.
Wartości jednolite in_libtonemap_displayMaxLuminance i in_libtonemap_inputMaxLuminance. Te wartości są używane przez shadery platformy podczas skalowania danych wejściowych do zakresu libtonemap i normalizowania danych wyjściowych w odpowiedni sposób.
Obecnie proces generowania jednolitych danych nie zależy od przestrzeni danych wejściowych ani wyjściowych.
Dostosowywanie
Implementacja referencyjna biblioteki libtonemap generuje akceptowalne wyniki. Jednak algorytm mapowania tonów używany przez kompozycję GPU może się różnić od algorytmu używanego przez kompozycję DPU, więc w niektórych przypadkach, np. podczas animacji obrotu, użycie implementacji referencyjnej może powodować migotanie. Dostosowanie może rozwiązać takie problemy z jakością obrazu, które są specyficzne dla danego dostawcy.
Zdecydowanie zalecamy producentom OEM zastąpienie implementacji libtonemap, aby zdefiniować własną podklasę ToneMapper, która jest zwracana przez getToneMapper().
Dostosowując wdrożenie, partnerzy powinni wykonać jedną z tych czynności:
bezpośrednio modyfikować wdrożenie libtonemap,
zdefiniować własną bibliotekę statyczną, skompilować ją jako samodzielną i zastąpić plik libtonemap biblioteki .a plikiem wygenerowanym z własnej biblioteki.
Dostawcy nie muszą modyfikować żadnego kodu jądra, ale wielu dostawców musi przekazywać szczegóły dotyczące algorytmów mapowania tonów DPU, aby zapewnić prawidłowe wdrożenie.
Weryfikacja
Aby sprawdzić wdrożenie:
Odtwarzaj filmy HDR na ekranie w dowolnym standardzie HDR, który obsługuje Twój system wyświetlania, np. HLG, HDR10, HDR10+ lub DolbyVision.
Przełącz kompozycję GPU, aby upewnić się, że nie występuje migotanie widoczne dla użytkownika.
Aby przełączyć kompozycję GPU, użyj tego polecenia adb:
adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
1 to force GPU composition>
Typowe problemy
W przypadku tej implementacji mogą wystąpić te problemy:
Paski powstają, gdy docelowy element renderowania używany przez kompozycję GPU ma niższą precyzję niż typowa wartość dla treści HDR. Na przykład pasy mogą pojawiać się, gdy implementacja HWC obsługuje nieprzezroczyste 10-bitowe formaty HDR, takie jak RGBA1010102 lub P010, ale wymaga, aby kompozycja GPU zapisywała dane w 8-bitowym formacie, takim jak RGBA8888, w celu obsługi kanału alfa.
Subtelna zmiana koloru jest spowodowana różnicami w kwantyzacji, jeśli DPU działa z inną precyzją niż GPU.
Każdy z tych problemów jest związany z różnicami w precyzji względnej sprzętu. Typowym obejściem jest zapewnienie, że na ścieżkach o niższej precyzji występuje etap ditheringu, dzięki czemu wszelkie różnice w precyzji są mniej zauważalne dla człowieka.
Treść strony i umieszczone na niej fragmenty kodu podlegają licencjom opisanym w Licencji na treści. Java i OpenJDK są znakami towarowymi lub zastrzeżonymi znakami towarowymi należącymi do firmy Oracle lub jej podmiotów stowarzyszonych.
Ostatnia aktualizacja: 2025-07-27 UTC.
[[["Łatwo zrozumieć","easyToUnderstand","thumb-up"],["Rozwiązało to mój problem","solvedMyProblem","thumb-up"],["Inne","otherUp","thumb-up"]],[["Brak potrzebnych mi informacji","missingTheInformationINeed","thumb-down"],["Zbyt skomplikowane / zbyt wiele czynności do wykonania","tooComplicatedTooManySteps","thumb-down"],["Nieaktualne treści","outOfDate","thumb-down"],["Problem z tłumaczeniem","translationIssue","thumb-down"],["Problem z przykładami/kodem","samplesCodeIssue","thumb-down"],["Inne","otherDown","thumb-down"]],["Ostatnia aktualizacja: 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."]]