Sto facendo qualche ricerca su come funziona la maggior parte delle librerie GUI con accelerazione hardware. In realtà mi preoccupo solo dei rendering backend di loro qui. Sto cercando di capire quale sarebbe il modo migliore per provare a scrivere il mio come una sorta di progetto parallelo. Sto cercando di andare per la massima performance qui invece di funzioni troppo stravaganti. Voglio poter disegnare primitive, testo e animazioni.
Alcune buone librerie che conosco sono Qt, Skia e Cairo (anche se non sono sicuro di quale sia lo stato di HWA su di esso). Ho anche guardato NanoVG che è una piccola libreria che sembra avere un seguito decente. Tuttavia, non sono riuscito a ottenere prestazioni decenti con NanoVG ...
L'unica cosa che mi ha colpito è che tutte queste librerie sembrano utilizzare il concetto di "pittura" dove sembra che ogni forma primitiva venga estratta da zero più e più volte. Quello che intendo è che dalle API, non sembra che le forme siano create come "oggetti" sulla GPU o qualunque sia la terminologia e quindi lasciate lì per essere rese "automaticamente". In altre parole, non vengono lasciati nella memoria della GPU per essere ridisegnati in un grande loop. Per elaborare, sembra che per ogni i.e. rettangolo che deve essere disegnato, un intero stato OpenGL è impostato solo per il rendering di quel rettangolo e quindi viene nuovamente distrutto. Tuttavia, sembra che queste forme renderizzate siano almeno renderizzate nelle loro destinazioni finali, consentendo alla GPU di comporre l'intera scena.
Il modo in cui mi aspettavo che queste librerie funzionassero è in realtà l'archiviazione dell'intera scena sulla GPU (scusate la terminologia orribile). Per esempio, le primitive sarebbero state triangolate e lasciate in memoria dove dopo un processo complesso sarebbe stato usato per avere un ciclo di rendering principale per la scena. Inoltre, ci sarebbero i meccanismi per aggiornare gli attributi o eliminare o aggiungere le primitive. Questa è una descrizione abbastanza vaga, ma penso che tu abbia l'idea.
Quello che vorrei chiedere ora è se c'è un vantaggio in termini di prestazioni nell'approccio "pittura" rispetto all'approccio "salvato" (di nuovo, non c'è idea se esistano nomi propri per queste cose ...). Forse alcuni complicati meccanismi di caching? O è molto più semplice lavorare con?
Mi rendo conto che l'approccio "salvato" potrebbe utilizzare più memoria sulla GPU ma tutte le chiamate OpenGL necessarie per l'approccio "pittura" non sono molto costose? Immagino che si possa essere in grado di compensare questo problema memorizzando nella cache le forme renderizzate, ma la GPU offre davvero un vantaggio così grande quando si esegue una rasterizzazione così una tantum (o non molto regolare) rispetto alla CPU, specialmente data la comunicazione in testa? Inoltre, questo overhead di comunicazione non pone seri problemi alle animazioni quando si deve eseguire il disegno per ogni frame?
Sono abbastanza certo che NanoVG non abbia un meccanismo di caching interno e presumo che questo potrebbe essere responsabile delle sue prestazioni piuttosto scialbe. Qt d'altra parte sembra avere prestazioni eccellenti, quindi deve fare qualcosa di giusto. Google sembra anche in grado di mettere Skia a buon uso.
PS. Non sono un professionista di nessun tipo e solo di recente ho iniziato ad imparare OpenGL.
EDIT: Un'altra possibilità che ho pensato è che forse l'approccio alla "pittura" è stato ritenuto necessario unicamente a causa dei benefici della memoria? La ragione per cui penso sarebbe che tutte queste librerie sono state ovviamente avviate in un'era diversa e hanno anche indirizzato le piattaforme embedded, il che significa che la memoria della GPU potrebbe essere così scarsa sulle piattaforme target (ed) e che usare il meno possibile di essa potrebbe essere più importante delle prestazioni. Tuttavia, in una situazione come questa, non sono convinto che la rasterizzazione della GPU frame-by-frame data l'overhead della comunicazione possa sovraperformare una CPU, specialmente considerando il numero di pixel probabilmente basso su piattaforme con così poca memoria.
Inoltre ho letto su link che Qt apparentemente unisce il codice shader dei segmenti precodificati in fase di esecuzione prima di "dipingere" e quindi spera che il compilatore OGL inserisca correttamente il codice in fase di runtime. Questo suona come l'ulteriore inizializzazione OGL per me ...