¿Por qué está bloqueando glClear en OpenGLES?

Estoy tratando de perfil mi procesador, y estoy viendo un comportamiento de perfil extraño que no puedo explicar.

Estoy usando un glSurfaceView, que he fijado para hacer continuamente.

Así es como mi onDrawFrame() está estructurado

 public void onDrawFrame(GL10 unused) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); executeAllDrawCommands(); } 

Esto se comportaba lentamente bajo carga ligera, así que creé una clase de temporizador y comencé a perfilar esto. Me sorprendió mucho lo que vi.

Puse algunas sondas en mi método onDrawFrame así:

 public void onDrawFrame(GL10 unused) { swapTimer.end(); clearTimer.start(); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); clearTimer.end(); drawTimer.start(); executeAllDrawCommands(); drawTimer.end(); swapTimer.start(); } 

clearTimer mide el tiempo que se tarda en llamar a glClear, drawTimer mide el tiempo que tarda en ejecutar todas mis llamadas de draw y swapTimer mide el tiempo desde que onDrawFrame sale y cuando regresa (el tiempo que se tarda en llamar a eglSwapBuffers).

Cuando corrí una escena muy ligeramente cargada, conseguí algunos números realmente extraños que no puedo explicar:

 swapTimer : 20ms (average) clearTimer : 11ms (average) drawTimer : 2ms (average) 

Esperaba que el tiempo de intercambio para ser un poco largish, ya que creo que el dispositivo tiene forzada vsync habilitar a ~ 30fps, aunque no sé por qué la llamada "claro" actual es el bloqueo de 11 milisegundos? Pensé que se suponía que debía emitir un comando asíncrono y volver?

Cuando dibujo una escena mucho más ocupada, los números cambian bastante:

 swapTimer : 2ms (average) clearTimer : 0ms (average) drawTimer : 44ms (average) 

En esta escena mis llamadas de dibujo están tomando tanto tiempo que parece que esconden mucho del período vsync, y el bloque en la llamada clara desaparece totalmente.

¿Hay alguna explicación de por qué glClear está bloqueando mi escena ligeramente cargada?

Enlace a mi código fuente de la clase 'Timer' en caso de que alguien sospeche de mi técnica de medición: http://pastebin.com/bhXt368W

One Solution collect form web for “¿Por qué está bloqueando glClear en OpenGLES?”

Pongo un glFinish (y finishTimer.start () / end () a su alrededor), y toma todo el tiempo lejos de glClear. Ahora glFinish toma un cierto número de milisegundos, y glClear se convierte en instantáneo.

Eso lo explica.

Cuando su escena es muy ligera y los dibujos son renderizados muy rápido, el tiempo para borrar y rellenar los píxeles con el nuevo color tomará algún tiempo (siempre tomará tiempo, de lo contrario el renderizador está detrás y es currenty dibujo nuevo material). Los dispositivos Android más nuevos tienen límites de llenado. Por ejemplo, Nexus One tiene un bloqueo de llenado a 30 Hz – la pantalla se sincronizará a esa frecuencia sin importar lo rápido que vayan los dibujos. Si los dibujos terminan por debajo de 30 Hz, el procesador se sincronizará con la pantalla. Esta es la razón por la que se nota este retraso, que debe observar incluso si quita la llamada glClear() . El procesador es anterior y más rápido que las actualizaciones de la pantalla.

Cuando el renderizador tiene muchos objetos que dibujar, la sincronización se detendrá (dados los datos del perfil de la escena ocupada) porque el procesador está ahora después de las actualizaciones de la pantalla.

Cuando utiliza glFinish() , elimina el tiempo que la función glClear() podría causar, lo cual, siguiendo la lógica de fillrate, significa que glFinish() es ahora la función que garantiza la sincronización con la pantalla.

Cálculos :

F = 1 / T

Escena fácil :

F = 1 / T = 1 / ((20 + 11 + 2) * 10 ^ -3) = ~ 30 Hz

El tiempo de retardo de sincronización aparece en su generador de perfiles. Renderer se está sincronizando con la pantalla. Esto significa que si quita la glClear() o glFinish() , la demora aparecería en otro lugar.

Escena pesada :

F = 1 / T = 1 / ((2 + 0 + 44) * 10 ^ -3)) = ~ 22 Hz

El tiempo de retardo de sincronización no aparece en su profiler. Renderer es después de la frecuencia de actualización de la pantalla.

Parece que esto está relacionado con vsync

Eso parece correcto.

  • ¿Por qué glReadPixels da resultados faltados en algunos dispositivos Android más antiguos?
  • OpenGL ES 2.0 múltiples programas o múltiples Shaders o qué? ¿Como funciona?
  • Solución para escribir el valor del búfer de profundidad / profundidad en OpenGL ES 2.0
  • Android EGL / OpenGL ES Frecuencia de fotogramas tartamudeando
  • GlCreateShader y glCreateProgram fallan en android
  • OpenGL ES 2.0 Error al asignar correctamente el atributo de color
  • Uso de FBO para grabar la pantalla en Android
  • Cómo dibujar una línea punteada dinámicamente utilizando OpenGL ES 2.0 en Android mediante programación?
  • Demostración de Android OpenGL "No config chosen"
  • Android NDK - OpenGL ES 2.0 - vinculación de la biblioteca
  • ¿Por qué mi programa de shader openGL para puntos tiene anillos de artefactos?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.