2012-02-14 11 views
6

Su MacOS X, è possibile renderizzare OpenGL su qualsiasi oggetto NSView di propria scelta, semplicemente creando un NSOpenGLContext e quindi chiamando -setView: su di esso. Tuttavia, puoi associare una sola visualizzazione a un singolo contesto OpenGL in qualsiasi momento. La mia domanda è, se voglio rendere OpenGL per due diversi punti di vista all'interno di una singola finestra (o possibilmente entro due finestre differenti), ho due opzioni:Cambia i contesti OpenGL o cambia destinazione del rendering del contesto, cosa è preferibile?

  1. Creare un contesto e cambiare sempre la vista, chiamando setView come appropriato ogni volta che voglio eseguire il rendering sull'altra vista. Funzionerà anche se le viste si trovano in finestre diverse o su schermi diversi.

  2. Creare due oggetti NSOpenGLContext e associare una vista a una delle due. Questi due contesti potrebbero essere condivisi, il che significa che la maggior parte delle risorse (come trame, buffer, ecc.) Saranno disponibili in entrambe le visualizzazioni senza sprecare il doppio della memoria. In tal caso, però, devo continuare a cambiare il contesto corrente ogni volta che voglio renderizzare l'altra vista, chiamando -makeCurrentContext nel giusto contesto prima di effettuare qualsiasi chiamata OpenGL.

ho infatti usato entrambe le opzioni in passato, ognuno di loro ha lavorato bene per le mie esigenze, però, mi sono chiesto, in che modo è migliore in termini di prestazioni, la compatibilità, e così via. Ho letto che il cambio di contesto è in realtà orribilmente lento, o almeno in passato era molto lento, potrebbe essere cambiato nel frattempo. Può dipendere dal numero di dati associati a un contesto (ad es. Risorse), poiché la commutazione del contesto attivo potrebbe causare il trasferimento dei dati tra la memoria di sistema e la memoria GPU.

D'altra parte, la visualizzazione potrebbe essere anche molto lenta, specialmente se ciò potrebbe causare il cambiamento del rendering sottostante; per esempio. se le due visualizzazioni fanno parte di due finestre diverse situate su due schermate diverse gestite da due adattatori grafici diversi. Anche se il renderer non cambia, non ho idea se il sistema esegua molte costose impostazioni OpenGL/clean-up quando si cambia una vista, come ad esempio la creazione/distruzione di oggetti render-/framebuffer.

risposta

4

Ho studiato il cambio di contesto tra 3 finestre su Lion, dove ho cercato di risolvere alcuni problemi di prestazioni con una libreria VTK un po 'usurata, che a sua volta è già molto lenta.

Sia che passa rendere contesti o le finestre non ha molta importanza, perché c'è sempre il sovraccarico di fare entrambe corrente al thread chiamante come una tripla. Ho misurato all'incirca 50ms per switch, dove alcuni overhead del gestore OS/Window si accontentano. Questo overhead dipende anche molto dalla disposizione delle altre chiamate GL, poiché il driver potrebbe essere costretto ad attendere il completamento dei comandi, che può essere ottenuto manualmente da una chiamata di blocco a glFinish().

Il setup più efficiente che ho funzionato è simile al tuo 2o, ma ha due thread di rendering dedicati con il loro contesto di rendering (condiviso) e la finestra vincolata in modo permanente. I suddetti interruttori/collegamenti di contesto vengono eseguiti una sola volta su init.

I thread possono essere controllati utilizzando alcune operazioni di threading come una barriera comune, che consente a entrambi i thread di rendere singoli fotogrammi sincronizzati (entrambi vengono bloccati sulla barriera prima che possano essere nuovamente avviati). La gestione dei dati deve anche essere interbloccata, operazione che può essere eseguita in un thread mentre si bloccano altri thread di rendering.

+0

I 50 ms, si riferiscono alla commutazione di GLContext o al cambio di destinazione del rendering? E se si riferiscono al primo, i contesti sono stati condivisi o non condivisi? – Mecki

+0

I contesti sono stati condivisi (obbligatorio), il sovraccarico era più o meno costante e derivava dal rendere diverse coppie di finestre e renderizzare i contesti attuali, indipendentemente da quale si modificava. Questa misurazione non può essere una verità generale, dal momento che non ho misurato l'overhead di commutazione senza dati condivisi o senza chiamate in attesa. È possibile che tu possa misurare le differenze per entrambi i tuoi approcci nel tuo caso specifico (con o senza disegno). – Sam

+2

Bene, ho provato a confrontare il sovraccarico del contesto con un benchmark sintattico, utilizzando contesti non condivisi con una sola risorsa (una trama molto grande) in ognuno di essi e senza chiamate di disegno in sospeso. Il risultato è stato che sono possibili circa 50'000 interruttori di contesto al secondo. Questo suona piuttosto bene, ma deve essere preso con un pizzico di sale, dal momento che, onestamente, quanto è realistico questo punto di riferimento? Quale app avrebbe quelle piccole risorse o mai nessuna chiamata in sospeso? Quindi il tuo numero è probabilmente molto migliore del mio, almeno più realistico. – Mecki

Problemi correlati