1 /* 2 * Copyright (c) 2006, 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 6366359 28 * @summary Test that we don't crash when changing from 8 to 16/32 bit modes 29 * @author Dmitri.Trembovetski@Sun.COM area=FullScreen 30 * @run main/othervm/timeout=200 DisplayChangeVITest 31 * @run main/othervm/timeout=200 -Dsun.java2d.d3d=false DisplayChangeVITest 32 * @run main/othervm/timeout=200 -Dsun.java2d.opengl=true DisplayChangeVITest 33 */ 34 35 import java.awt.Color; 36 import java.awt.DisplayMode; 37 import java.awt.Graphics; 38 import java.awt.GraphicsDevice; 39 import java.awt.GraphicsEnvironment; 40 import java.awt.event.KeyAdapter; 41 import java.awt.event.KeyEvent; 42 import java.awt.image.BufferedImage; 43 import java.awt.image.VolatileImage; 44 import java.lang.Exception; 45 import java.lang.Thread; 46 import java.util.ArrayList; 47 import java.util.Random; 48 import javax.swing.JFrame; 49 50 /** 51 * The test enters fullscreen mode (if it's supported) and then tries 52 * to switch between display moes with different depths and dimensions 53 * while doing both rendering to the screen (via a VolatileImage) 54 * and Swing repainting just to make things more chaotic. 55 * 56 * The procedure is repeated TEST_REPS times (3 by default). 57 * 58 * Don't pay attention to what happens on the screen, it won't be pretty. 59 * If the test doesn't crash or throw exceptions, it passes, otherwise 60 * it fails. 61 */ 62 public class DisplayChangeVITest extends JFrame implements Runnable { 63 64 private final Random rnd = new Random(); 65 private VolatileImage bb; 66 private BufferedImage sprite; 67 private VolatileImage volSprite; 68 69 private static boolean done = false; 70 private static final Object lock = new Object(); 71 private static final int TEST_REPS = 3; 72 73 private ArrayList<DisplayMode> dms; 74 75 DisplayChangeVITest() { 76 selectDisplayModes(); 77 addKeyListener(new KeyAdapter() { 78 public void keyPressed(KeyEvent e) { 79 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 80 synchronized (lock) { 81 done = true; 82 } 83 } 84 } 85 }); 86 sprite = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); 87 sprite.getRaster().getDataBuffer(); 88 Graphics g = sprite.getGraphics(); 89 g.setColor(Color.yellow); 90 g.fillRect(0, 0, sprite.getWidth(), sprite.getHeight()); 91 } 92 93 void render(Graphics g) { 94 do { 95 // volatile images validated here 96 initBackbuffer(); 97 98 g.setColor(Color.black); 99 g.fillRect(0, 0, getWidth(), getHeight()); 100 101 Graphics gg = bb.getGraphics(); 102 gg.setColor(new Color(rnd.nextInt(0x00ffffff))); 103 gg.fillRect(0, 0, bb.getWidth(), bb.getHeight()); 104 for (int x = 0; x < 10; x++) { 105 gg.drawImage(sprite, x*200, 0, null); 106 gg.drawImage(volSprite, x*200, 500, null); 107 } 108 109 g.drawImage(bb, 0, 0, null); 110 } while (bb.contentsLost()); 111 } 112 113 private static void sleep(long msec) { 114 try { Thread.sleep(msec); } catch (InterruptedException e) {} 115 } 116 117 private int reps = 0; 118 public void run() { 119 GraphicsDevice gd = getGraphicsConfiguration().getDevice(); 120 if (gd.isDisplayChangeSupported() && dms.size() > 0) { 121 while (!done && reps++ < TEST_REPS) { 122 for (DisplayMode dm : dms) { 123 System.err.printf("Entering DisplayMode[%dx%dx%d]\n", 124 dm.getWidth(), dm.getHeight(), dm.getBitDepth()); 125 gd.setDisplayMode(dm); 126 127 initBackbuffer(); 128 for (int i = 0; i < 10; i++) { 129 // render to the screen 130 render(getGraphics()); 131 // ask Swing to repaint 132 repaint(); 133 sleep(100); 134 } 135 sleep(1500); 136 } 137 } 138 } else { 139 System.err.println("Display mode change " + 140 "not supported. Test passed."); 141 } 142 dispose(); 143 synchronized (lock) { 144 done = true; 145 lock.notify(); 146 } 147 } 148 149 private void createBackbuffer() { 150 if (bb == null || 151 bb.getWidth() != getWidth() || bb.getHeight() != getHeight()) 152 { 153 bb = createVolatileImage(getWidth(), getHeight()); 154 } 155 } 156 157 private void initBackbuffer() { 158 createBackbuffer(); 159 160 int res = bb.validate(getGraphicsConfiguration()); 161 if (res == VolatileImage.IMAGE_INCOMPATIBLE) { 162 bb = null; 163 createBackbuffer(); 164 bb.validate(getGraphicsConfiguration()); 165 res = VolatileImage.IMAGE_RESTORED; 166 } 167 if (res == VolatileImage.IMAGE_RESTORED) { 168 Graphics g = bb.getGraphics(); 169 g.setColor(new Color(rnd.nextInt(0x00ffffff))); 170 g.fillRect(0, 0, bb.getWidth(), bb.getHeight()); 171 172 volSprite = createVolatileImage(100, 100); 173 } 174 volSprite.validate(getGraphicsConfiguration()); 175 } 176 177 private void selectDisplayModes() { 178 GraphicsDevice gd = 179 GraphicsEnvironment.getLocalGraphicsEnvironment(). 180 getDefaultScreenDevice(); 181 dms = new ArrayList<DisplayMode>(); 182 DisplayMode dmArray[] = gd.getDisplayModes(); 183 boolean found8 = false, found16 = false, 184 found24 = false, found32 = false; 185 for (DisplayMode dm : dmArray) { 186 if (!found8 && 187 (dm.getBitDepth() == 8 || 188 dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && 189 (dm.getWidth() >= 800 && dm.getWidth() < 1024)) 190 { 191 dms.add(dm); 192 found8 = true; 193 continue; 194 } 195 if (!found32 && 196 (dm.getBitDepth() == 32 || 197 dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && 198 dm.getWidth() >= 1280) 199 { 200 dms.add(dm); 201 found32 = true; 202 continue; 203 } 204 if (!found16 && 205 dm.getBitDepth() == 16 && 206 (dm.getWidth() >= 1024 && dm.getWidth() < 1280)) 207 { 208 dms.add(dm); 209 found16 = true; 210 continue; 211 } 212 if (found8 && found16 && found32) { 213 break; 214 } 215 } 216 System.err.println("Found display modes:"); 217 for (DisplayMode dm : dms) { 218 System.err.printf("DisplayMode[%dx%dx%d]\n", 219 dm.getWidth(), dm.getHeight(), dm.getBitDepth()); 220 } 221 } 222 223 public static void main(String[] args) throws Exception { 224 DisplayChangeVITest test = new DisplayChangeVITest(); 225 GraphicsDevice gd = 226 GraphicsEnvironment.getLocalGraphicsEnvironment(). 227 getDefaultScreenDevice(); 228 if (gd.isFullScreenSupported()) { 229 gd.setFullScreenWindow(test); 230 Thread t = new Thread(test); 231 t.run(); 232 synchronized (lock) { 233 while (!done) { 234 try { 235 lock.wait(50); 236 } catch (InterruptedException ex) { 237 ex.printStackTrace(); 238 } 239 } 240 } 241 System.err.println("Test Passed."); 242 } else { 243 System.err.println("Full screen not supported. Test passed."); 244 } 245 } 246 }