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 wlibtonemap_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 dlaRenderEngine
, komponentu komponowania z akceleracją GPU dla SurfaceFlingera. Shader jest też podłączony dolibhwui
, dzięki czemu można wydajnie przeprowadzać mapowanie tonów z HDR na SDR w przypadkuTextureView
. 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)
, gdzielinearRGB
to wartość bezwzględnych nitów pikseli RGB w przestrzeni liniowej, axyz
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ć przedrostekin_libtonemap_
.
- Ciąg cieniowania musi mieć punkt wejścia o sygnaturze
Generowanie zmiennych uniform w języku SkSL
Interfejs
ToneMapper::generateShaderSkSLUniforms()
zwraca te informacje, gdy otrzyma metadanestruct
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
iin_libtonemap_inputMaxLuminance
. Te wartości są używane przez shadery platformy podczas skalowania danych wejściowych do zakresulibtonemap
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.