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