8158524: Adding a test case to compare the rendered output of VolatileImage with that of BufferedImage
authorpnarayanan
Tue, 23 Aug 2016 14:47:53 +0530
changeset 40716 5f30f35b9ad4
parent 40715 ce1eb413f9f1
child 40717 02500a642a8e
8158524: Adding a test case to compare the rendered output of VolatileImage with that of BufferedImage Reviewed-by: serb, psadhukhan
jdk/test/java/awt/image/VolatileImage/TransparentVImage.java
jdk/test/java/awt/image/VolatileImage/duke.gif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/VolatileImage/TransparentVImage.java	Tue Aug 23 14:47:53 2016 +0530
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2016, 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
+ * @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
+ * @run main/othervm -Dsun.java2d.uiScale=1 -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false TransparentVImage
+ * @run main/othervm -Dsun.java2d.uiScale=1 -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=true 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.");
+                }
+            }
+        });
+    }
+}
Binary file jdk/test/java/awt/image/VolatileImage/duke.gif has changed