SilverlightDraw 1.0a — Аналог Canvas из WinForms
Пост из моего блога.
Пришел 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.
*FPS — Frames Per Second(количество кадров в секунду)
Тесты заключались в полной заливке области 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) |
Рис 1. Визуализация возможностей
В процессе реализации Font manager был создан класс PNGDecoder который может преобразовать картинку формата PNG(8bit per channel, ARGB — ONLY) в класс Graphics, что позволяет загружать и использовать картинки в процессе растеризации.
Шрифты хранятся виде двух файлов:
*.png – картинка с шрифтом
*.FontConfig – в котором храниться настройки, информация о шрифте и координаты символов
Для удобства создания шрифтов была создана программа SilverlightFontGenerator.
Которая сама создает файлы необходимые для «шрифта».
Для оценки производительности SilverlightDraw(OneMem) было создано тестовое приложение, которое рисует на изображении размером 400х400 заданное количество линий(ItemCount) с интервалом(Interval, ms).
Тестируются быстродействие рисования линий технологией SilverlightDraw и рисование линий при помощи объекта Path, задание у последнего геометрии(поле Data). Все результаты получены без перезапуска страницы.
Как видно из графиков при большом количестве объектов 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.
В дальнейшем планируется реализовать поддержку эллипсов, заливку произвольной области и произвести глобальный фикс багов.
Ссылка на демо.
П.С.: Это мой первый пост.