Механизм скининга в Windows: рисовать только "грязные" области или все окно сразу?
Я хочу сделать движок для создания скинов, способный рисовать окна специальной формы с альфа-смешиванием. То есть он будет использовать многослойные окна (UpdateLayeredWindow). Типичное окно будет содержать среди своего фона пару десятков других растровых изображений в диапазоне от 10×10 до, скажем, 300×150 пикселей. В худшем случае большинство этих элементов будут иметь плавную анимацию до 30 кадров в секунду. Все будет в альфа-смешении, и я собираюсь использовать Direct2D для этого (да, я знаю, что старые версии Windows не поддерживают его). В целом, современный скин-движок Winamp является наиболее близким примером.
Учитывая все это и принимая во внимание производительность современных ПК, могу ли я просто перерисовывать все окно в каждом отдельном кадре или мне нужно ограничиться каким-либо прямоугольником клипа?
2 ответа
У меня есть некоторый опыт с этим.
Если вам требуется поддержка Windows XP, использование UpdateLayeredWindow - единственный доступный вариант для решения этой проблемы. Документация для этого вызова говорит, что он копирует все растровое изображение на экран каждый раз, когда он вызывается, и это узкое место показало в моем тестировании как реальный ограничивающий фактор. Если ваше окно 300х300, вы платите эту цену за каждое обновление, даже если вы стараетесь изменить только пару пикселей. Было бы очень легко чрезмерно оптимизировать сторону рендеринга без реальной выгоды, поэтому реализуйте что-то простое, измерьте, а затем решите, нужно ли оптимизировать.
Если вы можете отказаться от поддержки Windows XP, вы можете полностью избежать UpdateLayeredWindow и использовать DwmExtendFrameIntoClientArea, чтобы создать тот же эффект, что и в многослойном окне. Вы напишите меньше кода, избежите узкого места UpdateLayeredWindow, и с D2D будет легче работать.
D2D требовал, чтобы вы отображали сообщения WM_Paint Honneslty, использовали интерфейс IAnimation и просто позволяли D2D и окнам беспокоиться о частоте перерисовки, хотя я сообщу вам, что winamp выполняется с помощью Adobe Air, а слоистые окна с d2d вызывают проблемы. (В некотором роде думаю, что вы должны использовать цель рендеринга DXGI, но с наложенным слоем окна необходимо, чтобы DC возвращался к завершающему вызову рисования, чтобы он мог обновить свой альфа-канал)