1 /* 2 * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @key headful 27 @bug 5085626 28 @summary Exponential performance regression in AWT components (multiple mon) 29 @run main WPanelPeerPerf 30 */ 31 32 import java.awt.*; 33 import java.awt.event.*; 34 import javax.swing.*; 35 36 /** 37 * This test must be run on a multi-screen system. 38 * This test works by moving a Frame back and forth between the screens a few 39 * times. When the bug is active, the first move will overwhelm the EDT with 40 * recursive display change calls. The test fails if it takes too long to 41 * service the setLocation() calls and send componentMoved() events. 42 */ 43 public class WPanelPeerPerf { 44 45 private static final int NESTED_PANELS = 25; 46 private static final int ITERATIONS_PER_SCREEN = 3; 47 private static final int MAX_WAIT_PER_SCREEN = 2500; 48 private static final int PAUSE_BETWEEN_MOVES = 500; 49 50 51 private static Object showLock = new Object(); 52 53 private static Counter instance = null; 54 public static Counter getCounter() { 55 if (instance == null) { 56 instance = new Counter(); 57 } 58 return instance; 59 } 60 61 private static class Counter { 62 int counter; 63 Counter() { counter = 0; } 64 } 65 66 // This one is very slow! 67 public static void testAWT() { 68 // fail if only on one screen 69 int numScreens = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length; 70 if (numScreens < 2) { 71 System.err.println("Test must be run on a multiscreen system"); 72 return; 73 } 74 final Frame frame = new Frame("AWT WPanelPeerPerf"); 75 frame.addWindowListener(new WindowAdapter() { 76 public void windowClosing(WindowEvent ev) { 77 System.exit(0); 78 } 79 public void windowOpened(WindowEvent e) { 80 synchronized(showLock) { 81 showLock.notify(); 82 } 83 } 84 }); 85 frame.setLayout(new BorderLayout()); 86 Label label = new Label("Hello world"); 87 frame.add(label, BorderLayout.NORTH); 88 Panel panel = new Panel(new BorderLayout()); 89 Panel currentPanel = panel; 90 for (int i = 0; i < NESTED_PANELS; i++) { 91 Panel newPanel = new Panel(new BorderLayout()); 92 currentPanel.add(newPanel, BorderLayout.CENTER); 93 currentPanel = newPanel; 94 } 95 currentPanel.add(new Label("WPanelPeerPerf")); 96 frame.add(panel, BorderLayout.CENTER); 97 Button btn = new Button("OK"); 98 frame.add(btn, BorderLayout.SOUTH); 99 frame.pack(); 100 101 frame.addComponentListener(new ComponentAdapter() { 102 public void componentMoved(ComponentEvent e) { 103 System.out.println("Frame moved: "); 104 Counter ctr = getCounter(); 105 synchronized(ctr) { 106 ctr.counter++; 107 ctr.notify(); 108 } 109 } 110 }); 111 synchronized(showLock) { 112 try { 113 frame.setVisible(true); 114 showLock.wait(); 115 } 116 catch (InterruptedException e) { 117 e.printStackTrace(); 118 throw new RuntimeException("Problem with showLock"); 119 } 120 } 121 runTest(frame); 122 } 123 124 public static void runTest(Frame theFrame) { 125 System.out.println("Running test"); 126 GraphicsDevice[] devs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); 127 Point[] points = new Point[devs.length]; 128 129 for (int i = 0; i < points.length; i++) { 130 Rectangle bounds = devs[i].getDefaultConfiguration().getBounds(); 131 points[i] = new Point(bounds.x + (bounds.width / 2), 132 bounds.y + (bounds.height / 2)); 133 System.out.println("Added point:" + points[i]); 134 } 135 136 final Frame localFrame = theFrame; 137 138 for (int n = 0; n < ITERATIONS_PER_SCREEN; n++) { 139 for (int i = 0; i < points.length; i++) { 140 final Point contextPoint = points[i]; 141 SwingUtilities.invokeLater(new Runnable() { 142 public void run() { 143 localFrame.setLocation(contextPoint); 144 } 145 }); 146 try { 147 Thread.sleep(PAUSE_BETWEEN_MOVES); 148 } 149 catch (InterruptedException e) { 150 System.out.println("Interrupted during iteration"); 151 } 152 } 153 } 154 Counter ctr = getCounter(); 155 synchronized(ctr) { 156 try { 157 if (ctr.counter < ITERATIONS_PER_SCREEN * devs.length) { 158 // If test hasn't finished, wait for maximum time 159 // If we get interrupted, test fails 160 ctr.wait((long)(ITERATIONS_PER_SCREEN * MAX_WAIT_PER_SCREEN * devs.length)); 161 System.out.println("after wait"); 162 if (ctr.counter < ITERATIONS_PER_SCREEN * devs.length) { 163 throw new RuntimeException("Waited too long for all the componentMoved()s"); 164 } 165 } 166 } 167 catch(InterruptedException e) { 168 e.printStackTrace(); 169 throw new RuntimeException("Wait interrupted - ???"); 170 } 171 System.out.println("Counter reads: " + ctr.counter); 172 } 173 174 } 175 public static void main(String[] args) { 176 testAWT(); 177 } 178 }