Как улучшить производительность и использование памяти с большим количеством полигонов на холсте? - PullRequest
5 голосов
/ 29 сентября 2008

Проект, над которым я работаю, должен визуализировать файл форм ESRI, который может иметь большое количество многоугольников / фигур. Когда я добавляю все эти многоугольники, линии, точки и т. Д. На холст, который я использую, он становится очень медленным.

Чтобы нарисовать фигуры на карте, я создаю объект Path и устанавливаю его свойство Data в StreamGeometry. Изначально я использовал Polygon, но, согласно MSDN, StreamGeometry намного легче.

Как я могу улучшить производительность? Поможет ли преобразование готового продукта в растровое изображение или VisualBrush? Есть ли более эффективный способ рендеринга всех этих фигур на холст?

РЕДАКТИРОВАТЬ: я забыл упомянуть, что это должно быть в состоянии работать в XBAP с частичным доверием.

Ответы [ 8 ]

7 голосов
/ 30 сентября 2008

Нет необходимости прибегать к GDI, вам просто нужно переместить слой вниз в API WPF и объединить вашу геометрию в меньшее количество визуальных элементов. Pablo Fermicola имеет некоторую полезную информацию о выборе слоя для использования в зависимости от ваших потребностей в производительности.

Мне удалось добиться отличной производительности, используя DrawingVisual и DrawingContext .

2 голосов
/ 29 сентября 2008

Вы можете попробовать использовать GDI + или direct x вместо WPF.

Я сделал аналогичный проект (рендеринг картографических данных через WPF) для статьи в журнале MSDN, которую написал около года назад.

Это было просто то, что я написал довольно быстро (статья + приложение заняло около 1 недели), и было разработано так, чтобы это было просто «это что-то изящное, что вы можете сделать», и поэтому я не особо сосредоточился на производительности , В любом случае я столкнулся с той же проблемой. Как только количество многоугольников на холсте стало большим, производительность рендеринга начала ухудшаться. Например, изменение размера окна потребует примерно 1/2 секунды или около того.

Многое из этого связано с накладными расходами WPF. Он в первую очередь разработан как инструментарий GUI, а не как высокопроизводительный графический движок. Это означает, что он фокусируется на богатстве функций по сравнению с эффективным рендерингом. С меньшим количеством объектов (что, вероятно, можно найти в большинстве приложений с графическим интерфейсом), производительность довольно хорошая, и функции привязки данных, анимации и декларативного стиля (а также вся маршрутизация событий и другие необходимые им вещи) действительно могут пригодиться .

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

Если вам не нужны декларативные стили и анимация, тогда я бы просто исключил WPF и использовал GDI +, чтобы нарисовать карту самостоятельно. В основном это включает в себя настройку правильной матрицы преобразования, чтобы карта отображалась на управляющей поверхности, а затем итерацию по всем полигонам и вызов нескольких методов DrawPolygon.

Чтобы включить взаимодействие, вам нужно будет написать свой собственный код тестирования на попадание, и вам придется перерисовывать карту каждый раз, когда размер формы изменяется. Вам также придется вручную кодировать любые анимации, изменения стиля или другие подобные вещи (например, выделение областей, когда мышь над ними). Но не должно быть так сложно написать этот код. Я хотел бы, чтобы вы могли сделать это примерно через 1,5 недели.

Однако это должно повысить производительность, поскольку сводится к выполнению только около 20-30К векторных преобразований, которые не потребляют много ресурсов процессора на большинстве современных процессоров. Вы также можете изучить использование Direct X, которое позволит вам также использовать преимущества графического процессора, что может повысить производительность.

1 голос
/ 29 сентября 2008

Вы можете быть ограничены производительностью виджета Canvas. Если у вас есть возможность использовать сторонний инструментарий, посмотрите на QT. . Он имеет высокопроизводительный холст-виджет , предназначенный для быстрой визуализации сложных форм. Это уже использовалось для хотя бы для одного ГИС-приложения , поэтому у него есть некоторый послужной список в этом пространстве.

Вы можете обернуть QT в качестве элемента управления ActiveX или использовать привязки Qyoto / Kimono .Net для взаимодействия с приложением .Net. Troll Tech только что обновила свой веб-сайт, и я не могу найти загружаемую демоверсию, которая у них там была, но она показывает виджет QGraphicsView, отображающий очень большой векторный рисунок и уменьшающий изображение в реальном времени.

0 голосов
/ 18 ноября 2009

, если вам не нужно показывать ВСЕ полигоны одновременно (например, из-за масштабирования, панорамирования и т. Д.), Посмотрите пример виртуализации холста здесь

0 голосов
/ 04 апреля 2009

Используйте DrawingGroup и добавьте / удалите объекты Drawing для решения этой проблемы. См. Мой ответ на аналогичный вопрос о DrawingVisual производительности с непрозрачностью = 0 . Я думаю, что мой ответ на самом деле лучше подходит для этого вопроса.

0 голосов
/ 26 ноября 2008

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

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

Больше информации от MSDN на VisualBrush

0 голосов
/ 29 сентября 2008

@ xmjx

И: преобразование объекта в растровое изображение: в чем разница с его отображением?

Я думал, что мое замедление может быть вызвано наличием n объектов на холсте вместо 1 растрового изображения. Тем не менее, я не знаю производительность или что происходит в фоновом режиме при преобразовании холста с n количеством объектов в растровое изображение.

Я бы предпочел не использовать растровое изображение, чтобы позволить пользователю взаимодействовать (изменять / удалять) с фигурами / полигонами.

0 голосов
/ 29 сентября 2008

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

И: преобразование объекта в растровое изображение: в чем разница с его отображением?

В конце концов, у вас есть n объектов, которые / каким-то образом / должны быть визуализированы (если только вы не можете выяснить, какие объекты скрыты за другими объектами, но это вам мало поможет, так как вам придется смотреть на n! Объектных отношений ).

Кроме того: может быть, стоит отказаться от ортодоксального подхода ООП и вместо этого пойти процедурным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...