Производительность WPF: отображение тысяч путей/фигур на холсте
В настоящее время я разрабатываю инструмент визуализации, который рисует формы WPF, такие как пути, эллипсы и т.д. на холсте. Я уже реализовал виртуализированный подход, при котором Shapes уничтожаются и создаются "на лету" в зависимости от их видимости. Однако даже при видимости всего лишь 600 эллипсов приложение, похоже, работает.
Каковы мои возможности ускорить работу? Я думаю, что рендеринг сгруппированных фигур (пусть говорят по 500 за раз) как прозрачные растровые изображения и только рисование их на холсте. Но я не знаю, хорошая ли это идея... Из того, что я собираю, это требует какого-то взлома, если бы были применены преобразования:
VisualBrush shapeBrush = new VisualBrush(shape);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
using (drawingContext)
{
drawingContext.DrawRectangle(shapeBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);
Как использовать большой WritableBitmap? Это будет другой подход?
Ответы
Ответ 1
WPF под обложками работает с рисунками и геометриями - когда вы говорите, что работаете с фигурами, являются ли эти фактические UIElements? Такие элементы довольно немного тяжелее. Если вы используете только базовые (предпочтительно потоковые) геометрии для рисования чертежей, вы получите наилучшую производительность в своем опыте.
Мне удалось получить около 10000 точек с разумной частотой кадров с этим подходом, но что-то более сложное, чем точка, начинает замедлять работу (скажем, круглые точки или даже прямоугольники). Тем не менее, основные геометрии и основные чертежи - это путь, если вы хотите избежать как можно большего количества накладных расходов WPF.
Записываемое растровое изображение, очевидно, в конечном счете быстрее, но это означает, что вы сами разгадываете все эти фигуры или кешируете растровое изображение результата, если оно в основном статично. Кроме того, вы обычно хотите применять преобразования перед рендерингом в растровое изображение, а не применять их к самому рендерингу.
Ответ 2
Я знаю, что это старый вопрос, я просто отвечаю интересам сообщества.
Я немного исследовал эту тему, и лучшее, что я нашел, - это вручную создать DrawingVisuals, как вы говорите. Это экономит много внутренней работы для WPF, так что это заканчивается намного быстрее. Я использовал технику для создания легкой диаграммы, которая может иметь пару сотен очков. Здесь статья, в которой я вдохновлялся, вы, возможно, уже знаете об этом.
http://blogs.microsoft.co.il/blogs/tamir/archive/2008/03/02/how-to-high-performance-graphics-in-wpf.aspx
EDIT: новый URL http://khason.net/blog/how-to-high-performance-graphics-in-wpf/
EDIT: новый URL: http://dedjo.blogspot.com/2008/03/how-to-high-performance-graphics-in-wpf.html
Удачи.
Ответ 3
Подход с грубой силой может состоять в том, чтобы внедрить элемент управления ActiveX и визуализировать графику напрямую с помощью Win32. Однако это будет несколько неудобно. Контроль холста QT может быть более теплым и пушистым подходом к тому же концу, и он отметил, что для этого типа вещей довольно быстро. Troll предоставляет оболочку ActiveX для коммерческих версий QT, поэтому ее проще интегрировать.