Android 13 wprowadza konfigurowalną przez dostawcę bibliotekę statyczną o nazwie libtonemap
, która definiuje operacje mapowania tonów i jest współdzielona z implementacjami procesu SurfaceFlinger i Hardware Composer (HWC). Ta funkcja umożliwia producentom OEM definiowanie i udostępnianie algorytmów mapowania tonów wyświetlacza między platformą a dostawcami, zmniejszając niedopasowanie w mapowaniu tonów.
Przed systemem Android 13 operacje mapowania tonalnego 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 prowadziło to do niedopasowania jakości obrazu, w którym zawartość HDR była mapowana tonalnie na przestrzeń wyjściową na różne sposoby. Było to zauważalne w scenariuszach, takich jak obracanie ekranu, w których strategia kompozycji zmienia się między GPU i DPU, oraz w różnicach w zachowaniu renderowania między TextureView i SurfaceView.
Ta strona opisuje szczegóły interfejsu, dostosowywania i sprawdzania poprawności biblioteki libtonemap
.
Interfejs do biblioteki mapowania tonów
Biblioteka libtonemap
zawiera implementacje wspierane przez procesor CPU i moduły cieniujące SkSL, które można podłączyć za pomocą SurfaceFlinger w celu tworzenia zaplecza GPU oraz za pomocą HWC w celu wygenerowania tabeli przeglądowej mapowania tonów (LUT). Punktem wejścia do libtonemap
jest android::tonemap::getToneMapper()
, który zwraca obiekt implementujący interfejs ToneMapper
.
Interfejs ToneMapper
obsługuje następujące funkcje:
Wygeneruj tablicę LUT mapowania tonów
Interfejs
ToneMapper::lookupTonemapGain
jest implementacją procesora modułu cieniującego zdefiniowanego wlibtonemap_LookupTonemapGain()
. Jest to używane przez testy jednostkowe w ramach i może być używane przez partnerów do pomocy przy generowaniu tabeli LUT mapowania tonów w ich potoku kolorów.libtonemap_LookupTonemapGain()
przyjmuje wartości kolorów w bezwzględnej, nieznormalizowanej przestrzeni liniowej, zarówno w liniowym RGB, jak i XYZ, i zwraca liczbę zmiennoprzecinkową opisującą, o ile należy pomnożyć wejściowe kolory w przestrzeni liniowej.Wygeneruj moduł cieniujący SkSL
Interfejs
ToneMapper::generateTonemapGainShaderSkSL()
zwraca łańcuch cieniujący SkSL, biorąc pod uwagę źródłową i docelową przestrzeń danych. Moduł cieniujący SkSL jest podłączony do implementacji Skia dlaRenderEngine
, akcelerowanego przez GPU komponentu do komponowania dla SurfaceFlinger. Moduł cieniujący jest również podłączony dolibhwui
, dzięki czemu mapowanie tonów HDR-to-SDR może być skutecznie wykonywane dlaTextureView
. Ponieważ wygenerowany ciąg jest wstawiany do innych shaderów SkSL używanych przez Skia, shader musi być zgodny z następującymi zasadami:- Ciąg modułu cieniującego musi mieć punkt wejścia z sygnaturą
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, gdzielinearRGB
to wartość bezwzględna nitów pikseli RGB w przestrzeni liniowej, axyz
tolinearRGB
przekonwertowany na XYZ. - Wszelkie metody pomocnicze używane przez ciąg modułu cieniującego muszą być poprzedzone ciągiem
libtonemap_
, aby definicje modułu cieniującego struktury nie powodowały konfliktów. Podobnie uniformy wejściowe muszą być poprzedzonein_libtonemap_
.
- Ciąg modułu cieniującego musi mieć punkt wejścia z sygnaturą
Generuj mundury SkSL
Interfejs
ToneMapper::generateShaderSkSLUniforms()
zwraca następujące informacje, biorąc pod uwagęstruct
metadanych opisującą metadane z różnych standardów HDR i warunków wyświetlania:Lista uniformów, które są powiązane shaderem SkSL.
Jednolite wartości
in_libtonemap_displayMaxLuminance
iin_libtonemap_inputMaxLuminance
. Wartości te są używane przez moduły cieniujące frameworka podczas skalowania danych wejściowych dolibtonemap
i normalizacji danych wyjściowych w stosownych przypadkach.
Obecnie proces generowania uniformów jest niezależny od wejściowej i wyjściowej przestrzeni danych.
Dostosowywanie
Referencyjna implementacja biblioteki libtonemap
daje akceptowalne wyniki. Ponieważ jednak algorytm mapowania tonów używany przez kompozycję GPU może różnić się od algorytmu używanego przez kompozycję DPU, użycie implementacji referencyjnej może powodować migotanie w niektórych scenariuszach, takich jak animacja obrotu. Dostosowanie może rozwiązać takie specyficzne dla dostawcy problemy z jakością obrazu.
Producenci OEM są zdecydowanie zachęcani do zastępowania implementacji libtonemap
w celu zdefiniowania własnej podklasy ToneMapper
, która jest zwracana przez getToneMapper()
. Podczas dostosowywania implementacji od partnerów oczekuje się wykonania jednej z następujących czynności:
- Zmodyfikuj bezpośrednio implementację
libtonemap
. - Zdefiniuj własną bibliotekę statyczną, skompiluj ją jako samodzielną bibliotekę i zastąp plik
.a
bibliotekilibtonemap
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 w celu prawidłowej implementacji.
Walidacja
Wykonaj następujące kroki, aby zweryfikować swoją implementację:
Odtwarzaj filmy HDR na ekranie dowolnego standardu HDR obsługiwanego przez Twój system wyświetlania , takiego jak HLG, HDR10, HDR10+ lub DolbyVision.
Przełącz układ GPU, aby upewnić się, że nie ma zauważalnego przez użytkownika migotania.
Użyj następującego polecenia
adb
, aby przełączyć kompozycję GPU:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
Powszechne problemy
W przypadku tej implementacji mogą wystąpić następujące problemy:
Pasmowanie powstaje, gdy cel renderowania używany przez kompozycję GPU ma niższą precyzję niż typowa wartość dla treści HDR. Na przykład pasmowanie może wystąpić, gdy implementacja HWC obsługuje nieprzezroczyste 10-bitowe formaty dla HDR, takie jak RGBA1010102 lub P010, ale wymaga, aby kompozycja GPU zapisywała w formacie 8-bitowym, takim jak RGBA8888, aby obsługiwać alfa.
Subtelne przesunięcie kolorów jest spowodowane różnicami w kwantyzacji, jeśli DPU działa z inną precyzją niż GPU.
Każdy z tych problemów jest związany ze względnymi różnicami w precyzji bazowego sprzętu. Typowym obejściem jest zapewnienie kroku ditheringu w ścieżkach o niższej precyzji, dzięki czemu wszelkie różnice w precyzji będą mniej dostrzegalne przez człowieka.