--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java Fri Apr 29 16:27:34 2011 -0700
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2010, 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 5089429 6982632
+ @summary Checks that we don't crash if rendering operations and state
+ changes are performed on a graphics context from different threads.
+
+ @author Dmitri.Trembovetski@sun.com area=Graphics
+ @run main MTGraphicsAccessTest
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+
+public class MTGraphicsAccessTest {
+
+ // in seconds
+ static final long STANDALONE_RUN_TIME = 20;
+ static final long JTREG_RUN_TIME = 7;
+
+ static boolean standaloneMode;
+ static boolean allowExceptions = true;
+ static long testRunTime;
+
+ volatile boolean done;
+ volatile int stillRunning;
+ volatile int numexceptions;
+
+ Graphics2D sharedGraphics;
+ BufferedImage sharedBI =
+ new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
+
+ static final Paint colors[] = {
+ Color.red,
+ new Color(0x7f, 0xff, 0x00, 0x7f),
+ new GradientPaint(0, 0, Color.red,
+ 50, 50, new Color(0x7f, 0xff, 0x00, 0x7f)),
+ };
+ static final Font fonts[] = {
+ new Font("Dialog", Font.PLAIN, 12),
+ new Font("Dialog", Font.BOLD, 16),
+ new Font("Dialog", Font.ITALIC, 18),
+ };
+ static final AlphaComposite comps[] = {
+ AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f),
+ AlphaComposite.Src,
+ AlphaComposite.Xor,
+ AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f),
+ null,
+ };
+ static final Stroke strokes[] = {
+ new BasicStroke(),
+ new BasicStroke(0.0f),
+ new BasicStroke(2.0f),
+ new BasicStroke(2.0f, BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_BEVEL),
+ new BasicStroke(5.0f, BasicStroke.CAP_SQUARE,
+ BasicStroke.JOIN_ROUND),
+ new BasicStroke(0.0f, BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_ROUND, 0,
+ new float[]{0,6,0,6}, 0),
+ };
+ static final AffineTransform transforms[] = {
+ new AffineTransform(),
+ AffineTransform.getRotateInstance(10.0),
+ AffineTransform.getShearInstance(10.0, 4.0),
+ AffineTransform.getScaleInstance(1.1, 1.2),
+ AffineTransform.getScaleInstance(3.0, 2.0),
+ };
+
+ public MTGraphicsAccessTest() {
+ BufferedImage bi =
+ new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
+ sharedGraphics = (Graphics2D)bi.getGraphics();
+
+ done = false;
+ numexceptions = 0;
+
+ for (int i = 0; i < (standaloneMode ? stateChangers.length : 3); i++) {
+ (new TesterThread(stateChangers[i])).start();
+ }
+ for (int i = 0; i < (standaloneMode ? renderTests.length : 5); i++) {
+ (new TesterThread(renderTests[i])).start();
+ }
+
+ mysleep(testRunTime);
+ done = true;
+ while (stillRunning > 0) { mysleep(500); }
+
+ if (numexceptions == 0) {
+ System.err.println("Test passed");
+ } else if (!allowExceptions) {
+ throw new RuntimeException("Test failed with "+
+ numexceptions+" exceptions");
+ } else {
+ System.err.println("Test finished with "+
+ numexceptions+" exceptions");
+ }
+ }
+
+ private void mysleep(long time) {
+ try {
+ // add +/-5ms variance to increase randomness
+ Thread.sleep(time + (long)(5 - Math.random()*10));
+ } catch (InterruptedException e) {};
+ }
+
+ public static void usage(String message) {
+ if (message != null) {
+ System.err.println(message);
+ }
+ System.err.println("Usage: MTGraphicsAccessTest [-full] "+
+ "[-time N/forever] [-help]");
+ System.err.println(" -full: run full suite of tests "+
+ "(default: limited number of tests is run)");
+ System.err.println(" -time N: test duration in seconds/forever"+
+ " (default: "+JTREG_RUN_TIME+"s for the short suite, "+
+ STANDALONE_RUN_TIME+"s for the full suite)");
+ System.err.println(" -help: print this help page");
+ System.exit(1);
+ }
+
+ public static void main(String[] args) {
+ boolean testRunSet = false;
+ for (int i = 0; i < args.length; i++) {
+ if ("-full".equals(args[i])) {
+ standaloneMode = true;
+ System.err.println("Running complete list of tests");
+ } else if ("-noexc".equals(args[i])) {
+ allowExceptions = false;
+ } else if ("-time".equals(args[i])) {
+ try {
+ String time = args[++i];
+ if ("forever".equals(time)) {
+ testRunTime = (Long.MAX_VALUE - 20)/1000;
+ } else {
+ testRunTime = 1000*Integer.parseInt(time);
+ }
+ testRunSet = true;
+ } catch (NumberFormatException e) {
+ usage("Can't parse number of seconds: " + args[i]);
+ } catch (ArrayIndexOutOfBoundsException e1) {
+ usage("Missing the 'seconds' argument for -time parameter");
+ }
+ } else if ("-help".equals(args[i])) {
+ usage(null);
+ } else {
+ usage("Unknown argument:" + args[i]);
+ }
+ }
+
+ if (!testRunSet) {
+ testRunTime = 1000 *
+ (standaloneMode ? STANDALONE_RUN_TIME : JTREG_RUN_TIME);
+ }
+
+ System.err.println("Approximate test run time: "+
+ testRunTime/1000+" seconds");
+
+ new MTGraphicsAccessTest();
+ }
+
+ class TesterThread extends Thread {
+ Runnable testRunnable;
+
+ public TesterThread(Runnable testRunnable) {
+ stillRunning++;
+ this.testRunnable = testRunnable;
+ }
+
+ public void run() {
+ try {
+ while (!done) {
+ try {
+ testRunnable.run();
+ yield();
+ } catch (Throwable t) {
+ numexceptions++;
+ t.printStackTrace();
+ }
+ }
+ } finally {
+ stillRunning--;
+ }
+ }
+ }
+
+ final Runnable stateChangers[] = {
+ new Runnable() {
+ public void run() {
+ sharedGraphics.setClip(10, 10, 30, 30);
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.setClip(10, 10, 30, 30);
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ int c = 0;
+ public void run() {
+ sharedGraphics.setPaint(colors[c++ % colors.length]);
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ boolean AA = false;
+ public void run() {
+ if (AA) {
+ sharedGraphics.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ } else {
+ sharedGraphics.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+ AA = !AA;
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ int t = 0;
+ public void run() {
+ sharedGraphics.setTransform(
+ transforms[t++ % transforms.length]);
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ int c = 0;
+ public void run() {
+ AlphaComposite comp = comps[c++ % comps.length];
+ if (comp == null) {
+ sharedGraphics.setXORMode(Color.green);
+ } else {
+ sharedGraphics.setComposite(comp);
+ }
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ int s = 0;
+ public void run() {
+ sharedGraphics.setStroke(strokes[s++ % strokes.length]);
+ mysleep(10);
+ }
+ },
+ new Runnable() {
+ int f = 0;
+ public void run() {
+ sharedGraphics.setFont(fonts[f++ % fonts.length]);
+ mysleep(10);
+ }
+ },
+ };
+
+ final Runnable renderTests[] = {
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawLine(10, 10, 30, 30);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawLine(10, 10, 30, 30);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawRect(10, 10, 30, 30);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.fillRect(10, 10, 30, 30);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawString("Stuff", 10, 10);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.draw3DRect(10, 10, 30, 30, true);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawImage(sharedBI, 10, 10, null);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.fill3DRect(10, 10, 30, 30, false);
+ }
+ },
+ // REMIND: copyArea doesn't work when transform is set..
+ // new Runnable() {
+ // public void run() {
+ // sharedGraphics.copyArea(10, 10, 30, 30, 20, 20);
+ // }
+ // },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawRoundRect(10, 10, 30, 30, 20, 20);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.fillRoundRect(10, 10, 30, 30, 20, 20);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawArc(10, 10, 30, 30, 0, 90);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.fillArc(10, 10, 30, 30, 0, 90);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.drawOval(10, 10, 30, 30);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ sharedGraphics.fillOval(10, 10, 30, 30);
+ }
+ }
+ };
+}