Главная » Silverlight » Аппаратное ускорение

0

Золотое правило графического программирования состоит в том, что нужно пере­ложить как можно больше работы на процессор GPU, расположенный на графической карте. В конце концов, графические карты специально созданы для быстрого и эффек­тивного решения определенных типов графических задач (например, масштабирования растрового изображения). Однако при выполнении типичного веб-приложения графи­ческая карта почти не работает. Во многих случаях имеет смысл прибегнуть к ее помо­щи, разгрузив, хотя бы немного, центральный процессор.

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

f

К сожалению, реализация аппаратного ускорения — не такая простая задача, как может показаться на первый взгляд. Наиболее существенная проблема состоит в том, что для реализации ускорения на платформе, на которой выполняется приложение Silverlight, необходим дополнительный слой программной поддержки видеокарты. На компьютерах Windows это означает необходимость видеокарты, совместимой с DirectX 9, а на Mac OSX — с OpenGL2 и соответствующими драйверами. Более того, в Мае аппа­ратное ускорение выполняется только в полноэкранном режиме приложения Silverlight. Платформа Windows не накладывает на Silverlight столь жесткого ограничения.

Еще одна проблема состоит в том, что видеокарты разработаны для ускорения лишь определенного типа графических операций (например, раскрашивания крошечных тре­угольников, из которых состоят трехмерные сцены). Многие процедуры ускорения для Silverlight непригодны. Фактически в приложении Silverlight можно применить лишь два типа оптимизации: задействовать способность видеокарты кешировать некоторые визуальные элементы (такие, как растровые изображения) и выполнять над ними пре­образования некоторых типов (такие, как масштабирование, отсечение, поворот, нало­жение частичной непрозрачности). Другие типы аппаратного ускорения, в принципе, возможны, однако в Silverlight они в данный момент не поддерживаются.

Включение аппаратного ускорения

Чтобы ускорение можно было применить в приложении, нужно соответствующим образом сконфигурировать входную страницу. Для этого необходимо добавить в объект <object> параметр enableGPUAcceleration и присвоить ему значение true.

<div id="silverlightControlHost"> cobject data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%"

height="100%"> <param name="enableGFUAcceleration" value="true" /> <param name="enableCacheVisualization" value="true" /> <param name="enableFrameRateCounter" value="true" />

</object>

<iframe style=’visibility:hidden;height:0; ‘Ъ width:0;border:Opx’></iframe>

</div>

В приведенной выше разметке добавлены также два необязательных параметра, используемых совместно с аппаратным ускорением. Параметр enableCacheVisual- ization отмечает подсвечиванием области приложения, в которых не используется кеширование растровых изображений в видеокарте. Параметр enableFrameRateCounter выводит счетчик частоты кадров, автоматически обновляемый во время выполнения анимации. Оба параметра предназначены для диагностики и тестирования приложе­ния. Они облегчают оценку производительности. В окончательной версии приложения их необходимо удалить. Установка параметра enableGPUAcceleration не приводит к немедленному эффекту. Он лишь предоставляет возможность подключать кеширова­ние к индивидуальным элементам. Пока не будет выполнена эта операция, производи­тельность приложения не улучшится.

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

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

Однако видеокарта может делать с растровым изображением не все. В Silverlight она поддерживает лишь следующие операции:

•    масштабирование растрового изображения с помощью объекта ScaleTransform;

•    поворот изображения с помощью объекта RenderTransform;

•    изменение прозрачности изображения с помощью свойства Opacity;

•       отсечение изображения прямоугольной секущей областью с помощью свойст­ва Clip.

Следовательно, если в анимации применяется масштабирование, повороты или за­тенение элементов, можно воспользоваться аппаратным ускорением. Однако если ани­мация делает что-либо еще (например, наклоняет элемент, изменяет его цвет, вращает объект в трехмерном пространстве методом перспективного проецирования, раскра­шивает пиксели и т.д.), видеокарта ничем не поможет. В этих ситуациях надстройка Silverlight вынуждена постоянно передавать обновленные копии растровых изображе­ний видеокарте, обновляя ее кеш несколько раз в секунду. Естественно, это существен­но ухудшает производительность.

Чтобы включить квитирование растрового изображения, нужно присвоить свойству CacheMode соответствующего элемента значение BitmapCache. Каждый элемент облада­ет этим свойством, поэтому вы можете точно задать, какие элементы должны кеширо- ваться, а какие — нет.

Примечание. При кешировании элемента, содержащего другие элементы (например, контейнера), все элементы (включая вложенные) сохраняются в одном растровом изображении. Следовательно, включать кеширование некоторых элементов (например, Canvas) нужно осторожно — только если вложенные элементы поддерживают кеширование перечисленных выше преобразований.

Чтобы лучше понять принципы кеширования, рассмотрим следующий пример (его можно найти в кодах, прилагаемых к данной главе). На рис. 10.15 выполняются две анимации. Первая поворачивает элемент Image, содержащий рисунок телефонной буд­ки, а вторая изменяет размеры кнопки с помощью объекта ScaleTransform, все время растягивая и сокращая ее. Обе анимации доступны для кеширования.

Рис. 10.15. Тестовая страница с двумя анимированными элементами

Ниже приведена разметка, включающая кеширование обоих элементов.

<Canvas>

<Image x:Name="img" Source="phone_booth.jpg"

Stretch="None" CacheMode="Bi tmapCache"> <Image.RenderTransform> <RotateTransform x:Name="rotateTransform"> </RotateTransform> </Image.RenderTransform> </Image>

<Button x:Name="cmd" СслЛепЪ="Изменяющаяся кнопка"

Canvas.Top="70" Canvas.Left="10" CacheMode="BitmapCache"> <Button.RenderTransform>

<ScaleTransform x:Name="scaleTransform"x/ScaleTransform> </Button.RenderTransform> </Button> </Canvas>

Ниже приведена разметка, в которой объявлены обе анимации.

<Storyboard х:Name="storyboard"> <DoubleAnimation Storyboard.TargetName="rotateTransform" Storyboard.TargetProperty="Angle" To="360"

Duration="0:0:2" RepeatBehavior="Forever"x/DoubleAnimation> <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" AutoReverse="True" To="20" Duration="0:0:1.8" RepeatBehavior="Forever">

</DoubleAnimation> <DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" AutoReverse="True" To="20" Duration="0:0:1.8" RepeatBehavior="Forever"> </DoubleAnimation>

</Storyboard>

Кеширование растрового изображения может породить существенную проблему. Обычно при включенном кешировании надстройка Silverlight копирует снимок элемен­та с его текущими размерами в память видеокарты. Если после этого применить объект ScaleTransform, чтобы увеличить растровое изображение, будет увеличено кеширован- ное изображение, а не фактический элемент. В рассматриваемом примере кнопка из-за этого станет пушистой.

Для решения этой проблемы можно включить кеширование всей растровой карты, однако тогда эффект исчезнет, потому что Silverlight считает кнопки и другие элемен­ты векторными изображениями. Другое решение состоит в явном задании увеличен­ных размеров растрового изображения, которое Silverlight передает в кеш видеокарты. Задать размеры можно с помощью свойства BitmapCache .RenderAtScale. По умолча­нию оно равно 1, и элемент передается с текущими размерами. В приведенной ниже разметке снимок кнопки увеличивается в пять раз.

<Button x:Name="cmd" Content="Il3MeHHioi4aHCfl кнопка" Canvas.Тор="70" Canvas.Left="10"> <Button.CacheMode>

<BitmapCache RenderAtScale="5"x/BitmapCache> </Button.CacheMode> <Button.RenderTransform> <ScaleTransform x:Name="scaleTransform"> </ScaleTransform> </Button.RenderTransform>

</Button>

Это решает проблему пушистости. Квитированное растровое изображение меньше максимального анимированного размера кнопки (она увеличивается в 10 раз), одна­ко видеокарта может увеличить размеры растрового изображения от 5 до 10 раз без побочных эффектов масштабирования. Способ, основанный на увеличении свойства RenderAtScale, имеет два потенциальных недостатка. Во-первых, вы заставляете над­стройку Silverlight передавать больше данных видеокарте, что замедляет начальный этап вывода. Во-вторых, вы сильнее загружаете память видеокарты. Разные видеокар­ты обладают разными объемами памяти. Когда видеокарта заполнит всю доступную память, она не сможет кешировать растровые изображения, и надстройка Silverlight пе­реключится обратно в режим без кеширования.

Оценка эффекта аппаратного ускорения

Оценить эффективность кеширования растровых изображений легче всего, выпол­няя приложение по очереди в двух режимах: с ускорением и без ускорения. В боль­шинстве случаев разница визуально незаметна. Возможно, у ваших пользователей компьютеры медленнее. Поэтому проверьте использование процессора и частоту ка­дров анимации. Чтобы проверить использование процессора, откройте окно диспетче­ра задач Windows, а в нем — вкладку Performance (Быстродействие). На моем компью­тере с одним процессором при выполнении рассматриваемого примера загрузка при включении кеширования уменьшилась с 50 до 20%. Вы можете включать и отключать кеширование с помощью флажка, расположенного в нижней части окна приложения. Включить кеширование программно можно с помощью следующего оператора.

img.CacheMode = new BitmapCache();

Еще один полезный инструмент Silverlight — встроенные средства диагностики. Параметры enableCacheVisualization и enableFrameRateCounter (см. выше) позволя­ют получить дополнительную диагностическую информацию. На рис. 10.16 показано приложение, когда оба эти параметра включены, а кеширование выключено.

Рис. 10.16. Использование визуализации кеша и счетчика частоты кадров

Элементы Image и Button отмечены красным цветом (благодаря параметру enable- CacheVisualization), сообщающим о том, что они не кешируются. Ряд чисел в верхнем левом углу окна предоставляют следующую информацию, полученную от счетчика ча­стоты кадров (благодаря параметру enableFrameRateCounter).

•       Первое число — это частота кадров анимации. В данном примере при отключе­нии кеширования она уменьшается от 55 до 35. Максимальная частота по умол­чанию равна 60.

•       Второе число — объем используемой памяти видеокарты. При включении кеши­рования он увеличивается.

•       Третье число — общее количество поверхностей, обрабатываемых процедурой ускорения. Включение кеширования одного элемента обычно приводит к необхо­димости обрабатывать несколько поверхностей. Например, если элемент — всего лишь кнопка, в ней все же есть как минимум еще один элемент — текстовый блок.

•       Четвертое число — количество неявно обрабатываемых поверхностей. В неко­торых ситуациях при включении кеширования одного элемента происходит ав­томатическое включение кеширования другого (например, если первый элемент перекрывает второй). В этих случаях надстройка Silverlight автоматически вклю­чает кеширование дополнительных элементов и появляются неявно обрабатыва­емые поверхности.

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

Резюме

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

Учитывая небольшой объем дистрибутива Silverlight, встроенные в него средства анимации, на удивление, богатые и мощные. Однако получить желаемый результат иногда нелегко. Если захотите анимировать отдельные части интерфейса, будете вы­нуждены погрязнуть в скучных подробностях, таких как отслеживание анимированных объектов и очистка раскадровок. Более того, ни один из анимационных классов не при­нимает аргументы. В результате код, необходимый для создания новой анимации, чаще всего получается простой, но длинный. Возможно, в следующих версиях Silverlight поя­вятся долгожданные высокоуровневые классы анимации, основанные на методах, рас­смотренных в данной главе. В идеале анимация должна быть такой, чтобы ее можно было встраивать в приложение, просто применяя предопределенные классы, заключая элементы в специализированные контейнеры и устанавливая несколько подключенных свойств. Впрочем, изучив главу, вы сами можете создавать высокоуровневые анимаци­онные классы, реализующие любые визуальные эффекты.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

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