2012-01-08 3 views
1

Я заметил, что когда я загружаю несколько десятков текстур, приложение падает без каких-либо уведомлений. Он просто возвращается на предыдущий экран телефона. Может быть, потому, что телефон не может хранить столько в памяти? Должен ли я загружать все текстуры перед началом игры?Сбой приложений после загрузки десятков текстур

+2

Пожалуйста, сообщите размер текстур, их количество и выдержку из вашего кода, чтобы лучше помочь вам :) Таким образом, моя машина не началась, в чем проблема? :) :) –

+0

также размещать журнал сбоев – nandeesh

+0

общий размер текстур составляет 3,2 МБ, со средним значением 100 кбайт на изображение.В общей сложности 27 PNG, каждый 1024 x 1024 в разрешении. –

ответ

2

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

Размер ваших активов в хранилище не имеет значения, так как они, вероятно, сжаты. Важен размер фактического рабочего набора. В случае изображений вы можете вычислить его как

width * height * sizeof(pixel) 

где

sizeof(pixel) = sum[channels]{ sizeof(channel) } 

В случае 1024х1024, 4 канала (RGBA), 1 байт на канал вашего рабочего набора размера одной текстуры будет быть:

1024*1024 = 1Mi 
1Mi * 4 * 1B = 4MiB 

в случае 27 текстуры это составляет 27*4MiB = 108MiB. Теперь OpenGL определен в терминах абстрактной машины, а это означает, что вы не можете спросить об этом, сколько памяти вам нужно потратить. Он просто скажет вам, если у него закончится память. OpenGL также может использовать обычную системную RAM, если не все вписывается в видеопамять. В любом случае на переносном устройстве у вас наверняка закончится нехватка памяти, если вы попытаетесь загрузить более 100 мегабайт данных текстуры.

Должен ли я не загружать все текстуры перед началом игры?

Нет, не следует. На самом деле лучше «потопить» содержимое вашей игры, загружать вещи по требованию. Также очень помогает сбор или сбор мусора. Выделение текстуры дорого (т. Е. Вызов glTexImage), тогда как замена данных является дешевой (glTexSubImage), поэтому я предлагаю добавить «неиспользуемый» счетчик к вашей структуре управления текстурой. Каждый раз, когда вы связываете текстуру и извлекаете ее, вы устанавливаете ее на ноль. По завершении инкремента кадра «неиспользуемый» счетчик каждого объекта текстуры. Если вам нужно загрузить новую текстуру, вы перебираете все объекты текстуры, выберите те, у которых соответствующий формат (одинаковый размер и количество каналов), отсортированы по неиспользуемому счетчику, затем повторно используйте объект текстуры со средой «неиспользуемых» значений , т. е. в середине отсортированного набора «неиспользуемых». Каждая «высшая неиспользуемая» текстура должна быть освобождена, остальные остаются резервными. Если вам нужно выделить более одной текстуры (скорее всего), сначала выделите из N медианных объектов. Использование этой стратегии позволяет вам поставлять готовый к использованию объект текстуры, а также иногда освобождает неиспользуемую память.

1

Чтобы отразить комментарии, выделив таким образом текстуры могут быть 27 в общей сложности 1024 на 1024 пикселя в режиме RGBA, вы каждый раз выделяете 4 МБ видеопамяти на каждую текстуру, в общей сложности 110 МБ.

Чтобы избежать подобных сбоев и быть совместимыми с несколькими системами Android, вы должны уменьшить размер текстур (иногда уменьшая общее качество).

Бесполезно говорить, что текстуры должны быть выгружены после того, как они больше не используются, чтобы освободить место для других новых нагрузок.

Смежные вопросы