JDK-6646703 : Differences in repainting behavior of JApplet with and without -Dsun.java2d.noddraw=true
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows
  • CPU: generic
  • Submitted: 2008-01-03
  • Updated: 2010-04-06
  • Resolved: 2008-01-05
Related Reports
Duplicate :  
Relates :  
Description
The test case from 6644662 raised an issue where the repainting behavior of JApplet is different with and without -Dsun.java2d.noddraw=true specified. The issue has been discussed at length with ###@###.### and this bug has been filed to track the potential issue.

If the user's applet extends JApplet and overrides paint(Graphics), then if g.clearRect(0, 0, getWidth(), getHeight()) is not called at the beginning of the overridden paint(), if -Dsun.java2d.noddraw=true is specified via the Java Applet Runtime Parameters in the Java Control Panel then garbage appears on the screen. If -Dsun.java2d.noddraw=true is not specified (i.e., the default), then the painting results are correct.

See the attached test cases. To reproduce the behavior with the "classic" plug-in, use the Java Control Panel, Java Applet Runtime Parameters, to toggle the setting of -Dsun.java2d.noddraw=true and view the two test cases with and without it specified. TestApplet.html renders correctly with the default parameters, and incorrectly with -Dsun.java2d.noddraw=true. TestAppletCorrect.html renders correctly both with and without -Dsun.java2d.noddraw=true.

Oddly enough, if super.paint(g) is called, then even if g.clearRect() is also called, the painting results are incorrect with -Dsun.java2d=noddraw=true. See the commented-out code in TestAppletCorrect.java.

Note that JApplet overrides update() to not call an "unnecessary" clearRect() present in java.awt.Container.paint(Graphics).

During discussions with ###@###.### we tried toggling the Swing buffer-per-window system property but were unable to provoke a difference in behavior with that system property specified in either direction (true or false).

It is unclear whether this behavior is a bug or lies in the unspecified areas of Java 2D and/or Swing. However, more investigation is needed.

Comments
EVALUATION To get things straight: a proper Swing applet or application never renders directly to the screen, which what this applet does by overriding paint() and rendering to the supplied graphics context. It is supposed to have added a jcomponent to JApplet and overridden paintComponent(). Here's how the applet behaves in earlier releases when a window is moved over the applet (btw it can be reproduced with the appletviewer): default noddraw=true ---------------------------------------------------- 1.5.*: no garbage* no garbage* 1.6.0-1.6.0_03: garbage garbage 1.6.0_10: no garbage** garbage *) tracing shows that there is a Java2D fill rect on expose which clears the background **) only if window is larger than certain size It appears that the behavior changed in jdk6 (likely because of the addition of the bufferPerWindow repainting mode in Swing), and then again in 6uN (6u_10). So if we assume that the "correct" behavior is in 1.6.0 (garbage on the screen on expose), then this is not a bug since "no garbage" is a specific case of "garbage" =) The reason in 6uN the bg doesn't show garbage on expose events when the d3d pipeline is enabled is because of the on-screen rendering redirecting mechinism introduced with the d3d pipeline. All on-screen rendering goes to an off-screen surface (swap chain), which is flipped occasionaly or on some cues (like copying an image to the screen). So in effect the window is double-buffered, and when the back-buffer is presented it obliterates the garbage. If this mechanism is disabled (for example, the window is resized to be less than 150x150, or via flag) then we'll get the same behavior as in 1.6.0. As for the other issue mentioned in the description: "if super.paint() is called then the drawString doesn't appear" This is because of the buffer per window rendering mode introduced in Java 6 (and it's reproducible witn 1.6.0). The call to super() actually redirects all rendering to the swing back-buffer, which is then flipped to the screen. In response to an expose event the flip will happen on the toolkit thread, so depending on timing whatever was rendered in this applet's overridden paint() may be obliteraed by the flip from the swing backbuffer which happens from a different thread. If buffer per window is disabled via flag the behavior will be as expected. I don't believe this is a bug but rather a limitation of the true double-buffering approach. Proper Swing applications (and applets) are supposed to render only to the screen. Given all this I'm closing this bug as not a defect.
05-01-2008