Формы Windows: Как эффективно обрабатывать перерисовку?

2

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

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

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

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

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

  • 0
    Какова спецификация вашего ПК? У вас есть видеокарта с видеокартой на борту?
  • 0
    Никакой встроенной видеокарты, это высокопроизводительный аппарат с игровой видеокартой - не новое поколение, но, безусловно, хорошее.
Теги:
winforms
user-interface
gdi+

3 ответа

1
Лучший ответ

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

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

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

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

1

Ограничьте циклы вытягивания.

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

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

0

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

  • 0
    Мне определенно нужно перерисовать как реакцию на перемещение мыши - есть области, которые меняют непрозрачность в зависимости от расстояния до мыши

Ещё вопросы

Сообщество Overcoder
Наверх
Меню