Tonalne mapowanie luminancji HDR do zakresu zgodnego z SDR

W systemie Android 13 wprowadzono konfigurowalną przez dostawcę bibliotekę statyczną o nazwie libtonemap , która definiuje operacje mapowania tonów i jest współdzielona z procesami SurfaceFlinger i implementacjami Hardware Composer (HWC). Ta funkcja umożliwia producentom OEM definiowanie i udostępnianie algorytmów mapowania tonów wyświetlacza pomiędzy platformą a dostawcami, zmniejszając niedopasowanie w mapowaniu tonów.

Przed Androidem 13 operacje mapowania tonów specyficzne dla wyświetlacza nie były współdzielone między HWC, SurfaceFlinger i aplikacjami. W zależności od ścieżki renderowania treści HDR prowadziło to do niedopasowania jakości obrazu, w przypadku którego tony treści HDR były na różne sposoby mapowane do przestrzeni wyjściowej. Było to zauważalne w scenariuszach takich jak rotacja ekranu, gdzie strategia kompozycji zmienia się pomiędzy GPU a DPU, oraz w różnicach w zachowaniu renderowania pomiędzy StructureView i SurfaceView.

Na tej stronie opisano interfejs, dostosowywanie i szczegóły sprawdzania poprawności biblioteki libtonemap .

Interfejs do biblioteki mapowania tonów

Biblioteka libtonemap zawiera implementacje oparte na procesorze i moduły cieniujące SkSL, które mogą być podłączone przez SurfaceFlinger w celu tworzenia zaplecza GPU oraz przez 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 możliwości:

  • Wygeneruj tabelę LUT mapowania tonów

    Interfejs ToneMapper::lookupTonemapGain jest implementacją CPU modułu cieniującego zdefiniowanego w libtonemap_LookupTonemapGain() . Jest to wykorzystywane w testach jednostkowych w ramach i może być wykorzystywane przez partnerów do pomocy przy generowaniu tablicy LUT mapującej tony w ich potoku kolorów.

    libtonemap_LookupTonemapGain() pobiera wartości kolorów w bezwzględnej, nieznormalizowanej przestrzeni liniowej, zarówno w liniowym RGB, jak i XYZ, i zwraca liczbę zmiennoprzecinkową opisującą, jak bardzo należy pomnożyć wejściowe kolory w przestrzeni liniowej.

  • Wygeneruj moduł cieniujący SkSL

    Interfejs ToneMapper::generateTonemapGainShaderSkSL() zwraca ciąg modułu cieniującego SkSL, biorąc pod uwagę źródłową i docelową przestrzeń danych. Moduł cieniujący SkSL jest podłączony do implementacji Skia dla RenderEngine , komponentu do komponowania akcelerowanego przez GPU dla SurfaceFlinger. Moduł cieniujący jest również podłączony do libhwui , dzięki czemu można efektywnie wykonać mapowanie tonów HDR-na-SDR dla TextureView . Ponieważ wygenerowany ciąg znaków jest osadzony w innych modułach cieniujących SkSL używanych przez Skia, moduł cieniujący musi przestrzegać następujących zasad:

    • Ciąg modułu cieniującego musi mieć punkt wejścia z sygnaturą float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz) , gdzie linearRGB to wartość bezwzględnych nitów pikseli RGB w przestrzeni liniowej, a xyz to linearRGB przekonwertowane 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 platformy nie powodowały konfliktów. Podobnie mundury wejściowe muszą być poprzedzone prefiksem in_libtonemap_ .
  • Wygeneruj 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 mundurów powiązanych z modułem cieniującym SkSL.

    • Jednolite wartości in_libtonemap_displayMaxLuminance i in_libtonemap_inputMaxLuminance . Wartości te są używane przez shadery frameworka podczas skalowania danych wejściowych do libtonemap i normalizowania danych wyjściowych, jeśli ma to zastosowanie.

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

Dostosowywanie

Referencyjna implementacja biblioteki libtonemap daje akceptowalne wyniki. Jednakże, ponieważ 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ć problemy związane z jakością obrazu, specyficzne dla dostawcy.

Zdecydowanie zachęca się producentów OEM do zastąpienia implementacji libtonemap w celu zdefiniowania własnej podklasy ToneMapper , która jest zwracana przez getToneMapper() . Podczas dostosowywania wdrożenia oczekuje się, że partnerzy wykonają jedną z następujących czynności:

  • Zmodyfikuj bezpośrednio implementację libtonemap .
  • Zdefiniuj własną bibliotekę statyczną, skompiluj ją jako samodzielną i zamień plik .a biblioteki libtonemap na plik wygenerowany z własnej biblioteki.

Dostawcy nie muszą modyfikować żadnego kodu jądra, ale wielu dostawców musi przekazać szczegółowe informacje na temat algorytmów mapowania tonów DPU, aby zapewnić prawidłową implementację.

Walidacja

Wykonaj poniższe kroki, aby sprawdzić poprawność implementacji:

  1. Odtwarzaj filmy HDR na ekranie dowolnego standardu HDR obsługiwanego przez Twój system wyświetlania , np. HLG, HDR10, HDR10+ lub DolbyVision.

  2. Przełącz kompozycję procesora graficznego, 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ę procesora graficznego ma niższą precyzję niż typowa wartość dla treści HDR. Na przykład pasma mogą wystąpić, gdy implementacja HWC obsługuje nieprzezroczyste 10-bitowe formaty HDR, takie jak RGBA1010102 lub P010, ale wymaga, aby kompozycja procesora graficznego 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 procesor DPU działa z inną precyzją niż procesor graficzny.

Każdy z tych problemów jest związany ze względnymi różnicami w precyzji podstawowego sprzętu. Typowym obejściem jest zapewnienie kroku ditheringu na ścieżkach o niższej precyzji, dzięki czemu wszelkie różnice w precyzji będą mniej zauważalne dla człowieka.