Che cosa causa fluttuazioni dei tempi di esecuzione al momento della presentazione del Renderbuffer?(OpenGL)

StackOverflow https://stackoverflow.com/questions/677211

  •  21-08-2019
  •  | 
  •  

Domanda

Questo è quello che succede:

  • Il drawGL funzione è chiamata alla data esatta della fine del telaio grazie a un usleep, come suggerito.Questo già si mantiene stabile il framerate.

  • La presentazione vera e propria del renderbuffer avviene con drawGL().Misura il tempo necessario per fare questo, mi fluttuante i tempi di esecuzione, risultante in una balbuzie nella mia animazione. Questo timer utilizza mach_absolute_time così è estremamente precisa.

  • Alla fine del mio telaio, mi misura timeDifference.Sì, è in media di 1 millisecondo, ma si discosta molto, che vanno da 0,8 millisecondi a 1.2 con picchi fino a più di 2 millisecondi.

Esempio:

// Every something of a second I call tick
-(void)tick
{
  drawGL(); 
}

- (void)drawGL
{   
  // startTime using mach_absolute_time;

  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
  [context presentRenderbuffer:GL_RENDERBUFFER_OES];

 // endTime using mach_absolute_time;
 // timeDifference = endTime - startTime;
}

La mia comprensione è che una volta che il framebuffer è stato creato, presentando il renderbuffer dovrebbe sempre prendere lo stesso sforzo, indipendentemente dalla complessità del telaio?È vero questo?E se no, come posso evitare questo?

A proposito, questo è un esempio di una applicazione per iPhone.Quindi stiamo parlando di OpenGL ES qui, anche se non credo che si tratta di una piattaforma problema specifico.Se lo è, che cosa sta succedendo?E non dovrebbe essere questo non accadendo?E ancora, se è così, come posso evitare che ciò accada?

È stato utile?

Soluzione

Le deviazioni che si incontrano forse essere causato da un sacco di fattori, tra utilità di sistema operativo che entra e dà la cpu ad un altro processo o questioni simili.Infatti umano normale non capire la differenza tra 1 e 2 ms tempi di rendering.Le immagini in movimento, eseguito a 25 fps, il che significa che ogni frame viene visualizzato per circa 40ms e sembra fluido per l'occhio umano.

Come per l'animazione balbuzie si dovrebbe esaminare il modo in cui mantenere costante la velocità di animazione.Approccio più comune ho visto sembra all'incirca come questo:

while(loop)
{
  lastFrameTime; // time it took for last frame to render
  timeSinceLastUpdate+= lastFrameTime;

  if(timeSinceLastUpdate > (1 second / DESIRED_UPDATES_PER_SECOND))
  {
     updateAnimation(timeSinceLastUpdate);
     timeSinceLastUpdate = 0;
  }

  // do the drawing

  presentScene();
}

Oppure si può semplicemente passare lastFrameTime per updateAnimation ogni fotogramma e l'interpolazione tra animazione e stati uniti.Il risultato sarà ancora più fluido.

Se stai già usando qualcosa come sopra, forse si dovrebbe cercare colpevoli in altre parti del tuo render loop.In Direct3D le cose preziose sono state le chiamate per le primitive di disegno e modifica di rendering stati, così si potrebbe desiderare di controllare in giro per OpenGL farmaceutici di quelli.

Altri suggerimenti

Il mio preferito OpenGL espressione di tutti i tempi: "l'attuazione di specifici".Penso che si applica qui molto bene.

Una rapida ricerca per mach_absolute_time risultati in questo articolo: Link

Sembra di precisione di che il timer su un iPhone è solo 166.67 ns (e forse peggio).Mentre questo può spiegare la grande differenza, non spiega che c'è una differenza a tutti.

I tre motivi principali sono probabilmente:

  • Diversi percorsi di esecuzione durante renderbuffer presentazione.Molto può accadere in 1ms e solo perché si chiama le stesse funzioni con gli stessi parametri non significa l'esatto le stesse istruzioni vengono eseguite.Questo è particolarmente vero se gli altri componenti sono coinvolti.
  • Interrupt/altri processi, c'è sempre qualcos'altro che distrae la CPU.Per quanto ne so l'iPhone OS non è un sistema operativo real-time e quindi non c'è alcuna garanzia che qualsiasi operazione verrà completata entro un certo limite di tempo (e anche un sistema operativo real-time vi sono variazioni di tempo).
  • Se ci sono altre chiamate di OpenGL ancora in fase di elaborazione da parte della GPU che potrebbe ritardare la presentRenderbuffer.Questo è il modo più semplice per eseguire il test, basta chiamare glFinish() prima di ottenere il tempo di avvio.

È meglio non fare affidamento su di un'alta costante frame rate per una serie di ragioni, la più importante è che il sistema operativo può fare qualcosa in background che rallenta cose.Meglio il campione di un timer e di capire quanto tempo è passato ogni fotogramma, questo dovrebbe assicurare una buona animazione.

È possibile che il timer non è preciso al sub ms di livello, anche se è un ritornare decimali 0.8->2.0?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top