United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6312510 : jdk 1.4.2_07 java apps color problem with patch 109147-34

Details
Type:
Bug
Submit Date:
2005-08-17
Status:
Resolved
Updated Date:
2010-12-03
Project Name:
JDK
Resolved Date:
2005-11-21
Component:
client-libs
OS:
solaris_8
Sub-Component:
2d
CPU:
sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2_07
Fixed Versions:

Related Reports
Backport:
Backport:

Sub Tasks

Description
The problem:
The testcase is in /share/esc/1-9895956/
you can reproduced it with jdk 1.4.2_5 or later with patch 109147-34.
You will see the color problem. The problem looks like a "color flashing" problem.
But it is not. The problem happens on all graphics cards, if you set it to 8 bit
only. With 1.4.2_2 or older, you do not see this problem. Without 109147-34, even
with 1.4.2_7 you do not see this problem either.

To run the testcase:
setenv JDKHOME /net/koori.sfbay/onestop/jdk/1.4.2_08/latest/binaries/solaris-sparc/bin
1. compile java program
$JDKHOME/javac colorProblem.java
2. run the program
$JDKHOME/java colorProblem
3. move mouse focus to app, then move away, you will see it.



testcase:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class colorProblem extends JFrame
{
   private static colorProblem fMaster = null;
   private static boolean toggle = true;

   public colorProblem(boolean master) {init(master);}
   private void init(boolean master)
   {
System.out.println("in init");
	//JFrame f = new JFrame();
	setBounds(100, 100, 300, 200);
	if(master)
	   setTitle("Master");
	else
           setTitle("Slave");
	Container content = getContentPane();
	JButton button = new JButton();
	button.setLabel("Exit");

	button.addActionListener(new ActionListener()
	{
         public void actionPerformed(ActionEvent event)
	 {
             toggle = !toggle;
             System.out.println("button press:"+toggle);
			System.exit(0);

	 }
       });
       content.add(button);
	setVisible(true);


   }
   public static void main(String[] args)
   {
System.out.println("in main");
	fMaster = new colorProblem(true);
   }
}

                                    

Comments
SUGGESTED FIX

*** /tmp/geta7379	Thu Oct 20 11:03:38 2005
--- awt_GraphicsEnv.c	Thu Oct 20 10:58:11 2005
***************
*** 252,257 ****
--- 252,259 ----
      xinawareScreen = usingXinerama ? 0 : screen;
      defaultVisualID = 
  	XVisualIDFromVisual(DefaultVisual(awt_display, xinawareScreen));
+ 
+     memset(&vinfo, 0, sizeof(XVisualInfo));
      vinfo.screen = xinawareScreen;
  
      if ((forcedVisualStr = getenv("FORCEDEFVIS"))) {
***************
*** 284,298 ****
      if (defaultConfig) {
  	return defaultConfig;
      }
!     
!     /* try the default visual if we haven't already */
!     if (vinfo.visualid != defaultVisualID) {
! 	vinfo.visualid = defaultVisualID;
! 	mask = VisualIDMask | VisualScreenMask;
! 	defaultConfig = findWithTemplate(&vinfo, mask);
! 	if (defaultConfig) {
! 	    return defaultConfig;
! 	}
      }
  
      /* try any TrueColor */
--- 286,298 ----
      if (defaultConfig) {
  	return defaultConfig;
      }
! 
!     /* try the default visual */
!     vinfo.visualid = defaultVisualID;
!     mask = VisualIDMask | VisualScreenMask;
!     defaultConfig = findWithTemplate(&vinfo, mask);
!     if (defaultConfig) {
!         return defaultConfig;
      }
  
      /* try any TrueColor */
                                     
2005-10-20
EVALUATION

Here's what causes us to choose a weird visual.

Here's how awt_GraphicsEnv.c' makeDefaultConfig() is supposed to work:
  if a specific visual is forced, try using it
  else first try 24-bit TrueColor visual
  if didn't succeed, try the screen's default visual
  if didn't succeed, try other visual classes

In this case all visuals are 8-bit, so we first fail to 
find a 24-bit visual, and are supposed to try a default visual,
which should've had succeded.

But before trying the default visual, we first check that we haven't tried it 
already (like if it was forced, for example):
if (vinfo.visualid != defaultVisualID) {
    vinfo.visualid = defaultVisualID;
    mask = VisualIDMask | VisualScreenMask;
    defaultConfig = findWithTemplate(&vinfo, mask);
    return defaultConfig;
}

The problem is that prior to this line vinfo.visualid hasn't been 
initialized. So if by a weird coincidence the uninizialized vinfo.visualid 
is equal to the default visual id, we would assume that we've already
tried the default visual and failed, so we proceed to trying the next
visual class in line, which happens to be TrueColor class. Since there's
a TrueColor 8-bit visual, we pick it.

Interestingly, this actually happens: the uninitialized field does
equal to the default visual id, but only in an optimized jdk.
I can't reproduce the bug with 1.4.2_05 with the debug build:
there vinfo.visuaid field contains some garbage, so the check fails
and we use the default visual as we were supposed to.

It's possible that the linker patch somehow affected the memory used
for the vinfo structure, making this bug more probable.

Anyway, if the vinfo structure is cleared prior to being used, the
bug goes away. I'm not sure what initial valueis guaranteed not to ever
be equal to the default visual id, so it's best to just use different
means of checking that we'd already tried the default config, or
just try it again anyway.

Note that even though this bug doesn't currently manifest in Mustang, we 
need to fix it there anyway, as it's just plain luck.
                                     
2005-10-20
EVALUATION

I still doubt that the problem is caused by the patch. I have a Solaris 8 system which
has -32 revision of this patch and yet I can reproduce the problem.

Which appears to be caused by the fix for 
  4639878: Java2D does not support 12 bit depth visuals

In this fix we've changed the way a default visual is selected.
Unfortunately in case when there are only 8 bit visuals it now
choses a TrueColor 8-bit visual instead of the default PseudoColor 
visual.
On some video boards this causes desktop/application flashing.
                                     
2005-10-18
WORK AROUND

Force the default visual by setting FORCEDEFVIS env. variable prior
to starting java application:
  FORCEDEFVIS=true    // force the default X server visual to be used by java
or
  FORCEDEFVIS=vis_num // force the use of visual vis_num as the default java's
	              // visual (you can get the desired visual number using xdpyinfo)
                                     
2005-10-18
EVALUATION

109147 is a Solaris linker patch -  I find it very hard to see the connection.

Patch Id: 109147-37
Summary: SunOS 5.8: linker patch

Is that the correct patch number?
Is this reproducible with JDK 1.5 or later?
requesting verification on both of these points.

Hi,
For point (1):
Yes, it is correct patch number. I did MANY tests with and without patch 109147-34. IT IS THE CORRECT PATCH ID. YES , IT IS. I was surprised too. 
For point (2):
As you request, I just tried Java 1.5.0_06, the problem is still there. This problem only shows up with 1.4.2_5 or later with patch 109147-34. If you use older java, or no 109147-34, there is no problem. This problem happens on PGX24, PGX32 and PGX64, namely it is very framebuffer independent, since PGX32 is 3rd party cards, it is a totally different animal comparing with PGX24 and PGX64. The wilder guess I have is that Jave2D is using its owner colormap, and the process it is loading its own colormap related to the linker.

Luke
                                     
2005-08-18



Hardware and Software, Engineered to Work Together