2010-03-29 12 views
10

Apple's Technical Q&A on addressing flickering (QA1650) incluye el siguiente párrafo. (Énfasis mío.)¿Cómo mejora glClear() el rendimiento?

Debe proporcionar un color a cada píxel en la pantalla. Al comienzo de su código de dibujo, es una buena idea usar glClear() para inicializar el búfer de color. Una pantalla completa despejada de cada uno de sus búferes de color, profundidad y esténcil (si los está utilizando) al comienzo de un cuadro generalmente también puede mejorar el rendimiento de su aplicación.

En otras plataformas, siempre he encontrado que sea una optimización de no borrar el buffer de color si se va a llamar a cada píxel. (¿Por qué perder el tiempo llenando el búfer de color si solo va a sobrescribir ese color claro?)

¿Cómo puede una llamada a glClear() mejorar el rendimiento?

+0

No ha sido el caso que descuidar borrar el búfer de color/profundidad/plantilla sería una optimización del rendimiento durante muchos años. Como se explica en algunos de mis comentarios sobre las otras respuestas, tiene que ver con la compresión del búfer en las GPU modernas. En las GPU modernas estoy hablando de la serie Radeon 9xxx. La eliminación de estos búferes es en realidad una ganancia de rendimiento en prácticamente todas las arquitecturas GPU. –

Respuesta

15

Lo más probable es que esté relacionado con la representación basada en mosaicos, que divide toda la ventana gráfica en mosaicos (ventanas más pequeñas, normalmente pueden tener un tamaño de 32x32) y estas fichas se guardan en memorias más rápidas. Las operaciones de copia entre esta memoria más pequeña y el framebuffer real pueden llevar algo de tiempo (las operaciones de memoria son mucho más lentas que las operaciones aritméticas). Al emitir un comando glClear, le está diciendo al hardware que no necesita contenido previo de memoria intermedia, por lo tanto, no necesita copiar el color/profundidad/lo que sea desde el framebuffer a la memoria de mosaico más pequeña.

+1

Si necesita más detalles, consulte estas referencias: - http://developer.amd.com/gpu_assets/gdc2008_ribble_maurice_TileBasedGpus.pdf - http://www.beyond3d.com/content/articles/38/ – AdilYalcin

+0

Es relacionado con la compresión de color/profundidad/stencil también. En pocas palabras, borrar el búfer con los medios adecuados hará que cada tesela (* esto también se aplique a GPU regulares, no solo a Render Diferido basado en Azulejos como los de PowerVR *) sea más fácil de comprimir y mejore el rendimiento. La compresión de estos buffers no se realiza para ahorrar espacio de almacenamiento, sino para reducir la cantidad de datos que se deben transferir. Limpiar las fichas es una cuestión trivial de establecer algunos bits en cada ficha y, una vez hecho esto, una ficha eliminada es muy barata de recuperar de la memoria. –

-4

Definitivamente puedo confirmar que tiene que proporcionar un color a cada píxel en la pantalla.

He verificado esto en una aplicación de prueba esqueleto construido sobre la plantilla iPhone OpenGL de XCode:

[context presentRenderbuffer:GL_RENDERBUFFER]; 
glClear(GL_COLOR_BUFFER_BIT); 

Si dejo fuera de la línea de glClear (o moverlo más abajo en el bucle, después de algún otro OpenGL llamadas), el hilo (que se ejecuta a través de CADisplayLink) ya casi no recibe ninguna actualización. Parece como si la sincronización CPU/GPU se vuelve loca y el hilo se bloquea. Bastante aterrador, si me preguntas, y no concuerda totalmente con mis expectativas.

Por cierto, no es necesario tener que usar glClear(), simplemente dibujar un quad de pantalla completa parece tener el mismo efecto (obviamente, con textura quad es más caro). Parece que solo tienes que invalidar todas las fichas.

+2

** - 1 **: Debe usar 'glClear (...)', las GPU modernas usan el buffer de color, el buffer de profundidad y la compresión del buffer de esténcil. La eliminación del búfer es extremadamente económica porque estos búferes suelen estar jerárquicamente en mosaico, y el proceso de borrar el búfer equivale a invertir uno o dos bits en cada mosaico. Incluso ayuda con muchas pruebas de fragmentos iniciales y con el rendimiento general del búfer de cuadros si borra regularmente los búferes. En GPU de renderizado diferido basado en mosaico (por ejemplo, PowerVR SGX, todos los dispositivos con iOS), es igualmente importante por motivos similares. –

3

Con la larga perspectiva de los comentarios oficiales en iOS 4, que es posterior a la respuesta aceptada ...

creo que debe leerse conjuntamente con los comentarios de Apple sobre la extensión GL_EXT_discard_framebuffer, que siempre deben ser utilizados en el final de un marco si es posible (y de hecho en otro lugar). Cuando descarta un búfer de cuadros, coloca sus contenidos en un estado indefinido. El beneficio de esto es que cuando unes otro búfer de cuadros, nunca hay necesidad de almacenar el contenido actual de tu búfer en algún lugar, y de manera similar, cuando vuelvas a restaurar tu búfer no hay necesidad de recuperarlos. Esas deberían ser todas copias de memoria GPU y, por lo tanto, bastante baratas, pero están lejos de ser gratis y la arquitectura de memoria compartida del iPhone probablemente significa que pueden surgir consideraciones aún más complicadas.

Según el modelo de composición de iOS, es razonable suponer que incluso si su aplicación no vincula y desconecta búferes de marcos en su contexto, la GPU tiene que realizar esas tareas implícitamente al menos una vez para cada fotograma.

Me atrevo a adivinar que el controlador es lo suficientemente inteligente como para que si lo primero que haces es claro, obtienes la mitad del beneficio de la extensión de descarte sin usarlo realmente.

-2

Intente disminuir el tamaño de su framebuffer en los atributos glSurface que pasa a ChooseConfig.

Por ejemplo, establezca los atributos en 0 para mínimo u omítalos por completo para usar los valores predeterminados a menos que tenga un requisito específico.

+0

Esto no tiene nada que ver con la pregunta de OP ... – RecursiveExceptionException

Cuestiones relacionadas