WPF 自定义绘图和透明度 - 如何优化?

发布于 2024-10-20 04:06:16 字数 1221 浏览 0 评论 0原文

我有一个具有自定义窗口样式的 WPF 应用程序(AllowsTransparency="True" WindowStyle="None")。此窗口有一个自定义 Peak Meter 控件,它使用 WriteableBitmap 从 DirectSound 音频输入中绘制数据。

我使用的位图将所有级别绘制为彩色矩形(红色/黄色/绿色/红色),当音频到达时,我只需在顶部的级别计上绘制一个黑色矩形。它在我的机器上运行良好(Windows 7、Pentium 4 单核)。但它在装有 Windows XP SP3 和集成视频的笔记本电脑上运行不佳。

我知道透明度效果在 DirectX 9 上存在一些问题,但我读到该问题应该在 SP3 中得到解决。在 XP 上,对 _writeableBitmap.AddDirtyRect 的调用仍然会占用 30-40% 的 CPU,有时会导致音频丢失(如果使用 USB 音频,并且这些丢失不是发生在我的应用程序中,而是发生在 DirectSound<-> 驱动程序子系统中的某处)。

在 Windows 7 上,同一应用程序占用的 CPU 不超过 3%,并且没有注意到音频丢失(但 Win7 PC 上的 CPU 实际上比 XP 笔记本电脑上的 CPU 更弱)。

我尝试不使用 AddDirtyRect,而只是在带有 LED 的图像上绘制一个 WPF 矩形元素,并在新的音频级别到达时设置矩形的高度。真是一个惊喜!不知何故,更改 Rectangle 元素的高度所需的资源明显少于为 100x20 像素矩形调用 _writeableBitmap.AddDirtyRect!现在,在 XP 上,使用 AddDirtyRect 只需要 10-20%,而不是 30-40%。

但是当我从窗口中删除透明效果时,最终 XP(甚至在 VirtualBox 上)CPU 占用率也下降到 2-6%。显然,透明度使得每秒重绘 20x100 矩形 10 次变得非常困难。

我可以忍受应用程序中没有透明度,但问题是 - 设计使用圆角窗口,我需要切断它们周围的区域。但是一旦我设置AllowsTransparency =“False”,窗口就会显示后面的背景颜色。

所以主要问题是 - 如何使窗口的内容剪掉窗口的背景,以便在不使用 XP 重透明度的情况下使角保持圆形?

我记得我可以做的比在 C++ Windows 应用程序上,只需设置自定义窗口区域而不使用任何透明度(在 Windows 98 计算机上)。在 WPF 上可以做同样的事情吗?

或者也许有一些技巧如何使 WriteableBitmap 在 XP 上使用更少的资源?

I have a WPF application with a custom windows style (AllowsTransparency="True" WindowStyle="None"). This window has a custom Peak Meter control which uses WriteableBitmap to draw data from DirectSound audio input.

I am using a bitmap with all levels drawn as colored rectangles (red/yellow/green/red) and when the audio arrives I just draw a black rectangle over my level meter form the top. It works fine on my machine (Windows 7, Pentium 4 single core). But it works bad on a laptop with Windows XP SP3 and integrated video.

I know that transparency effects have some issues on DirectX 9, but I have read the problem should be fixed in SP3. Still the call to _writeableBitmap.AddDirtyRect takes 30-40% CPU on XP and sometimes it causes dropouts in audio (if USB audio is used, and those dropouts occur not in my application but somewhere in DirectSound<->drivers subsystem).

On Windows 7 the same app takes no more than 3% CPU and no audio dropouts noticed (but the CPU is actually weaker on the Win7 PC than on the laptop with XP).

I tried not to use AddDirtyRect but just draw a WPF Rectangle element over the Image with leds and set the height of the rectangle when new audio level arrives. What a surprise! Somehow changing the height of a Rectangle element takes noticeably less resources than calling _writeableBitmap.AddDirtyRect for 100x20 pixel rectangle! Now on XP it took just 10-20% instead of 30-40% with AddDirtyRect.

But when I removed transparency effect from the window, finally also XP (and even on VirtualBox) went down to 2-6% CPU. Obviously transparency makes it really hard to redraw 20x100 rectangle 10 times per second.

I could live with no transparency in my application, but the problem is - the design uses rounded corner windows and I need to cutoff the area around them. But as soon as I set AllowsTransparency="False", the window shows the background color behind.

So the main question is - how do I make the contents of the window to clip away the background of the window so the corners stay round without using XP-heavy transparency?

I remember that I could do than even on a C++ Windows application just by setting a custom window region and not using any transparency (that was on a Windows 98 machine). Can the same thing be done on WPF?

Or maybe there is some trick how to make WriteableBitmap to use less resources on XP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

茶色山野 2024-10-27 04:06:16

由于我没有找到更好的方法,所以我使用了旧方法:SetWindowRgn API。

这有点复杂,因为我的应用程序使用了一些突出于主窗口的动画滑出部分,因此我必须将 WPF 动画与 SetWindowRgn 调用同步,以使滑出效果看起来尽可能干净。结果并不理想,但可以接受。最重要的是 - 不再需要高 CPU 和音频丢失。

As I did not find anything better, I used the old way: SetWindowRgn API.

It was a bit complicated because my application uses some animated slide-out parts which protrude out of the main window so I had to sync WPF animation with SetWindowRgn calls to make slide-out effect look as clean as possible. The result is not ideal but acceptable. And the main thing - no more high CPU and no audio dropouts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文