Текстуры iOS занимают 33% дополнительной памяти - PullRequest
9 голосов
/ 25 февраля 2012

Я тестировал свою игру для iOS и заметил несоответствие между тем, сколько памяти она занимает, и сколько считает, что должно занимать. В конце концов я сузил проблему до текстур, занимающих на 33% больше памяти, чем я думал, что они должны брать.

Например, я бы подумал, что несжатая 32-битная текстура 256x256 должна занимать 256 * 256 * 4 байта = 256 КБ. Однако я бы заметил, что при выделении текстуры 256x256 память приложения увеличивается примерно на 340 КБ. Как будто устройство выделяло достаточно памяти для хранения текстуры и всех своих мипмапов, но я не использую мипкарты и не спрашиваю пространство каким-либо образом.

Эта дополнительная память выделялась, потому что это могло произойти только на определенных устройствах. Я заметил дополнительную память при тестировании игры на iPod Touch 4. Однако проблема не возникла на iPhone 3GS, iPod 3G или iPad 1.

Версии os на устройствах:

iPod 3G - iOS 3.1.2 (7D11) iPhone 3GS - iOS 4.3.5 (8L1) iPod 4 - iOS 4.2.1 (8C148) iPad - iOS 4.3 (8F190)

EDIT

Вот немного больше информации. Я измеряю память приложения следующим образом

int PlatformIOS::GetProcessMemUsage()
{
    task_basic_info info;
    mach_msg_type_number_t size = sizeof( info );
    kern_return_t kerr = task_info( mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size );
    if ( kerr == KERN_SUCCESS ) 
        return info.resident_size;

    return 0;
}

Возвращает то же значение, которое вы увидите в программе Insturments для Real Mem. Это на самом деле очень полезно.

А вот как я распределяю свои текстуры:

bool GL3DTextureDataPiece::CreateTextureSurface(X3DInterfaceImpl *theInterface, int theWidth, int theHeight, PixelFormat theFormat, RefCount *thePalette, bool generateMipMap)
{
    glGenTextures(1,&mTexture);
    theInterface->SetCurTexture(this);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,mLinearFilter?GL_LINEAR:GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,mLinearFilter?GL_LINEAR:GL_NEAREST);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, theWidth, theHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    return true;
}

Это все очень простые вещи. Единственное, что привело меня к обнаружению проблем с памятью, в первую очередь, было несоответствие между разными устройствами. Фактически, это было несоответствие между общей памятью приложения и памятью ресурса (я сам отслеживаю изображения и звуковую память), что заставило меня исследовать эту ошибку.

Ответы [ 2 ]

8 голосов
/ 25 февраля 2012

Я уже нашел обходной путь, поэтому я собираюсь ответить на свой вопрос.Но я подумал, что опубликую это, потому что это важная информация, которую нужно знать.

Другие люди нашли эту ошибку.Например, см. Здесь:

http://www.cocos2d -iphone.org / forum / topic / 29121

Хорошая новость заключается в том, что существует обходной путь для ошибки.Обходной путь должен использовать только текстуры не-степени-2 (npot).Текстуры NPOT не могут быть отображены mip, поэтому iOS не пытается выделить дополнительную память карты mip (по крайней мере, это теория, почему это работает.)

К счастью, это было легко сделать в моем движке, так какон уже делит изображения на несколько текстур, если это необходимо, чтобы вписаться в текстуры степени 2, не используя слишком много памяти.Итак, я просто настроил свой код, чтобы не разделять изображения, чтобы они соответствовали текстурам степени 2, и далее заставлял любое изображение, которое оказалось степенью 2 в обоих измерениях, загружаться в текстуру, которая была на 1 пиксель больше, чемнеобходимо по ширине.Так, например, я бы поместил изображение 256x256 в текстуру 257x256.

Это исключило дополнительный рост памяти на 33%.

Обратите внимание, что старые устройства, такие как iPod 3G, не могут делать текстуры npot, поэтому важно проверить, возможно ли это, прежде чем делать это исправление.Чтобы проверить это, вы можете запросить расширение GL_APPLE_texture_2D_limited_npot.Кроме того, будьте осторожны, чтобы не превысить максимальный размер текстуры при добавлении этого дополнительного пикселя, чтобы заставить текстуру быть npot.

4 голосов
/ 25 февраля 2012

Убедитесь, что вы не генерируете мипмапы автоматически: http://www.opengl.org/wiki/Texture#Automatic_mipmap_generation

Цепочка mipmap займет 33% дополнительного пространства, поскольку цепочка mipmap примерно на 1/3 больше - см. Серию ниже, где t - размер исходной текстуры: = т + т / 4 + т / 16 + т / 64 и т. д ...

EDIT:

Обратите внимание, что было бы также полезно опубликовать метод, который вы использовали для измерения памяти приложения, и какой метод вы использовали для создания текстуры.

Возможно, метод, который вы использовали, всегда создает дополнительный 33% буфер, или вы просто неправильно вызываете метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...