Пост из моего блога.
Пришел 2008 год и пришло время SL 2 Beta 1, это было уже законченное решение, без JS корней…Первые испытания показали хорошую производительность и удобство, у MS получился достойный продукт. Хотя у него были и свои недостатки, он был заточен на спрайтовые концепции. Невозможно было ничего нарисовать, Path очень медленный, а Ellipse, Rectangle и Line имеют совсем плохую производительность. Долгое время я искал способы рисования растром, а не объектами. Случайно попалась статья Joe Stegman, Dynamic Image Generation in Silverlight. После исследования было замечено что производительность SL очень сильно зависит от выделения памяти. После оптимизации и минимизации выделения памяти в кодере, была создана технология OneMem. Ниже приведены результаты сравнения двух технологий.
Окружение:
* Athlon 64 X2 4800+, Mem 2Gb.
* WinXP SP2, .Net1.1, .Net2.0, .Net3.5, Firefox 2.0.1.4.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/ef0/469/a0a/ef0469a0abd81b62fae83488d29c4e61.png)
*FPS — Frames Per Second(количество кадров в секунду)
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/508/5e1/802/5085e18027a1c1491e228eac1ac25d9e.png)
Тесты заключались в полной заливке области 400х400px цветом, с периодичностью Interval. Все измерения загрузки CPU проводились через диспетчер задач, для приложения Firefox 2. FPS замерялось через встроенный в SL счетчик, максимальное значение 62.
Как видно из таблицы технология OneMem позволила поднять производительность в 8 раз по CPU% и более чем в 3 раза по FPS относительно Original PNG Encoder.
Так же были минимизированы выделения памяти, что избавило от утечки 640кб памяти на одну отрисовку кадра(400х400), что при Interval=50, сокращает утечку 12мб памяти.
В данный момент доступна более новая версия Original PNG Encoder, возможно скорость работы у нее выше.
После оптимизации Encoder`а, было решено сделать законченное решение SilverlightDraw, реализовав в ней класс Graphics с помощью которого, было бы легко экспортировать работу графики из десктопных программ .Net в SL.
После окончания работы над Alpha версией SilverlightDraw, были реализованы следующие возможности:
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/c75/b94/a15/c75b94a157d406757bce5191b44e1fc4.png)
Рис 1. Визуализация возможностей
В процессе реализации Font manager был создан класс PNGDecoder который может преобразовать картинку формата PNG(8bit per channel, ARGB — ONLY) в класс Graphics, что позволяет загружать и использовать картинки в процессе растеризации.
Шрифты хранятся виде двух файлов:
*.png – картинка с шрифтом
*.FontConfig – в котором храниться настройки, информация о шрифте и координаты символов
Для удобства создания шрифтов была создана программа SilverlightFontGenerator.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/033/5e3/d12/0335e3d123ae9dd66abdbc672cd3cf28.png)
Которая сама создает файлы необходимые для «шрифта».
Для оценки производительности SilverlightDraw(OneMem) было создано тестовое приложение, которое рисует на изображении размером 400х400 заданное количество линий(ItemCount) с интервалом(Interval, ms).
Тестируются быстродействие рисования линий технологией SilverlightDraw и рисование линий при помощи объекта Path, задание у последнего геометрии(поле Data). Все результаты получены без перезапуска страницы.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/89c/d26/ce2/89cd26ce2fbec8c49409b23e4948f430.png)
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/e7d/ea7/c20/e7dea7c2046b71f5e367aea682ab4010.png)
Как видно из графиков при большом количестве объектов Path резко увеличивает загрузку CPU%, что приводит к катастрофическому падению FPS, а SilverlightDraw плавно снижает свою производительность при увеличении количества линий. Вероятнее всего, сильная загрузка CPU при отображении Path связана с тем, что движок SL2 при выводе объектов применяет Anti-aliasing фильтрацию.
При этом надо принять во внимание, что SilverlightDraw позволяет рисовать каждую линию любым цветом, в отличие от объекта Path который может рисовать все линии только одним выбранным цветом.
К сожалению, замерить FPS на FireFox3 не удалось так как в строке состояния не выводиться количество FPS, поэтому все замеры производились на Internet Explorer 6.0.2900.2180.xpsp_sp2_qfe.070719-1309
Оборудование, ОС и программы остались прежними, см. первый тест.
Дополнительной причиной уменьшения производительности Path, является использования XamlReader для задания геометрии:
Это связано с тем что в Silverlight 2 Beta 2 стало не возможно напрямую присвоить свойству Data строку с геометрией, вследствие чего используется XamlReader.
В дальнейшем планируется реализовать поддержку эллипсов, заливку произвольной области и произвести глобальный фикс багов.
Ссылка на демо.
П.С.: Это мой первый пост.
Пришел 2008 год и пришло время SL 2 Beta 1, это было уже законченное решение, без JS корней…Первые испытания показали хорошую производительность и удобство, у MS получился достойный продукт. Хотя у него были и свои недостатки, он был заточен на спрайтовые концепции. Невозможно было ничего нарисовать, Path очень медленный, а Ellipse, Rectangle и Line имеют совсем плохую производительность. Долгое время я искал способы рисования растром, а не объектами. Случайно попалась статья Joe Stegman, Dynamic Image Generation in Silverlight. После исследования было замечено что производительность SL очень сильно зависит от выделения памяти. После оптимизации и минимизации выделения памяти в кодере, была создана технология OneMem. Ниже приведены результаты сравнения двух технологий.
Окружение:
* Athlon 64 X2 4800+, Mem 2Gb.
* WinXP SP2, .Net1.1, .Net2.0, .Net3.5, Firefox 2.0.1.4.
![](https://habrastorage.org/getpro/habr/post_images/ef0/469/a0a/ef0469a0abd81b62fae83488d29c4e61.png)
*FPS — Frames Per Second(количество кадров в секунду)
![](https://habrastorage.org/getpro/habr/post_images/508/5e1/802/5085e18027a1c1491e228eac1ac25d9e.png)
Тесты заключались в полной заливке области 400х400px цветом, с периодичностью Interval. Все измерения загрузки CPU проводились через диспетчер задач, для приложения Firefox 2. FPS замерялось через встроенный в SL счетчик, максимальное значение 62.
Как видно из таблицы технология OneMem позволила поднять производительность в 8 раз по CPU% и более чем в 3 раза по FPS относительно Original PNG Encoder.
Так же были минимизированы выделения памяти, что избавило от утечки 640кб памяти на одну отрисовку кадра(400х400), что при Interval=50, сокращает утечку 12мб памяти.
В данный момент доступна более новая версия Original PNG Encoder, возможно скорость работы у нее выше.
После оптимизации Encoder`а, было решено сделать законченное решение SilverlightDraw, реализовав в ней класс Graphics с помощью которого, было бы легко экспортировать работу графики из десктопных программ .Net в SL.
После окончания работы над Alpha версией SilverlightDraw, были реализованы следующие возможности:
Feature | Status |
---|---|
Clip | Yes |
Transform | Только перемещение |
DrawPoint | Yes |
DrawLine | Yes, алгоритм Брезенхема |
Pen | Color,Width(Только для прямолинейных линий), DashStyle(Только для Width==1) |
Brush | Только SolidBrush |
DrawPolygon | Yes |
FillRectangle | Yes |
CopyBitmap | Поддержка различных фильтров (Copy, AND, OR и т.д.) Можно создать свой фильтр |
Font | Загрузка «шрифтов» с сервера Необходима предварительная загрузка шрифтом перед использованием. |
DrawString | Вывод только в горизонтальном направлении |
PNGDecoder | Преобразование PNG картинок в Graphics Поддерживается только формат PNG32(ARGB) |
![](https://habrastorage.org/getpro/habr/post_images/c75/b94/a15/c75b94a157d406757bce5191b44e1fc4.png)
Рис 1. Визуализация возможностей
В процессе реализации Font manager был создан класс PNGDecoder который может преобразовать картинку формата PNG(8bit per channel, ARGB — ONLY) в класс Graphics, что позволяет загружать и использовать картинки в процессе растеризации.
Шрифты хранятся виде двух файлов:
*.png – картинка с шрифтом
*.FontConfig – в котором храниться настройки, информация о шрифте и координаты символов
Для удобства создания шрифтов была создана программа SilverlightFontGenerator.
![](https://habrastorage.org/getpro/habr/post_images/033/5e3/d12/0335e3d123ae9dd66abdbc672cd3cf28.png)
Которая сама создает файлы необходимые для «шрифта».
Для оценки производительности SilverlightDraw(OneMem) было создано тестовое приложение, которое рисует на изображении размером 400х400 заданное количество линий(ItemCount) с интервалом(Interval, ms).
Тестируются быстродействие рисования линий технологией SilverlightDraw и рисование линий при помощи объекта Path, задание у последнего геометрии(поле Data). Все результаты получены без перезапуска страницы.
![](https://habrastorage.org/getpro/habr/post_images/89c/d26/ce2/89cd26ce2fbec8c49409b23e4948f430.png)
![](https://habrastorage.org/getpro/habr/post_images/e7d/ea7/c20/e7dea7c2046b71f5e367aea682ab4010.png)
Как видно из графиков при большом количестве объектов Path резко увеличивает загрузку CPU%, что приводит к катастрофическому падению FPS, а SilverlightDraw плавно снижает свою производительность при увеличении количества линий. Вероятнее всего, сильная загрузка CPU при отображении Path связана с тем, что движок SL2 при выводе объектов применяет Anti-aliasing фильтрацию.
При этом надо принять во внимание, что SilverlightDraw позволяет рисовать каждую линию любым цветом, в отличие от объекта Path который может рисовать все линии только одним выбранным цветом.
К сожалению, замерить FPS на FireFox3 не удалось так как в строке состояния не выводиться количество FPS, поэтому все замеры производились на Internet Explorer 6.0.2900.2180.xpsp_sp2_qfe.070719-1309
Оборудование, ОС и программы остались прежними, см. первый тест.
Дополнительной причиной уменьшения производительности Path, является использования XamlReader для задания геометрии:
var sb = new StringBuilder("<Path xmlns=\"http://schemas.microsoft.com/client/2007\" Data=\"\""); sb.Append(path_data).Append("\"/>"); Path path1 = (Path)XamlReader.Load(sb.ToString() ); var o = path1.GetValue(System.Windows.Shapes.Path.DataProperty); path1.Data = null; path.SetValue(System.Windows.Shapes.Path.DataProperty,o);
Это связано с тем что в Silverlight 2 Beta 2 стало не возможно напрямую присвоить свойству Data строку с геометрией, вследствие чего используется XamlReader.
В дальнейшем планируется реализовать поддержку эллипсов, заливку произвольной области и произвести глобальный фикс багов.
Ссылка на демо.
П.С.: Это мой первый пост.