| /* |
| * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * @test |
| * @bug 4881082 4916294 5002129 8158524 8198613 |
| * @summary The test verifies whether the rendering operations on transparent |
| * and translucent VolatileImage objects generate identical output |
| * as generated with transparent and translucent BufferedImages. |
| * @key headful |
| * @run main/othervm -Dsun.java2d.uiScale=1 TransparentVImage |
| */ |
| import java.awt.GraphicsConfiguration; |
| import java.awt.Graphics; |
| import java.awt.Image; |
| import java.awt.Transparency; |
| import java.awt.image.BufferedImage; |
| import java.awt.image.VolatileImage; |
| import java.awt.Color; |
| import javax.swing.JFrame; |
| import javax.swing.JComponent; |
| import javax.swing.ImageIcon; |
| import javax.swing.SwingUtilities; |
| |
| /* |
| * This test draws the same contents to 4 images: 2 BufferedImages that are |
| * transparent and translucent and 2 VolatileImages that are transparent and |
| * translucent. It compares the results pixel-by-pixel and fails if the |
| * results are not the same. |
| */ |
| public class TransparentVImage |
| extends JComponent { |
| |
| BufferedImage cImgTransparent, cImgTranslucent; |
| VolatileImage vImgTransparent, vImgTranslucent; |
| Image sprite; |
| static final int IMAGE_SIZE = 250; |
| static final int WINDOW_SIZE = 600; |
| static boolean doneComparing = false; |
| static JFrame testFrame = null; |
| |
| @Override |
| public void paint(Graphics g) { |
| if (cImgTransparent == null) { |
| GraphicsConfiguration gc = getGraphicsConfiguration(); |
| // doesn't exist yet: create it (and the other images) |
| cImgTransparent = (BufferedImage) |
| gc.createCompatibleImage(IMAGE_SIZE, IMAGE_SIZE, |
| Transparency.BITMASK); |
| cImgTranslucent = (BufferedImage) |
| gc.createCompatibleImage(IMAGE_SIZE, IMAGE_SIZE, |
| Transparency.TRANSLUCENT); |
| vImgTransparent = gc.createCompatibleVolatileImage(IMAGE_SIZE, |
| IMAGE_SIZE, Transparency.BITMASK); |
| vImgTranslucent = gc.createCompatibleVolatileImage(IMAGE_SIZE, |
| IMAGE_SIZE, Transparency.TRANSLUCENT); |
| |
| String fileName = "duke.gif"; |
| String separator = System.getProperty("file.separator"); |
| String dirPath = System.getProperty("test.src", "."); |
| String filePath = dirPath + separator + fileName; |
| sprite = new ImageIcon(filePath).getImage(); |
| |
| // Now they exist; render to them |
| Graphics gImg[] = new Graphics[4]; |
| gImg[0] = cImgTransparent.getGraphics(); |
| gImg[1] = cImgTranslucent.getGraphics(); |
| gImg[2] = vImgTransparent.getGraphics(); |
| gImg[3] = vImgTranslucent.getGraphics(); |
| |
| for (int i = 0; i < gImg.length; ++i) { |
| /* |
| * VolatileImage utilizes the power of accelerated rendering |
| * using GPU. The GPU drivers for D3d and OpenGL are supplied |
| * by OEM vendors and are external to graphics subsystem. Thus |
| * one cannot guarentee that the drivers will render the |
| * primitives using exactly the same algorithms as those used |
| * by BufferedImage. This could result in minor differences in |
| * pixel values between BufferedImage and VolatileImage. |
| * |
| * The pipelines for D3d and OpenGL adjust the rendering with |
| * fudge factors to align output of GPU rendering with that of |
| * CPU rendering. Some of the draw calls in this paint method |
| * are commented indicating a need to fine tune the fudge |
| * factors in the future. Once they are found to work on all |
| * hardware, the draw calls will be enabled. |
| */ |
| // rectangular fill |
| gImg[i].setColor(Color.blue); |
| gImg[i].fillRect(0, 0, IMAGE_SIZE, IMAGE_SIZE); |
| |
| /* |
| * Image copy. Copy it 3 times to get any image management |
| * acceleration going |
| */ |
| int spriteW = sprite.getWidth(null); |
| gImg[i].drawImage(sprite, 0, 0, null); |
| gImg[i].drawImage(sprite, spriteW, 0, null); |
| gImg[i].drawImage(sprite, 2 * spriteW, 0, null); |
| |
| // horizontal/vertical/diagonal lines |
| gImg[i].setColor(Color.red); |
| gImg[i].drawLine(0, 0, |
| IMAGE_SIZE - 1, IMAGE_SIZE - 1); |
| gImg[i].drawLine(IMAGE_SIZE / 2, 0, |
| IMAGE_SIZE / 2, IMAGE_SIZE - 1); |
| //gImg[i].drawLine(IMAGE_SIZE, 0, |
| // 0, IMAGE_SIZE - 1); |
| gImg[i].drawLine(0, IMAGE_SIZE / 2, |
| IMAGE_SIZE - 1, IMAGE_SIZE / 2); |
| |
| // filled circle |
| //gImg[i].setColor(Color.yellow); |
| //gImg[i].fillOval(IMAGE_SIZE / 2 - 20, IMAGE_SIZE / 2 - 20, |
| // 40, 40); |
| } |
| |
| /* |
| * Now everything is drawn: let's compare pixels |
| * First, grab the pixel arrays |
| */ |
| int cRgbTransparent[] = new int[IMAGE_SIZE * IMAGE_SIZE]; |
| int cRgbTranslucent[] = new int[IMAGE_SIZE * IMAGE_SIZE]; |
| int vRgbTransparent[] = new int[IMAGE_SIZE * IMAGE_SIZE]; |
| int vRgbTranslucent[] = new int[IMAGE_SIZE * IMAGE_SIZE]; |
| cImgTransparent.getRGB(0, 0, IMAGE_SIZE, IMAGE_SIZE, |
| cRgbTransparent, 0, IMAGE_SIZE); |
| cImgTranslucent.getRGB(0, 0, IMAGE_SIZE, IMAGE_SIZE, |
| cRgbTranslucent, 0, IMAGE_SIZE); |
| BufferedImage bImgTransparent = vImgTransparent.getSnapshot(); |
| bImgTransparent.getRGB(0, 0, IMAGE_SIZE, IMAGE_SIZE, |
| vRgbTransparent, 0, IMAGE_SIZE); |
| BufferedImage bImgTranslucent = vImgTranslucent.getSnapshot(); |
| bImgTranslucent.getRGB(0, 0, IMAGE_SIZE, IMAGE_SIZE, |
| vRgbTranslucent, 0, IMAGE_SIZE); |
| |
| boolean failed = false; |
| for (int pixel = 0; pixel < cRgbTransparent.length; ++pixel) { |
| if (cRgbTransparent[pixel] != vRgbTransparent[pixel]) { |
| failed = true; |
| System.out.println("Error in transparent image: " + |
| "BI[" + pixel + "] = " + |
| Integer.toHexString(cRgbTransparent[pixel]) + |
| "VI[" + pixel + "] = " + |
| Integer.toHexString(vRgbTransparent[pixel])); |
| break; |
| } |
| if (cRgbTranslucent[pixel] != vRgbTranslucent[pixel]) { |
| failed = true; |
| System.out.println("Error in translucent image: " + |
| "BI[" + pixel + "] = " + |
| Integer.toHexString(cRgbTranslucent[pixel]) + |
| "VI[" + pixel + "] = " + |
| Integer.toHexString(vRgbTranslucent[pixel])); |
| break; |
| } |
| } |
| if (failed) { |
| throw new RuntimeException("Failed: Pixel mis-match observed"); |
| } |
| else { |
| System.out.println("Passed"); |
| } |
| doneComparing = true; |
| } |
| |
| g.drawImage(cImgTransparent, 0, 0, null); |
| g.drawImage(cImgTranslucent, getWidth() - IMAGE_SIZE, 0, null); |
| g.drawImage(vImgTransparent, 0, getHeight() - IMAGE_SIZE, null); |
| g.drawImage(vImgTranslucent, getWidth() - IMAGE_SIZE, |
| getHeight() - IMAGE_SIZE, null); |
| } |
| |
| private static void constructTestUI() { |
| testFrame = new JFrame(); |
| testFrame.setSize(600, 600); |
| testFrame.setResizable(false); |
| testFrame.getContentPane().add(new TransparentVImage()); |
| |
| testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
| testFrame.setLocationRelativeTo(null); |
| testFrame.setVisible(true); |
| } |
| |
| private static void destroyTestUI() { |
| testFrame.dispose(); |
| } |
| |
| public static void main(String args[]) throws Exception { |
| SwingUtilities.invokeAndWait(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| // Construct the test interface |
| constructTestUI(); |
| } catch (Exception ex) { |
| // Throw an exception indicating error while creating UI |
| throw new RuntimeException("Test Failed: Error while" + |
| " creating the test interface."); |
| } |
| } |
| }); |
| |
| /* |
| * Wait until the image comparison between VolatileImage and |
| * BufferedImage is complete. |
| */ |
| while (!doneComparing) { |
| try { |
| Thread.sleep(100); |
| } |
| catch (Exception e) {} |
| } |
| |
| /* |
| * Now sleep just a little longer to let the user see the resulting |
| * images in the frame |
| */ |
| try { |
| Thread.sleep(5000); |
| } |
| catch (Exception e) {} |
| |
| SwingUtilities.invokeAndWait(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| // Destroy the test interface |
| destroyTestUI(); |
| } catch (Exception ex) { |
| // Throw an exception indicating error while deleting UI |
| throw new RuntimeException("Test Failed: Error while" + |
| " deleting the test interface."); |
| } |
| } |
| }); |
| } |
| } |