Home
Compressione texture: quanti elefanti stanno…?

05 Novembre 2014

Compressione texture: quanti elefanti stanno…?

di

Anche i cosiddetti device hanno una scheda video. Cosa cambia? Facciamo due conti per puntare al massimo risparmio.

Solitamente né al rivenditore né tantomeno al cliente interessa conoscere nel dettaglio le specifiche della GPU, o Graphics Processing Unit, presente nello smartphone oppure nella tavoletta oggetto della compravendita.
Se sia giusto lo lascio decidere a voi. Vorrei tuttavia raccontare alcune implicazioni, sia per l’utente finale che per lo sviluppatore di app, dell’avere a che fare con schede grafiche diverse nei dispositivi nelle vostre tasche. Se non siete del settore però, per capirci qualcosa devo ahimé srotolarvi una velocissima introduzione alla unità di elaborazione grafica (traduzione di GPU).
Partirò dallo schermo e quindi penetrerò verso il grosso chip della scheda grafica; perdonatemi da subito leggerezze ed eventuali semplificazioni. Unico presupposto: avere una vaga idea di cosa sia un bit e dell’ordine di grandezza di un byte, un megabyte, un gigabyte e via dicendo.

Dentro la matrice

Lo schermo del dispositivo, come quello di un computer, è composto da una matrice (o griglia) rettangolare di punti o pixel, ognuno dei quali può comporre una terna RGB composta da 256 valori di rosso(R), verde(G) e blu(B) per colorare la cella di un colore desiderato. Per scrivere il numero 256 in binario servono almeno otto bit, quindi per tre colori primari servono 24 bit per pixel (bpp) e quindi circa sedici milioni di combinazioni possibili. Si parla di profondità colore a 24 bit, o truecolor.
Il numero di celle della matrice di pixel determina la risoluzione dello schermo. Se stiamo utilizzando una risoluzione Full HD di 1920×1080 abbiamo davanti a noi 2.073.600 pixel che, per essere colorati, richiedono 24 x 2.073.600 = 49.766.400 bit = circa sei megabyte di dati, di fatto residenti in una particolare sezione di memoria della GPU che prende il nome di framebuffer. Ad ogni refresh dello schermo, che negli smartphone e nei tablet avviene 30 o 60 volte al secondo, la GPU rileva il colore di ogni pixel leggendo dal framebuffer.
Modificando nel tempo il framebuffer (o parte di esso) attraverso chiamate alle API (interfacce di programmazione) della scheda grafica, possiamo disegnare e creare animazioni sullo schermo. Ad esempio, se volessimo ridisegnare l’intero schermo 60 volte al secondo avremmo bisogno di un flusso di 6 megabyte x 60 hertz = 360 megabyte per secondo di dati sul nostro framebuffer (ovvero di banda passante). Quando la scrittura sul framebuffer avviene direttamente su ordine della CPU abbiamo un esempio di accelerazione 2D, mentre se interponiamo il nostro processore grafico tra questi due elementi per eseguire un rendering 3D parliamo di accelerazione 3D.
Senza entrare nel merito del funzionamento della pipeline di rendering, per utilizzare immagini bidimensionali (texture) su disco fisso bisogna sapere che ogni applicazione (sia 2D che 3D) deve necessariamente precaricare in memoria video la matrice di punti che compongono l’immagine stessa – in un formato riconosciuto – così da leggerne il contenuto e trasferire informazioni sul framebuffer ad una velocità sufficiente da non rappresentare un collo di bottiglia per l’intero processo. Una texture può avere, a seconda delle esigenze, da uno a quattro canali:

  1. monocanale, o alpha, per memorizzare immagini in bianco e nero o maschere di trasparenza.
  2. due canali o RG, formato raramente utilizzato.
  3. tre canali o RGB, per immagini a colori senza trasparenze.
  4. quattro canali o RGBA, per memorizzare immagini a colori con trasparenze o semitrasparenze.

Tornando al punto iniziale, ciò che cambia (tra l’altro) tra una GPU e l’altra sono i formati texture riconosciuti dall’hardware. Il formato compatibile con tutte le GPU ma al contempo più pretenzioso in termini di memoria video è il non compresso a quattro o otto bit per canale (16/32 bpp). Affiancati a questi, secondo il chip, possiamo trovare i seguenti formati compressi nei più diffusi tablet e smartphone:

  • PVRTC: PowerVR Texture Compression, RGB/RGBA a 2 o 4bpp
  • ETC: Ericsson Texture Compression RGB
  • S3TC: S3 Texture Compression o DXTC
  • ATC: AMD Texture Compression

Utilizzando uno di questi formati è possibile risparmiare un quantitativo considerevole di memoria e conseguentemente di banda passante. Segue una tabella riassuntiva che evidenzia l’ingombro in rapporto alla risoluzione ed al formato della texture.

FORMATO TEXTURE 512X512 1024X1024 2048X2048 4096×4096
RGBA 32 bpp – non compresso 1 MB 4 MB 16 MB 64 MB
RGB 24 bpp – non compresso 750 kB 3 MB 12 MB 48 MB
RGBA 16 bpp – non compresso 512 kB 2 MB 8 MB 32 MB
RGB 12 bpp – non compresso 375 kB 1,5 MB 6 MB 24 MB
Alpha 8 bpp – non compresso 250 kB 1 MB 4 MB 16 MB
PVRTC RGBA 4 bpp 128 kB 512 kB 2 MB 8 MB
PVRTC RGB 4 bpp 128 kB 512 kB 2 MB 8 MB
PVRTC RGBA 2 bpp 64 kB 256 kB 1 MB 4 MB
PVRTC RGB 2bpp 64 kB 256 kB 1 MB 4 MB
ETC RGB 4 bpp 128 kB 512 kB 2 MB 8 MB
DXT1 RGB 4 bpp 128 kB 512 kB 2 MB 8 MB
DXT5 RGBA 8 bpp 250 kB 1 MB 4 MB 16 MB
ATC RGB 4 bpp 128 kB 512 kB 2 MB 8 MB
ATC RGBA 8 bpp 250 kB 1 MB 4 MB 16 MB

 
È bene sottolineare che stiamo parlando di compressioni lossy (con sacrificio di informazioni non essenziali) e quindi, a seconda della natura dell’algoritmo e dei parametri di compressione, sarà necessario gestire artefatti e rumore all’interno dell’immagine processata.
Pongo un caso reale: sviluppiamo un gioco multipiattaforma per iOS, Android e PC. Ipotizziamo che il progetto sia destinato solo a dispositivi high-end e necessiti di tre texture: una RGBA a 32 bpp 1024×1024 per i menu più due 4096×4096, una con trasparenza ed una senza.
Per PC verranno proposte le configurazioni grafiche HD e SD lossless, per iOS due soluzioni HD ed SD compresse PVRTC (tutti i dispositivi iOS supportano questo formato) e quattro differenti soluzioni per Android: PVRTC HD, ATC, DXT ed ETC (tutti i dispositivi Android supportano ETC, mentre gli altri formati dipendono dalla GPU del dispositivo).

Versione 1024 x 1024 RGBA32 4096 x 4096 RGB 4096 x 4096 RGBA Totale
PC
HD
4 MB
(RGBA32)
48 MB
(RGB24)
64 MB
(RGBA32)
116 MB
PC
Normale
4 MB
(RGBA32)
24 MB
(RGB12)
32 MB
(RGBA16)
60 MB
iOS
PVRTC HD
4 MB
(RGBA32)
8 MB
(PVRTC-4bpp)
8 MB
(PVRTC-4bpp)
20 MB
iOS
PVRTC SD
4 MB
(RGBA32)
4 MB
(PVRTC-2bpp)
4 MB
(PVRTC-2bpp)
12 MB
Android
PVRTC HD
4 MB
(RGBA32)
8 MB
(PVRTC-4bpp)
8 MB
(PVRTC-4bpp)
20 MB
Android
DXT
4 MB
(RGBA32)
8 MB
(DXT1-4bpp)
16 MB
(DXT5-8bpp)
28 MB
Android
ATC
4 MB
(RGBA32)
8 MB
(ATC-4bpp)
16 MB
(ATC-8bpp)
28 MB
Android
ETC
4 MB
(RGBA32)
8 MB
(ETC-4bpp)
32 MB
(RGBA16)
44 MB

 
Notiamo come il risparmio ottenuto grazie alla compressione delle texture raggiunga, considerando l’intera forbice, un fattore 10. Notiamo anche come un dispositivo Android che monti una GPU compatibile con uno dei formati superiori allo standard (PVRTC, DXT, ATC) risparmi parecchio in confronto al formato ETC. Oltretutto il rispamio non è solo prestazionale: l’app peserà meno anche da “ferma”, per la gioia dei megabyte consumati del vostro abbonamento dati.
È quindi evidente il potenziale di una GPU con compressione hardware rispetto ai formati lossless, ma anche come i diversi produttori di GPU stiano lottando per l’imposizione del proprio formato sul mercato.
Dovere di noi sviluppatori è sfruttare questo potenziale piegando ogni singola texture ad ogni vizio del mercato, anche se tempi e costi spesso non lo permettono.
Dulcis in fundo, questa tabella solleva anche un’altra questione: quattro versioni Android, avrò installato quella giusta sul mio tablet? Ma di questo parleremo in un prossimo articolo.

Vuoi rimanere aggiornato?
Iscriviti alla nostra newletter

Novità, promozioni e approfondimenti per imparare sempre qualcosa di nuovo

Gli argomenti che mi interessano:
Iscrivendomi dichiaro di aver preso visione dell’Informativa fornita ai sensi dell'art. 13 e 14 del Regolamento Europeo EU 679/2016.