Mappatura dei toni della luminanza HDR su un intervallo compatibile con SDR

Android 13 introduce una libreria statica configurabile dal fornitore chiamata libtonemap, che definisce le operazioni di mappatura tonale ed è condivisa con il processo SurfaceFlinger e le implementazioni di Hardware Composer (HWC). Questa funzionalità consente agli OEM di definire e condividere i propri algoritmi di mappatura della tonalità del display tra il framework e i fornitori, riducendo la mancata corrispondenza nella mappatura della tonalità.

Prima di Android 13, le operazioni di mappatura tonale specifiche del display non erano condivise tra HWC, SurfaceFlinger e le app. A seconda del percorso di rendering, per i contenuti HDR ciò ha comportato una mancata corrispondenza della qualità dell'immagine, poiché i contenuti HDR sono stati sottoposti a mappatura tonale in uno spazio di output in modi diversi. Questo è stato percepito in scenari come la rotazione dello schermo, dove la strategia di composizione varia tra la GPU e la DPU, e nelle differenze di comportamento nel rendering tra TextureView e SurfaceView.

Questa pagina descrive l'interfaccia, la personalizzazione e i dettagli di convalida della librerialibtonemap.

Interfaccia con la libreria di mappatura tonale

La libreria libtonemap contiene implementazioni basate su CPU e shader SkSL, che possono essere collegate da SurfaceFlinger per la composizione del backend GPU e dall'HWC per generare una tabella di ricerca (LUT) per la mappatura tonale. L'entry point di libtonemap è android::tonemap::getToneMapper(), che restituisce un oggetto che implementa l'interfaccia ToneMapper.

L'interfaccia ToneMapper supporta le seguenti funzionalità:

  • Generare una LUT di mappatura tonale

    L'interfaccia ToneMapper::lookupTonemapGain è un'implementazione della CPU dell'shader definito in libtonemap_LookupTonemapGain(). Questo viene utilizzato dai test di unità nel framework e può essere utilizzato dai partner per ricevere assistenza per la generazione di una LUT di mappatura tonale all'interno della pipeline di colori.

    libtonemap_LookupTonemapGain() accetta valori di colore nello spazio lineare assoluto e non normalizzato, sia in RGB lineare che in XYZ, e restituisce un valore float che descrive il fattore di moltiplicazione dei colori di input nello spazio lineare.

  • Genera uno shader SkSL

    L'interfaccia ToneMapper::generateTonemapGainShaderSkSL() restituisce una stringa dello shader SkSL, dato uno spazio dati di origine e di destinazione. Lo shader SkSL è collegato all'implementazione di Skia per RenderEngine, il componente di composizione con accelerazione GPU per SurfaceFlinger. Lo shader è collegato anche a libhwui, in modo che la mappatura tonale HDR-SDR possa essere eseguita in modo efficiente per TextureView. Poiché la stringa generata è in linea con altri shader SkSL utilizzati da Skia, lo shader deve rispettare le seguenti regole:

    • La stringa dello shader deve avere un punto di contatto con la firma float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz), dove linearRGB è il valore dei nit assoluti dei pixel RGB nello spazio lineare e xyz è linearRGB convertito in XYZ.
    • Tutti i metodi di supporto utilizzati dalla stringa dello shader devono avere un prefisso con la stringa libtonemap_ in modo che le definizioni degli shader del framework non entrino in conflitto. Analogamente, le uniformi di input devono essere precedute dal prefisso in_libtonemap_.
  • Genera uniformi SkSL

    L'interfaccia ToneMapper::generateShaderSkSLUniforms() restituisce quanto segue, dato un struct di metadati che descrive i metadati di diversi standard HDR e condizioni di visualizzazione:

    • Un elenco di uniformi vincolate da uno shader SkSL.

    • I valori uniformi in_libtonemap_displayMaxLuminance e in_libtonemap_inputMaxLuminance. Questi valori vengono utilizzati dagli shader del framework per eseguire la scalatura dell'input in libtonemap e normalizzare l'output, se applicabile.

    Al momento, il processo di generazione delle uniformi è indipendente dallo spazio dati di input e di output.

Personalizzazione

L'implementazione di riferimento della libreria libtonemap produce risultati accettabili. Tuttavia, poiché l'algoritmo di mappatura tonale utilizzato dalla composizione GPU può essere diverso da quello utilizzato dalla composizione DPU, l'utilizzo dell'implementazione di riferimento può causare sfarfallio in alcuni scenari, ad esempio nell'animazione di rotazione. La personalizzazione può risolvere questi problemi di qualità delle immagini specifici del fornitore.

Consigliamo vivamente agli OEM di eseguire l'override dell'implementazione di libtonemap per definire la propria sottoclasse ToneMapper, restituita da getToneMapper(). Quando personalizzi l'implementazione, i partner devono eseguire una delle seguenti operazioni:

  • Modificare direttamente l'implementazione di libtonemap.
  • Definire la propria libreria statica, compilarla come autonoma e sostituire il file .a della libreria libtonemap con quello generato dalla libreria personalizzata.

I fornitori non devono modificare alcun codice del kernel, ma più fornitori devono comunicare i dettagli sugli algoritmi di mappatura tonale della DPU per un'implementazione corretta.

Convalida

Per convalidare l'implementazione:

  1. Riproduci video HDR sullo schermo di qualsiasi standard HDR supportato dal tuo sistema di visualizzazione, come HLG, HDR10, HDR10+ o Dolby Vision.

  2. Attiva/disattiva la composizione GPU per assicurarti che non ci sia sfarfallio percepibile dall'utente.

    Utilizza il seguente comando adb per attivare/disattivare la composizione GPU:

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

Problemi comuni

Con questa implementazione possono verificarsi i seguenti problemi:

  • Le bande si verificano quando il target di rendering utilizzato dalla composizione GPU è meno preciso rispetto al valore tipico per i contenuti HDR. Ad esempio, la visualizzazione a bande può verificarsi quando un'implementazione HWC supporta formati opachi a 10 bit per l'HDR, come RGBA1010102 o P010, ma richiede che la composizione della GPU scriva in un formato a 8 bit come RGBA8888 per supportare l'alfa.

  • Un leggero cambiamento di colore è causato dalle differenze di quantizzazione se la DPU opera con una precisione diversa rispetto alla GPU.

Ognuno di questi problemi è correlato alle differenze di precisione relative dell'hardware di base. Una soluzione tipica consiste nell'assicurarsi che sia presente un passaggio di dithering nei percorsi con precisione inferiore, in modo da rendere meno percepibili eventuali differenze di precisione.