GLX sono le estensioni OpenGL del sistema X Window.
Come ogni altra estensione di X Window le GLX utilizzano il sistema di autenticazione e connessione di X e il flusso di comandi OpenGL tra il server e il client è incapsulato all'interno del protocollo di rete X Window.
Spesso per ragioni di performance oltre al procedimento tradizionale, che prende il nome di rendering indiretto, viene data la possibilità di ottenere l'accesso alla pipeline grafica evitando le operazioni di incapsulamento nel protocollo X. Questa soluzione viene denominata rendering diretto.
Elementi principali di GLX
GLX si basa su due principali entità, il Rendering Context e i GLXDrawables.
Il Rendering Context (RC) può essere considerato una astrazione della macchina a stati OpenGL, su di esso vengono effettuate tutte le operazioni di rendering da parte della libreria grafica. Il vantaggio di utilizzare un rendering context è quello di avere a disposizione un contesto virtuale indipendente dal sistema operativo o hardware sottostante.
Ci sono alcune limitazioni nell'utilizzo dei RC: un processo o thread non può avere più di un Rendering Context attivo in ogni momento e un dato Rendering Context non può essere attivo in più di un thread o processo alla volta.
Una nota importante quando ci si riferisce agli elementi di GLX è dato dall'address space, ovvero dalla spazio degli indirizzi nel quale un determinato oggetto è accessibile.
Un RC è composto da una parte server, la quale condivide alcuni informazioni con il server X come ad esempio il buffer attivo (in caso di double buffering) e il valore dei pixel nel X framebuffer, e da una parte client.
Normalmente quando si utilizza un rendering indiretto la sezione client è accessibile nell'address space del processo client mentre la sezione server lo è nello spazio di indirizzi del server X.
In questo modo una parte del RC (che può contenere diverse oggetti come le Display List e le Texture) sono disponibili per altri processi.
Al contrario, in caso di rendering diretto, entrambi le parti del RC sono disponibili nell'address space del client.
E' importante ricordare che il direct rendering è disponibile (sempre che l'implementazione OpenGL ne sia dotata) solo se il server X è sulla macchina locale, nel caso invece che la comunicazione client/server avvenga su rete l'incapsulazione dei comandi OpenGL nel X Byte Stream è inevitabile.
I GLXdrawables sono le superfici su cui è possibile disegnare e si distinguono in superfici di rendering onscreen e superfici di rendering offscreen.
Delle prime fanno parte le GLXWindow, ovvero aree rettangolari di pixel contenute nel framebuffer (nella memoria video), ogni GLXWindow è associata a una Window di X.
Le superfici di rendering offscreen sono invece le GLXPixmap e i GLXPBuffer, esse sono delle zone di memoria simili alle GLXWindow ma che non sono visibili a schermo.
I GLXPBuffer (come i WGL PBuffer per le piattaforme Windows) sono una innovazione abbastanza recente (supportate a partire dalla versione GLX 1.3) e si differenziano dalle GLXPixmap per il fatto di essere allocati nella zone non visibili del framebuffer.
Essendo contenuti nella memoria video le operazioni di rendering o di lettura sui PBuffer da parte della scheda grafica sono molto veloci rispetto alle operazioni analoghe sulle Pixmap mantenute nella RAM e quindi accessibili solo mediante BUS di sistema.
Configurazione del Frame Buffer
Per configurare il tipo di framebuffer da utilizzare per le operazioni di rendering OpenGL GLX mette a disposizione un set di funzioni che servono a manipolare e richiedere dei GLXFBConfig, oggetti che contengono la configurazione del buffer.
Attraverso questi oggetti è possibile selezionare le caratteristiche del FB che ci interessano e creare dei rendering context e dei drawables che rispettino le nostre richieste.
Associare rendering context e drawables
Per poter renderizzare con OpenGL è necessario associare il Rendering Context a un drawable, per farlo i due elementi devono essere compatibili, ovvero devono essere stati creati con lo stessa configurazione di GLXFBConfig.
Questo signifa che:
- Utilizzano lo stesso tipo di color buffer, RGBA o Index
- I buffer ausiliari (depth, stencil, accumulation etc.) sono configurati in modo identico
Infine sia il RC che il drawables devono far pare dello stesso X Screen ed appartenere allo stesso spazio di indirizzi (del client).
GLX permette di utilizzare un rendering context associato a più drawables oppure più rendering context (per esempio appartenenti a diversi thread) associati ad uno stesso drawable, a questo scopo i buffer ausiliari sono "attaccati" al drawable e non al RC in modo che le loro informazioni possano essere condivise tra i vari RC associati al drawable.
Purtroppo nonostante queste interessanti potenzialità il rendering parallelo su sistemi multiprocessore non è supportato dato che diversi RC non possono operare simultaneamente sullo stesso drawable.
Alcune implementazioni OpenGL, come quella di Sun per Solaris, sono MT-Safe (Multithread Safe) e garantiscono il rendering parallelo pagando però un prezzo in prestazioni.
Di fatto il consiglio è quello di utilizzare molteplici thread per il calcolo e per la gestione della GUI (comunicazione con X) ed un unico thread per il rendering OpenGL vero e proprio.