Path: blob/jdk8u272-b10-aarch32-20201026/jdk/test/sun/java2d/OpenGL/GradientPaints.java
48795 views
/*1* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 6521533 652599726* @summary Verifies that the OGL-accelerated codepaths for GradientPaint,27* LinearGradientPaint, and RadialGradientPaint produce results that are28* sufficiently close to those produced by the software codepaths.29* @run main/othervm -Dsun.java2d.opengl=True GradientPaints30* @author campbelc31*/3233import java.awt.*;34import java.awt.MultipleGradientPaint.ColorSpaceType;35import java.awt.MultipleGradientPaint.CycleMethod;36import java.awt.geom.*;37import java.awt.image.*;38import java.io.File;39import java.util.Arrays;40import javax.imageio.ImageIO;4142public class GradientPaints extends Canvas {4344private static final int TESTW = 600;45private static final int TESTH = 500;4647/*48* We expect slight differences in rendering between the OpenGL and49* software pipelines due to algorithmic and rounding differences.50* The purpose of this test is just to make sure that the OGL pipeline51* is producing results that are "reasonably" consistent with those52* produced in software, so we will allow +/-TOLERANCE differences53* in each component. When comparing the test and reference images,54* we add up the number of pixels that fall outside this tolerance55* range and if the sum is larger than some percentage of the total56* number of pixels.57*58* REMIND: Note that we have separate thresholds for linear and radial59* gradients because the visible differences between OGL and software60* are more apparent in the radial cases. In the future we should try61* to reduce the number of mismatches between the two approaches, but62* for now the visible differences are slight enough to not cause worry.63*/64private static final int TOLERANCE = 5;65private static final int ALLOWED_MISMATCHES_LINEAR =66(int)(TESTW * TESTH * 0.18);67private static final int ALLOWED_MISMATCHES_RADIAL =68(int)(TESTW * TESTH * 0.45);6970private static boolean done;71private static boolean verbose;7273private static final Color[] COLORS = {74new Color(0, 0, 0),75new Color(128, 128, 128),76new Color(255, 0, 0),77new Color(255, 255, 0),78new Color(0, 255, 0),79new Color(0, 255, 255),80new Color(128, 0, 255),81new Color(128, 128, 128),82};8384private static enum PaintType {BASIC, LINEAR, RADIAL};85private static enum XformType {IDENTITY, TRANSLATE, SCALE, SHEAR, ROTATE};86private static final int[] numStopsArray = {2, 4, 7};87private static final Object[] hints = {88RenderingHints.VALUE_ANTIALIAS_OFF,89RenderingHints.VALUE_ANTIALIAS_ON,90};9192public void paint(Graphics g) {93synchronized (this) {94if (!done) {95done = true;96notifyAll();97}98}99}100101private void testOne(BufferedImage refImg, VolatileImage testImg) {102Graphics2D gref = refImg.createGraphics();103Graphics2D gtest = testImg.createGraphics();104Paint paint =105makePaint(PaintType.RADIAL, CycleMethod.REPEAT,106ColorSpaceType.SRGB, XformType.IDENTITY, 7);107Object aahint = hints[0];108renderTest(gref, paint, aahint);109renderTest(gtest, paint, aahint);110Toolkit.getDefaultToolkit().sync();111compareImages(refImg, testImg.getSnapshot(),112TOLERANCE, 0, "");113gref.dispose();114gtest.dispose();115}116117private void testAll(Graphics gscreen,118BufferedImage refImg, VolatileImage testImg)119{120Graphics2D gref = refImg.createGraphics();121Graphics2D gtest = testImg.createGraphics();122for (PaintType paintType : PaintType.values()) {123for (CycleMethod cycleMethod : CycleMethod.values()) {124for (ColorSpaceType colorSpace : ColorSpaceType.values()) {125for (XformType xform : XformType.values()) {126for (Object aahint : hints) {127for (int numStops : numStopsArray) {128Paint paint =129makePaint(paintType, cycleMethod,130colorSpace, xform, numStops);131String msg =132"type=" + paintType +133" cycleMethod=" + cycleMethod +134" colorSpace=" + colorSpace +135" xformType=" + xform +136" numStops=" + numStops +137" aa=" + aahint;138renderTest(gref, paint, aahint);139renderTest(gtest, paint, aahint);140gscreen.drawImage(testImg, 0, 0, null);141Toolkit.getDefaultToolkit().sync();142int allowedMismatches =143paintType == PaintType.RADIAL ?144ALLOWED_MISMATCHES_RADIAL :145ALLOWED_MISMATCHES_LINEAR;146compareImages(refImg, testImg.getSnapshot(),147TOLERANCE, allowedMismatches,148msg);149}150}151}152}153}154}155gref.dispose();156gtest.dispose();157}158159private Paint makePaint(PaintType paintType,160CycleMethod cycleMethod,161ColorSpaceType colorSpace,162XformType xformType, int numStops)163{164int startX = TESTW/6;165int startY = TESTH/6;166int endX = TESTW/2;167int endY = TESTH/2;168int ctrX = TESTW/2;169int ctrY = TESTH/2;170int focusX = ctrX + 20;171int focusY = ctrY + 20;172float radius = 100.0f;173Paint paint;174AffineTransform transform;175176Color[] colors = Arrays.copyOf(COLORS, numStops);177float[] fractions = new float[colors.length];178for (int i = 0; i < fractions.length; i++) {179fractions[i] = ((float)i) / (fractions.length-1);180}181182switch (xformType) {183default:184case IDENTITY:185transform = new AffineTransform();186break;187case TRANSLATE:188transform = AffineTransform.getTranslateInstance(2, 2);189break;190case SCALE:191transform = AffineTransform.getScaleInstance(1.2, 1.4);192break;193case SHEAR:194transform = AffineTransform.getShearInstance(0.1, 0.1);195break;196case ROTATE:197transform = AffineTransform.getRotateInstance(Math.PI / 4,198getWidth()/2,199getHeight()/2);200break;201}202203switch (paintType) {204case BASIC:205boolean cyclic = (cycleMethod != CycleMethod.NO_CYCLE);206paint =207new GradientPaint(startX, startY, Color.RED,208endX, endY, Color.BLUE, cyclic);209break;210211default:212case LINEAR:213paint =214new LinearGradientPaint(new Point2D.Float(startX, startY),215new Point2D.Float(endX, endY),216fractions, colors,217cycleMethod, colorSpace,218transform);219break;220221case RADIAL:222paint =223new RadialGradientPaint(new Point2D.Float(ctrX, ctrY),224radius,225new Point2D.Float(focusX, focusY),226fractions, colors,227cycleMethod, colorSpace,228transform);229break;230}231232return paint;233}234235private void renderTest(Graphics2D g2d, Paint p, Object aahint) {236g2d.setColor(Color.white);237g2d.fillRect(0, 0, TESTW, TESTH);238g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aahint);239g2d.setPaint(p);240g2d.fillOval(0, 0, TESTW, TESTH);241}242243public Dimension getPreferredSize() {244return new Dimension(TESTW, TESTH);245}246247private static void compareImages(BufferedImage refImg,248BufferedImage testImg,249int tolerance, int allowedMismatches,250String msg)251{252int numMismatches = 0;253int x1 = 0;254int y1 = 0;255int x2 = refImg.getWidth();256int y2 = refImg.getHeight();257258for (int y = y1; y < y2; y++) {259for (int x = x1; x < x2; x++) {260Color expected = new Color(refImg.getRGB(x, y));261Color actual = new Color(testImg.getRGB(x, y));262if (!isSameColor(expected, actual, tolerance)) {263numMismatches++;264}265}266}267268if (verbose) {269System.out.println(msg);270}271if (numMismatches > allowedMismatches) {272try {273ImageIO.write(refImg, "png",274new File("GradientPaints.ref.png"));275ImageIO.write(testImg, "png",276new File("GradientPaints.cap.png"));277} catch (Exception e) {278}279if (!verbose) {280System.err.println(msg);281}282throw new RuntimeException("Test failed: Number of mismatches (" +283numMismatches +284") exceeds limit (" +285allowedMismatches +286") with tolerance=" +287tolerance);288}289}290291private static boolean isSameColor(Color c1, Color c2, int e) {292int r1 = c1.getRed();293int g1 = c1.getGreen();294int b1 = c1.getBlue();295int r2 = c2.getRed();296int g2 = c2.getGreen();297int b2 = c2.getBlue();298int rmin = Math.max(r2-e, 0);299int gmin = Math.max(g2-e, 0);300int bmin = Math.max(b2-e, 0);301int rmax = Math.min(r2+e, 255);302int gmax = Math.min(g2+e, 255);303int bmax = Math.min(b2+e, 255);304if (r1 >= rmin && r1 <= rmax &&305g1 >= gmin && g1 <= gmax &&306b1 >= bmin && b1 <= bmax)307{308return true;309}310return false;311}312313public static void main(String[] args) {314if (args.length == 1 && args[0].equals("-verbose")) {315verbose = true;316}317318GradientPaints test = new GradientPaints();319Frame frame = new Frame();320frame.add(test);321frame.pack();322frame.setVisible(true);323324// Wait until the component's been painted325synchronized (test) {326while (!done) {327try {328test.wait();329} catch (InterruptedException e) {330throw new RuntimeException("Failed: Interrupted");331}332}333}334335GraphicsConfiguration gc = frame.getGraphicsConfiguration();336if (gc.getColorModel() instanceof IndexColorModel) {337System.out.println("IndexColorModel detected: " +338"test considered PASSED");339frame.dispose();340return;341}342343BufferedImage refImg =344new BufferedImage(TESTW, TESTH, BufferedImage.TYPE_INT_RGB);345VolatileImage testImg = frame.createVolatileImage(TESTW, TESTH);346testImg.validate(gc);347348try {349test.testAll(test.getGraphics(), refImg, testImg);350} finally {351frame.dispose();352}353}354}355356357