Swing Painting Improvements: No More Gray Rect!
In scoping out various performance related projects for mustang we wanted to tackle one of Swing's long standing problem areas that has contributed to bad perceived performance. That is, when a Swing based app is exposed after being hidden by another application there is a noticeable delay between when the background of the window is erased and when the actual contents are painted. We've come to call this the 'gray rect' problem. I'm happy to report that with the promotion of mustang build 32 this bug (4967886) has been fixed! Download it now and give us feedback!
The fix involved adding true double buffering support to Swing. That is, each window will now have an off-screen image that is kept in sync with the on-screen image. When a window is exposed we copy directly from the off-screen image, on the toolkit thread, to the screen. That's it! Your application will no longer see paint events in this scenario!
I've been running various Netbeans 4.1 builds for a while now with this fix and while subtle, it makes a big difference! I no longer see the Netbeans window flash when alt-tab'ing back and forth between Netbeans and other apps. Painting of exposed windows is nearly instantaneous.
An added bonus of this fix is that if your application is blocking the event dispatch thread, say you're contacting a server and a user hides your window and exposes it the app will still paint. Nice!
This fix is the most substantial change to Swing's painting architecture since pre 1.0. I'll have a follow on article that discusses the changes in more details. Until then, download the beta, kick the tires and give us feedback! We're not only interested in feedback on this change, but other areas that effect runtime performance you feel we should be focusing on.
For the hackers that want to see the Swing side of the code changes grab the latest source from the JDK source snapshot and look in javax.swing.BufferStrategyPaintManager, javax.swing.SwingPaintEventDispatcher and javax.swing.RepaintManager.
The fine print. For compatibility sake there are a handful of situations that will trigger turning off true double buffering. Most notably if you install your own RepaintManager. Additionally, true double buffering is currently only enabled on Windows. The code works on all platforms, but we have as yet to enable it everywhere. Yes, we're evaluating that now!