-
Bug
-
Resolution: Fixed
-
P3
-
1.4.2
-
06
-
x86
-
windows_xp
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2120722 | 6 | Brent Christian | P3 | Resolved | Fixed | b08 |
JDK-2120721 | 5.0u1 | Brent Christian | P3 | Resolved | Fixed | 01 |
JDK-2120720 | 1.4.2_07 | Brent Christian | P3 | Resolved | Fixed | b01 |
Name: rmT116609 Date: 08/11/2004
FULL PRODUCT VERSION :
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)
*BUT*
This occurs for any JDK 1.4+
ADDITIONAL OS VERSION INFORMATION :
Windows XP
Windows (Any)
EXTRA RELEVANT SYSTEM CONFIGURATION :
My video setup is two NEC MultiSync LCD 1980SX monitors using
an NVIDIA Quadro NVS graphics card, though this problem would occur in any multi monitor environment.
A DESCRIPTION OF THE PROBLEM :
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.Panel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* Instructions:
*
* The following snippet demonstrates a severe performance regression in AWT
* starting in 1.4 (merlin), and still present in the current version of the JDK
* (tiger beta 2). In a multimonitor Windows XP environment set up as a single
* display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
* an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
* between the two monitors. In the AWT program, the event dispatch thread is
* frozen while all of the surface datas are being recreated in the hierarchy
* (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
* the behavior because it does not have native peers.
*/
public class Test {
private static final int NESTED_PANELS = 25;
// This one is very slow!
public static void testAWT() {
Frame frame = new Frame("AWT Test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
Label label = new Label("Hello world");
frame.add(label, BorderLayout.NORTH);
Panel panel = new Panel(new BorderLayout());
Panel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
Panel newPanel = new Panel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
// This one works swell!
public static void testSwing() {
JFrame frame = new JFrame("Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JLabel label = new JLabel("Hello world");
frame.getContentPane().add(label, BorderLayout.NORTH);
JPanel panel = new JPanel(new BorderLayout());
JPanel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
JPanel newPanel = new JPanel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.getContentPane().add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.getContentPane().add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
testAWT();
// testSwing();
}
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the above code snippet documentation. Drag the window from one monitor to the other. Try to press the button.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See the Swing version for bug-free behavior.
ACTUAL -
Exponential performance degredation depending on number of levels in the component hierarchy.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Stuck in Win32SurfaceData.initOps for all of the components while it exponentially goes through the hierarchy.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.Panel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* Instructions:
*
* The following snippet demonstrates a severe performance regression in AWT
* starting in 1.4 (merlin), and still present in the current version of the JDK
* (tiger beta 2). In a multimonitor Windows XP environment set up as a single
* display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
* an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
* between the two monitors. In the AWT program, the event dispatch thread is
* frozen while all of the surface datas are being recreated in the hierarchy
* (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
* the behavior because it does not have native peers.
*/
public class Test {
private static final int NESTED_PANELS = 25;
// This one is very slow!
public static void testAWT() {
Frame frame = new Frame("AWT Test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
Label label = new Label("Hello world");
frame.add(label, BorderLayout.NORTH);
Panel panel = new Panel(new BorderLayout());
Panel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
Panel newPanel = new Panel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
// This one works swell!
public static void testSwing() {
JFrame frame = new JFrame("Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JLabel label = new JLabel("Hello world");
frame.getContentPane().add(label, BorderLayout.NORTH);
JPanel panel = new JPanel(new BorderLayout());
JPanel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
JPanel newPanel = new JPanel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.getContentPane().add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.getContentPane().add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
testAWT();
// testSwing();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The fix (WPanelPeer.java) :
private void recursiveDisplayChanged(Component component)
{
if(component instanceof Container)
{
Component acomponent[] = ((Container)component).getComponents();
for(int i = 0; i < acomponent.length; i++)
recursiveDisplayChanged(acomponent[i]);
}
java.awt.peer.ComponentPeer componentpeer = component.getPeer();
//sanjiv: added this if condition so that WPanelPeer displayChanged() is not called //which will again call this method
System.out.println("Component : " + component.getName());
if(componentpeer != null && (componentpeer instanceof WPanelPeer)){
super.displayChanged();
}
else
if(componentpeer != null && (componentpeer instanceof WComponentPeer))
{
WComponentPeer wcomponentpeer = (WComponentPeer)componentpeer;
wcomponentpeer.displayChanged();
}
}
(Incident Review ID: 296521)
======================================================================
FULL PRODUCT VERSION :
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)
*BUT*
This occurs for any JDK 1.4+
ADDITIONAL OS VERSION INFORMATION :
Windows XP
Windows (Any)
EXTRA RELEVANT SYSTEM CONFIGURATION :
My video setup is two NEC MultiSync LCD 1980SX monitors using
an NVIDIA Quadro NVS graphics card, though this problem would occur in any multi monitor environment.
A DESCRIPTION OF THE PROBLEM :
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.Panel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* Instructions:
*
* The following snippet demonstrates a severe performance regression in AWT
* starting in 1.4 (merlin), and still present in the current version of the JDK
* (tiger beta 2). In a multimonitor Windows XP environment set up as a single
* display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
* an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
* between the two monitors. In the AWT program, the event dispatch thread is
* frozen while all of the surface datas are being recreated in the hierarchy
* (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
* the behavior because it does not have native peers.
*/
public class Test {
private static final int NESTED_PANELS = 25;
// This one is very slow!
public static void testAWT() {
Frame frame = new Frame("AWT Test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
Label label = new Label("Hello world");
frame.add(label, BorderLayout.NORTH);
Panel panel = new Panel(new BorderLayout());
Panel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
Panel newPanel = new Panel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
// This one works swell!
public static void testSwing() {
JFrame frame = new JFrame("Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JLabel label = new JLabel("Hello world");
frame.getContentPane().add(label, BorderLayout.NORTH);
JPanel panel = new JPanel(new BorderLayout());
JPanel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
JPanel newPanel = new JPanel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.getContentPane().add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.getContentPane().add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
testAWT();
// testSwing();
}
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the above code snippet documentation. Drag the window from one monitor to the other. Try to press the button.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See the Swing version for bug-free behavior.
ACTUAL -
Exponential performance degredation depending on number of levels in the component hierarchy.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Stuck in Win32SurfaceData.initOps for all of the components while it exponentially goes through the hierarchy.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Frame;
import java.awt.Label;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.Panel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* Instructions:
*
* The following snippet demonstrates a severe performance regression in AWT
* starting in 1.4 (merlin), and still present in the current version of the JDK
* (tiger beta 2). In a multimonitor Windows XP environment set up as a single
* display area (my video setup is two NEC MultiSync LCD 1980SX monitors using
* an NVIDIA Quadro NVS graphics card), take the window and drag it rapidly
* between the two monitors. In the AWT program, the event dispatch thread is
* frozen while all of the surface datas are being recreated in the hierarchy
* (in Win32SurfaceData.initOps). Note that the Swing program does not exhibit
* the behavior because it does not have native peers.
*/
public class Test {
private static final int NESTED_PANELS = 25;
// This one is very slow!
public static void testAWT() {
Frame frame = new Frame("AWT Test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
Label label = new Label("Hello world");
frame.add(label, BorderLayout.NORTH);
Panel panel = new Panel(new BorderLayout());
Panel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
Panel newPanel = new Panel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
// This one works swell!
public static void testSwing() {
JFrame frame = new JFrame("Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JLabel label = new JLabel("Hello world");
frame.getContentPane().add(label, BorderLayout.NORTH);
JPanel panel = new JPanel(new BorderLayout());
JPanel currentPanel = panel;
for (int i = 0; i < NESTED_PANELS; i++) {
JPanel newPanel = new JPanel(new BorderLayout());
currentPanel.add(newPanel, BorderLayout.CENTER);
currentPanel = newPanel;
}
currentPanel.add(new Label("Test"));
frame.getContentPane().add(panel, BorderLayout.CENTER);
Button btn = new Button("OK");
frame.getContentPane().add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
testAWT();
// testSwing();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The fix (WPanelPeer.java) :
private void recursiveDisplayChanged(Component component)
{
if(component instanceof Container)
{
Component acomponent[] = ((Container)component).getComponents();
for(int i = 0; i < acomponent.length; i++)
recursiveDisplayChanged(acomponent[i]);
}
java.awt.peer.ComponentPeer componentpeer = component.getPeer();
//sanjiv: added this if condition so that WPanelPeer displayChanged() is not called //which will again call this method
System.out.println("Component : " + component.getName());
if(componentpeer != null && (componentpeer instanceof WPanelPeer)){
super.displayChanged();
}
else
if(componentpeer != null && (componentpeer instanceof WComponentPeer))
{
WComponentPeer wcomponentpeer = (WComponentPeer)componentpeer;
wcomponentpeer.displayChanged();
}
}
(Incident Review ID: 296521)
======================================================================
- backported by
-
JDK-2120720 Exponential performance regression in AWT components (multiple monitors)
- Resolved
-
JDK-2120721 Exponential performance regression in AWT components (multiple monitors)
- Resolved
-
JDK-2120722 Exponential performance regression in AWT components (multiple monitors)
- Resolved
- relates to
-
JDK-4452373 display change on win32 not propagating to all heavyweight components
- Resolved
-
JDK-6567564 Canvas's graphics config does not change when moved across monitors, Linux
- Closed