Nell’appuntamento della scorsa settimana abbiamo visto come funziona l’infrastruttura grafica attuale in un ambiente X11. Nell’articolo di oggi analizzeremo l’architettura di wayland.
Mentre nell’attuale architettura il compositor comunica con il server grafico in wayland il compositor è il vero e proprio server grafico. Il controllo del Kernel Mode Setting e degli eventi viene gestito direttamente dal compositor. Gli eventi in input sono spediti direttamente ai client e i client mandano il “damage event” direttamente al compositor.
La figura rappresenta cosa avviene nello scenario presentato nel precedente articolo, dall’occorrenza di un evento di un dispositivo di input (il classico click del mouse) a quando i cambiamenti che questo evento porta vengono rappresentati su schermo (per esempio il ridimensionamento di una finestra).
- Il kernel registra un evento e lo invia al compositor in maniera analoga a quanto avviene con X. Il fatto che la gestione degli eventi sia analoga a quella di X permette di riutilizzare tutti i driver di input del kernel senza doverli riscrivere.
- Il compositor analizza lo scenegraph per determinare la finestra bersaglio dell’evento. Lo scenegraph è una struttura dati che contiene al suo interno la rappresentazione ti tutto ciò che viene mostrato a schermo. In questo modo il compositor, conoscendo le possibili trasformazioni che sono state applicate, è in grado di selezionare la finestra giusta e trasformare le coordinate globali dello schermo in coordinate locali della finestra. L’unica limitazione al tipo di trasformazioni è ovviamente la capacità del compositor di calcolare la trasformazione inversa per gli eventi di input.
- Come nel caso di X, alla ricezione dell’evento il client aggiornerà l’interfaccia grafica. A differenza di X nel caso di wayland, il rendering avviene lato client, e al compositor viene mandata una richiesta che contiene soltanto la regione che è stata aggiornata.
- Il compositor raccoglie le varie “damage request” dai client e ricompone la scena. A questo punto attraverso una system call di tipo ioctl può schedulare un pageflip grazie al KMS.
Naturalmente la fase più delicata è il rendering lato client. La parte del rendering avviene con lo stesso meccanismo del “direct rendering” attualmente presente in X. Il direct rendering consiste nella condivisione tra server e client di un buffer di memoria. Attraverso l’utilizzo di librerie come OpenGL il client renderizza direttamente nel buffer condiviso. A questo punto il compositor può prendere il buffer e utilizzarlo come texture in fase di composizione del desktop.
Dopo la fase di inizializzazione, il client ha solo il compito di dire al compositor quale buffer utilizzare e quando e dove ha renderizzato il nuovo contenuto al suo interno.
In questo modo una applicazione ha 2 modi per aggiornare il contenuto della propria finestra.
- Renderizzare il contenuto in un nuovo buffer e comunicare al compositor di utilizzarlo al posto del vecchio. L’applicazione può allocare un nuovo buffer ogni volta che si renda necessario aggiornare la finestra o in alternativa mantenere due o più buffer su cui lavorare. La gestione dei buffer è quindi interamente sotto il controllo dell’applicazione.
- Renderizzare il nuovo contenuto nel buffer passato precedentemente al compositor. Nonostante sia possibile renderizzare direttamente all’interno del buffer condiviso con il compositor, si potrebbero avere situazioni di corsa critica. Una tipica situazione è quella in cui il ridisegno della finestra venga interrotto dal compositor che sta ridisegnando il desktop. Se l’applicazione dopo l’inizializzazione ma prima che abbia finito il repaint il compositor utilizzerà per la scena un frame bianco o incompleto causando l’effetto conosciuto come “flickering”. Il metodo tradizionale per evitare questo comportamento è quello di utilizzare un backbuffer per i nuovi contenuti che verrà poi copiato nel front buffer del compositor. Anche in questo caso il controllo è sempre lato client.
In entrambi i casi, l’applicazione deve comunicare al compositor quale zona della superficie contiene dati aggiornati. Quando l’applicazione renderizza direttamente nel buffer condiviso, il compositor deve essere avvisato della presenza di nuovi contenuti. Anche nel caso di scambio di buffer, il compositor non assume mai che qualcosa sia cambiato e necessita di una richiesta esplicita dell’applicazione prima di ridisegnare il desktop. Questa scelta è stata fatta considerando che spesso anche passando un nuovo buffer al compositor solo una piccola parte può essere diversa (Pensate ad un cursore che lampeggia o ad un menu a tendina).
Il secondo appuntamento finisce qui. Nella prossima puntata vedremo di fare il punto della situazione tenendo conto delle sfide che attendono questo giovane e promettente progetto.