1 /* 2 * Copyright (c) 2007, 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 6613860 6691934 28 * @summary Tests that the pipelines can handle (in somewhat limited 29 * manner) mutable Colors 30 * 31 * @run main/othervm MutableColorTest 32 * @run main/othervm -Dsun.java2d.noddraw=true MutableColorTest 33 * @run main/othervm -Dsun.java2d.opengl=True MutableColorTest 34 */ 35 36 import java.awt.Color; 37 import java.awt.Graphics2D; 38 import java.awt.GraphicsConfiguration; 39 import java.awt.GraphicsEnvironment; 40 import java.awt.Image; 41 import java.awt.Transparency; 42 import java.awt.geom.Ellipse2D; 43 import java.awt.image.BufferedImage; 44 import java.awt.image.VolatileImage; 45 import java.io.File; 46 import java.io.IOException; 47 import javax.imageio.ImageIO; 48 49 public class MutableColorTest { 50 51 static Image bmImage; 52 static Image argbImage; 53 54 static class EvilColor extends Color { 55 Color colors[] = { Color.red, Color.green, Color.blue }; 56 int currentIndex = 0; 57 EvilColor() { 58 super(Color.red.getRGB()); 59 } 60 61 @Override 62 public int getRGB() { 63 return colors[currentIndex].getRGB(); 64 } 65 void nextColor() { 66 currentIndex++; 67 } 68 } 69 70 private static int testImage(Image im, 71 boolean doClip, boolean doTx) 72 { 73 int w = im.getWidth(null); 74 int h = im.getHeight(null); 75 Graphics2D g = (Graphics2D)im.getGraphics(); 76 EvilColor evilColor = new EvilColor(); 77 g.setColor(evilColor); 78 g.fillRect(0, 0, w, h); 79 g.dispose(); 80 81 evilColor.nextColor(); 82 83 g = (Graphics2D)im.getGraphics(); 84 85 if (doTx) { 86 g.rotate(Math.PI/2.0, w/2, h/2); 87 } 88 g.setColor(evilColor); 89 g.fillRect(0, 0, w, h); 90 if (doClip) { 91 g.clip(new Ellipse2D.Float(0, 0, w, h)); 92 } 93 g.fillRect(0, h/3, w, h/3); 94 95 // tests native BlitBg loop 96 g.drawImage(bmImage, 0, 2*h/3, evilColor, null); 97 // tests General BlitBg loop 98 g.drawImage(argbImage, 0, 2*h/3+h/3/2, evilColor, null); 99 100 return evilColor.getRGB(); 101 } 102 103 private static void testResult(final String desc, 104 final BufferedImage snapshot, 105 final int evilColor) { 106 for (int y = 0; y < snapshot.getHeight(); y++) { 107 for (int x = 0; x < snapshot.getWidth(); x++) { 108 int snapRGB = snapshot.getRGB(x, y); 109 if (!isSameColor(snapRGB, evilColor)) { 110 System.err.printf("Wrong RGB for %s at (%d,%d): 0x%x " + 111 "instead of 0x%x\n", desc, x, y, snapRGB, evilColor); 112 String fileName = "MutableColorTest_"+desc+".png"; 113 try { 114 ImageIO.write(snapshot, "png", new File(fileName)); 115 System.err.println("Dumped snapshot to "+fileName); 116 } catch (IOException ex) {} 117 throw new RuntimeException("Test FAILED."); 118 } 119 } 120 } 121 } 122 123 public static void main(String[] args) { 124 GraphicsConfiguration gc = 125 GraphicsEnvironment.getLocalGraphicsEnvironment(). 126 getDefaultScreenDevice().getDefaultConfiguration(); 127 128 bmImage = gc.createCompatibleImage(64, 64, Transparency.BITMASK); 129 argbImage = gc.createCompatibleImage(64, 64, Transparency.TRANSLUCENT); 130 131 if (gc.getColorModel().getPixelSize() > 8) { 132 VolatileImage vi = 133 gc.createCompatibleVolatileImage(64, 64, Transparency.OPAQUE); 134 do { 135 if (vi.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) { 136 vi = gc.createCompatibleVolatileImage(64, 64, 137 Transparency.OPAQUE); 138 vi.validate(gc); 139 } 140 141 int color = testImage(vi, false, false); 142 testResult("vi_noclip_notx", vi.getSnapshot(), color); 143 144 color = testImage(vi, true, true); 145 testResult("vi_clip_tx", vi.getSnapshot(), color); 146 147 color = testImage(vi, true, false); 148 testResult("vi_clip_notx", vi.getSnapshot(), color); 149 150 color = testImage(vi, false, true); 151 testResult("vi_noclip_tx", vi.getSnapshot(), color); 152 } while (vi.contentsLost()); 153 } 154 155 BufferedImage bi = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB); 156 int color = testImage(bi, false, false); 157 testResult("bi_noclip_notx", bi, color); 158 159 color = testImage(bi, true, true); 160 testResult("bi_clip_tx", bi, color); 161 162 color = testImage(bi, true, false); 163 testResult("bi_clip_notx", bi, color); 164 165 color = testImage(bi, false, true); 166 testResult("bi_noclip_tx", bi, color); 167 168 System.err.println("Test passed."); 169 } 170 171 /* 172 * We assume that colors with slightly different components 173 * are the same. This is done just in order to workaround 174 * peculiarities of OGL rendering pipeline on some platforms. 175 * See CR 6989217 for more details. 176 */ 177 private static boolean isSameColor(int color1, int color2) { 178 final int tolerance = 2; 179 180 for (int i = 0; i < 32; i += 8) { 181 int c1 = 0xff & (color1 >> i); 182 int c2 = 0xff & (color2 >> i); 183 184 if (Math.abs(c1 - c2) > tolerance) { 185 return false; 186 } 187 } 188 return true; 189 } 190 }