2012-04-20 10 views
6

Attualmente sto sviluppando un'applicazione iOS (iPad e iPhone) che utilizza OpenGL ES 1.0 per rendere alcune texture di base. Uso gli atlanti per archiviare e presentare le mie trame.OpenGL ES non cancellerà la mia texture in memoria

Il mio atlante principale è relativamente grande (2000x2000) ma i miei algoritmi interni caricano e ridimensionano la trama a 2048x2048 poiché OpenGL ES accetta solo la potenza di 2 trame di dimensioni. Sono in grado di disegnare le tessere, va tutto bene da questa parte.

Sono di fronte a una grave perdita di memoria ogni volta che provo a caricare e scaricare (distruggere) la trama. Questo dovrebbe accadere nella versione finale ma dovevo assicurarmi che il mio caricamento e scaricamento andassero bene. In memoria la trama occupa 2048x2048x4 (RGBA) byte = 16 MB circa. Questa è un'enorme quantità di byte, quindi capisci che il problema è abbastanza fastidioso per me (iOS uccide l'applicazione dopo alcuni minuti ..)

Quando carico una trama, Strumenti indica che la memoria complessiva utilizzata dalla l'applicazione aumenta di 16 MB e questo è corretto (io uso la colonna "Real Memory"). Il problema si verifica quando ho bisogno di distruggere la trama per liberare tutti i possibili byte usati da essa: non perde mai il 16MB ... e dal momento che carico e scarico in un loop, la memoria continua ad essere usata e mai liberata.

Ecco come ho caricare le texture:

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); 

Ecco come ho scaricare la trama (questo è chiamato, ho controllato)

glDeleteTextures(1, &_texture); 

ho usato glGetError() in tutto il mondo per verificare se un errore si verifica ma restituisce sempre 0 (anche dopo glDeleteTexture).

Qualcuno ha un'idea? Grazie!

+0

Come nota a margine, tutti i dispositivi iOS di iPhone 3G S e successivi dovrebbero supportare trame non di potenza in OpenGL ES 1.1: http://stackoverflow.com/a/4761453/19679. Inoltre, hai pensato di convertire il tuo atlante in PowerVR Texture Compression (PVRTC)? Le trame compresse in questo modo vengono effettivamente memorizzate nella loro forma compressa, che può rendere il loro ingombro molto, molto più piccolo delle trame non compresse. Non risolverà la tua perdita, ma potrebbe essere una buona idea in generale. –

risposta

14

Assicurati di distruggere la trama sullo stesso thread, in cui hai creato il contesto. Se stai facendo delle chiamate GL senza contesto non ci sarebbero errori.

+0

Grazie !! Ha funzionato. –

+1

Max, questa risposta mi ha aiutato a rintracciare una perdita di texture davvero brutta in Core Image (perché un CIContext veniva condiviso attraverso un limite di thread). Grazie mille per questo breve, ma molto utile, post! – chockenberry

1

Hai provato l'estensione GL_APPLE_client_storage? Significa che, invece di avere OpenGL con una copia della memoria delle texture, si promette di mantenere il blocco dei dati passato a glTexImage2D vivo fino a quando è stato chiamato glDeleteTextures.

+0

È abilitato su iOS? Ho la sensazione che questo non è documentato per iOS .. –

+0

Sì, penso che l'estensione è solo per il Mac. Su iOS 5.0, possiamo usare qualcosa di simile nelle cache delle texture, ma non è quello che sembra essere il caso qui. –