Формы Windows: Как эффективно обрабатывать перерисовку? - PullRequest
2 голосов
/ 15 января 2010

У меня есть форма с картинкой, которая отображает картинку и наложение, нарисованное в обработчике события Paint в картинке. Наложение обновляет свою часть (в основном изменяет непрозрачность различных частей наложения) в зависимости от движения мыши.

В настоящее время я звоню pictureBox.Invalidate() из обработчика перемещения мыши, чтобы убедиться, что наложение перекрашено. Я также реализовал некоторую логику, чтобы определить, действительно ли нужен перекрашивание - если ни один объект не изменил свою непрозрачность движением мыши, PictureBox не будет аннулирован.

Я все еще получаю 50-процентную загрузку процессора на двухъядерной машине, когда я двигаю мышь быстрее, чем очень медленно - я предполагаю, что подпрограмме рисования просто не удается перекрасить так часто, как мышь двигалась события генерируются.

Нарисовано не так много объектов, до 10 заполненных прямоугольников с 4 заполненными углами треугольника каждый. Проблема там уже с одним объектом наложения. В основном для рисования используются только методы FillRectangle и FillArea.

Какой подход вы бы предложили в этой ситуации для предотвращения такой высокой загрузки ЦП?

Ответы [ 3 ]

1 голос
/ 15 января 2010

Ограничить циклы отрисовки.

Например, в программировании игры типичная частота кадров составляет 30-60fps или от тридцати до шестидесяти кадров в секунду. Это означает, что экран отрисовывается 30-60 раз в секунду. Примените какое-то ограничение к вашему приложению тоже. 12fps - это примерно самая низкая частота кадров, которую человеческий глаз обманывает, полагая, что это анимация, поэтому я бы не стал опускаться ниже.

На ходы мыши кажется неправильным, если честно. Например, быстрый спам мыши увеличит скорость прорисовки.

1 голос
/ 15 января 2010

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

Использование таймера для фиксирования частоты обновления на некоторой постоянной (начните с задержки 40 мс для частоты обновления приблизительно 25 Гц и увеличивайте или уменьшайте при необходимости) - это простой способ сделать это ... Таймеры (System.Windows. По крайней мере, Forms.Timer) также имеют низкий приоритет, поэтому вам не нужно беспокоиться о логике обновления, вытесняющей более важные обработчики событий.

Конечно, сохраните существующий код, который вы используете, чтобы определить, действительно ли что-либо изменилось . Установите флаг, когда он установлен, и когда этот флаг установлен , а не , просто ничего не делайте в обработчике событий таймера.

После этого вы увидите немедленное уменьшение максимального времени обработки, поскольку вы отсоединили частоту обновления от скорости мыши. Вы также обнаружите, что у вас больше контроля над временем обработки медиана , так как частота обновления находится под вашим контролем: слишком высокое, уменьшите частоту тиков таймера; недостаточно гладко, увеличение это!

0 голосов
/ 15 января 2010

Если вы перерисовываете событие перемещения мыши, то вы будете много перерисовывать. Вопрос в том, нужно ли вам рисовать каждый раз, когда мышь фактически двигается, или вы хотите, чтобы она рисовала, когда она закончила двигаться? Или где-то посередине? Добавьте некоторую логику, которая перерисовывается только в конце движения мыши, или что-то в этом роде.

...