reinterpretcast
Nell’esempio precedente può inizialmente sembrare che una frequenza di aggiornamento di 0,26 Hz e un framerate di 0,2 FPS (Frames Per Second) possano essere abbastanza vicini da essere visualizzati correttamente, tuttavia è chiaro guardando la demo che i due sono completamente fuori sincrono e quindi lo screen tearing si verifica regolarmente.
Il vero problema con questo esempio è che si tratta di una ‘applicazione single-buffered’. Scriviamo i nostri fotogrammi direttamente nel buffer che viene alimentato al display, e così quando il display vuole aggiornare la sua immagine, c’è il rischio che riceva un fotogramma che non è ancora completamente finito. In un’applicazione reale il framerate può spesso cambiare drasticamente a seconda di certe circostanze, il che può peggiorare questo problema nelle applicazioni a singolo buffer e rendere lo screen tearing ancora più imprevedibile.
Double Buffering
Un modo per alleviare alcuni di questi problemi è usare il double-buffering. Questo metodo di disegno consiste nello scrivere i dati del fotogramma in un back buffer, e poi copiarli sul buffer primario (il feed video per il display) solo quando un fotogramma è completo. In questo modo l’utente non vedrà mai nessun fotogramma mezzo completato, giusto? Sbagliato.
Mentre lo screen tearing tende ad essere ridotto significativamente con il doppio buffering, la copia dei dati richiede tempo, e come tale è completamente possibile che il monitor aggiorni la sua immagine a metà del processo di copia del buffer! Questo problema può essere visualizzato esattamente come il tearing a singolo buffer – nella demo precedente, immagina solo che i pixel che vengono scritti nel buffer primario non siano generati direttamente dalla scheda grafica, ma siano invece messi nel buffer in modo sequenziale come risultato di un’operazione di copia da un buffer secondario.
Double Buffering + VSync
Un’ulteriore tattica di attenuazione è l’uso del VSync. Abbreviazione di ‘sincronizzazione verticale’, VSync funziona lasciando che il buffer posteriore scriva sul buffer primario solo dopo che il display si è aggiornato. La speranza è che l’operazione di copia del buffer sia completa prima del prossimo refresh. Questo funziona nel ridurre drasticamente lo screen tearing, tuttavia ha i suoi problemi.
Se avete un’applicazione ad alto framerate, VSync di solito funziona perfettamente. Il tuo framerate è limitato alla frequenza di aggiornamento del tuo monitor, ma questo va bene perché il tuo monitor visualizzerebbe comunque a quella frequenza. Il problema arriva quando raggiungi un framerate inferiore alla frequenza di aggiornamento del tuo display.
Si supponga di raggiungere 60 FPS su un monitor a 75 Hz – ciò significa che il frame buffer si sta aggiornando all’80% della frequenza di aggiornamento. Se VSync è abilitato, i fotogrammi devono essere copiati nel buffer dello schermo a una suddivisione della frequenza di aggiornamento. In questo caso, l’applicazione mancherà la ‘scadenza’ ad ogni altro ciclo, quindi ci ritroveremo con la metà della frequenza di aggiornamento come nostro framerate: 37,5 FPS. Questo è significativamente inferiore ai 60 FPS che la scheda grafica può raggiungere.
Il TL;DR per il VSync a doppio buffer è che se si ottiene un FPS costantemente più alto del proprio refresh rate, può essere una buona idea per ridurre lo screen tearing, ma se l’FPS scenderà sotto il refresh rate del proprio display, il VSync può ridurre significativamente gli FPS.
Triple Buffering + VSync
Il santo graal di tutto questo casino è solitamente il triple buffering con VSync. Il limite del VSync con doppio buffering è che il framerate può diminuire significativamente a causa del tempo speso ad aspettare il momento giusto per copiare il buffer secondario nel buffer primario. L’attesa spesso non è un’idea fantastica in informatica dove può essere evitata, quindi una soluzione in questo caso è semplicemente aggiungere un altro buffer.
Con tre buffer, i due buffer posteriori possono essere attinti alternativamente in modo che sia sempre il caso che un buffer sia completo e uno sia in corso. Questo significa che subito dopo un aggiornamento del monitor, qualsiasi buffer sia attualmente completo può essere copiato nel buffer primario – fornendo i vantaggi del VSync senza lo svantaggio del framerate discusso in precedenza.
Lo svantaggio principale del triple buffering dove è disponibile nelle applicazioni è che occupa più memoria – se stiamo parlando di schede grafiche, questo significa più VRAM (Video RAM). Questa è una memoria veloce usata direttamente dalla scheda grafica, e quindi in alcuni casi il triple buffering potrebbe causare un significativo calo degli FPS mentre la RAM a latenza più alta viene usata per compensare la mancanza di VRAM nativa. In genere questo non è un problema enorme, poiché la quantità di memoria occupata dal terzo buffer è spesso piccola rispetto alla dimensione totale della VRAM, tuttavia VSync con solo due buffer può fornire un framerate migliore in alcuni casi molto di nicchia! Gira e rigira, eh?