IncorrectClipXorModeSW2Surface.java revision 14851:980da45565c8
1/*
2 * Copyright (c) 2014, 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
24import java.awt.Color;
25import java.awt.Graphics2D;
26import java.awt.GraphicsConfiguration;
27import java.awt.GraphicsEnvironment;
28import java.awt.Image;
29import java.awt.Rectangle;
30import java.awt.Shape;
31import java.awt.geom.AffineTransform;
32import java.awt.image.BufferedImage;
33import java.awt.image.DataBuffer;
34import java.awt.image.DataBufferByte;
35import java.awt.image.DataBufferInt;
36import java.awt.image.DataBufferShort;
37import java.awt.image.VolatileImage;
38import java.io.File;
39import java.io.IOException;
40
41import javax.imageio.ImageIO;
42
43import static java.awt.geom.Rectangle2D.Double;
44
45/**
46 * @test
47 * @key headful
48 * @bug 8061456
49 * @summary Tests drawing BI to volatile image using different clips + xor mode.
50 *          Results of the blit BI to compatibleImage is used for comparison.
51 * @author Sergey Bylokhov
52 */
53public final class IncorrectClipXorModeSW2Surface {
54
55    private static int[] SIZES = {2, 10, 100};
56    private static final Shape[] SHAPES = {
57                                           new Rectangle(0, 0, 0, 0),
58                                           new Rectangle(0, 0, 1, 1),
59                                           new Rectangle(0, 1, 1, 1),
60                                           new Rectangle(1, 0, 1, 1),
61                                           new Rectangle(1, 1, 1, 1),
62
63                                           new Double(0, 0, 0.5, 0.5),
64                                           new Double(0, 0.5, 0.5, 0.5),
65                                           new Double(0.5, 0, 0.5, 0.5),
66                                           new Double(0.5, 0.5, 0.5, 0.5),
67                                           new Double(0.25, 0.25, 0.5, 0.5),
68                                           new Double(0, 0.25, 1, 0.5),
69                                           new Double(0.25, 0, 0.5, 1),
70
71                                           new Double(.10, .10, .20, .20),
72                                           new Double(.75, .75, .20, .20),
73                                           new Double(.75, .10, .20, .20),
74                                           new Double(.10, .75, .20, .20),
75    };
76
77    public static void main(final String[] args) throws IOException {
78        GraphicsEnvironment ge = GraphicsEnvironment
79                .getLocalGraphicsEnvironment();
80        GraphicsConfiguration gc = ge.getDefaultScreenDevice()
81                                     .getDefaultConfiguration();
82        AffineTransform at;
83        for (int size : SIZES) {
84            at = AffineTransform.getScaleInstance(size, size);
85            for (Shape clip : SHAPES) {
86                clip = at.createTransformedShape(clip);
87                for (Shape to : SHAPES) {
88                    to = at.createTransformedShape(to);
89                    // Prepare test images
90                    BufferedImage snapshot;
91                    BufferedImage bi = getBufferedImage(size);
92                    VolatileImage vi = getVolatileImage(gc, size);
93                    while (true) {
94                        vi.validate(gc);
95                        Graphics2D g2d = vi.createGraphics();
96                        g2d.setColor(Color.GREEN);
97                        g2d.fillRect(0, 0, size, size);
98                        g2d.dispose();
99                        if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
100                            continue;
101                        }
102                        draw(clip, to, bi, vi);
103                        snapshot = vi.getSnapshot();
104                        if (vi.contentsLost()) {
105                            continue;
106                        }
107                        break;
108                    }
109                    // Prepare gold images
110                    BufferedImage goldvi = getCompatibleImage(gc, size);
111                    BufferedImage goldbi = getBufferedImage(size);
112                    draw(clip, to, goldbi, goldvi);
113                    validate(snapshot, goldvi);
114                    vi.flush();
115                }
116            }
117        }
118    }
119
120    private static void draw(Shape clip, Shape shape, Image from, Image to) {
121        Graphics2D g2d = (Graphics2D) to.getGraphics();
122        g2d.setXORMode(Color.BLACK);
123        g2d.setClip(clip);
124        Rectangle toBounds = shape.getBounds();
125        g2d.drawImage(from, toBounds.x, toBounds.y, toBounds.width,
126                      toBounds.height, null);
127        g2d.dispose();
128    }
129
130    private static BufferedImage getBufferedImage(int sw) {
131        final BufferedImage bi = new BufferedImage(sw, sw, BufferedImage.TYPE_INT_ARGB);
132        Graphics2D g2d = bi.createGraphics();
133        g2d.setColor(Color.RED);
134        g2d.fillRect(0, 0, sw, sw);
135        g2d.dispose();
136
137        final DataBuffer db = bi.getRaster().getDataBuffer();
138        if (db instanceof DataBufferInt) {
139            ((DataBufferInt) db).getData();
140        } else if (db instanceof DataBufferShort) {
141            ((DataBufferShort) db).getData();
142        } else if (db instanceof DataBufferByte) {
143            ((DataBufferByte) db).getData();
144        } else {
145            try {
146                bi.setAccelerationPriority(0.0f);
147            } catch (final Throwable ignored) {
148            }
149        }
150        return bi;
151    }
152
153    private static VolatileImage getVolatileImage(GraphicsConfiguration gc,
154                                                  int size) {
155        return gc.createCompatibleVolatileImage(size, size);
156    }
157
158    private static BufferedImage getCompatibleImage(GraphicsConfiguration gc,
159                                                    int size) {
160        BufferedImage image = gc.createCompatibleImage(size, size);
161        Graphics2D g2d = image.createGraphics();
162        g2d.setColor(Color.GREEN);
163        g2d.fillRect(0, 0, size, size);
164        g2d.dispose();
165        return image;
166    }
167
168    private static void validate(BufferedImage bi, BufferedImage goldbi)
169            throws IOException {
170        for (int x = 0; x < bi.getWidth(); ++x) {
171            for (int y = 0; y < bi.getHeight(); ++y) {
172                if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) {
173                    ImageIO.write(bi, "png", new File("actual.png"));
174                    ImageIO.write(goldbi, "png", new File("expected.png"));
175                    throw new RuntimeException("Test failed.");
176                }
177            }
178        }
179    }
180}
181