Mapowanie tonów w zakresie luminancji HDR do zakresu zgodnego z SDR

Android 13 wprowadza stałą bibliotekę o nazwie libtonemap, którą można konfigurować na poziomie dostawcy. Określa ona operacje mapowania tonów i jest współdzielona z procesem SurfaceFlinger i implementacjami sterownika sprzętowego (HWC). Ta funkcja umożliwia OEM-om definiowanie i udostępnianie algorytmów mapowania tonacji wyświetlania między platformą 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 treści HDR może to prowadzić do niezgodności w jakości obrazu, ponieważ treści HDR były mapowane na przestrzeń wyjściową na różne sposoby. Było to zauważalne w takich scenariuszach jak obracanie ekranu, w których strategia kompozycyjna zmienia się między procesorem graficznym a procesorem do przetwarzania obrazu, oraz w różnicach w zachowaniu renderowania między komponentem TextureView a komponentem SurfaceView.

Na tej stronie znajdziesz informacje o interfejsie, dostosowaniu i weryfikacji biblioteki libtonemap.

Interfejs biblioteki mapowania tonacji

Biblioteka libtonemap zawiera implementacje oparte na procesorze i shadery SkSL, które można podłączyć do SurfaceFlingera do tworzenia kompozycji na tylnym końcu GPU oraz do HWC do generowania tabeli odwzorowania tonalnego (LUT). Punkt wejścia do libtonemap to android::tonemap::getToneMapper(), która zwraca obiekt implementujący interfejs ToneMapper.

Interfejs ToneMapper obsługuje te funkcje:

  • Generowanie LUT do mapowania tonalnego

    Interfejs ToneMapper::lookupTonemapGain to implementacja shadera na procesorze CPU zdefiniowana w pliku libtonemap_LookupTonemapGain(). Jest on używany przez testy jednostkowe w ramach, a partnerzy mogą go wykorzystywać do generowania LUT do mapowania tonalnego w ramach swojego 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.

  • Generowanie shadera SkSL

    Interfejs ToneMapper::generateTonemapGainShaderSkSL() zwraca ciąg znaków shadera SkSL, podając źródłowy i docelowy zbiór danych. Shader SkSL jest podłączony do implementacji Skia w RenderEngine, czyli komponentu do komponowania przyspieszonego przez GPU w programie SurfaceFlinger. Jest on też podłączony do libhwui, aby można było efektywnie przeprowadzić mapowanie tonalne HDR na SDR w przypadku TextureView. Wygenerowany ciąg znaków jest wbudowany w inne shadery SkSL używane przez Skię, więc shader musi przestrzegać tych zasad:

    • Ciąg shadera musi zawierać punkt wejścia z signaturą float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), gdzie linearRGB to wartość bezwzględna nits pikseli RGB w przestrzeni liniowej, a xyz to linearRGB przekonwertowany 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. Podobnie nazwy strojów muszą być poprzedzone ciągiem in_libtonemap_.
  • Generowanie jednolitej odzieży w SkSL

    Interfejs ToneMapper::generateShaderSkSLUniforms() zwraca te informacje, jeśli metadane struct opisują metadane z różnych standardów HDR i warunków wyświetlania:

    • Lista uniformów powiązanych z shaderem SkSL.

    • Wartości jednolite in_libtonemap_displayMaxLuminancein_libtonemap_inputMaxLuminance. Te wartości są używane przez shadery frameworku podczas skalowania danych wejściowych do wartości libtonemap i ujednolicania danych wyjściowych w odpowiednich przypadkach.

    Obecnie proces generowania uniformów jest niezależny od przestrzeni danych wejściowych i wyjściowych.

Dostosowywanie

Implementacja referencyjna biblioteki libtonemap daje zadowalające wyniki. Jednak ze względu na to, że algorytm mapowania tonacji używany przez kompozycję GPU może się różnić od algorytmu używanego przez kompozycję DPU, korzystanie z implementacji referencyjnej może powodować migotanie w niektórych scenariuszach, takich jak animacja obrotu. Dzięki niej można rozwiązać problemy z jakością obrazu związane z konkretnym dostawcą.

Producentów OEM zdecydowanie zachęcamy do zastąpienia implementacji libtonemap, aby zdefiniować własną podklasę ToneMapper, która jest zwracana przez funkcję getToneMapper(). Podczas dostosowywania implementacji partnerzy muszą wykonać jedną z tych czynności:

  • Zmień bezpośrednio implementację libtonemap.
  • zdefiniować własną stałą bibliotekę, skompilować ją jako samodzielną i zastąpić plik .a biblioteki libtonemap plikiem wygenerowanym z niestandardowej biblioteki.

Dostawcy nie muszą modyfikować żadnego kodu jądra, ale aby zapewnić prawidłowe wdrożenie, wielu dostawców musi przekazać szczegóły dotyczące algorytmów mapowania tonacji DPU.

Weryfikacja

Aby sprawdzić implementację:

  1. Odtwarzanie filmów HDR na ekranie w dowolnych standardach HDR, które są obsługiwane przez system wyświetlania, takich jak HLG, HDR10, HDR10+ lub Dolby Vision.

  2. Przełącz kompozycję GPU, aby upewnić się, że użytkownik nie zauważy 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 tej implementacji mogą wystąpić następujące problemy:

  • Paskowanie występuje, gdy docel renderowania używany przez kompozycję GPU ma mniejszą dokładność niż typowa wartość dla 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.

  • Delikatna zmiana koloru jest spowodowana różnicami w kwantyzacji, jeśli DPU działa z inną dokładnością 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.