Hi everyone-
I’m finally getting back to this. I’ve been trying to benchmark the Direct2D renderer versus the JUCE software renderer to see if Direct2D is actually an improvement. My answer is a qualified “yes” - the D2D renderer is much better at doing things like rendering paths with thousands of points or other CPU-intensive operations. However, there are still a few outstanding issues that need to be solved:
- Smooth animation with multiple windows and a single process
- Window resizing
- Flicker
That’s the executive summary. Buckle up if you want more detail.
Stress Test App
I built a renderer stress test app that spawns multiple windows and attempts to animate all of them at once.
It’s probably hard to make out details in the screen shot; the top bar is a window with controls to select the renderer type, timer rate, etc. Most of the lower area of the screen is divided up into separate windows; you can sort of see the red outlines of each window. This particular setup is trying to run scroll the rectangles horizontally at 60 Hz.
The app can select from multiple renderers:
- JUCE software renderer
- JUCE Direct2D 1.1 renderer
- Direct2D 1.0 (not using the JUCE renderer, just native Direct2D)
- Direct2D 1.1 (not using the JUCE renderer, just native Direct2D)
This particular PC has an Intel Core i9-10900 CPU, 32 GB of RAM, and an NVIDIA GeFore RTX 2080 Ti.
The JUCE Direct2D renderer so far seems to perform similarly to the native D2D code, which is encouraging. But…
Direct2D with multiple windows from a single process
Animating multiple windows simultaneously from a single process doesn’t work very well; the animation hitches and jerks. Weirdly, if I spawn a multiple child processes, the animation is butter-smooth. Looks great! But that’s probably not a practical solution.
So that’s just confusing! Clearly the hardware can keep up. It suggests that there is some internal synchronization within Direct2D that is handled differently for single processes versus multiple processes.
This is using Direct2D 1.1, which is really Direct3D. Apparently Direct3D has a similar issue.
So…
Flip-model swap chain
Direct2D 1.1 uses DXGI swap chains. DXGI swap chains support a number of different swap modes.
The multiple-window single-process test was using the “blt” present model, which is the older swap mode. Microsoft really wants everyone to switch to the new flip model:
https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/for-best-performance–use-dxgi-flip-model
So I tried the flip model, and multi-window-single-process animation looks great. So, problem solved!
Except…
Window resizing
Resizing a window with the flip model swap mode is rough. Dragging the mouse results in unpleasant graphical artifacts around the window edges. Window resizing with the blt mode is perfect. Searching around shows that this is a fairly common issue.
Also…
Flickering
I tried the flip model swap mode with one of my apps and saw a lot of visible flicker drawing the UI. Nasty. Again, using the older blt mode is fine.
Next steps?
Using the flip model really would be preferable. So the challenge seems to be solving the window resizing and flickering. Again, I’d be happy to provide even more detail and documentation if anyone else is interested.
Take care-
Matt