Производительность DrawingVisual vs Canvas.OnRender для множества постоянно меняющихся фигур - PullRequest
12 голосов
/ 23 февраля 2010

Я работаю над игровым приложением, которое имеет до тысячи фигур (эллипсов и линий), которые постоянно меняются со скоростью 60 кадров в секунду. Прочитав превосходную статью о рендеринге многих движущихся фигур , я реализовал это с помощью пользовательского потомка Canvas, который переопределяет OnRender для рисования через DrawingContext. Производительность вполне разумная, хотя загрузка ЦП остается высокой.

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

Изменение реализации таким способом - не легкое усилие, поэтому я хотел бы понять причины и их применимость перед тем, как принять решение о переключении. Почему подход DrawingVisual может привести к более низкой загрузке ЦП, чем подход OnRender в этом сценарии?

Ответы [ 4 ]

15 голосов
/ 23 февраля 2010

Из Pro WPF в C # 2008:

Проблема, связанная с этими приложения не сложность искусство, но огромное количество отдельные графические элементы. Даже если вы заменяете свои элементы Path на Геометрические объекты легче накладные расходы все еще будут препятствовать производительность приложения. WPF Решение для такой ситуации использовать визуальный слой нижнего уровня модель. Основная идея заключается в том, что вы определить каждый графический элемент как Визуальный объект, который является чрезвычайно легкий ингредиент, который имеет меньше накладные расходы, чем объект Geometry или Путь объекта.

Что сводится к тому, что каждый из тех эллипсов и линий, которые вы создаете, является отдельным FrameworkElement; это означает, что он поддерживает не только тестирование попаданий, но также макет, ввод, фокус, события, стили, привязку данных, ресурсы и анимацию. Это довольно тяжелый объект для того, что вы пытаетесь сделать! Объект Visual пропускает все это и наследует непосредственно от DependencyObject. Он по-прежнему поддерживает тестирование попаданий, преобразование координат и вычисления ограничивающих рамок, но не поддерживает другие формы, которые поддерживают фигуры. Он гораздо более легкий и, вероятно, значительно улучшит вашу производительность.

EDIT:

Хорошо, я неправильно понял ваш вопрос в первый раз.

В случае, если вы используете OnRender, это действительно зависит от того, как вы создаете визуальные эффекты и отображаете их. Если вы используете DrawingContext и добавляете все визуальные эффекты к одному элементу, это ничем не отличается от использования подхода DrawingVisual. Если бы вы создавали отдельный элемент для каждого созданного Visual, это было бы проблемой. Мне кажется, что вы делаете все правильно.

8 голосов
/ 13 июня 2010

Все в ответах ошиблись. Вопрос в том, быстрее ли рендеринг фигур непосредственно в контексте рисования, чем создание DrawingVisual. Ответ, очевидно, «да». Такие функции, как DrawLine, DrawEllipse, DrawRectangle и т. Д., Не создают никаких элементов пользовательского интерфейса. DrawingVisual намного медленнее, потому что он создает элемент пользовательского интерфейса, хотя и легкий. Путаница в ответах заключается в том, что люди просто копируют / вставляют DrawingVisual лучше, чем отдельные операторы форм UIElement из MSDN.

7 голосов
/ 26 февраля 2010

Я думал, что Петцольд объясняет в этом параграфе;

Класс ScatterPlotVisual работает создание объекта DrawingVisual для каждый DataPoint. Когда свойства изменение объекта DataPoint, класс нужно только изменить DrawingVisual связанный с этим DataPoint.

Который основан на более раннем объяснении;

Всякий раз, когда свойство ItemsSource изменения, или изменения коллекции, или свойство объектов DataPoint в коллекция меняется, ScatterPlotRender вызывает InvalidateVisual. Это создает вызов OnRender, который рисует весь график рассеяния .

Это то, о чем вы спрашиваете?

Кстати, это - сравнительно недавнее высокопроизводительное учебное пособие по WPF, много десятков тысяч точек на этом графике, оно также отрисовывается в 3D и анимировано (даже использует ввод с помощью мыши для управления некоторыми из преобразования).

2 голосов
/ 22 декабря 2010

В моих тестах (панорамирование анимации) я не заметил разницы в скорости. Я бы сказал, что использование элемента хоста для многих визуальных элементов рисования немного быстрее. Этот подход, при котором вы создаете свое визуальное дерево с множеством визуальных элементов, дает вам больше контроля. Более того, если вы хотите выполнить сложное тестирование попаданий, процесс фильтрации быстрее, потому что вы можете пропустить целые «ветви» визуальных элементов

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