Статьи

Производительность турбонаддува с кешированием

Это третья установка из моей серии Flex Mobile. В моем первом посте я говорил о мультитач, а во втором посте я рассказал о том, как управлять программной клавиатурой. Этот пост подробно описывает производительность, в частности, кеширование.

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

К счастью, в платформе Flash есть функция cacheAsBitmap (и ее новый одноуровневый элемент cacheAsBitmapMatrix), которая позволяет повысить производительность рендеринга за счет памяти.

Кэш как растровое изображение

CacheAsBitmap является логическим свойством DisplayObject, и благодаря этому все визуальные элементы, которые вы используете во Flash и Flex, включая Sprites и UIComponents, имеют доступ к этой переменной. Если задано значение true, каждый раз, когда DisplayObject или один из его дочерних элементов изменяется, он будет делать снимок текущего состояния и сохранять его в заэкранном буфере. Затем для будущих операций рендеринга он будет перерисовывать сохраненный внеэкранный буфер, который может быть на несколько порядков быстрее для сложной части сцены.

Чтобы включить cacheAsBitmap для DisplayObject, вы должны сделать следующее:

cacheAsBitmap = true;

Flex UIComponents имеет политику кэширования, которая автоматически включает cacheAsBitmap на основе эвристики. Вы можете переопределить это поведение и принудительно включить cacheAsBitmap, выполнив следующие действия:

cachePolicy = UIComponentCachePolicy.ON;

Несмотря на то, что cacheAsBitmap является очень мощным инструментом для оптимизации перерисовки вашего приложения, он является обоюдоострым мечом, если не используется должным образом. Полноразмерный экранный буфер сохраняется и обновляется для каждого DisplayObject с параметром cacheAsBitmap, установленным в значение true, которое может занимать много памяти устройства или исчерпывать ограниченную память графического процессора, если вы работаете в режиме графического ускорения.

Кроме того, если у вас есть объект, который часто обновляется или применено преобразование, то cacheAsBitmap просто замедлит ваше приложение ненужными операциями буферизации.

Кэш как матрица растровых изображений

CacheAsBitmapMatrix также является свойством DisplayObject и работает вместе с cacheAsBitmap. Чтобы cacheAsBitmapMatrix имел какой-либо эффект, необходимо также включить cacheAsBitmap.

CacheAsBitmap не работает, когда к объекту применяется преобразование, например поворот или перекос. Причина этого в том, что применение такого преобразования к сохраненному растровому изображению приводит к появлению артефактов масштабирования, которые ухудшают внешний вид конечного изображения. Поэтому, если вы хотите, чтобы кэширование применялось к объектам с примененным преобразованием, Flash требует, чтобы вы также указали матрицу преобразования для растрового изображения, которое хранится в свойстве cacheAsBitmapMatrix.

В большинстве случаев установка cacheAsBitmapMatrix в матрицу идентификации будет делать то, что вы ожидаете. Закадровое растровое изображение будет сохранено в нетрансформированной позиции, и любые последующие преобразования в DisplayObject будут применены к этому растровому изображению. Следующий код показывает, как установить cacheAsBitmapMatrix для идентифицирующего преобразования:

cacheAsBitmap = true;
cacheAsBitmapMatrix = new Matrix();

Совет: если вы планируете установить cacheAsBitmapMatrix для нескольких объектов, вы можете повторно использовать одну и ту же матрицу, чтобы избавиться от затрат на ее создание.

Недостатком этого является то, что на конечном изображении может быть небольшое смещение, особенно если изображение увеличено или прямые линии повернуты. Чтобы учесть это, вы можете указать матрицу преобразования, которая масштабирует изображение до его буферизации. Точно так же, если вы знаете, что окончательная графика всегда будет отображаться в уменьшенном размере, вы можете указать матрицу преобразования, которая уменьшает буферизованное изображение для экономии памяти.

Если вы используете cacheAsBitmapMatrix для уменьшения размера изображения, вы должны быть осторожны, чтобы никогда не отображать объект DisplayObject в исходном размере. На следующем рисунке показан пример того, что происходит, если установить матрицу кэша, которая сначала уменьшает и поворачивает изображение, а затем пытается отобразить объект в его исходном размере:

Обратите внимание, что конечное изображение имеет немного псевдонимов от масштабирования. Даже если вы отображаете его с преобразованием один-к-одному из оригинала, Flash увеличит масштаб кэшированной версии, что приведет к получению изображения с низкой точностью.

Оптимальное использование cacheAsBitmapMatrix — установить его немного больше, чем ожидаемое преобразование, чтобы у вас было достаточно информации о пикселях для получения высококачественных преобразованных изображений.

Flash Mobile Bench

Flash Mobile Bench — это простое приложение, которое позволяет проверить влияние различных настроек на производительность развернутого мобильного приложения.

Функциональность, которую он позволяет вам тестировать, включает в себя следующее:

  • Добавление большого количества фигур в список отображения
  • Скорость анимации простого х / у перевода
  • Скорость анимации простого вращения по часовой стрелке
  • Влияние cacheAsBitmap на производительность
  • Влияние cacheAsBitmapMatrix на производительность
  • Влияние автоматической эвристики кэша Flex на производительность

Код, который обновляет поведение кэша группы фигур, показан ниже:

private var identityMatrix:Matrix = new Matrix();
 
private function cacheOff():void {
  shapeGroup.cachePolicy = UIComponentCachePolicy.OFF;
}
 
private function cacheAuto():void {
  shapeGroup.cachePolicy = UIComponentCachePolicy.AUTO;
}
 
private function cacheAsBitmapX():void {
  shapeGroup.cachePolicy = UIComponentCachePolicy.ON;
  shapeGroup.cacheAsBitmapMatrix = null;
}
 
private function cacheAsBitmapMatrixX():void {
  shapeGroup.cachePolicy = UIComponentCachePolicy.ON;
  shapeGroup.cacheAsBitmapMatrix = identityMatrix;
}

Несмотря на то, что у нас есть только один экземпляр объекта для применения cacheAsBitmapMatrix, мы следуем передовой практике повторного использования общей матрицы идентификаторов, чтобы избежать дополнительных затрат памяти и сбора мусора.

Запустив Flash Mobile Bench, вы сразу увидите максимальный счетчик FPS на вашем устройстве. Нажмите на кнопки, чтобы добавить фигуры в сцену, установите желаемый параметр кеша и посмотрите, как работает ваше устройство. На следующем рисунке показано приложение Flash Mobile Bench, работающее на Motorola Droid 2 с 300 кружками, отрисованными с использованием cacheAsBitmapMatrix:

Как сравнить производительность вашего устройства?

 

С http://flash.steveonjava.com/turbocharging-performance-with-caching/