Qué superficie usar para eglMakeCurrent para el context que solo se convierte en FBOs

Estoy teniendo la siguiente situación:

En una biblioteca de representación multiplataforma para iOS y Android (escrita en c (++)), tengo dos hilos que cada uno necesita su propio EGLContext: El hilo A es el hilo principal; se rinde a la window. El subprocess B es un subprocess del generador, que realiza varios cálculos y convierte los resultados en texturas que posteriormente se utilizan con el subprocess A.

Como no puedo utilizar EGL en iOS, la biblioteca utiliza pointers de function para funciones Obj.-C estáticas para crear un nuevo context y configurarlo actual. Esto ya funciona, creo el context para el hilo A usando

EAGLContext *contextA = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 

El context para el subprocess B se crea usando

 EAGLContext *contextB = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[contextA sharegroup]]; 

Entonces puedo establecer cualquiera de las dos actuales:

 [EAGLContext setCurrentContext:context]; 

Para usar la misma lógica (pointers de function pasados ​​a la biblioteca) en Android, quiero hacer esto en el lado C de los enlaces JNI, esta vez usando EGL real en lugar de EAGL de Apple. Puedo crear contextualmente A usando una window de superficie y la window nativa, puedo crear contextB y pasar el context A al parámetro shareContext de la llamada eglCreateContext.

Pero cuando quiero hacer contextB actual, tengo que pasar una superficie a la llamada eglMakeCurrent, y estoy tratando de averiguar qué tipo de superficie pasar allí.

  • No puedo usar WindowSurface que uso para contextA, ya que la especificación dice en la sección 3.7 que "como máximo un context para cada API de cliente soportada puede estar actualizado a un hilo particular en un momento dado, y como máximo un context puede estar vinculado a un particular superficie en un momento dado ".
  • No puedo especificar EGL_NO_SURFACE, porque eso daría como resultado un error EGL_BAD_MATCH en la llamada eglMakeCurrent.
  • Parece que podría usar una superficie de PBuffer, pero dudo porque tendría que especificar el ancho y la altura cuando creo esa superficie, y el hilo B podría querer crear texturas de diferentes tamaños. Además de eso, la "Guía de progtwigción de OpenGL ES 2.0" de Munshi, Ginsburg y Shreiner dice en la sección 3.8 que "los Pbuffers se usan con mayor frecuencia para generar maps de textura. Si lo único que queremos hacer es renderizar a una textura, recomendamos usar objects de framebuffer […] en lugar de pbuffers porque son más eficientes ", que es exactamente lo que quiero hacer en el hilo B.

No entiendo lo que significan Munshi, Ginsurg y Shreiner con esa frase, ¿cómo sería un object framebuffer un sustituto de una superficie pbuffer? ¿Qué pasa si creo una superficie de pbuffer muy pequeña (digamos 1x1px) para hacer que el context sea actual? ¿Puedo volver a aparecer en FBO arbitrariamente grandes? ¿Hay otras posibilidades de las que aún no conozco?

¡Muchas gracias por tu ayuda!

La superficie que pase a eglMakeCurrent () debe ser una superficie EGL de eglCreateWindowSurface (). Por ejemplo:

  EGLSurface EglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, maEGLconfigs[0], surfaceTexture, null); mEgl.eglMakeCurrent(mEglDisplay, EglSurface, EglSurface, mEglContext); 

Pero, eglCreateWindowSurface () requiere una SurfaceTexture que se proporciona a la callback onSurfaceTextureAvailable () cuando se crea una TextureView, pero también puede crear SurfaceTextures fuera de la pantalla sin ninguna vista.

Hay una aplicación de ejemplo que utiliza TextureView en el SDK de Android aquí, aunque utiliza SurfaceTexture para video de camera en lugar de renderización de OpenGL ES:

 sources\android-17\com\android\test\hwui\GLTextureViewActivity.java 

Por defecto, la superficie de EGL para FBO tendrá el mismo tamaño que SurfaceTexture de la que se crearon. Puede cambiar el tamaño de una SurfaceTexture con:

  surfaceTexture.setDefaultBufferSize(width, height); 

No utilice pbuffers en Android porque algunas plataforms (Nvidia Tegra) no las admiten. Este artículo explica en detalle las ventajas de las FBO sobre los pbuffers:

http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

Terminé usando una superficie de PBuffer (tamaño 1×1); luego, creo un FBO y lo transformo en texturas bien. Para mostrarlos (en un hilo diferente y en un context de context diferente (compartido)), utilizo una superficie de Windows con ANativeWindow (hay una muestra de eso en algún lugar del SDK).