android - TextureView vs. GLSurfaceView o cómo usar GLSurfaceView con EGL14
(2)
Me estoy confundiendo con EGL.
Mi GLSurfaceView crea un EGLContext. Ahora creo un contexto compartido. Ahora necesito usar una extensión EGLE.
El método que tengo que usar se llama (> = API18):
EGLExt.eglPresentationTimeANDROID(android.opengl.EGLDisplay display, android.opengl.EGLSurface surface, long time);
El problema es que GLSurfaceView solo crea javax.microedition.khronos.egl.EGLContext s.
Lo que me dice, NO usar GLSurfaceView. Así que probé TextureView, que es un poco similar, con la diferencia de que tienes que manejar tus propias cosas de EGL. Lo cual es bueno para ese propósito.
Pero: El TextureView es más lento, al menos se veía así, así que registré algunos diagramas con el Perfilador de métodos:
Aquí el TextureView con manejo propio de EGL: El Hilo en la parte superior es un reloj que despierta el Hilo en el medio, que se reproduce en el TextureView. El hilo principal se llamará después de eso, para volver a dibujar el TextureView.
... y aquí el GLSurfaceView con su propio manejo de EGL El reloj está en el medio esta vez, llama al Thread en la parte superior para renderizar mi imagen en un framebuffer, que entrego directamente en SurfaceView (RENDERMODE_WHEN_DIRTY) y llamé a requestRender para Solicita la vista para renderizar.
Como se puede ver con una mirada breve, con GLSurfaceView se ve mucho más limpio que con TextureView.
En ambos ejemplos, no he tenido nada más en la pantalla y han renderizado exactamente las mismas mallas con el mismo sombreado.
A mi pregunta: ¿Hay alguna manera de usar GLSurfaceView con los contextos EGL14?
¿Hice algo mal?
Gracias a Fadden! Funcionó como se esperaba.
A todos los que piensan hacer algo similar:
Tiene ventajas Y desventajas al usar SurfaceView (GL) para renderizar imágenes en él.
Mis resultados de prueba en la publicación anterior no tienen nada más en la pantalla que la imagen renderizada. Si tiene otros elementos de la interfaz de usuario en la pantalla, especialmente si se actualizan con frecuencia, debería reconsiderar mi elección de preferir la SurfaceView (GL).
SurfaceView crea una nueva ventana en el sistema Windows de Android. Su ventaja es que si se actualiza SurfaceView, solo se actualizará esta ventana. Si además actualiza los elementos de la interfaz de usuario (que están en otra ventana del sistema de ventanas), entonces ambas operaciones de actualización se bloquean a sí mismas (especialmente cuando el dibujo de la interfaz de usuario es compatible), ya que opengl no puede manejar el dibujo de múltiples subprocesos correctamente.
Para tal caso, podría ser mejor usar TextureView, ya que no es otra ventana del sistema operativo Android. por lo tanto, si actualiza su Vista, todos los elementos de la interfaz de usuario también se actualizarán. (Probablemente) todo en un hilo.
Espero poder ayudar a algunos de ustedes!
Lo que probablemente quieras hacer es usar un SurfaceView simple.
Aquí está la versión corta:
-
SurfaceView
tiene dos partes, laSurface
y un poco de cosas falsas en laView
. LaSurface
se pasa directamente al compositor de superficie (SurfaceFlinger), por lo que cuando se dibuja con OpenGL hay relativamente poca sobrecarga. Esto lo hace rápido, pero también hace que no se juegue bien con la jerarquía de vistas, ya que laSurface
está en una capa y la interfaz de usuario basada en vistas está en una capa diferente. -
TextureView
también tiene dos partes, pero la parte en la que dibuja vive detrás de la escena (ahí es donde entra enSurfaceTexture
laSurfaceTexture
). Cuando se completa el marco, las cosas que dibujó se mezclan en la capa de vista. La GPU puede hacer esto rápidamente, pero "algo de trabajo" siempre es más lento que "no trabajar". -
GLSurfaceView
es unSurfaceView
con una clase de envoltorio que realiza toda la configuración de EGL y la mensajería entre subprocesos por usted.
Edición: la versión larga está disponible here .
Si puede realizar la configuración de GL / EGL y la administración de subprocesos usted mismo, lo cual, si ahora está ejecutando en un TextureView, claramente puede - entonces probablemente debería usar un SurfaceView
simple.
Dicho todo esto, debería ser posible hacer que su código original funcione con GLSurfaceView
. Espero que desee llamar a eglPresentationTimeANDROID()
en el contexto de EGL que se comparte con GLSurfaceView
, no desde GLSurfaceView
sí, por lo que no importa que GLSurfaceView
utilice EGL10 internamente. Lo que importa para compartir el contexto es la versión del cliente de contexto (por ejemplo, GLES2 vs. GLES3), no la versión de la interfaz EGL utilizada para configurar el contexto.
Puedes ver ejemplos de todo esto trabajando en Grafika . En particular:
- "Mostrar + capturar cámara" utiliza un
GLSurfaceView
, la cámara y el codificador de video. Tenga en cuenta que el contexto EGL es compartido. El ejemplo es complicado y algo doloroso, principalmente porque trata deliberadamente de utilizarGLSurfaceView
y un contexto EGL compartido. ( Actualización : tenga en cuenta este problema sobre las condiciones de carrera con contextos compartidos). - "Play video (TextureView)" y "Basic GL en TextureView" muestran
TextureView
en acción. - "Grabar la aplicación GL con FBO" utiliza un
SurfaceView
simple.