JDK-6600226 : D3D: Repainting Issues while resizing a Swing application.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6u5
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2007-09-03
  • Updated: 2010-10-14
  • Resolved: 2007-09-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6u10 b04Fixed
Related Reports
Relates :  
Relates :  
Description
D3D:Repainting Issues while resizing a Swing application.
Steps to reproduce:
1)Run the SwingSet2 demo or any other Swing application, with the current 6u5-b03 pit on a D3D enabled system with a Windows Vista OS.
2)Resize the application randomly. 
While resizing the Frame, a black rect appears, before the Frame repaints itself completely. 
This is not occuring when d3d is disabled. 
The bug is is also not reproducible if I run the application with flipBufferStrategy property set to true. (-Dswing.useflipBufferStrategy=True)
This is seen since 6u5b01 jdk pit, on a 32 bit Vista Home Premimum.

Comments
SUGGESTED FIX http://sa.sfbay.sun.com/projects/java2d_data/6u5/6600226.0
05-09-2007

EVALUATION The flashing is because of the back-buffer present that we make on the toolkit thread in response to the expose event during resize. Here's what happens: - user resizes the window - awt receives the size event, fires up replaceSurfaceDataLater() - to replace the surface data at some later time on the EDT; at the same time synchronously changing the bounds of the component being resized - awt receives expose event (paint), and executes Swing's painting code on the toolkit thread (BufferStrategyPaintManager.show()) - show() used to validate() the strategy before showing it. However, it never validated it against the dimensions of the component (it was calling revalidate(false) - meaning 'do not validate back-buffer against the comp. dimensions). Not sure why. The current code doesn't call validate() because it could cause deadlocks. Note that we still have the old surfaceData in WComponentPeer at this point since the replaceSurfaceData aven hasn't arrived yet - we're still on the Toolkit thread. - anyway, show() presents the back-buffers and for some reason this present (which is, again, for the newly exposed area - typically a thin strip on the right/bottom of the frame) - just shows up as black recntangle the size of the frame before the resize. My guess is that the DWM's own buffer for this window (where our present() actually copies the contents - not to the screen) gets screwed up somehow and ends up black - note that the bounds of the swap may even be 'legal' - because our swap chain has a back-buffer the size of the window, not the client area. There are no errors, no warnings. This does look like a Vista DWM's bug. The only workaround I found so far is to detect the size change in FlipSubRegionBufferStrategy.showIfNotLost(): boolean sizeChanged = (getWidth() != width || getHeight() != height); if (!sizeChanged && !contentsLost()) { showSubRegion(x1, y1, x2, y2); return !contentsLost(); } and do not present the swap chain. This reduces the flickering significantly, but not eliminates it completely, as sometimes there appears to be a race condition between the size of the window and the swap bounds - so every once in a while we still get a flicker or two. I will need to check if there are any other visual artifacts because of this workaround. It would be interesting to see if the Vista service pack will fix this issue.
03-09-2007

EVALUATION Excellent timing! I've been working on these issues and was about to file a bug myself =) There are a few issues with resizing besides the flickering. One is that we do not recreate the d3d surface in some cases during live resize. The Opengl pipeline had the same issue (6290245). The fix is exactly the same. Another (after the previous one is fixed) is that with with bufferPerWindow=false during the resize one can see some garbage appearing along the right and bottom edges of the frame. This is because when the back-buffer surface is first created, we do not fill it with background color bug issue a repaint call. But if before this repaint comes through another arrives (from the previous resize, with smaller bounds), some of the background will be left uninitialized before the flip. The fix for this one is to fill the back-buffer with the component's background color after the restoration. Now regarding the main problem - the flickering with bufferPerWindow=true . It is not yet clear what's causing it. I can reproduce the same problem with some of the native applications from the D3D9 SDK. And I have also stumbled upon this thread: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=110115&SiteID=1&pageid=0 Here's a quote from the MS response: "The problem should only be visible on Vista with the Aero theme (DWM on). As described above, it is a complex interaction issue between the new window management system and D3D. Since WPF is built on top of D3D it suffers from this issue too. We are working on a fix and I will post an update here once the fix becomes available." Doesn't necessarily apply to our case, and it it doesn't explain why aren't we seeing this with bufferPerWindow=false. This is what I'm currently trying to investigate.
03-09-2007