WPF WriteableBitmap and transparency on Windows XP - how to optimize? RRS feed

  • Question

  • I have a WPF application with a custom windows style (AllowsTransparency="True" WindowStyle="None"). This window has a custom Peak Meter 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 XP 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 on the Win7 PC the CPU is weaker 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 combining Image with WriteableBitmap and periodically changing the height of a Rectangle element takes noticeably less resources than periodically calling _writeableBitmap.AddDirtyRect for 100x20 pixel rectangle! Now on XP it uses just 10-20%. Why using Image+Rectangle is faster than using only Image with AddDirtyRect even for such a small 20x100 image?

    But when I removed transparency effect from the window, finally also XP (and even on VirtualBox) went down to 2-6% CPU, hooray!. 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 window uses rounded corner borders 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 with SetWindowRgn 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 to make it down to 2% CPU?
    Friday, March 4, 2011 3:01 PM


  • Hi midix,

    Unfortunately this feature is not supported in WPF. I recall a similar case which chose to use the normal window style instead.

    As to your concern about WriteableBitmap, the less desirable performance on XP is due to the copying the front buffer to the video card. Vista spends most of its time in the DX UpdateSurface call, while XP spends most of its time in a simple memcpy.Reusing the system-memory texture needed to copy the WriteableBitmap's front buffer to the video card.XP is not as efficient as Vista since Vista can create the system-memory texture around the existing system-memory front buffer of the WriteableBitmap, avoiding a copy.

    Hope this explanation is helpful to you.

    Best regards


    Yves Zhang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Yves.Z Sunday, March 20, 2011 6:40 AM
    Tuesday, March 8, 2011 8:30 AM