2012-04-20 21 views
6

Actualmente estoy desarrollando una aplicación para iOS (iPad y iPhone) que usa OpenGL ES 1.0 para renderizar algunas texturas básicas. Yo uso atlas para almacenar y presentar mis texturas.OpenGL ES no borrará mi textura en la memoria

Mi atlas principal es relativamente grande (2000x2000) pero mis algoritmos internos cargan y cambian el tamaño de la textura a 2048x2048 ya que OpenGL ES solo acepta potencia de 2 texturas de tamaño. Soy capaz de dibujar las fichas, todo está bien en este lado.

Tengo una fuga de memoria grave cada vez que intento cargar y descargar (destruir) la textura. Esto debería suceder en la versión final, pero necesitaba asegurarme de que mi carga y descarga estuvieran bien. En memoria, la textura ocupa 2048x2048x4 (RGBA) bytes = 16MB aprox. Esto es una gran cantidad de bytes, así que entiendo que el problema es bastante molesto para mí (iOS mata la aplicación después de unos minutos ...)

Cuando cargo una textura, Instruments indica que la memoria total utilizada por el la aplicación aumenta en 16 MB, esto es correcto (utilizo la columna "Memoria real"). El problema ocurre cuando necesito destruir la textura para liberar todos los bytes posibles que usa: nunca pierde los 16MB ... y como cargo y descargo en un bucle, la memoria se sigue utilizando y nunca se libera.

Así es como me carga las texturas:

GLubyte *outData = malloc((_dataWidth * _dataHeight * 4) * sizeof(*outData)); 
GLuint _texture; // declared as un instance variable so its address never changes 
glGenTextures(1, &_texture); 
glBindTexture(GL_TEXTURE_2D, _texture); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _dataWidth, _dataHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, outData); 
free(outData); 

Así es como descargo la textura (esto se llama, he comprobado)

glDeleteTextures(1, &_texture); 

que utilizan glGetError() en todas partes para comprobar si un error ocurre pero siempre devuelve 0 (incluso después de glDeleteTexture).

¿Alguien tiene una idea? ¡Gracias!

+0

Como nota al margen, cada dispositivo iOS del iPhone 3G S y posterior debe admitir texturas que no sean de potencia de dos en OpenGL ES 1.1: http://stackoverflow.com/a/4761453/19679. Además, ¿ha pensado en convertir su atlas para usar PowerVR Texture Compression (PVRTC)? Las texturas comprimidas de esa manera se almacenan realmente en la memoria en su forma comprimida, lo que puede hacer que su huella sea mucho, mucho más pequeña que las texturas sin comprimir. No resolverá su fuga, pero podría ser una buena idea en general. –

Respuesta

14

Asegúrese de destruir su textura en el mismo hilo, donde ha creado su contexto. Si está haciendo llamadas GL sin contexto, no habría errores.

+0

¡¡Gracias !! Funcionó. –

+1

Máx., Esta respuesta me ayudó a encontrar una fuga de textura realmente desagradable en Core Image (porque un CIContext se estaba compartiendo a través de un límite de subprocesos). Muchas gracias por esta breve pero útil publicación. – chockenberry

1

¿Has probado la extensión GL_APPLE_client_storage? Significa que en lugar de tener OpenGL con una copia de la memoria de textura, promete mantener el bloque de datos pasado al glTexImage2D con vida hasta que se llame al glDeleteTextures.

+0

¿Está habilitado en iOS? Tengo la sensación de que esto no está documentado para iOS ... –

+0

Sí, creo que la extensión es solo para Mac. En iOS 5.0, podemos usar algo similar en los cachés de texturas, pero ese no es el caso aquí. –