JDK-6343853 : Rendering issues on Vista caused by use of GDI and DDraw on onscreen surfaces
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2005-10-31
  • Updated: 2010-05-09
  • Resolved: 2006-03-22
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.
Other Other JDK 6
1.4.2_19-revFixed 1.4.2_20Fixed 6 b77Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Description
Check out the attached pictures.  One (ssetokay.png) shows how SwingSet should look.  Another (ssetbad.png) shows SwingSet with black rectangles and offset rendering.  The last (ssetcomparison.png) shows the good and bad images side by side.

To get the bad results, run SwingSet2 with no command line options (so it will use the defatul ddraw renderer).  The window will probably look fine when it comes up.  Now resize the window and notice how the window cycles through bad offsets and black rectangles, ending up randomly with either bad offsets or not.

Comments
EVALUATION A simple fix was put in for now, which disables the use of DDraw on Windows Vista. To override, use -Dsun.java2d.noddraw=false .
15-03-2006

EVALUATION The bug was reported to Microsoft and it appears that this is something we'll have to live with. Basically, applications are not supposed to render to onscreen surfaces using DDraw and GDI, at least, to the same area. Unfortunately we do that and there appears to be no easy way to fix this given our current pipelines. It does work in previous releases but apparently it was never guaranteed. So, an application should either use GDI or DDraw exclusively. Since rendering to offscreen surfaces using DDraw and copying them to the screen using GDI is extremely slow (basically it's a read from vram to system memory and then back to vram), we'll have to disable ddraw completely. This actually yields quite acceptable performance on Vista. There's still an issue of full screen mode, where we would like to use DDraw and Direct3D.
08-03-2006

EVALUATION I've been able to reproduce similar behavior in [an attached] native application. Here's what it does: - creates and initializes an offscreen dd surface - for paint event it uses GDI to clear the window with changing colors, so you can see if the window was repainted; and every third time it also copies the dd surface to the window This is done to show that painting with GDI only w/o copying the bb to the screen works fine - just to make things more visual it can launch a separate thread that repaints the window every 2 seconds (File/Run Update Thread). The thread doesn't just request a repaint event but renders directly - you can request the back-buffer to be updated before it's copied to the screen (see below to why this is interesting) - File/UpdateBackBuffer - by default it uses DDraw to clear the window on each rendering/repant event - this is to illustrate that the bug doesn't manifest if ddraw only is used for rendering to the window. You can change this in the File/ menu. The app clears the window with different color on every repaint, and copies the offscreen surface to the window on every third repaint. Here's what happens: on Vista when the app is launched you can see that it it works fine - this is because by default it uses only DDraw for rendering to the window. But if you uncheck the "File/Clear using DD" menu, it will use GDI for clearing the window and you'll see that the repainting stops as soon as the back-buffer is copied to the window. Actually what happens is that the app keeps the rendering, but the window doesn't get updated. If you check "Update BackBuffer", then it'll update the offscreen surface before copying it to the screen (by filling it with some color). In this case you'll see a funny effect: the area where the bb is copied to is updated, but the rest of the window still isn't. I haven't been able to reproduce the problem where the image of the window is shifted by the insets - I guess the way Java does insets stuff is a bit different, but I'm sure I can reproduce it as well given more time. I bet it involves fiddling with the OffsetViewportOrgEx function, which we use when setting up a display GC prior to using it (see Win32SurfaceData.cpp : SetupThreadGraphicsInfo() function). I've also attached an AWT application which does the same thing as the native one, except w/o all the different menu choices.
17-01-2006

EVALUATION My testing was done on Vista build 5270 and mustang b65. The insets problem is only the tip of the iceberg. It's not like the rendering is offset by twice the insets needed, the application window doesn't refresh correctly as well - like you'd click on the menu and it won't appear but the tracing says that we do render it. Also, it's not necessary to resize the window to get the effect, sometimes it's enough to just move the application frame around a bit. There are many other funny issues. For example, run SwingSet2 and drag one of the internal frames down (or just scroll down) - the rendering gets messed up. After this menus stop working, for example. Dragging it up or left-right works fine. I can't yet reproduce it with smaller test case with just copyAreas. It appears that all these problems are related to using ddraw for blitting to the screen. When DDraw blits to the screen are disabled (offscreen->offscreen blits remain enabled), all problems disappear. So, for example, if -Dsun.java2d.ddblits=false flag is used everything works fine, but we lose the offscreen->offscreen blits as well. I've modified the code to only allow offscreen blits and the bug went away. I suspect that this is really a vista bug. I've seen very weird things happening with the way application frame is updated, which couldn't have been caused by our stuff.
06-01-2006

EVALUATION Disabling swing.bufferPerWindow does not fix the problem. Disabling ddraw does. Note how the black rectangles in ssetbad.png are exactly the size of the window borders on the left (for the vertical rectangle) and on the top (for the horizontal rectangle). Presumably we are double-counting the insets in some situations. Not clear whether this is a 2D issue or an AWT one, but since it's not reproducible with ddraw disabled, it seems like it's specific to the ddraw/2D code. This bug is present on all builds of Vista since Beta1 (Beta1, 5219 and 5231)
31-10-2005