Android 13 wprowadza konfigurowaną przez dostawcę bibliotekę statyczną libtonemap
, która definiuje operacje mapowania tonów i jest udostępniana procesowi SurfaceFlinger i implementacje Hardware Composer (HWC).
Ta funkcja umożliwia OEM-om zdefiniowanie i udostępnianie algorytmów mapowania tonacji wyświetlania między frameworkiem a dostawcami, co zmniejsza niezgodności w mapowaniu tonacji.
Przed Androidem 13 operacje mapowania tonacji dla poszczególnych wyświetlaczy nie były udostępniane między HWC, SurfaceFlingerem i aplikacjami. W zależności od ścieżki renderowania w przypadku treści HDR mogło to prowadzić do niezgodności w jakości obrazu, ponieważ treści HDR były mapowane tonowo na przestrzeń wyjściową na różne sposoby. Było to widoczne w sytuacjach takich jak obrót ekranu, gdzie strategia kompozycji zmienia się między GPU a DPU, a także przy różnicach w renderowaniu w obiektach TextureView i SurfaceView.
Na tej stronie opisujemy interfejs, dostosowywanie i szczegóły weryfikacji biblioteki libtonemap
.
interfejs biblioteki mapowania tonów;
Biblioteka libtonemap
zawiera implementacje obsługiwane przez procesor oraz cieniowanie SkSL, które można podłączyć przez SurfaceFlinger do tworzenia kompozycji w backendzie GPU oraz przez HWC do generowania tabeli wyszukiwania 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 te funkcje:
Generowanie LUT do mapowania tonalnego
Interfejs
ToneMapper::lookupTonemapGain
to implementacja procesora cieniowania zdefiniowany wlibtonemap_LookupTonemapGain()
. Jest on używany w testach jednostkowych w ramach struktury i może być używany przez partnerów do pomocy w generowaniu mapowania tonów LUT w ramach potoku kolorów.Funkcja
libtonemap_LookupTonemapGain()
przyjmuje wartości kolorów w bezwzględnej, nienormalizowanej przestrzeni liniowej, zarówno w RGB, jak i w XYZ, i zwraca wartość typu float, która określa, o ile należy pomnożyć wejściowe kolory w przestrzeni liniowej.Wygeneruj program do cieniowania SkSL
Interfejs
ToneMapper::generateTonemapGainShaderSkSL()
zwraca ciąg cieniowania SSH dla podanej źródłowej i docelowej przestrzeni danych. Moduł cieniowania SkSL jest podłączony do implementacji Skia dlaRenderEngine
, czyli komponentu do komponowania z akceleracją za pomocą GPU, platformy SurfaceFlinger. Jest on też podłączony dolibhwui
, aby można było efektywnie przeprowadzić mapowanie tonacji HDR na SDR w przypadkuTextureView
. Wygenerowany ciąg znaków jest wbudowany w inne shadery SkSL używane przez Skię, więc shader musi przestrzegać tych zasad:- Ciąg cieniowania musi mieć punkt wejścia z podpisem
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, gdzielinearRGB
to wartość bezwzględnych nitów pikseli RGB w przestrzeni liniowej, axyz
to wartośćlinearRGB
przekształcona na XYZ. - Wszystkie metody pomocnicze używane przez ciąg shadera muszą mieć przedrostek
libtonemap_
, aby definicje shadera w ramach nie powodowały konfliktów. Analogicznie, określenie uniformy wejściowe musi mieć poprzedzony prefiksemin_libtonemap_
.
- Ciąg cieniowania musi mieć punkt wejścia z podpisem
Generowanie jednolitej odzieży w SkSL
Interfejs
ToneMapper::generateShaderSkSLUniforms()
zwraca te informacje, jeśli metadanestruct
opisują metadane z różnych standardów HDR i warunków wyświetlania:Lista uniformów objętych cieniowaniem SkSL.
Jednolite wartości
in_libtonemap_displayMaxLuminance
iin_libtonemap_inputMaxLuminance
. Wartości te są używane przez cieniowanie platformy podczas skalowania danych wejściowych do typulibtonemap
i normalizacji danych wyjściowych w odpowiedni sposób.
Obecnie proces generowania jednolitych jednostek jest niezależny od przestrzeni danych wejściowych i wyjściowych.
Dostosowywanie
Referencyjna implementacja biblioteki libtonemap
daje akceptowalne wyniki. Ponieważ jednak algorytm mapowania tonów wykorzystywany przez kompozycje GPU może się różnić od algorytmu stosowanego w kompozycji DPU, użycie referencyjnej implementacji może w niektórych sytuacjach powodować migotanie, np. w przypadku animacji obracania. Dzięki niej można rozwiązać problemy z jakością obrazu związane z konkretnym dostawcą.
Zdecydowanie zachęcamy producentów OEM do zastąpienia implementacji libtonemap
w celu zdefiniowania własnej podklasy ToneMapper
, która jest zwracana przez funkcję getToneMapper()
.
Podczas dostosowywania implementacji partnerzy muszą wykonać jedną z tych czynności:
- Bezpośrednio zmień implementację elementu
libtonemap
. - zdefiniować własną stałą bibliotekę, skompilować ją jako samodzielną i zastąpić plik
libtonemap
biblioteki.a
plikiem wygenerowanym z niestandardowej biblioteki.
Dostawcy nie muszą modyfikować żadnego kodu jądra, ale wielu z nich musi podać szczegółowe informacje o algorytmach mapowania tonów DPU, aby umożliwić ich prawidłową implementację.
Weryfikacja
Aby zweryfikować implementację:
Odtwarzaj filmy HDR na ekranie zgodnie ze standardami HDR, które są obsługiwane przez system wyświetlacza, np. HLG, HDR10, HDR10+ czy DolbyVision.
Włącz lub wyłącz kompozycję GPU, aby mieć pewność, że nie widać migotania.
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 takiej implementacji mogą wystąpić te problemy:
Paski powstają, gdy cel renderowania używany przez kompozycję GPU ma mniejszą dokładność niż typowa wartość w przypadku treści HDR. Pasy mogą się pojawiać, gdy implementacja HWC obsługuje nieprzezroczyste formaty 10-bitowe HDR, takie jak RGBA1010102 lub P010, ale wymaga, aby kompozycja procesora graficznego zapisywała w formacie 8-bitowym, takim jak RGBA8888, aby obsługiwać kanał 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 z względnymi różnicami w dokładności sprzętu. Typowym obejściem jest zapewnienie, aby na ścieżkach o niższej dokładności występował krok ditherowania, dzięki czemu różnice w dokładności są mniej zauważalne dla człowieka.