2013-06-11 17 views
11

WebGL è bello e asincrono in quanto è possibile inviare una lunga lista di comandi di rendering senza attendere il completamento. Tuttavia, se per qualche motivo hai bisogno di attendere il completamento del rendering, devi farlo in modo sincrono con gl.finish(). Sicuramente sarebbe meglio se gl.finish accettasse una richiamata e restituisse immediatamente?WebGL è possibile emulare una chiamata asincrona a gl.finish()

Domanda: C'è un modo per emularlo in modo affidabile?

caso Uso: Sto rendering di un gran numero di vertici per una grande tela fuori dallo schermo e quindi utilizzando drawImage per copiare sezioni di questo grande tela di piccole tele sulla pagina. In realtà non uso gl.finish() ma drawImage() sembra avere lo stesso effetto. Nella mia applicazione, il re-rendering viene attivato solo quando l'utente esegue un'azione (ad esempio facendo clic su un pulsante) e potrebbe richiedere diverse centinaia di millisecondi. Sarebbe bello se durante il rendering il browser fosse ancora reattivo permettendo lo scrolling ecc. Sto cercando in particolare una soluzione Chrome, anche se qualcosa che funziona anche con Firefox e Safari sarebbe buono.

Possible (cattiva) risposta: Si potrebbe cercare di stimare quanto tempo il rendering sta andando a prendere e quindi impostare un timeout che inizia con la chiamata a gl.finish(). Tuttavia, fare in modo affidabile questa stima per tutte le dimensioni del vertex buffer e tutti gli utenti sarà piuttosto complicato e impreciso.

Possibile risposta (non):requestAnimationFrame fa quello che sto cercando ... non lo fa, vero?

+0

Non è possibile eseguire il rendering dalla stessa pagina, con 'async' gl.finish() poiché non esiste una versione asincrona.Se il disegno di un'immagine fuori schermo è considerato "pesante", è possibile utilizzare Web Worker per generarlo, quindi postare nuovamente Message con tale immagine e disegnarlo su tela. Ciò salverebbe leggermente le prestazioni, ma il disegno deve essere sincronizzato. Ridurre la risoluzione della tela potrebbe velocizzarlo. – moka

+0

@MaksimsMihejevs - il rendering di un'immagine da un web worker sarebbe asincrono, ma sarebbe utilizzare la CPU non la GPU, quindi sarà molto più lento. (Non puoi accedere a WebGL da WebWorkers.) –

+0

Ho parlato più del contesto di canvas 2d, come hai menzionato 'drawImage'. – moka

risposta

4

Hai già parzialmente risposto alla tua risposta: drawImage() ha effettivamente un comportamento simile al finale in quanto obbliga tutti i comandi di disegno in sospeso a completare prima di leggere i dati dell'immagine. Il problema è che anche se gl.finish() facesse quello che volevi, attendi il completamento del rendering, avresti comunque lo stesso comportamento usandolo come fai ora. Il thread principale verrebbe bloccato mentre il rendering termina, interrompendo la capacità dell'utente di interagire con la pagina.

Idealmente, ciò che si vorrebbe in questo scenario è una sorta di callback che indica quando una serie di comandi di disegno sono stati completati senza effettivamente bloccarli per attenderli. Sfortunatamente non esiste una tale callback (e sarebbe sorprendentemente difficile fornirne una, dato il funzionamento degli interni del browser!)

Un discreto mezzo di comunicazione nel tuo caso potrebbe essere quello di fare delle stime intelligenti di quando senti l'immagine potrebbe essere pronto Ad esempio, una volta che hai inviato la chiamata di estrazione, fai scorrere fino a 3 o 4 requestAnimationFrame s prima di chiamare drawImage. Se osservi costantemente che impiega più tempo (10 fotogrammi?), Ruota più a lungo. Ciò consentirebbe agli utenti di continuare ad interagire con la pagina normalmente e non produrre alcun ritardo quando si fa l'immagine di disegno, perché il contenuto ha finito il rendering, o molto meno ritardo perché si fa il passo sincrono a metà del rendering. A seconda dell'uso previsto del tuo sito, il rendering non in tempo reale potrebbe probabilmente continuare a girare per un secondo intero prima della presentazione.

Questa certamente non è una soluzione perfetta, e vorrei avere una risposta migliore per voi. Forse WebGL otterrà la possibilità di interrogare questo tipo di stato in futuro, perché sarebbe utile in casi come il tuo, ma per ora questo è probabilmente il meglio che puoi fare.

+0

Ho appena letto il tuo [post Webgl 2.0] (http://blog.tojicode.com/2013/09/whats-coming-in-webgl-20.html). Avrei ragione nel pensare che gli oggetti di sincronizzazione risolverebbero il problema qui? –

Problemi correlati