У меня есть приложение WPF с пользовательским стилем окон (AllowsTransparency = "True" WindowStyle = "None"). В этом окне есть пользовательский элемент управления Peak Meter, который использует WriteableBitmap для извлечения данных из аудиовхода DirectSound.
Я использую растровое изображение со всеми уровнями, нарисованными в виде цветных прямоугольников (красный / желтый / зеленый / красный), и когда звук поступает, я просто рисую черный прямоугольник над уровнемером сверху. Он отлично работает на моей машине (Windows 7, Pentium 4 одноядерный). Но он плохо работает на ноутбуке с Windows XP SP3 и встроенным видео.
Я знаю, что у эффектов прозрачности есть некоторые проблемы в DirectX 9, но я прочитал, что проблема должна быть исправлена в SP3. Тем не менее, вызов _writeableBitmap.AddDirtyRect занимает 30-40% ЦП в XP и иногда вызывает пропадание звука (если используется звук USB, и эти пропадания происходят не в моем приложении, а где-то в подсистеме драйверов DirectSound <->).
В Windows 7 одно и то же приложение занимает не более 3% ЦП, при этом пропадание звука не замечено (но ЦП фактически слабее на ПК с Win7, чем на ноутбуке с XP).
Я пытался не использовать AddDirtyRect, а просто нарисовать элемент WPF Rectangle поверх изображения с помощью светодиодов и установить высоту прямоугольника при появлении нового уровня звука. Какой сюрприз! Каким-то образом изменение высоты элемента Rectangle требует заметно меньше ресурсов, чем вызов _writeableBitmap.AddDirtyRect для прямоугольника размером 100x20 пикселей! Теперь на XP это заняло всего 10-20% вместо 30-40% с AddDirtyRect.
Но когда я удалил эффект прозрачности из окна, наконец, XP (и даже на VirtualBox) снизился до 2-6% CPU. Очевидно, что из-за прозрачности очень трудно перерисовывать прямоугольник 20x100 10 раз в секунду.
Я мог бы жить без прозрачности в моем приложении, но проблема в том, что в дизайне используются окна с закругленными углами, и мне нужно обрезать область вокруг них. Но как только я установлю AllowsTransparency = "False", в окне появится цвет фона позади.
Итак, главный вопрос - как сделать так, чтобы содержимое окна отсекало фон окна, чтобы углы оставались круглыми, не используя прозрачность с высоким уровнем XP?
Я помню, что я мог сделать больше, чем даже в приложении C ++ для Windows, просто установив пользовательскую область окна и не используя никакой прозрачности (которая была на компьютере с Windows 98). Можно ли сделать то же самое в WPF?
Или, может быть, есть какой-то трюк, как заставить WriteableBitmap использовать меньше ресурсов в XP?