jdk/test/sun/java2d/SunGraphics2D/SimplePrimQuality.java
changeset 887 0aab8d3fa11a
child 5506 202f599c92aa
equal deleted inserted replaced
886:7eb22e81bb28 887:0aab8d3fa11a
       
     1 /*
       
     2  * Copyright 2005-2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 4832224 6322584 6328478 6328481 6322580 6588884 6587863
       
    27  * @summary Verifies that the pixelization of simple primitives (drawLine,
       
    28  * fillRect, drawRect, fill, draw) with the OGL pipeline enabled
       
    29  * matches that produced by our software loops.  (The primitives tested here
       
    30  * are simple enough that the OGL results should match the software results
       
    31  * exactly.)  There is some overlap with PolyVertTest as we test both
       
    32  * solid and XOR rendering here, but this testcase is a bit simpler and
       
    33  * more appropriate for quick OGL testing.  This test is also useful for
       
    34  * comparing quality between our X11/GDI and software pipelines.
       
    35  * @run main/othervm SimplePrimQuality
       
    36  * @run main/othervm -Dsun.java2d.opengl=True SimplePrimQuality
       
    37  * @author campbelc
       
    38  */
       
    39 
       
    40 import java.awt.*;
       
    41 import java.awt.geom.*;
       
    42 import java.awt.image.*;
       
    43 import java.io.File;
       
    44 import java.io.IOException;
       
    45 import javax.imageio.ImageIO;
       
    46 
       
    47 public class SimplePrimQuality extends Canvas {
       
    48 
       
    49     private static final int SIZE = 300;
       
    50     private static boolean done;
       
    51     private static boolean testVI;
       
    52     private static volatile BufferedImage capture;
       
    53     private static void doCapture(Component test) {
       
    54         // Grab the screen region
       
    55         try {
       
    56             Robot robot = new Robot();
       
    57             Point pt1 = test.getLocationOnScreen();
       
    58             Rectangle rect =
       
    59                 new Rectangle(pt1.x, pt1.y, test.getWidth(), test.getHeight());
       
    60             capture = robot.createScreenCapture(rect);
       
    61         } catch (Exception e) {
       
    62             e.printStackTrace();
       
    63         }
       
    64     }
       
    65 
       
    66     private static final int[][] rpts = {
       
    67         {2, 0, 0, 0},
       
    68         {12, 0, 1, 0},
       
    69         {22, 0, 0, 1},
       
    70         {32, 0, 1, 1},
       
    71         {42, 0, 2, 1},
       
    72         {52, 0, 1, 2},
       
    73         {62, 0, 2, 2},
       
    74         {72, 0, 5, 5},
       
    75         {82, 0, 10, 10},
       
    76         {97, 0, 15, 15},
       
    77     };
       
    78 
       
    79     private void drawLine(Graphics2D g, int x, int y, int dx, int dy) {
       
    80         g.drawLine(x, y, x + dx, y + dy);
       
    81     }
       
    82 
       
    83     private void drawLines(Graphics2D g, int s) {
       
    84         drawLine(g, 2, 0, 0, 0);
       
    85         drawLine(g, 12, 0, 0, s);
       
    86         drawLine(g, 22, 0, s, 0);
       
    87         drawLine(g, 32, 0, s, s);
       
    88         drawLine(g, 42, 0, 0, -s);
       
    89         drawLine(g, 52, 0, -s, 0);
       
    90         drawLine(g, 62, 0, -s, -s);
       
    91         drawLine(g, 72, 0, -s, s);
       
    92         drawLine(g, 82, 0, s, -s);
       
    93     }
       
    94 
       
    95     private void fillRects(Graphics2D g) {
       
    96         for (int i = 0; i < rpts.length; i++) {
       
    97             g.fillRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]);
       
    98         }
       
    99     }
       
   100 
       
   101     private void drawRects(Graphics2D g) {
       
   102         for (int i = 0; i < rpts.length; i++) {
       
   103             g.drawRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]);
       
   104         }
       
   105     }
       
   106 
       
   107     private void fillOvals(Graphics2D g) {
       
   108         for (int i = 0; i < rpts.length; i++) {
       
   109             // use fill() instead of fillOval(), since the former is more
       
   110             // likely to be consistent with our software loops when the
       
   111             // OGL pipeline cannot be enabled
       
   112             g.fill(new Ellipse2D.Float(rpts[i][0], rpts[i][1],
       
   113                                        rpts[i][2], rpts[i][3]));
       
   114         }
       
   115     }
       
   116 
       
   117     private void drawOvals(Graphics2D g) {
       
   118         for (int i = 0; i < rpts.length; i++) {
       
   119             // use draw() instead of drawOval(), since the former is more
       
   120             // likely to be consistent with our software loops when the
       
   121             // OGL pipeline cannot be enabled
       
   122             g.draw(new Ellipse2D.Float(rpts[i][0], rpts[i][1],
       
   123                                        rpts[i][2], rpts[i][3]));
       
   124         }
       
   125     }
       
   126 
       
   127     private void renderShapes(Graphics2D g) {
       
   128         // drawLine tests...
       
   129         g.translate(0, 5);
       
   130         drawLines(g, 1);
       
   131         g.translate(0, 10);
       
   132         drawLines(g, 4);
       
   133 
       
   134         // fillRect tests...
       
   135         g.translate(0, 10);
       
   136         fillRects(g);
       
   137 
       
   138         // drawRect tests...
       
   139         g.translate(0, 20);
       
   140         drawRects(g);
       
   141 
       
   142         // fillOval tests...
       
   143         g.translate(0, 20);
       
   144         fillOvals(g);
       
   145 
       
   146         // drawOval tests...
       
   147         g.translate(0, 20);
       
   148         drawOvals(g);
       
   149     }
       
   150 
       
   151     private void renderTest(Graphics2D g, int w, int h) {
       
   152         // on the left side, render the shapes in solid mode
       
   153         g.setColor(Color.black);
       
   154         g.fillRect(0, 0, w, h);
       
   155         g.setColor(Color.green);
       
   156         renderShapes(g);
       
   157 
       
   158         // on the right side, render the shapes in XOR mode
       
   159         g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0));
       
   160         g.setXORMode(Color.black);
       
   161         renderShapes(g);
       
   162         g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0));
       
   163         renderShapes(g);
       
   164     }
       
   165 
       
   166     public void paint(Graphics g) {
       
   167 
       
   168         Graphics2D g2d = (Graphics2D)g;
       
   169         renderTest(g2d, SIZE, SIZE);
       
   170 
       
   171         Toolkit.getDefaultToolkit().sync();
       
   172 
       
   173         synchronized (this) {
       
   174             if (!done) {
       
   175                 doCapture(this);
       
   176                 done = true;
       
   177             }
       
   178             notifyAll();
       
   179         }
       
   180     }
       
   181 
       
   182     public Dimension getPreferredSize() {
       
   183         return new Dimension(SIZE, SIZE);
       
   184     }
       
   185 
       
   186     public static void main(String[] args) {
       
   187         boolean show = false;
       
   188         for (String arg : args) {
       
   189             if (arg.equals("-testvi")) {
       
   190                 System.out.println("Testing VolatileImage, not screen");
       
   191                 testVI = true;
       
   192             } else if (arg.equals("-show")) {
       
   193                 show = true;
       
   194             }
       
   195         }
       
   196 
       
   197         SimplePrimQuality test = new SimplePrimQuality();
       
   198         Frame frame = new Frame();
       
   199         frame.add(test);
       
   200         frame.pack();
       
   201         frame.setVisible(true);
       
   202 
       
   203         // Wait until the component's been painted
       
   204         synchronized (test) {
       
   205             while (!done) {
       
   206                 try {
       
   207                     test.wait();
       
   208                 } catch (InterruptedException e) {
       
   209                     throw new RuntimeException("Failed: Interrupted");
       
   210                 }
       
   211             }
       
   212         }
       
   213 
       
   214         // REMIND: We will allow this test to pass silently on Windows
       
   215         // (when OGL is not enabled) until we fix the GDI pipeline so that
       
   216         // its stroked/filled GeneralPaths match our software loops (see
       
   217         // 6322554).  This check should be removed when 6322554 is fixed.
       
   218         GraphicsConfiguration gc = frame.getGraphicsConfiguration();
       
   219         if (gc.getClass().getSimpleName().startsWith("Win")) {
       
   220             System.out.println("GDI pipeline detected: " +
       
   221                                "test considered PASSED");
       
   222             frame.dispose();
       
   223             return;
       
   224         }
       
   225 
       
   226 
       
   227         if (testVI) {
       
   228             // render to a VI instead of the screen
       
   229             VolatileImage vi = frame.createVolatileImage(SIZE, SIZE);
       
   230             do {
       
   231                 vi.validate(frame.getGraphicsConfiguration());
       
   232                 Graphics2D g1 = vi.createGraphics();
       
   233                 test.renderTest(g1, SIZE, SIZE);
       
   234                 g1.dispose();
       
   235                 capture = vi.getSnapshot();
       
   236             } while (vi.contentsLost());
       
   237             frame.dispose();
       
   238         }
       
   239 
       
   240         if (!show) {
       
   241             frame.dispose();
       
   242         }
       
   243         if (capture == null) {
       
   244             throw new RuntimeException("Error capturing the rendering");
       
   245         }
       
   246 
       
   247         // Create reference image
       
   248         int w = SIZE, h = SIZE;
       
   249         BufferedImage refimg = new BufferedImage(w, h,
       
   250                                                  BufferedImage.TYPE_INT_RGB);
       
   251         Graphics2D g = refimg.createGraphics();
       
   252         test.renderTest(g, w, h);
       
   253         g.dispose();
       
   254 
       
   255         // Test pixels
       
   256         for (int y = 0; y < h; y++) {
       
   257             for (int x = 0; x < w; x++) {
       
   258                 int actual = capture.getRGB(x, y);
       
   259                 int expected = refimg.getRGB(x, y);
       
   260                 if (actual != expected) {
       
   261                     String expectedName = "SimplePrimQuality_expected.png";
       
   262                     String actualName = "SimplePrimQuality_actual.png";
       
   263                     try {
       
   264                         System.out.println("Writing expected image to: "+
       
   265                                            expectedName);
       
   266                         ImageIO.write(refimg, "png", new File(expectedName));
       
   267                         System.out.println("Writing actual image   to: "+
       
   268                                            actualName);
       
   269                         ImageIO.write(capture, "png", new File(actualName));
       
   270                     } catch (IOException ex) {}
       
   271                     throw new RuntimeException("Test failed at x="+x+" y="+y+
       
   272                                                " (expected="+
       
   273                                                Integer.toHexString(expected) +
       
   274                                                " actual="+
       
   275                                                Integer.toHexString(actual) +
       
   276                                                ")");
       
   277                 }
       
   278             }
       
   279         }
       
   280     }
       
   281 }