2

I am looking to create a custom rounded frame for an application window (border-radius and shadow) From a performance point of view, what would be the best technique for this?

a. Use regions (SetWindowRgn) for the rounded application window and a layered window (UpdateLayeredWindow) for the shadow.

b. Use layered windows for both the rounded application window and the shadow.

The docs for UpdateLayeredWindow specify:

For best drawing performance by the layered window and any underlying windows, the layered window should be as small as possible.

I am asking this specifically for the application main window, so a large window that can have a high complexity and is most of the times visible on the screen.

Should I go with regions or layered window for the application window? Which one would be lighter on the CPU/memory?

Dan
  • 217
  • 2
  • 5
  • 1
    I'm voting to close this as being "primarily opinion-based". If you want to know which one is more efficient, test both yourself and see which one works better for your needs. – Remy Lebeau Jan 26 '18 at 01:27
  • The only way to find out is to test. I would - however - expect layered windows to be more efficient as windows actually uses them. Window regions were introduced with windows 95 - always were a bit of a novelty, and don't anti-alias the way layered windows can. – Chris Becke Jan 26 '18 at 06:39
  • From a performance point of view it would be best to leave default window frame. I bet that there are considerably more important things to improve in your application rather than rounded frame. – user7860670 Jan 26 '18 at 08:11
  • @RemyLebeau I believe people who worked with both would probably have some insights from their experience. Closing the question would not allow those insights to be known. – Dan Jan 26 '18 at 08:24

1 Answers1

4

SetWindowRgn disables DWM for the given Window. DWM ist the component that is responsible for performantly drawing the Window frame using the available graphics hardware. That should pretty much rule out SetWindowRgn. Also, SetWindowRgn produces very "ancient" looking results because antialiasing is not possible. A pixel can be either fully transparent or fully opaque.

For best drawing performance by the layered window and any underlying windows, the layered window should be as small as possible.

I believe that in 2018, this hint is less relevant. The documentation was written 18 years ago when the hardware was way more limited than today.

Still, UpdateLayeredWindow is not the fastest way to draw custom window frames, especially when you have to update the bitmap often (e. g. during window resize). The bottleneck is that these updates have to go from system memory to graphics memory. To minimize window size, create four small windows which are only large enough to draw the borders/corners of your window. This trick is pulled by Visual Studio for instance. Using Spy++ one can see 4 instances of "VisualStudioGlowWindow" which are layered windows that are just 9 pixels wide/tall (on my system):

enter image description here

If you want maximum performance, you may also look into Direct Composition, combined with the WS_EX_NOREDIRECTIONBITMAP extended window style, as explained in the article "High-Performance Window Layering Using the Windows Composition Engine". This technique requires Windows 8 at least.

zett42
  • 25,437
  • 3
  • 35
  • 72
  • From my experience a layered window is very fast. You can also implement a direct dragging around of it and this is also very smooth - without any special video hardware. – Nick Feb 05 '20 at 15:17