undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, JetBrains s.r.o.. 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
* @key headful
* @bug 8267116
* @summary AlphaComposite for VolatileImage graphics
* @author Alexey Ushakov
* @run main AlphaCompositeTest
*/
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
public class AlphaCompositeTest {
public static void main(String[] args) throws IOException {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(100, 100, Transparency.TRANSLUCENT);
BufferedImage gold = gc.createCompatibleImage(100, 100, Transparency.TRANSLUCENT);
render(gold.createGraphics());
BufferedImage snapshot = null;
Graphics2D g2 = vi.createGraphics();
do {
render(g2);
snapshot = vi.getSnapshot();
} while (vi.contentsLost());
for (int x = 0; x < gold.getWidth(); ++x) {
for (int y = 0; y < gold.getHeight(); ++y) {
if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
ImageIO.write(gold, "png", new File("gold.png"));
ImageIO.write(snapshot, "png", new File("bi.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
private static void render(Graphics2D g2) {
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 100, 100);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f));
g2.setColor(Color.RED);
g2.fillRect(10, 10, 80, 80);
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2015, 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.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import static java.awt.Transparency.BITMASK;
/**
* @test
* @key headful
* @bug 7188942
* @summary We should get correct volatile image, when we use BITMASK
* transparency
*/
public final class BitmaskVolatileImage {
public static final int S = 8;
public static void main(final String[] args) {
GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(S, S, BITMASK);
BufferedImage ci = gc.createCompatibleImage(S, S, BITMASK);
int attempt = 0;
do {
if (++attempt > 10) {
throw new RuntimeException("Too many attempts: " + attempt);
}
vi.validate(gc);
test(vi, ci, gc);
} while (vi.contentsLost());
}
private static void test(VolatileImage vi, BufferedImage ci, GraphicsConfiguration gc) {
for (int r = 0; r <= 255; ++r) {
for (int a = 0; a <= 255; ++a) {
fill(vi, new Color(r, 0, 0, a));
fill(ci, new Color(r, 0, 0, a));
validate(ci, vi.getSnapshot());
}
}
}
private static void fill(Image image, Color color) {
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setColor(color);
g2d.setComposite(AlphaComposite.Src);
g2d.fillRect(0, 0, S, S);
g2d.dispose();
}
private static void validate(BufferedImage ci, BufferedImage snapshot) {
for (int y = 0; y < ci.getHeight(); y++) {
for (int x = 0; x < ci.getWidth(); x++) {
int ci_rgb = ci.getRGB(x, y);
int vi_rgb = snapshot.getRGB(x, y);
if (ci_rgb != vi_rgb) {
System.err.println("Exp:" + Integer.toHexString(ci_rgb));
System.err.println("Actual:" + Integer.toHexString(vi_rgb));
throw new RuntimeException("Colors mismatch!");
}
}
}
}
}

View file

@ -0,0 +1,267 @@
/*
* Copyright (c) 2012, 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
* @key headful
* @bug 7124347 8198613
* @summary Verifies that rendering with XOR composite, and arbitraty
* custom composite doesn not cause internal errors.
*
* @run main/othervm CustomCompositeTest
*/
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.ImageCapabilities;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.Raster;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.VolatileImage;
import java.awt.image.WritableRaster;
import java.util.concurrent.CountDownLatch;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class CustomCompositeTest {
private static JFrame frame;
private static CountDownLatch paintLatch;
private static Throwable paintError;
public static void main(String[] args) {
paintLatch = new CountDownLatch(1);
paintError = null;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initGUI();
}
});
try {
paintLatch.await();
} catch (InterruptedException e) {
};
System.out.println("Paint is done!");
if (paintError != null) {
frame.dispose();
throw new RuntimeException("Test FAILED.", paintError);
}
System.out.println("Phase 1: PASSED.");
// now resise the frame in order to cause re-paint with accelerated
// source images.
paintError = null;
paintLatch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Dimension size = frame.getSize();
size.width += 50;
size.height += 50;
frame.setSize(size);
}
});
try {
paintLatch.await();
} catch (InterruptedException e) {
};
if (paintError != null) {
frame.dispose();
throw new RuntimeException("Resize test FAILED.", paintError);
}
frame.dispose();
System.out.println("Phase 2: PASSED.");
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration cfg = env.getDefaultScreenDevice().getDefaultConfiguration();
// test rendering to accelerated volatile image
testVolatileImage(cfg, true);
System.out.println("Phase 3: PASSED.");
// test rendering to unaccelerated volatile image
testVolatileImage(cfg, false);
System.out.println("Phase 4: PASSED.");
}
private static void testVolatileImage(GraphicsConfiguration cfg,
boolean accelerated)
{
VolatileImage dst = null;
try {
dst = cfg.createCompatibleVolatileImage(640, 480,
new ImageCapabilities(accelerated));
} catch (AWTException e) {
System.out.println("Unable to create volatile image, skip the test.");
return;
}
renderToVolatileImage(dst);
}
private static void renderToVolatileImage(VolatileImage dst) {
Graphics2D g = dst.createGraphics();
do {
System.out.println("Render to volatile image..");
try {
MyComp.renderTest(g, dst.getHeight(), dst.getHeight());
} catch (Throwable e) {
throw new RuntimeException("Test FAILED.", e);
}
} while (dst.contentsLost());
System.out.println("Done.");
}
private static void initGUI() {
frame = new JFrame("Silly composite");
frame.getContentPane().add(new MyComp());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static class MyComp extends JComponent {
private static BufferedImage theImage;
public MyComp() {
}
private static BufferedImage getTestImage() {
if (theImage == null) {
theImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = theImage.createGraphics();
g2d.setColor(Color.red);
g2d.fillRect(0, 0, 256, 256);
g2d.setPaint(new GradientPaint(0, 0, Color.red, 256, 256, Color.blue));
g2d.fillRect(0, 100, 256, 256);
g2d.dispose();
}
return theImage;
}
public Dimension getPreferredSize() {
return new Dimension(640, 375);
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
try {
renderTest(g2d, getWidth(), getHeight());
} catch (Throwable e) {
paintError = e;
}
if (paintLatch != null) {
paintLatch.countDown();
}
}
public static void renderTest(Graphics2D g2d, int w, int h) {
g2d.setColor(Color.yellow);
g2d.fillRect(0, 0, w, h);
BufferedImage image = getTestImage();
// draw original image
g2d.drawRenderedImage(image, null);
// draw image with custom composite
g2d.translate(175, 25);
Composite currentComposite = g2d.getComposite();
g2d.setComposite(new TestComposite());
g2d.drawRenderedImage(image, null);
g2d.setComposite(currentComposite);
// draw image with XOR
g2d.translate(175, 25);
g2d.setXORMode(Color.red);
g2d.drawRenderedImage(image, null);
System.out.println("Painting is done...");
}
}
// A silly custom Composite to demonstrate the problem - just inverts the RGB
private static class TestComposite implements Composite {
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
return new TestCompositeContext();
}
}
private static class TestCompositeContext implements CompositeContext {
public void dispose() {
}
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
int w = src.getWidth();
int h = src.getHeight();
DataBufferInt srcDB = (DataBufferInt) src.getDataBuffer();
DataBufferInt dstOutDB = (DataBufferInt) dstOut.getDataBuffer();
int srcRGB[] = srcDB.getBankData()[0];
int dstOutRGB[] = dstOutDB.getBankData()[0];
int srcOffset = srcDB.getOffset();
int dstOutOffset = dstOutDB.getOffset();
int srcScanStride = ((SinglePixelPackedSampleModel) src.getSampleModel()).getScanlineStride();
int dstOutScanStride = ((SinglePixelPackedSampleModel) dstOut.getSampleModel()).getScanlineStride();
int srcAdjust = srcScanStride - w;
int dstOutAdjust = dstOutScanStride - w;
int si = srcOffset;
int doi = dstOutOffset;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
dstOutRGB[doi] = srcRGB[si] ^ 0x00ffffff;
si++;
doi++;
}
si += srcAdjust;
doi += dstOutAdjust;
}
}
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2014, 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
* @key headful
* @bug 8040617 8198613
* @summary Test verifies that an attempt to get an accelerated copy of
* a huge buffered image does not result in an OOME.
*
* @run main DrawHugeImageTest
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
public class DrawHugeImageTest {
// we have to render the BI source several times in order
// to get an accelerated copy to be used.
static {
System.setProperty("sun.java2d.accthreshold", "1");
}
private static final int max_rendering_count = 5;
private static final Color srcColor = Color.red;
private static final Color dstColor = Color.blue;
public static void main(String[] args) {
BufferedImage src = createSrc();
VolatileImage dst = createDst();
System.out.println("Dst: " + dst);
boolean status;
int count = max_rendering_count;
do {
System.out.println("render image: " + (max_rendering_count - count));
status = render(src, dst);
} while (status && count-- > 0);
if (!status || count > 0) {
throw new RuntimeException("Test failed: " + count);
}
}
private static boolean render(BufferedImage src, VolatileImage dst) {
int cnt = 5;
do {
Graphics2D g = dst.createGraphics();
g.setColor(dstColor);
g.fillRect(0, 0, dst.getWidth(), dst.getHeight());
g.drawImage(src, 0, 0, null);
g.dispose();
} while (dst.contentsLost() && (--cnt > 0));
if (cnt == 0) {
System.err.println("Test failed: unable to render to volatile destination");
return false;
}
BufferedImage s = dst.getSnapshot();
return s.getRGB(1,1) == srcColor.getRGB();
}
private static BufferedImage createSrc() {
final int w = 20000;
final int h = 5;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = img.createGraphics();
g.setColor(srcColor);
g.fillRect(0, 0, w, h);
g.dispose();
return img;
}
private static VolatileImage createDst() {
GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
return gc.createCompatibleVolatileImage(200, 200);
}
}

View file

@ -0,0 +1,356 @@
/*
* Copyright (c) 2007, 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
* @key headful
* @bug 6521533 6525997 7102282 8198613
* @summary Verifies that the accelerated codepaths for GradientPaint,
* LinearGradientPaint, and RadialGradientPaint produce results that are
* sufficiently close to those produced by the software codepaths.
* @run main/othervm -Dsun.java2d.uiScale=1 GradientPaints
* @author campbelc
*/
import java.awt.*;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.File;
import java.util.Arrays;
import javax.imageio.ImageIO;
public class GradientPaints extends Canvas {
private static final int TESTW = 600;
private static final int TESTH = 500;
/*
* We expect slight differences in rendering between the OpenGL and
* software pipelines due to algorithmic and rounding differences.
* The purpose of this test is just to make sure that the OGL pipeline
* is producing results that are "reasonably" consistent with those
* produced in software, so we will allow +/-TOLERANCE differences
* in each component. When comparing the test and reference images,
* we add up the number of pixels that fall outside this tolerance
* range and if the sum is larger than some percentage of the total
* number of pixels.
*
* REMIND: Note that we have separate thresholds for linear and radial
* gradients because the visible differences between OGL and software
* are more apparent in the radial cases. In the future we should try
* to reduce the number of mismatches between the two approaches, but
* for now the visible differences are slight enough to not cause worry.
*/
private static final int TOLERANCE = 5;
private static final int ALLOWED_MISMATCHES_LINEAR =
(int)(TESTW * TESTH * 0.18);
private static final int ALLOWED_MISMATCHES_RADIAL =
(int)(TESTW * TESTH * 0.45);
private static boolean done;
private static boolean verbose;
private static final Color[] COLORS = {
new Color(0, 0, 0),
new Color(128, 128, 128),
new Color(255, 0, 0),
new Color(255, 255, 0),
new Color(0, 255, 0),
new Color(0, 255, 255),
new Color(128, 0, 255),
new Color(128, 128, 128),
};
private static enum PaintType {BASIC, LINEAR, RADIAL};
private static enum XformType {IDENTITY, TRANSLATE, SCALE, SHEAR, ROTATE};
private static final int[] numStopsArray = {2, 4, 7};
private static final Object[] hints = {
RenderingHints.VALUE_ANTIALIAS_OFF,
RenderingHints.VALUE_ANTIALIAS_ON,
};
public void paint(Graphics g) {
synchronized (this) {
if (!done) {
done = true;
notifyAll();
}
}
}
private void testOne(BufferedImage refImg, VolatileImage testImg) {
Graphics2D gref = refImg.createGraphics();
Graphics2D gtest = testImg.createGraphics();
Paint paint =
makePaint(PaintType.RADIAL, CycleMethod.REPEAT,
ColorSpaceType.SRGB, XformType.IDENTITY, 7);
Object aahint = hints[0];
renderTest(gref, paint, aahint);
renderTest(gtest, paint, aahint);
Toolkit.getDefaultToolkit().sync();
compareImages(refImg, testImg.getSnapshot(),
TOLERANCE, 0, "");
gref.dispose();
gtest.dispose();
}
private void testAll(Graphics gscreen,
BufferedImage refImg, VolatileImage testImg)
{
Graphics2D gref = refImg.createGraphics();
Graphics2D gtest = testImg.createGraphics();
for (PaintType paintType : PaintType.values()) {
for (CycleMethod cycleMethod : CycleMethod.values()) {
for (ColorSpaceType colorSpace : ColorSpaceType.values()) {
for (XformType xform : XformType.values()) {
for (Object aahint : hints) {
for (int numStops : numStopsArray) {
Paint paint =
makePaint(paintType, cycleMethod,
colorSpace, xform, numStops);
String msg =
"type=" + paintType +
" cycleMethod=" + cycleMethod +
" colorSpace=" + colorSpace +
" xformType=" + xform +
" numStops=" + numStops +
" aa=" + aahint;
renderTest(gref, paint, aahint);
renderTest(gtest, paint, aahint);
gscreen.drawImage(testImg, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
int allowedMismatches =
paintType == PaintType.RADIAL ?
ALLOWED_MISMATCHES_RADIAL :
ALLOWED_MISMATCHES_LINEAR;
compareImages(refImg, testImg.getSnapshot(),
TOLERANCE, allowedMismatches,
msg);
}
}
}
}
}
}
gref.dispose();
gtest.dispose();
}
private Paint makePaint(PaintType paintType,
CycleMethod cycleMethod,
ColorSpaceType colorSpace,
XformType xformType, int numStops)
{
int startX = TESTW/6;
int startY = TESTH/6;
int endX = TESTW/2;
int endY = TESTH/2;
int ctrX = TESTW/2;
int ctrY = TESTH/2;
int focusX = ctrX + 20;
int focusY = ctrY + 20;
float radius = 100.0f;
Paint paint;
AffineTransform transform;
Color[] colors = Arrays.copyOf(COLORS, numStops);
float[] fractions = new float[colors.length];
for (int i = 0; i < fractions.length; i++) {
fractions[i] = ((float)i) / (fractions.length-1);
}
switch (xformType) {
default:
case IDENTITY:
transform = new AffineTransform();
break;
case TRANSLATE:
transform = AffineTransform.getTranslateInstance(2, 2);
break;
case SCALE:
transform = AffineTransform.getScaleInstance(1.2, 1.4);
break;
case SHEAR:
transform = AffineTransform.getShearInstance(0.1, 0.1);
break;
case ROTATE:
transform = AffineTransform.getRotateInstance(Math.PI / 4,
getWidth()/2,
getHeight()/2);
break;
}
switch (paintType) {
case BASIC:
boolean cyclic = (cycleMethod != CycleMethod.NO_CYCLE);
paint =
new GradientPaint(startX, startY, Color.RED,
endX, endY, Color.BLUE, cyclic);
break;
default:
case LINEAR:
paint =
new LinearGradientPaint(new Point2D.Float(startX, startY),
new Point2D.Float(endX, endY),
fractions, colors,
cycleMethod, colorSpace,
transform);
break;
case RADIAL:
paint =
new RadialGradientPaint(new Point2D.Float(ctrX, ctrY),
radius,
new Point2D.Float(focusX, focusY),
fractions, colors,
cycleMethod, colorSpace,
transform);
break;
}
return paint;
}
private void renderTest(Graphics2D g2d, Paint p, Object aahint) {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, TESTW, TESTH);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aahint);
g2d.setPaint(p);
g2d.fillOval(0, 0, TESTW, TESTH);
}
public Dimension getPreferredSize() {
return new Dimension(TESTW, TESTH);
}
private static void compareImages(BufferedImage refImg,
BufferedImage testImg,
int tolerance, int allowedMismatches,
String msg)
{
int numMismatches = 0;
int x1 = 0;
int y1 = 0;
int x2 = refImg.getWidth();
int y2 = refImg.getHeight();
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
Color expected = new Color(refImg.getRGB(x, y));
Color actual = new Color(testImg.getRGB(x, y));
if (!isSameColor(expected, actual, tolerance)) {
numMismatches++;
}
}
}
if (verbose) {
System.out.println(msg);
}
if (numMismatches > allowedMismatches) {
try {
ImageIO.write(refImg, "png",
new File("GradientPaints.ref.png"));
ImageIO.write(testImg, "png",
new File("GradientPaints.cap.png"));
} catch (Exception e) {
}
if (!verbose) {
System.err.println(msg);
}
throw new RuntimeException("Test failed: Number of mismatches (" +
numMismatches +
") exceeds limit (" +
allowedMismatches +
") with tolerance=" +
tolerance);
}
}
private static boolean isSameColor(Color c1, Color c2, int e) {
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
int rmin = Math.max(r2-e, 0);
int gmin = Math.max(g2-e, 0);
int bmin = Math.max(b2-e, 0);
int rmax = Math.min(r2+e, 255);
int gmax = Math.min(g2+e, 255);
int bmax = Math.min(b2+e, 255);
if (r1 >= rmin && r1 <= rmax &&
g1 >= gmin && g1 <= gmax &&
b1 >= bmin && b1 <= bmax)
{
return true;
}
return false;
}
public static void main(String[] args) {
if (args.length == 1 && args[0].equals("-verbose")) {
verbose = true;
}
GradientPaints test = new GradientPaints();
Frame frame = new Frame();
frame.add(test);
frame.pack();
frame.setVisible(true);
// Wait until the component's been painted
synchronized (test) {
while (!done) {
try {
test.wait();
} catch (InterruptedException e) {
throw new RuntimeException("Failed: Interrupted");
}
}
}
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
frame.dispose();
return;
}
BufferedImage refImg =
new BufferedImage(TESTW, TESTH, BufferedImage.TYPE_INT_RGB);
VolatileImage testImg = frame.createVolatileImage(TESTW, TESTH);
testImg.validate(gc);
try {
test.testAll(test.getGraphics(), refImg, testImg);
} finally {
frame.dispose();
}
}
}

View file

@ -0,0 +1,132 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
/*
* @test id=default
* @bug 8272288
* @key headful
* @summary Broken rendering should be reported by the contentsLost()
*
* @run main/othervm ReportRenderingError
*/
/*
* @test id=windows
* @bug 8272288
* @key headful
* @summary Broken rendering should be reported by the contentsLost()
* @requires (os.family == "windows")
*
* @run main/othervm -Dsun.java2d.opengl=True ReportRenderingError
* @run main/othervm -Dsun.java2d.d3d=True ReportRenderingError
* @run main/othervm -Dsun.java2d.d3d=false ReportRenderingError
*/
/*
* @test id=macos
* @bug 8272288
* @key headful
* @summary Broken rendering should be reported by the contentsLost()
*
* @requires (os.family == "mac")
* @run main/othervm -Dsun.java2d.opengl=True ReportRenderingError
* @run main/othervm -Dsun.java2d.metal=True ReportRenderingError
*/
/*
* @test id=linux
* @bug 8272288
* @key headful
* @summary Broken rendering should be reported by the contentsLost()
*
* @requires (os.family == "linux")
* @run main/othervm -Dsun.java2d.opengl=True ReportRenderingError
* @run main/othervm -Dsun.java2d.xrender=True ReportRenderingError
* @run main/othervm -Dsun.java2d.xrender=false ReportRenderingError
*/
public final class ReportRenderingError {
public static void main(String[] args) {
var gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration();
var vi = gc.createCompatibleVolatileImage(10, 10);
Image image = new EmptyImage();
BufferedImage snapshot;
int attempt = 0;
do {
vi.validate(gc);
Graphics2D g = vi.createGraphics();
g.setColor(Color.RED);
g.drawImage(image, 0, 0, null); // <- can cause InvalidPipeException
g.fillRect(0, 0, vi.getWidth(), vi.getHeight());
g.dispose();
snapshot = vi.getSnapshot();
} while (vi.contentsLost() && (++attempt <= 10));
if (vi.contentsLost()) {
System.out.println("Content is lost, skip the pixel validation");
} else {
if (snapshot.getRGB(5, 5) != Color.RED.getRGB()) {
throw new RuntimeException("Test failed");
}
}
}
private static final class EmptyImage extends Image {
@Override
public int getWidth(ImageObserver observer) {
return 10;
}
@Override
public int getHeight(ImageObserver observer) {
return 10;
}
@Override
public ImageProducer getSource() {
return null;
}
@Override
public Graphics getGraphics() {
return null;
}
@Override
public Object getProperty(String name, ImageObserver observer) {
return null;
}
}
}

View file

@ -0,0 +1,258 @@
/*
* 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.");
}
}
});
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, 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.
*/
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.VolatileImage;
/**
* @test
* @key headful
* @bug 8140530
* @run main VolatileImageBug
* @summary Creating volatileimage(0,0) should throw IAE
*/
public class VolatileImageBug {
public static void main(String[] args) {
boolean iaeThrown = false;
GraphicsEnvironment ge = GraphicsEnvironment.
getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().
getDefaultConfiguration();
try {
VolatileImage volatileImage = gc.createCompatibleVolatileImage(0, 0);
} catch (IllegalArgumentException iae) {
iaeThrown = true;
}
if (!iaeThrown) {
throw new RuntimeException ("IllegalArgumentException not thrown " +
"for createCompatibleVolatileImage(0,0)");
}
}
}

View file

@ -0,0 +1,267 @@
/*
* 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 8165212
* @summary This manual test case displays scale values of Graphics and the
* underlying device configuration. Any change to host display's DPI
* value should reflect corresponding changes in the scale values
* of both Frame and Backbuffer (VolatileImage).
* @run main/othervm/manual -Dsun.java2d.d3d=false -Dsun.java2d.opengl=false VolatileImageConfigurationTest
*/
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.VolatileImage;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
public class VolatileImageConfigurationTest
extends JFrame
implements ActionListener {
/* Test frame and completion status */
private static JFrame testFrame;
private static volatile boolean testComplete = false;
private static volatile boolean testResult = false;
/* Main frame's dimensions */
private static final int TEST_WIDTH = 600;
private static final int TEST_HEIGHT = 600;
private static final int TEST_MIN_DURATION = 3000;
private static final int TEST_TOTAL_DURATION = 45000;
/*
* Frame will display information text explaining how to run the manual
* test, and two buttons- Pass and Fail to determine the end-result.
*/
private JTextArea infoTextArea;
private JPanel buttonPanel;
private JPanel testPanel;
private JButton passButton;
private JButton failButton;
public VolatileImageConfigurationTest() {
/* Default constructor. Initialize the UI components */
super("Volatile Image Configuration Update Test");
initComponents();
}
private void initComponents() {
/* Create the text area with steps to execute the test */
String description
= "\n Volatile Image Configuration Update Test.\n"
+ " 1. The test displays scale values of component and the"
+ " underlying graphics device configuration.\n"
+ " 2. Kindly change the display's DPI settings from OS"
+ " control panel and observe the application.\n"
+ " 3. Select Pass if the scale values for both component & "
+ "underlying device configuration are updated as per the "
+ "\ndisplay's DPI value.\n";
infoTextArea = new JTextArea(description);
/* Create the test panel where user will observe the drawing */
testPanel = new DisplayPanel();
/* Create the buttons with event listeners */
passButton = new JButton("Pass");
passButton.setActionCommand("Pass");
passButton.setEnabled(true);
passButton.addActionListener(this);
failButton = new JButton("Fail");
failButton.setActionCommand("Fail");
failButton.setEnabled(true);
failButton.addActionListener(this);
/* Add the buttons to a separate panel with flowlayout */
buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(passButton);
buttonPanel.add(failButton);
/* Add all the created components to the master frame */
setLayout(new BorderLayout(10, 10));
add(infoTextArea, BorderLayout.NORTH);
add(buttonPanel, BorderLayout.SOUTH);
add(testPanel, BorderLayout.CENTER);
/* Set the dimensions */
setSize(TEST_WIDTH, TEST_HEIGHT);
}
@Override
public void actionPerformed(ActionEvent e) {
/* Button event listener */
String command = e.getActionCommand();
if (command.equals("Pass")) {
/* Test has passed. Dispose the frame with success message */
testComplete = true;
testResult = true;
System.out.println("Test Passed.");
} else if (command.equals("Fail")) {
/* Test has failed. Dispose the frame and throw exception */
testComplete = true;
testResult = false;
}
}
private static void constructTestUI() {
/* Construct the test's user interface */
testFrame = new VolatileImageConfigurationTest();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testFrame.setLocationRelativeTo(null);
testFrame.setVisible(true);
}
private static void destructTestUI() {
/* Destroy the test's user interface */
testFrame.dispose();
}
static class DisplayPanel extends JPanel {
/* Display panel settings */
private static final int PANEL_WIDTH = 600;
private static final int PANEL_HEIGHT = 500;
private static final int PANEL_X = 20;
private static final int PANEL_Y = 80;
private static final String MSG = "%s scale: [%2.2f, %2.2f]";
private VolatileImage vImg;
public DisplayPanel() throws HeadlessException {
setSize(PANEL_WIDTH, PANEL_HEIGHT);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT);
/* Display graphics configuration values of the component */
drawInfo(g, PANEL_X, PANEL_Y, "Frame", Color.BLUE);
int attempts = 0;
do {
/* Display graphics configuration values of volatile image */
drawBackingStoreImage(g);
} while (vImg.contentsLost() && ++attempts < 3);
}
private void drawInfo(Graphics g, int x, int y,
String msg, Color color) {
g.setColor(color);
g.setFont(g.getFont().deriveFont(24f));
Graphics2D g2d = (Graphics2D) g;
AffineTransform tx = g2d.getTransform();
g.drawString(msg, x, y);
String text = String.format(MSG,
"Graphics",
tx.getScaleX(),
tx.getScaleY());
int dy = 20;
g.drawString(text, x, y + dy);
tx = g2d.getDeviceConfiguration().getDefaultTransform();
text = String.format(MSG,
"Device Config",
tx.getScaleX(),
tx.getScaleY());
g.drawString(text, x, y + 2 * dy);
}
private void drawBackingStoreImage(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
GraphicsConfiguration gc = g2d.getDeviceConfiguration();
if (vImg == null ||
vImg.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
/* Create a new volatile image */
vImg = createVolatileImage(PANEL_WIDTH, PANEL_HEIGHT / 3);
}
Graphics vImgGraphics = vImg.createGraphics();
vImgGraphics.setColor(Color.WHITE);
vImgGraphics.fillRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT / 3);
drawInfo(vImgGraphics,
PANEL_X,
PANEL_Y,
"Backbuffer",
Color.MAGENTA);
g.drawImage(vImg, 0, PANEL_Y * 2, this);
}
}
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.");
}
}
});
try {
/* Provide sufficient time for user to act upon the manual test */
long totalWaitDuration = 0;
do {
Thread.sleep(TEST_MIN_DURATION);
totalWaitDuration += TEST_MIN_DURATION;
} while (!testComplete && totalWaitDuration < TEST_TOTAL_DURATION);
} catch(InterruptedException ite) {
/* No-op. The thread continues execution further */
}
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
/* Destroy the test interface */
destructTestUI();
} catch (Exception ex) {
/* No-op */
}
}
});
/* Check for the test result and throw exception if required */
if (testResult == false) {
throw new RuntimeException("Test Failed. Incorrect scale values "
+ "were seen during the test execution.");
}
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2012, 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.
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
/**
* @test
* @key headful
* @bug 7181438 8198613
* @summary Verifies that we get correct alpha, when we draw opaque
* BufferedImage to non opaque VolatileImage via intermediate opaque texture.
* @author Sergey Bylokhov
* @run main/othervm -Dsun.java2d.accthreshold=0 bug7181438
*/
public final class bug7181438 {
private static final int SIZE = 500;
public static void main(final String[] args) {
final BufferedImage bi = createBufferedImage();
final VolatileImage vi = createVolatileImage();
final Graphics s2dVi = vi.getGraphics();
//sw->texture->surface blit
s2dVi.drawImage(bi, 0, 0, null);
final BufferedImage results = vi.getSnapshot();
for (int i = 0; i < SIZE; ++i) {
for (int j = 0; j < SIZE; ++j) {
//Image should be opaque: (black color and alpha = 255)
if (results.getRGB(i, j) != 0xFF000000) {
throw new RuntimeException("Failed: Wrong alpha");
}
}
}
System.out.println("Passed");
}
private static VolatileImage createVolatileImage() {
final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
final GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
return gc.createCompatibleVolatileImage(SIZE, SIZE,
Transparency.TRANSLUCENT);
}
private static BufferedImage createBufferedImage() {
final BufferedImage bi = new BufferedImage(SIZE, SIZE,
BufferedImage.TYPE_INT_RGB);
final Graphics bg = bi.getGraphics();
//Black color and alpha = 0
bg.setColor(new Color(0, 0, 0, 0));
bg.fillRect(0, 0, SIZE, SIZE);
bg.dispose();
return bi;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB