Главная » Программирование игр под Android » ОПТИМИЗАЦИЯ ПРОИЗВОДИТЕЛЬНОСТИ – РАЗРАБОТКА ИГР ДЛЯ ОС ANDROID

0

 

Когда мы запускаем подобный пример на мощном устройстве второго поколения, как, например, Droid или Nexus One, все работает быстро и правильно. Если мы запустим его на Него, все начнет тормозить, что весьма неприятно. Но разве мы с вами не говорили, что OpenGL ES – это как раз то, что нам нужно для быстрой визуализации графики? Да, это действительно так. Но только, если мы все делаем так, как этого хочет OpenGL ES.

Измерение частоты кадров

BobTest – это отличный материал для того, чтобы начать оптимизацию. Перед тем как мы приступим, нам нужно сначала оценить работу. Осмотр вручную (то есть простая оценка скорости работы на глаз) недостаточно точен. Лучший способ измерить то, как быстро работает программа, – подсчитать количество кадров, которые мы визуализируем в секунду. Помните, мы говорили о вертикальной синхронизации, или vsync. Эта функция есть на всех устройствах с Android, которые сейчас присутствуют на рынке. Она сокращает максимальное количество кадров в секунду, которые мы можем получить, до 60. Как мы знаем, подобная частота кадров вполне подходит для нашего кода.

ПРИМЕЧАНИЕ

Хотя неплохо было бы иметь частоту 60 кадров в секунду, на самом деле этого не так просто достичь. У таких устройств, как Nexus One и Droid, слишком много пикселов, которые надо заполнить, даже если мы просто очищаем экран. Нас вполне устроит, если игра будет визуализировать мир на частоте более 30 кадров в секунду. Хотя, конечно, и лишние кадры не помешают.

Напишем небольшой вспомогательный класс, который считает кадры в секунду и периодически выводит это значение. В листинге 7.14 показан код класса FPSCounter.

Листинг 7.14. FPSCounter.java; считаем фреймы и записываем их в LogCat каждую секунду

Мы можем поместить экземпляр этого класса в наш класс BobScreen и один раз вызвать метод 1ogFrame в методе BobScreen. present . Я только что сделал это, и вот результат для Него (работает на Android 1.5), Droid (работает на Android 2.2) и Nexus One (работает на Android 2.2.1):

С первого взгляда мы видим следующее: НТС Него в два раза медленнее, чем Droid и Nexus One; Nexus One немного быстрее по сравнению с Droid; мы генерируем мусор на НТС Него в нашем процессе (17883).

Последний пункт в этом списке не очень понятен. Мы запускаем один и тот же код на трех устройствах. Но мы не создаем никаких временных объектов ни в методе present, ни в методе update. Что же происходит на НТС Него?

Любопытный случай с Него на Android 1.5

Как оказалось, в Android 1.5 есть небольшой баг. Вообще-то это даже не баг, а просто пример неаккуратного программирования. Помните, мы используем NIO-буферы для наших вершин и индексов? Фактически они являются блоками памяти в нативной куче памяти. Каждый раз, когда мы вызываем gl VertexPoi nter , gl ColorPointer  или любой другой метод gl XXXPointer, OpenGL ES пытается получить адрес памяти нативной кучи буфера, чтобы найти вершины для перевода данных в видеопамять. Проблема на Android 1.5 заключается в том, что каждый раз, когда мы запрашиваем адрес памяти из буфера NIO, он генерирует временный объект PI atformAddress. Поскольку у нас множество вызовов методов gl XXXPoi nter и glDrawElements (помните, последний переносит адрес из ShortBuffer), Android создает множество временных экземпляров класса PlatformAdress, и мы ничего не можем с этим поделать. (Вообще-то выход есть, но мы не будем его сейчас обсуждать.) Давайте просто учтем тот факт, что пользование буферами NIO в Android 1.5 доставляет массу проблем, и пойдем дальше.

Источник: Mario Zechner / Марио Цехнер, «Программирование игр под Android», пер. Егор Сидорович, Евгений Зазноба, Издательство «Питер»

По теме:

  • Комментарии