diff options
author | lana <none@none> | 2008-07-24 21:12:50 -0700 |
---|---|---|
committer | lana <none@none> | 2008-07-24 21:12:50 -0700 |
commit | 1015cd70b8294b2505e5c265d2ab081823c64f85 (patch) | |
tree | 20caa9b99b2c3f29ab84761a8b86b34a9bf4c652 /test | |
parent | 13ed324e155f4c5e3b311eb5d1433185cd381281 (diff) | |
parent | 3770d88ff7d368240f39657079ed4df0b6572c9a (diff) |
Merge
Diffstat (limited to 'test')
30 files changed, 5945 insertions, 0 deletions
diff --git a/test/java/awt/FullScreen/BufferStrategyExceptionTest/BufferStrategyExceptionTest.java b/test/java/awt/FullScreen/BufferStrategyExceptionTest/BufferStrategyExceptionTest.java new file mode 100644 index 000000000..b50cf5939 --- /dev/null +++ b/test/java/awt/FullScreen/BufferStrategyExceptionTest/BufferStrategyExceptionTest.java @@ -0,0 +1,134 @@ +/* + * Copyright 2006-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6366813 6459844 + * @summary Tests that no exception is thrown if a frame is resized just + * before we create a bufferStrategy + * @author Dmitri.Trembovetski area=FullScreen/BufferStrategy + * @run main/othervm -Dsun.java2d.opengl=true BufferStrategyExceptionTest + * @run main/othervm BufferStrategyExceptionTest + */ + +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.ImageCapabilities; +import java.awt.image.BufferStrategy; +import java.awt.image.BufferedImage; + +/** + * The purpose of this test is to make sure that we do not throw an + * IllegalStateException during the creation of BufferStrategy if + * a window has been resized just before our creation attempt. + * + * We test both windowed and fullscreen mode, although the exception has + * been observed in full screen mode only. + */ +public class BufferStrategyExceptionTest { + private static final int TEST_REPS = 20; + + public static void main(String[] args) { + GraphicsDevice gd = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice(); + + for (int i = 0; i < TEST_REPS; i++) { + TestFrame f = new TestFrame(); + f.pack(); + f.setSize(400, 400); + f.setVisible(true); + if (i % 2 == 0) { + gd.setFullScreenWindow(f); + } + // generate a resize event which will invalidate the peer's + // surface data and hopefully cause an exception during + // BufferStrategy creation in TestFrame.render() + Dimension d = f.getSize(); + d.width -= 5; d.height -= 5; + f.setSize(d); + + f.render(); + gd.setFullScreenWindow(null); + sleep(100); + f.dispose(); + } + System.out.println("Test passed."); + } + + private static void sleep(long msecs) { + try { + Thread.sleep(msecs); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + private static final BufferedImage bi = + new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + + static class TestFrame extends Frame { + TestFrame() { + setUndecorated(true); + setIgnoreRepaint(true); + setSize(400, 400); + } + + public void render() { + ImageCapabilities imgBackBufCap = new ImageCapabilities(true); + ImageCapabilities imgFrontBufCap = new ImageCapabilities(true); + BufferCapabilities bufCap = + new BufferCapabilities(imgFrontBufCap, + imgBackBufCap, BufferCapabilities.FlipContents.COPIED); + try { + + createBufferStrategy(2, bufCap); + } catch (AWTException ex) { + createBufferStrategy(2); + } + + BufferStrategy bs = getBufferStrategy(); + do { + Graphics g = bs.getDrawGraphics(); + g.setColor(Color.green); + g.fillRect(0, 0, getWidth(), getHeight()); + + g.setColor(Color.red); + g.drawString("Rendering test", 20, 20); + + g.drawImage(bi, 50, 50, null); + + g.dispose(); + bs.show(); + } while (bs.contentsLost()||bs.contentsRestored()); + } + } + +} diff --git a/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java b/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java new file mode 100644 index 000000000..7e615068c --- /dev/null +++ b/test/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java @@ -0,0 +1,387 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 5041219 + * @bug 5101561 + * @bug 5035272 + * @bug 5096011 + * @bug 5101712 + * @bug 5098624 + * @summary Here are a few assertions worth verification: + * - the fullscreen window is positioned at 0,0 + * - the fs window appears on the correct screen + * - if the exclusive FS mode is supported, no other widndow should + * overlap the fs window (including the taskbar). + * You could, however, alt+tab out of a fullscreen window, or at least + * minimize it (if you've entered the fs mode with a Window, you'll need + * to minimize the owner frame). + * Note that there may be issues with FS exclusive mode with ddraw and + * multiple fullscreen windows (one per device). + * - if display mode is supported that it did change + * - that the original display mode is restored once + * the ws window is disposed + * All of the above should work with and w/o DirectDraw + * (-Dsun.java2d.noddraw=true) on windows, and w/ and w/o opengl on X11 + * (-Dsun.java2d.opengl=True). + * @run main/manual/othervm -Dsun.java2d.pmoffscreen=true MultimonFullscreenTest + * @run main/manual/othervm -Dsun.java2d.pmoffscreen=false MultimonFullscreenTest + * @run main/manual/othervm -Dsun.java2d.d3d=True MultimonFullscreenTest + * @run main/manual/othervm -Dsun.java2d.noddraw=true MultimonFullscreenTest + * @run main/manual/othervm -Dsun.java2d.opengl=True MultimonFullscreenTest + */ + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.DisplayMode; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferStrategy; +import java.util.HashMap; +import java.util.Random; + +/** + */ + +public class MultimonFullscreenTest extends Frame implements ActionListener { + GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice(); + GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getScreenDevices(); + HashMap<Button, GraphicsDevice> deviceMap; + + private static boolean dmChange = false; + static boolean setNullOnDispose = false; + static boolean useFSFrame = true; + static boolean useFSWindow = false; + static boolean useFSDialog = false; + static boolean useBS = false; + static boolean runRenderLoop = false; + static boolean addHWChildren = false; + static volatile boolean done = true; + + public MultimonFullscreenTest(String title) { + super(title); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + Panel p = new Panel(); + deviceMap = new HashMap<Button, GraphicsDevice>(gd.length); + int num = 0; + for (GraphicsDevice dev : gd) { + Button b; + if (dev == defDev) { + b = new Button("Primary screen: " + num); + System.out.println("Primary Dev : " + dev + " Bounds: " + + dev.getDefaultConfiguration().getBounds()); + } else { + b = new Button("Secondary screen " + num); + System.out.println("Secondary Dev : " + dev + " Bounds: " + + dev.getDefaultConfiguration().getBounds()); + } + b.addActionListener(this); + p.add(b); + deviceMap.put(b, dev); + num++; + } + add("South", p); + Panel p1 = new Panel(); + p1.setLayout(new GridLayout(2,0)); + Checkbox cb = new Checkbox("Change DM on entering FS"); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + dmChange = ((Checkbox)e.getSource()).getState(); + } + }); + p1.add(cb); +// cb = new Checkbox("Exit FS on window dispose"); +// cb.addItemListener(new ItemListener() { +// public void itemStateChanged(ItemEvent e) { +// setNullOnDispose = ((Checkbox)e.getSource()).getState(); +// } +// }); +// p1.add(cb); + CheckboxGroup cbg = new CheckboxGroup(); + cb = new Checkbox("Use Frame to enter FS", cbg, true); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + useFSFrame = true; + useFSWindow = false; + useFSDialog = false; + } + }); + p1.add(cb); + cb = new Checkbox("Use Window to enter FS", cbg, false); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + useFSFrame = false; + useFSWindow = true; + useFSDialog = false; + } + }); + p1.add(cb); + cb = new Checkbox("Use Dialog to enter FS", cbg, false); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + useFSFrame = false; + useFSWindow = false; + useFSDialog = true; + } + }); + p1.add(cb); + cb = new Checkbox("Run render loop"); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + runRenderLoop = ((Checkbox)e.getSource()).getState(); + } + }); + p1.add(cb); + cb = new Checkbox("Use BufferStrategy in render loop"); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + useBS = ((Checkbox)e.getSource()).getState(); + } + }); + p1.add(cb); + cb = new Checkbox("Add Children to FS window"); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + addHWChildren = ((Checkbox)e.getSource()).getState(); + } + }); + p1.add(cb); + add("North", p1); + + pack(); + setVisible(true); + } + + Font f = new Font("Dialog", Font.BOLD, 24); + Random rnd = new Random(); + public void renderDimensions(Graphics g, Rectangle rectWndBounds, + GraphicsConfiguration gc) { + g.setColor(new Color(rnd.nextInt(0xffffff))); + g.fillRect(0, 0, rectWndBounds.width, rectWndBounds.height); + + g.setColor(new Color(rnd.nextInt(0xffffff))); + Rectangle rectStrBounds; + + g.setFont(f); + + rectStrBounds = g.getFontMetrics(). + getStringBounds(rectWndBounds.toString(), g).getBounds(); + rectStrBounds.height += 30; + g.drawString(rectWndBounds.toString(), 50, rectStrBounds.height); + int oldHeight = rectStrBounds.height; + String isFSupported = "Exclusive Fullscreen mode supported: " + + gc.getDevice().isFullScreenSupported(); + rectStrBounds = g.getFontMetrics(). + getStringBounds(isFSupported, g).getBounds(); + rectStrBounds.height += (10 + oldHeight); + g.drawString(isFSupported, 50, rectStrBounds.height); + + oldHeight = rectStrBounds.height; + String isDMChangeSupported = "Display Mode Change supported: " + + gc.getDevice().isDisplayChangeSupported(); + rectStrBounds = g.getFontMetrics(). + getStringBounds(isDMChangeSupported, g).getBounds(); + rectStrBounds.height += (10 + oldHeight); + g.drawString(isDMChangeSupported, 50, rectStrBounds.height); + + oldHeight = rectStrBounds.height; + String usingBS = "Using BufferStrategy: " + useBS; + rectStrBounds = g.getFontMetrics(). + getStringBounds(usingBS, g).getBounds(); + rectStrBounds.height += (10 + oldHeight); + g.drawString(usingBS, 50, rectStrBounds.height); + + final String m_strQuitMsg = "Double-click to dispose FullScreen Window"; + rectStrBounds = g.getFontMetrics(). + getStringBounds(m_strQuitMsg, g).getBounds(); + g.drawString(m_strQuitMsg, + (rectWndBounds.width - rectStrBounds.width) / 2, + (rectWndBounds.height - rectStrBounds.height) / 2); + + + } + + public void actionPerformed(ActionEvent ae) { + GraphicsDevice dev = deviceMap.get(ae.getSource()); + System.err.println("Setting FS on device:"+dev); + final Window fsWindow; + + if (useFSWindow) { + fsWindow = new Window(this, dev.getDefaultConfiguration()) { + public void paint(Graphics g) { + renderDimensions(g, getBounds(), + this.getGraphicsConfiguration()); + } + }; + } else if (useFSDialog) { + fsWindow = new Dialog((Frame)null, "FS Dialog on device "+dev, false, + dev.getDefaultConfiguration()); + fsWindow.add(new Component() { + public void paint(Graphics g) { + renderDimensions(g, getBounds(), + this.getGraphicsConfiguration()); + } + }); + } else { + fsWindow = new Frame("FS Frame on device "+dev, + dev.getDefaultConfiguration()) + { + public void paint(Graphics g) { + renderDimensions(g, getBounds(), + this.getGraphicsConfiguration()); + } + }; + if (addHWChildren) { + fsWindow.add("South", new Panel() { + public void paint(Graphics g) { + g.setColor(Color.red); + g.fillRect(0, 0, getWidth(), getHeight()); + } + }); + fsWindow.add("North", new Button("Button, sucka!")); + } + } + fsWindow.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() > 1) { + done = true; + fsWindow.dispose(); + } + } + }); + + fsWindow.addWindowListener(new WindowHandler()); + dev.setFullScreenWindow(fsWindow); + if (dmChange && dev.isDisplayChangeSupported()) { + DisplayMode dms[] = dev.getDisplayModes(); + DisplayMode myDM = null; + for (DisplayMode dm : dms) { + if (dm.getWidth() == 800 && dm.getHeight() == 600 && + (dm.getBitDepth() >= 16 || + dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI) && + (dm.getRefreshRate() >= 60 || + dm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)) + { + myDM = dm; + break; + } + } + if (myDM != null) { + System.err.println("Setting Display Mode: "+ + myDM.getWidth() + "x" + myDM.getHeight() + "x" + + myDM.getBitDepth() + "@" + myDM.getRefreshRate() + + "Hz on device" + dev); + dev.setDisplayMode(myDM); + } else { + System.err.println("Can't find suitable display mode."); + } + } + done = false; + if (runRenderLoop) { + Thread updateThread = new Thread(new Runnable() { + public void run() { + BufferStrategy bs = null; + if (useBS) { + fsWindow.createBufferStrategy(2); + bs = fsWindow.getBufferStrategy(); + } + while (!done) { + if (useBS) { + Graphics g = bs.getDrawGraphics(); + renderDimensions(g, fsWindow.getBounds(), + fsWindow.getGraphicsConfiguration()); + bs.show(); + } else { + fsWindow.repaint(); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + } + if (useBS) { + bs.dispose(); + } + } + }); + updateThread.start(); + } + } + + public static void main(String args[]) { + for (String s : args) { + if (s.equalsIgnoreCase("-dm")) { + System.err.println("Do Display Change after entering FS mode"); + dmChange = true; + } else if (s.equalsIgnoreCase("-usewindow")) { + System.err.println("Using Window to enter FS mode"); + useFSWindow = true; + } else if (s.equalsIgnoreCase("-setnull")) { + System.err.println("Setting null FS window on dispose"); + setNullOnDispose = true; + } else { + System.err.println("Usage: MultimonFullscreenTest " + + "[-dm][-usewindow][-setnull]"); + } + + } + MultimonFullscreenTest fs = + new MultimonFullscreenTest("Test Full Screen"); + } + class WindowHandler extends WindowAdapter { + public void windowClosing(WindowEvent we) { + done = true; + Window w = (Window)we.getSource(); + if (setNullOnDispose) { + w.getGraphicsConfiguration().getDevice().setFullScreenWindow(null); + } + w.dispose(); + } + } +} diff --git a/test/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java b/test/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java new file mode 100644 index 000000000..2e6ccdfb0 --- /dev/null +++ b/test/java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java @@ -0,0 +1,216 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6646411 + * @summary Tests that full screen window and its children receive resize + event when display mode changes + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm NoResizeEventOnDMChangeTest + * @run main/othervm -Dsun.java2d.d3d=false NoResizeEventOnDMChangeTest + */ + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.DisplayMode; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Window; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class NoResizeEventOnDMChangeTest { + public static void main(String[] args) { + final GraphicsDevice gd = GraphicsEnvironment. + getLocalGraphicsEnvironment().getDefaultScreenDevice(); + + if (!gd.isFullScreenSupported()) { + System.out.println("Full screen not supported, test passed"); + return; + } + + DisplayMode dm = gd.getDisplayMode(); + final DisplayMode dms[] = new DisplayMode[2]; + for (DisplayMode dm1 : gd.getDisplayModes()) { + if (dm1.getWidth() != dm.getWidth() || + dm1.getHeight() != dm.getHeight()) + { + dms[0] = dm1; + break; + } + } + if (dms[0] == null) { + System.out.println("Test Passed: all DMs have same dimensions"); + return; + } + dms[1] = dm; + + Frame f = new Frame() { + @Override + public void paint(Graphics g) { + g.setColor(Color.red); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.green); + g.drawRect(0, 0, getWidth()-1, getHeight()-1); + } + }; + f.setUndecorated(true); + testFSWindow(gd, dms, f); + + Window w = new Window(f) { + @Override + public void paint(Graphics g) { + g.setColor(Color.magenta); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.cyan); + g.drawRect(0, 0, getWidth()-1, getHeight()-1); + } + }; + testFSWindow(gd, dms, w); + System.out.println("Test Passed."); + } + + private static void testFSWindow(final GraphicsDevice gd, + final DisplayMode dms[], + final Window fsWin) + { + System.out.println("Testing FS window: "+fsWin); + Component c = new Canvas() { + @Override + public void paint(Graphics g) { + g.setColor(Color.blue); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.magenta); + g.drawRect(0, 0, getWidth()-1, getHeight()-1); + g.setColor(Color.red); + g.drawString("FS Window : " + fsWin, 50, 50); + DisplayMode dm = + getGraphicsConfiguration().getDevice().getDisplayMode(); + g.drawString("Display Mode: " + + dm.getWidth() + "x" + dm.getHeight(), 50, 75); + } + }; + fsWin.add("Center", c); + fsWin.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + fsWin.dispose(); + if (fsWin.getOwner() != null) { + fsWin.getOwner().dispose(); + } + } + }); + + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + gd.setFullScreenWindow(fsWin); + } + }); + } catch (Exception ex) {} + + sleep(1000); + + final ResizeEventChecker r1 = new ResizeEventChecker(); + final ResizeEventChecker r2 = new ResizeEventChecker(); + + if (gd.isDisplayChangeSupported()) { + fsWin.addComponentListener(r1); + c.addComponentListener(r2); + for (final DisplayMode dm1 : dms) { + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + System.err.printf("----------- Setting DM %dx%d:\n", + dm1.getWidth(), dm1.getHeight()); + try { + gd.setDisplayMode(dm1); + r1.incDmChanges(); + r2.incDmChanges(); + } catch (IllegalArgumentException iae) {} + } + }); + } catch (Exception ex) {} + for (int i = 0; i < 3; i++) { + fsWin.repaint(); + sleep(1000); + } + } + fsWin.removeComponentListener(r1); + c.removeComponentListener(r2); + } + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + gd.setFullScreenWindow(null); + fsWin.dispose(); + if (fsWin.getOwner() != null) { + fsWin.getOwner().dispose(); + } + } + }); + } catch (Exception ex) {} + + System.out.printf("FS Window: resizes=%d, dm changes=%d\n", + r1.getResizes(), r1.getDmChanges()); + System.out.printf("Component: resizes=%d, dm changes=%d\n", + r2.getResizes(), r2.getDmChanges()); + if (r1.getResizes() < r1.getDmChanges()) { + throw new RuntimeException("FS Window didn't receive all resizes!"); + } + if (r2.getResizes() < r2.getDmChanges()) { + throw new RuntimeException("Component didn't receive all resizes!"); + } + } + + static void sleep(long ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException ex) {} + } + static class ResizeEventChecker extends ComponentAdapter { + int dmChanges; + int resizes; + + @Override + public synchronized void componentResized(ComponentEvent e) { + System.out.println("Received resize event for "+e.getSource()); + resizes++; + } + public synchronized int getResizes() { + return resizes; + } + public synchronized void incDmChanges() { + dmChanges++; + } + public synchronized int getDmChanges() { + return dmChanges; + } + } +} diff --git a/test/java/awt/FullScreen/SetFSWindow/FSFrame.java b/test/java/awt/FullScreen/SetFSWindow/FSFrame.java new file mode 100644 index 000000000..c4d423114 --- /dev/null +++ b/test/java/awt/FullScreen/SetFSWindow/FSFrame.java @@ -0,0 +1,204 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6240507 6662642 + * @summary verify that isFullScreenSupported and getFullScreenWindow work + * correctly with and without a SecurityManager. Note that the test may fail + * on older Gnome versions (see bug 6500686). + * @run main FSFrame + * @run main/othervm -Dsun.java2d.noddraw=true FSFrame + * @author cheth + */ + +import java.awt.*; +import java.awt.image.*; +import java.applet.*; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import javax.imageio.ImageIO; + +public class FSFrame extends Frame implements Runnable { + + // Don't start the test until the window is visible + boolean visible = false; + Robot robot = null; + static volatile boolean done = false; + + public void paint(Graphics g) { + if (!visible && getWidth() != 0 && getHeight() != 0) { + visible = true; + try { + GraphicsDevice gd = getGraphicsConfiguration().getDevice(); + robot = new Robot(gd); + } catch (Exception e) { + System.out.println("Problem creating robot: cannot verify FS " + + "window display"); + } + } + g.setColor(Color.green); + g.fillRect(0, 0, getWidth(), getHeight()); + } + + @Override + public void update(Graphics g) { + paint(g); + } + + boolean checkColor(int x, int y, BufferedImage bImg) { + int pixelColor; + int correctColor = Color.green.getRGB(); + pixelColor = bImg.getRGB(x, y); + if (pixelColor != correctColor) { + System.out.println("FAILURE: pixelColor " + + Integer.toHexString(pixelColor) + + " != correctColor " + + Integer.toHexString(correctColor) + + " at coordinates (" + x + ", " + y + ")"); + return false; + } + return true; + } + + void checkFSDisplay(boolean fsSupported) { + GraphicsConfiguration gc = getGraphicsConfiguration(); + GraphicsDevice gd = gc.getDevice(); + Rectangle r = gc.getBounds(); + Insets in = null; + if (!fsSupported) { + in = Toolkit.getDefaultToolkit().getScreenInsets(gc); + r = new Rectangle(in.left, in.top, + r.width - (in.left + in.right), + r.height - (in.top + in.bottom)); + } + BufferedImage bImg = robot.createScreenCapture(r); + // Check that all four corners and middle pixel match the window's + // fill color + if (robot == null) { + return; + } + boolean colorCorrect = true; + colorCorrect &= checkColor(0, 0, bImg); + colorCorrect &= checkColor(0, bImg.getHeight() - 1, bImg); + colorCorrect &= checkColor(bImg.getWidth() - 1, 0, bImg); + colorCorrect &= checkColor(bImg.getWidth() - 1, bImg.getHeight() - 1, bImg); + colorCorrect &= checkColor(bImg.getWidth() / 2, bImg.getHeight() / 2, bImg); + if (!colorCorrect) { + System.err.println("Test failed for mode: fsSupported="+fsSupported); + if (in != null) { + System.err.println("screen insets : " + in); + } + System.err.println("screen shot rect: " + r); + String name = "FSFrame_fs_"+ + (fsSupported?"supported":"not_supported")+".png"; + try { + ImageIO.write(bImg, "png", new File(name)); + System.out.println("Dumped screen shot to "+name); + } catch (IOException ex) {} + throw new Error("Some pixel colors not correct; FS window may not" + + " have been displayed correctly"); + } + } + + void checkFSFunctionality(boolean withSecurity) { + GraphicsDevice gd = getGraphicsConfiguration().getDevice(); + if (withSecurity) { + SecurityManager sm = new SecurityManager(); + System.setSecurityManager(sm); + } + try { + // None of these should throw an exception + final boolean fs = gd.isFullScreenSupported(); + System.out.println("FullscreenSupported: " + (fs ? "yes" : "no")); + gd.setFullScreenWindow(this); + try { + // Give the system time to set the FS window and display it + // properly + Thread.sleep(2000); + } catch (Exception e) {} + if (!withSecurity) { + // See if FS window got displayed correctly + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + repaint(); + checkFSDisplay(fs); + } + }); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + // reset window + gd.setFullScreenWindow(null); + try { + // Give the system time to set the FS window and display it + // properly + Thread.sleep(2000); + } catch (Exception e) {} + } catch (SecurityException e) { + e.printStackTrace(); + throw new Error("Failure: should not get an exception when " + + "calling isFSSupported or setFSWindow"); + } + } + + public void run() { + boolean firstTime = true; + while (!done) { + if (visible) { + checkFSFunctionality(false); + checkFSFunctionality(true); + done = true; + } else { + // sleep while we wait + try { + // Give the system time to set the FS window and display it + // properly + Thread.sleep(100); + } catch (Exception e) {} + } + } + System.out.println("PASS"); + } + + public static void main(String args[]) { + FSFrame frame = new FSFrame(); + frame.setUndecorated(true); + Thread t = new Thread(frame); + frame.setSize(500, 500); + frame.setVisible(true); + t.start(); + while (!done) { + try { + // Do not exit the main thread until the test is finished + Thread.sleep(1000); + } catch (Exception e) {} + } + frame.dispose(); + } +} diff --git a/test/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java b/test/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java new file mode 100644 index 000000000..a3062bcef --- /dev/null +++ b/test/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java @@ -0,0 +1,168 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/** + * @test + * @bug 6614214 + * @summary Verifies that we enter the fs mode on the correct screen. + * Here is how to test: start the test on on a multi-screen system. + * Verify that the display is correctly tracked by dragging the frame back + * and forth between screens. Then verify that the correct device enters + * the full-screen mode - when "Enter FS mode" is pressed it should enter on + * the device where the frame is. + * + * Then change the order of the monitors in the DisplayProperties dialog, + * (while the app is running) and see that it still works. + * Restart the app, verify again. + * + * Now change the primary monitor on the system and verify with the + * app running, as well as after restarting it that we still enter the + * fs mode on the right device. + * + * @run main/manual/othervm DeviceIdentificationTest + * @run main/manual/othervm -Dsun.java2d.noddraw=true DeviceIdentificationTest + * @run main/manual/othervm -Dsun.java2d.opengl=True DeviceIdentificationTest + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class DeviceIdentificationTest { + + public static void main(String args[]) { + final Frame f = new Frame("DeviceIdentificationTest"); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + f.dispose(); + } + }); + f.addComponentListener(new ComponentAdapter() { + public void componentMoved(ComponentEvent e) { + f.setTitle("Currently on: "+ + f.getGraphicsConfiguration().getDevice()); + } + }); + + Panel p = new Panel(); + Button b = new Button("Print Current Devices"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + GraphicsDevice gds[] = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getScreenDevices(); + int i = 0; + System.err.println("--- Devices: ---"); + for (GraphicsDevice gd : gds) { + System.err.println("Device["+i+"]= "+ gd); + System.err.println(" bounds = "+ + gd.getDefaultConfiguration().getBounds()); + i++; + } + System.err.println("-------------------"); + } + }); + p.add(b); + + b = new Button("Print My Device"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + GraphicsConfiguration gc = f.getGraphicsConfiguration(); + GraphicsDevice gd = gc.getDevice(); + System.err.println("--- My Device ---"); + System.err.println("Device = "+ gd); + System.err.println(" bounds = "+ + gd.getDefaultConfiguration().getBounds()); + } + }); + p.add(b); + + b = new Button("Create FS Frame on my Device"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + GraphicsConfiguration gc = f.getGraphicsConfiguration(); + final GraphicsDevice gd = gc.getDevice(); + System.err.println("--- Creating FS Frame on Device ---"); + System.err.println("Device = "+ gd); + System.err.println(" bounds = "+ + gd.getDefaultConfiguration().getBounds()); + final Frame fsf = new Frame("Full-screen Frame on dev"+gd, gc) { + public void paint(Graphics g) { + g.setColor(Color.green); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(Color.red); + g.drawString("FS on device: "+gd, 200, 200); + g.drawString("Click to exit Full-screen.", 200, 250); + } + }; + fsf.setUndecorated(true); + fsf.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + gd.setFullScreenWindow(null); + fsf.dispose(); + } + }); + gd.setFullScreenWindow(fsf); + } + }); + p.add(b); + f.add("North", p); + + p = new Panel(); + b = new Button("Test Passed"); + b.setBackground(Color.green); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("Test Passed"); + f.dispose(); + } + }); + p.add(b); + b = new Button("Test Failed"); + b.setBackground(Color.red); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("Test FAILED"); + f.dispose(); + throw new RuntimeException("Test FAILED"); + } + }); + p.add(b); + f.add("South", p); + + f.pack(); + f.setVisible(true); + } +} diff --git a/test/java/awt/font/TextLayout/VisibleAdvance.java b/test/java/awt/font/TextLayout/VisibleAdvance.java index 446d16dba..224b23861 100644 --- a/test/java/awt/font/TextLayout/VisibleAdvance.java +++ b/test/java/awt/font/TextLayout/VisibleAdvance.java @@ -1,3 +1,27 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + import java.awt.*; import java.awt.font.*; import java.awt.geom.*; diff --git a/test/java/awt/image/MemoryLeakTest/MemoryLeakTest.java b/test/java/awt/image/MemoryLeakTest/MemoryLeakTest.java new file mode 100644 index 000000000..ace1bb497 --- /dev/null +++ b/test/java/awt/image/MemoryLeakTest/MemoryLeakTest.java @@ -0,0 +1,175 @@ +/* + * Copyright 1998-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 4078566 6658398 + @summary Test for a memory leak in Image. + @run main/manual MemoryLeakTest +*/ + +import java.applet.Applet; +import java.lang.*; +import java.awt.*; +import java.awt.event.*; + +class Globals { + static boolean testPassed=false; + static Thread mainThread=null; +} + +public class MemoryLeakTest extends Applet { + +public static void main(String args[]) throws Exception { + new TestDialog(new Frame(), "MemoryLeakTest").start(); + new MemoryLeak().start(); + Globals.mainThread = Thread.currentThread(); + try { + Thread.sleep(300000); + } catch (InterruptedException e) { + if (!Globals.testPassed) + throw new Exception("MemoryLeakTest failed."); + } +} + +} + +class TestDialog extends Dialog + implements ActionListener { + +TextArea output; +Button passButton; +Button failButton; +String name; + +public TestDialog(Frame frame, String name) +{ + super(frame, name + " Pass/Fail Dialog"); + this.name = name; + output = new TextArea(11, 50); + add("North", output); + output.append("Do the following steps on Solaris only.\n"); + output.append("Maximize and minimize the Memory Leak Test window.\n"); + output.append("Execute the following after minimize.\n"); + output.append(" ps -al | egrep -i 'java|PPID'\n"); + output.append("Examine the size of the process under SZ.\n"); + output.append("Maximize and minimize the Memory Leak Test window again.\n"); + output.append("Execute the following after minimize.\n"); + output.append(" ps -al | egrep -i 'java|PPID'\n"); + output.append("Examine the size of the process under SZ.\n"); + output.append("If the two SZ values are the same, plus or minus one,\n"); + output.append("then click Pass, else click Fail."); + Panel buttonPanel = new Panel(); + passButton = new Button("Pass"); + failButton = new Button("Fail"); + passButton.addActionListener(this); + failButton.addActionListener(this); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + add("South", buttonPanel); + pack(); +} + +public void start() +{ + show(); +} + +public void actionPerformed(ActionEvent event) +{ + if ( event.getSource() == passButton ) { + Globals.testPassed = true; + System.err.println(name + " Passed."); + } + else if ( event.getSource() == failButton ) { + Globals.testPassed = false; + System.err.println(name + " Failed."); + } + this.dispose(); + if (Globals.mainThread != null) + Globals.mainThread.interrupt(); +} + +} + + +class MemoryLeak extends Frame implements ComponentListener +{ +private Image osImage; + +public MemoryLeak() +{ + super("Memory Leak Test"); + setSize(200, 200); + addComponentListener(this); +} + +public static void main(String args[]) +{ + new MemoryLeak().start(); +} + +public void start() +{ + show(); +} + +public void paint(Graphics g) { + if (osImage != null) { + g.drawImage(osImage, 0, 0, this); + } +} + +public void update(Graphics g) +{ + paint(g); +} + +public void componentResized(ComponentEvent e) +{ + Image oldimage = osImage; + osImage = createImage(getSize().width, getSize().height); + Graphics g = osImage.getGraphics(); + if (oldimage != null) { + g.drawImage(oldimage, 0, 0, getSize().width, getSize().height, this); + oldimage.flush(); + } else { + g.setColor(Color.blue); + g.drawLine(0, 0, getSize().width, getSize().height); + } + g.dispose(); +} + +public void componentMoved(ComponentEvent e) {} + +public void componentShown(ComponentEvent e) +{ + osImage = createImage(getSize().width, getSize().height); + Graphics g = osImage.getGraphics(); + g.setColor(Color.blue); + g.drawLine(0, 0, getSize().width, getSize().height); + g.dispose(); +} + +public void componentHidden(ComponentEvent e) {} + +} diff --git a/test/java/awt/print/PrinterJob/PrintAWTImage.java b/test/java/awt/print/PrinterJob/PrintAWTImage.java new file mode 100644 index 000000000..0cb3b4eb8 --- /dev/null +++ b/test/java/awt/print/PrinterJob/PrintAWTImage.java @@ -0,0 +1,90 @@ +/* + * Copyright 1999-2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/** + * @test + * @bug 4257262 6708509 + * @summary Image should be sent to printer. +* @run main/manual PrintAWTImage + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.print.*; + + +public class PrintAWTImage extends Frame + implements ActionListener, Printable { + + public Image imgJava; + + + public static void main(String args[]) { + PrintAWTImage f = new PrintAWTImage(); + f.show(); + } + + public PrintAWTImage() { + + Button printButton = new Button("Print"); + setLayout(new FlowLayout()); + add(printButton); + printButton.addActionListener(this); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + pack(); + } + + public void actionPerformed(ActionEvent e) { + + PrinterJob pj = PrinterJob.getPrinterJob(); + + if (pj != null && pj.printDialog()) { + pj.setPrintable(this); + try { + pj.print(); + } catch (PrinterException pe) { + } finally { + System.err.println("PRINT RETURNED"); + } + } + } + + + public int print(Graphics g, PageFormat pgFmt, int pgIndex) { + if (pgIndex > 0) + return Printable.NO_SUCH_PAGE; + + Graphics2D g2d = (Graphics2D)g; + g2d.translate(pgFmt.getImageableX(), pgFmt.getImageableY()); + Image imgJava = Toolkit.getDefaultToolkit().getImage("duke.gif"); + g2d.drawImage(imgJava, 0, 0, this); + + return Printable.PAGE_EXISTS; + } + +} diff --git a/test/java/awt/print/PrinterJob/duke.gif b/test/java/awt/print/PrinterJob/duke.gif Binary files differnew file mode 100644 index 000000000..ed32e0ff7 --- /dev/null +++ b/test/java/awt/print/PrinterJob/duke.gif diff --git a/test/sun/java2d/DirectX/AccelPaintsTest/AccelPaintsTest.java b/test/sun/java2d/DirectX/AccelPaintsTest/AccelPaintsTest.java new file mode 100644 index 000000000..f58ee5a9e --- /dev/null +++ b/test/sun/java2d/DirectX/AccelPaintsTest/AccelPaintsTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6659345 + * @summary Tests that various paints work correctly when preceeded by a + * textured operaiton. + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm AccelPaintsTest + * @run main/othervm -Dsun.java2d.opengl=True AccelPaintsTest + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.LinearGradientPaint; +import java.awt.MultipleGradientPaint.CycleMethod; +import java.awt.Paint; +import java.awt.RadialGradientPaint; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.TexturePaint; +import java.awt.Transparency; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class AccelPaintsTest extends JPanel { + BufferedImage bi = + new BufferedImage(80, 100, BufferedImage.TYPE_INT_ARGB_PRE); + + RadialGradientPaint rgp = + new RadialGradientPaint(100, 100, 100, new float[] {0f, 0.2f, 0.6f, 1f}, + new Color[] { Color.red, + Color.yellow, + Color.blue, + Color.green}, + CycleMethod.REFLECT); + LinearGradientPaint lgp = + new LinearGradientPaint(30, 30, 120, 130, new float[] {0f, 0.2f, 0.6f, 1f}, + new Color[] {Color.red, + Color.yellow, + Color.blue, + Color.green}); + GradientPaint gp = + new GradientPaint(30, 30, Color.red, 120, 130, Color.yellow, true); + + TexturePaint tp = + new TexturePaint(bi, new Rectangle2D.Float(30, 30, 120, 130)); + + + public AccelPaintsTest() { + Graphics g = bi.getGraphics(); + g.setColor(Color.blue); + g.fillRect(0, 0, bi.getWidth(), bi.getHeight()); + + setPreferredSize(new Dimension(250, 4*120)); + } + + private void renderWithPaint(Graphics2D g2d, Paint p) { + g2d.drawImage(bi, 130, 30, null); + + g2d.setPaint(p); + g2d.fillRect(30, 30, 80, 100); + } + + private void render(Graphics2D g2d) { + renderWithPaint(g2d, rgp); + g2d.translate(0, 100); + + renderWithPaint(g2d, lgp); + g2d.translate(0, 100); + + renderWithPaint(g2d, gp); + g2d.translate(0, 100); + + renderWithPaint(g2d, tp); + g2d.translate(0, 100); + } + + private void test() { + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + if (gc.getColorModel().getPixelSize() < 16) { + System.out.println("<16 bit depth detected, test passed"); + return; + } + + VolatileImage vi = + gc.createCompatibleVolatileImage(250, 4*120, Transparency.OPAQUE); + BufferedImage res; + do { + vi.validate(gc); + Graphics2D g2d = vi.createGraphics(); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, vi.getWidth(), vi.getHeight()); + + render(g2d); + + res = vi.getSnapshot(); + } while (vi.contentsLost()); + + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getWidth(); x++) { + if (res.getRGB(x, y) == Color.black.getRGB()) { + System.err.printf("Test FAILED: found black at %d,%d\n", + x, y); + try { + String fileName = "AccelPaintsTest.png"; + ImageIO.write(res, "png", new File(fileName)); + System.err.println("Dumped rendering to " + fileName); + } catch (IOException e) {} + throw new RuntimeException("Test FAILED: found black"); + } + } + } + } + + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D)g; + + render(g2d); + } + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException + { + + if (args.length > 0 && args[0].equals("-show")) { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + JFrame f = new JFrame("RadialGradientTest"); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + AccelPaintsTest t = new AccelPaintsTest(); + f.add(t); + f.pack(); + f.setVisible(true); + } + }); + } else { + AccelPaintsTest t = new AccelPaintsTest(); + t.test(); + System.out.println("Test Passed."); + } + } +} diff --git a/test/sun/java2d/DirectX/AcceleratedScaleTest/AcceleratedScaleTest.java b/test/sun/java2d/DirectX/AcceleratedScaleTest/AcceleratedScaleTest.java new file mode 100644 index 000000000..654d03ed7 --- /dev/null +++ b/test/sun/java2d/DirectX/AcceleratedScaleTest/AcceleratedScaleTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2006-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/** + * @test + * @bug 6429665 + * @bug 6588884 + * @summary Tests that the transform is correctly handled + * @author Dmitri.Trembovetski area=Graphics + * @run main AcceleratedScaleTest + * @run main/othervm -Dsun.java2d.d3d=true AcceleratedScaleTest + * @run main/othervm -Dsun.java2d.opengl=true AcceleratedScaleTest + */ +public class AcceleratedScaleTest { + private static final int IMAGE_SIZE = 200; + private static VolatileImage destVI; + + private static void initVI(GraphicsConfiguration gc) { + int res; + if (destVI == null) { + res = VolatileImage.IMAGE_INCOMPATIBLE; + } else { + res = destVI.validate(gc); + } + if (res == VolatileImage.IMAGE_INCOMPATIBLE) { + if (destVI != null) destVI.flush(); + destVI = gc.createCompatibleVolatileImage(IMAGE_SIZE, IMAGE_SIZE); + destVI.validate(gc); + res = VolatileImage.IMAGE_RESTORED; + } + if (res == VolatileImage.IMAGE_RESTORED) { + Graphics vig = destVI.getGraphics(); + vig.setColor(Color.red); + vig.fillRect(0, 0, destVI.getWidth(), destVI.getHeight()); + vig.dispose(); + } + } + + public static void main(String[] args) { + Frame f = new Frame(); + f.pack(); + GraphicsConfiguration gc = f.getGraphicsConfiguration(); + if (gc.getColorModel().getPixelSize() < 16) { + System.out.printf("Bit depth: %d . Test considered passed.", + gc.getColorModel().getPixelSize()); + f.dispose(); + return; + } + + BufferedImage bi = + new BufferedImage(IMAGE_SIZE/4, IMAGE_SIZE/4, + BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D)bi.getGraphics(); + g.setColor(Color.red); + g.fillRect(0, 0, bi.getWidth(), bi.getHeight()); + BufferedImage snapshot; + do { + initVI(gc); + g = (Graphics2D)destVI.getGraphics(); + // "accelerate" BufferedImage + for (int i = 0; i < 5; i++) { + g.drawImage(bi, 0, 0, null); + } + g.setColor(Color.white); + g.fillRect(0, 0, destVI.getWidth(), destVI.getHeight()); + + // this will force the use of Transform primitive instead of + // Scale (the latter doesn't do bilinear filtering required by + // VALUE_RENDER_QUALITY, which triggers the bug in D3D pipeline + g.setRenderingHint(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + g.drawImage(bi, 0, 0, destVI.getWidth(), destVI.getHeight(), null); + g.fillRect(0, 0, destVI.getWidth(), destVI.getHeight()); + + g.drawImage(bi, 0, 0, destVI.getWidth(), destVI.getHeight(), null); + + snapshot = destVI.getSnapshot(); + } while (destVI.contentsLost()); + + f.dispose(); + int whitePixel = Color.white.getRGB(); + for (int y = 0; y < snapshot.getHeight(); y++) { + for (int x = 0; x < snapshot.getWidth(); x++) { + if (snapshot.getRGB(x, y) == whitePixel) { + System.out.printf("Found untouched pixel at %dx%d\n", x, y); + System.out.println("Dumping the dest. image to " + + "AcceleratedScaleTest_dst.png"); + try { + ImageIO.write(snapshot, "png", + new File("AcceleratedScaleTest_dst.png")); + } catch (IOException ex) { + ex.printStackTrace(); + } + throw new RuntimeException("Test failed."); + } + } + } + System.out.println("Test Passed."); + } + +} diff --git a/test/sun/java2d/DirectX/IAEforEmptyFrameTest/IAEforEmptyFrameTest.java b/test/sun/java2d/DirectX/IAEforEmptyFrameTest/IAEforEmptyFrameTest.java new file mode 100644 index 000000000..ffe9eb2de --- /dev/null +++ b/test/sun/java2d/DirectX/IAEforEmptyFrameTest/IAEforEmptyFrameTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6668439 + * @summary Verifies that no exceptions are thrown when frame is resized to 0x0 + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm IAEforEmptyFrameTest + * @run main/othervm -Dsun.java2d.d3d=false IAEforEmptyFrameTest + */ +import javax.swing.JFrame; + +public class IAEforEmptyFrameTest { + public static void main(String[] args) { + JFrame f = null; + try { + f = new JFrame("IAEforEmptyFrameTest"); + f.setUndecorated(true); + f.setBounds(100, 100, 320, 240); + f.setVisible(true); + try { Thread.sleep(1000); } catch (Exception z) {} + f.setBounds(0, 0, 0, 0); + try { Thread.sleep(1000); } catch (Exception z) {} + f.dispose(); + } finally { + f.dispose(); + }; + } +} diff --git a/test/sun/java2d/DirectX/InfiniteValidationLoopTest/InfiniteValidationLoopTest.java b/test/sun/java2d/DirectX/InfiniteValidationLoopTest/InfiniteValidationLoopTest.java new file mode 100644 index 000000000..a520a3880 --- /dev/null +++ b/test/sun/java2d/DirectX/InfiniteValidationLoopTest/InfiniteValidationLoopTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6648018 + * @summary Tests that we don't run into infinite validation loop when copying + a VolatileImage to the screen + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm InfiniteValidationLoopTest + * @run main/othervm -Dsun.java2d.d3d=false InfiniteValidationLoopTest + */ +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import static java.awt.image.VolatileImage.*; +import java.awt.image.VolatileImage; +import java.util.concurrent.CountDownLatch; + +public class InfiniteValidationLoopTest extends Frame { + private static volatile boolean failed = false; + private static final int LOOP_THRESHOLD = 50; + private static volatile CountDownLatch latch; + private VolatileImage vi; + + public InfiniteValidationLoopTest() { + super("InfiniteValidationLoopTest"); + } + + @Override + public void paint(Graphics g) { + try { + runTest(g); + } finally { + latch.countDown(); + } + } + + private void runTest(Graphics g) { + int status = IMAGE_OK; + int count1 = 0; + do { + GraphicsConfiguration gc = getGraphicsConfiguration(); + int count2 = 0; + while (vi == null || (status = vi.validate(gc)) != IMAGE_OK) { + if (++count2 > LOOP_THRESHOLD) { + System.err.println("Infinite loop detected: count2="+count2); + failed = true; + return; + } + if (vi == null || status == IMAGE_INCOMPATIBLE) { + if (vi != null) { vi.flush(); vi = null; } + vi = gc.createCompatibleVolatileImage(100, 100); + continue; + } + if (status == IMAGE_RESTORED) { + Graphics gg = vi.getGraphics(); + gg.setColor(Color.green); + gg.fillRect(0, 0, vi.getWidth(), vi.getHeight()); + break; + } + } + g.drawImage(vi, getInsets().left, getInsets().top, null); + if (++count1 > LOOP_THRESHOLD) { + System.err.println("Infinite loop detected: count1="+count1); + failed = true; + return; + } + } while (vi.contentsLost()); + } + + public static void main(String[] args) { + latch = new CountDownLatch(1); + InfiniteValidationLoopTest t1 = new InfiniteValidationLoopTest(); + t1.pack(); + t1.setSize(200, 200); + t1.setVisible(true); + try { latch.await(); } catch (InterruptedException ex) {} + t1.dispose(); + + latch = new CountDownLatch(1); + t1 = new InfiniteValidationLoopTest(); + t1.pack(); + t1.setSize(50, 50); + t1.setVisible(true); + try { latch.await(); } catch (InterruptedException ex) {} + t1.dispose(); + + if (failed) { + throw new + RuntimeException("Failed: infinite validattion loop detected"); + } + System.out.println("Test PASSED"); + } +} diff --git a/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java b/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java new file mode 100644 index 000000000..65439f909 --- /dev/null +++ b/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java @@ -0,0 +1,209 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6664068 6666931 + * @summary Tests that resizing a window to which a tight loop is rendering + * doesn't produce artifacts or crashes + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm OnScreenRenderingResizeTest + * @run main/othervm -Dsun.java2d.d3d=false OnScreenRenderingResizeTest + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class OnScreenRenderingResizeTest { + + private static volatile boolean done = false; + private static volatile boolean nocheck = false; + + private static final int FRAME_W = 256; + private static final int FRAME_H = 256; + private static final int IMAGE_W = 128; + private static final int IMAGE_H = 128; + private static long RUN_TIME = 1000*20; + + private static final Color renderColor = Color.green; + private static final Color bgColor = Color.white; + + public static void main(String[] args) { + + for (String arg : args) { + if ("-inf".equals(arg)) { + System.err.println("Test will run indefinitely"); + RUN_TIME = Long.MAX_VALUE; + } else if ("-nocheck".equals(arg)) { + System.err.println("Test will not check rendering results"); + nocheck = true; + } else { + System.err.println("Usage: OnScreenRenderingResizeTest [-inf][-nocheck]"); + } + } + + BufferedImage output = + new BufferedImage(IMAGE_W, IMAGE_H, BufferedImage.TYPE_INT_RGB); + output.setAccelerationPriority(0.0f); + Graphics g = output.getGraphics(); + g.setColor(renderColor); + g.fillRect(0, 0, output.getWidth(), output.getHeight()); + + final Frame frame = new Frame("OnScreenRenderingResizeTest") { + public void paint(Graphics g) {} + public void update(Graphics g) {} + }; + frame.setBackground(bgColor); + frame.pack(); + frame.setSize(FRAME_W, FRAME_H); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + done = true; + } + }); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + frame.setVisible(true); + } + }); + // wait for Vista's effects to complete + Thread.sleep(2000); + } catch (Exception ex) { + ex.printStackTrace(); + } + + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + int maxW = gc.getBounds().width /2; + int maxH = gc.getBounds().height/2; + int minW = frame.getWidth(); + int minH = frame.getHeight(); + int incW = 10, incH = 10, cnt = 0; + Robot robot = null; + if (!nocheck && gc.getColorModel().getPixelSize() > 8) { + try { + robot = new Robot(); + } catch (AWTException ex) { + System.err.println("Robot creation failed, continuing."); + } + } else { + System.err.println("No screen rendering checks."); + } + + VolatileImage vi = gc.createCompatibleVolatileImage(512, 512); + vi.validate(gc); + + long timeStarted = System.currentTimeMillis(); + while (!done && (System.currentTimeMillis() - timeStarted) < RUN_TIME) { + + if (++cnt > 100) { + int w = frame.getWidth() + incW; + int h = frame.getHeight() + incH; + if (w < minW || w > maxW ) { + incW = -incW; + } + if (h < minH || h > maxH ) { + incH = -incH; + } + frame.setSize(w, h); + cnt = 0; + } + + // try to put the device into non-default state, for example, + // this operation below will set the transform + vi.validate(gc); + Graphics2D vig = (Graphics2D)vi.getGraphics(); + vig.rotate(30.0f, vi.getWidth()/2, vi.getHeight()/2); + vig.drawImage(output, 0, 0, + vi.getWidth(), vi.getHeight(), null); + + Insets in = frame.getInsets(); + frame.getGraphics().drawImage(output, in.left, in.top, null); + if (cnt == 90 && robot != null) { + // area where we blitted to should be either white or green + Point p = frame.getLocationOnScreen(); + p.move(in.left+10, in.top+10); + BufferedImage bi = + robot.createScreenCapture( + new Rectangle(p.x, p.y, IMAGE_W/2, IMAGE_H/2)); + int accepted1[] = { Color.white.getRGB(), Color.green.getRGB()}; + checkBI(bi, accepted1); + + // the are where we didn't render should stay white + p = frame.getLocationOnScreen(); + p.move(in.left, in.top+IMAGE_H+5); + bi = robot.createScreenCapture( + new Rectangle(p.x, p.y, + frame.getWidth()-in.left-in.right, + frame.getHeight()-in.top-in.bottom-5-IMAGE_H)); + int accepted2[] = { Color.white.getRGB() }; + checkBI(bi, accepted1); + } + + Thread.yield(); + } + frame.dispose(); + System.out.println("Test Passed"); + } + + private static void checkBI(BufferedImage bi, int accepted[]) { + for (int x = 0; x < bi.getWidth(); x++) { + for (int y = 0; y < bi.getHeight(); y++) { + int pix = bi.getRGB(x, y); + boolean found = false; + for (int acc : accepted) { + if (pix == acc) { + found = true; + break; + } + } + if (!found) { + try { + String name = "OnScreenRenderingResizeTest.png"; + ImageIO.write(bi, "png", new File(name)); + System.out.println("Screen shot file: " + name); + } catch (IOException ex) {} + + throw new + RuntimeException("Test failed at " + x + "-" + y + + " rgb=0x" + Integer.toHexString(pix)); + } + } + } + } +} diff --git a/test/sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java b/test/sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java new file mode 100644 index 000000000..658f42ac9 --- /dev/null +++ b/test/sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java @@ -0,0 +1,150 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6694230 + * @summary Tests that components overriding getInsets paint correctly + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm OverriddenInsetsTest + * @run main/othervm -Dsun.java2d.opengl=True OverriddenInsetsTest + */ + +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Insets; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import javax.imageio.ImageIO; + +public class OverriddenInsetsTest { + + public static final Insets INSETS1 = new Insets(25,25,0,0); + public static final Insets INSETS2 = new Insets(100,100,0,0); + static final CountDownLatch lock = new CountDownLatch(1); + static boolean failed = false; + + public static void main(String[] args) { + + if (GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(). + getColorModel().getPixelSize() < 16) + { + System.out.println("<16 bit mode detected, test passed"); + } + + final Frame f = new Frame("OverriddenInsetsTest"); + f.setSize(260,260); + + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + f.setVisible(false); + System.exit(0); + } + }); + + f.setBackground(Color.gray); + Panel p1 = new Panel() { + public Insets getInsets() { + return INSETS1; + } + }; + p1.setLayout(null); + p1.setSize(250, 250); + + Panel p = new Panel(){ + @Override + public Insets getInsets() { + return INSETS2; + } + + public void paint(Graphics g) { + // make sure Vista is done with its effects + try { + Thread.sleep(2000); + } catch (InterruptedException ex) {} + g.setColor(Color.red); + g.drawRect(0,0,getWidth()-1,getHeight()-1 ); + g.setColor(Color.blue); + g.fillRect(0,0,getWidth()/2,getHeight()/2); + + Point p = getLocationOnScreen(); + try { + Robot r = new Robot(); + BufferedImage bi = + r.createScreenCapture(new + Rectangle(p.x, p.y, getWidth()/2, getHeight()/2)); + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getWidth(); x++) { + if (bi.getRGB(x, y) != Color.blue.getRGB()) { + failed = true; + System.err.printf("Test failed at %d %d c=%x\n", + x, y, bi.getRGB(x, y)); + String name = "OverriddenInsetsTest_res.png"; + try { + ImageIO.write(bi, "png", new File(name)); + System.out.println("Dumped res to: "+name); + } catch (IOException e) {} + return; + } + } + } + } catch (Exception e) { + failed = true; + } finally { + lock.countDown(); + } + } + }; + p.setSize(200, 200); + + p1.add(p); + p.setLocation(50, 50); + f.add(p1); + f.setVisible(true); + + try { + lock.await(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + if (args.length <= 0 || !"-show".equals(args[0])) { + f.dispose(); + } + + if (failed) { + throw new RuntimeException("Test FAILED."); + } + System.out.println("Test PASSED"); + } +} diff --git a/test/sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java b/test/sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java new file mode 100644 index 000000000..e5f44ab0d --- /dev/null +++ b/test/sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6648018 6652662 + * @summary Verifies that rendering to a cached onscreen Graphics works + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm RenderingToCachedGraphicsTest + * @run main/othervm -Dsun.java2d.d3d=false RenderingToCachedGraphicsTest + */ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferStrategy; +import java.awt.image.BufferedImage; +import static java.awt.image.VolatileImage.*; +import java.awt.image.VolatileImage; +import java.io.File; +import java.util.concurrent.CountDownLatch; +import javax.imageio.ImageIO; + +public class RenderingToCachedGraphicsTest extends Frame { + private static volatile boolean failed = false; + private static volatile CountDownLatch latch; + private Graphics cachedGraphics; + private Canvas renderCanvas; + + public RenderingToCachedGraphicsTest() { + super("Test starts in 2 seconds"); + renderCanvas = new Canvas() { + @Override + public void paint(Graphics g) { + if (getWidth() < 100 || getHeight() < 100) { + repaint(); + return; + } + // wait for a bit so that Vista's Window manager's animation + // effects on window's appearance are completed (6652662) + try { Thread.sleep(2000); } catch (InterruptedException ex) {} + + try { + runTest(); + } catch (Throwable t) { + failed = true; + } finally { + latch.countDown(); + } + } + @Override + public void update(Graphics g) {} + }; + + add("Center", renderCanvas); + } + + private void runTest() { + // this will cause screen update manager to dump the accelerated surface + // for this canvas + renderCanvas.createBufferStrategy(2); + BufferStrategy bs = renderCanvas.getBufferStrategy(); + do { + Graphics bsg = bs.getDrawGraphics(); + bsg.setColor(Color.blue); + bsg.fillRect(0, 0, + renderCanvas.getWidth(), renderCanvas.getHeight()); + } while (bs.contentsLost() || bs.contentsRestored()); + + // grab the "unaccelerated" onscreen surface + cachedGraphics = renderCanvas.getGraphics(); + cachedGraphics.setColor(Color.red); + cachedGraphics.fillRect(0, 0, getWidth(), getHeight()); + + bs.dispose(); + bs = null; + // now the update manager should be able to accelerate onscreen + // rendering to it again + + cachedGraphics.setColor(Color.green); + // this causes restoration of the new accelerated onscreen surface + // (it is created in "lost" state) + cachedGraphics.fillRect(0, 0, + renderCanvas.getWidth(), + renderCanvas.getHeight()); + Toolkit.getDefaultToolkit().sync(); + // and now we should be able to render to it + cachedGraphics.fillRect(0, 0, + renderCanvas.getWidth(), + renderCanvas.getHeight()); + Toolkit.getDefaultToolkit().sync(); + + Robot robot = null; + try { + robot = new Robot(); + } catch (Exception e) { + e.printStackTrace(); + failed = true; + return; + } + + Point p = renderCanvas.getLocationOnScreen(); + Rectangle r = new Rectangle(p.x, p.y, + renderCanvas.getWidth(), + renderCanvas.getHeight()); + BufferedImage bi = robot.createScreenCapture(r); + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getWidth(); x++) { + if (bi.getRGB(x, y) != Color.green.getRGB()) { + System.err.println("Colors mismatch!"); + String name = "RenderingToCachedGraphicsTest.png"; + try { + ImageIO.write(bi, "png", new File(name)); + System.err.println("Dumped grabbed image to: "+name); + } catch (Exception e) {} + failed = true; + return; + } + } + } + } + + public static void main(String[] args) { + int depth = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(). + getColorModel().getPixelSize(); + if (depth < 16) { + System.out.println("Test PASSED (depth < 16bit)"); + return; + } + + latch = new CountDownLatch(1); + RenderingToCachedGraphicsTest t1 = new RenderingToCachedGraphicsTest(); + t1.pack(); + t1.setSize(300, 300); + t1.setVisible(true); + + try { latch.await(); } catch (InterruptedException ex) {} + t1.dispose(); + + if (failed) { + throw new + RuntimeException("Failed: rendering didn't show up"); + } + System.out.println("Test PASSED"); + } +} diff --git a/test/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java b/test/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java new file mode 100644 index 000000000..6d0e07941 --- /dev/null +++ b/test/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6705443 + * @summary tests that we don't crash during exit if font strikes were disposed + * during the lifetime of the application + * + * @run main/othervm -Dsun.java2d.font.reftype=weak StrikeDisposalCrashTest + * @run main/othervm -Dsun.java2d.font.reftype=weak -Dsun.java2d.noddraw=true StrikeDisposalCrashTest + * @run main/othervm -Dsun.java2d.font.reftype=weak -Dsun.java2d.opengl=True StrikeDisposalCrashTest + */ + +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.awt.Toolkit; +import java.awt.image.VolatileImage; + +public class StrikeDisposalCrashTest { + + public static void main(String[] args) { + System.setProperty("sun.java2d.font.reftype", "weak"); + + GraphicsDevice gd[] = + GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); + + Frame frames[] = new Frame[gd.length]; + for (int i = 0; i < frames.length; i++) { + GraphicsConfiguration gc = gd[i].getDefaultConfiguration(); + Frame f = new Frame("Frame on "+gc, gc); + f.setSize(100, 100); + f.setLocation(gc.getBounds().x, gc.getBounds().y); + f.pack(); + frames[i] = f; + } + + Font f1 = new Font("Dialog", Font.PLAIN, 10); + Font f2 = new Font("Dialog", Font.ITALIC, 12); + + for (int i = 0; i < frames.length/2; i++) { + // making sure the glyphs are cached in the accel. cache on + // one frame, then the other + renderText(frames[i], f1); + renderText(frames[frames.length -1 - i], f1); + + // and now the other way around, with different glyphs + renderText(frames[frames.length -1 - i], f2); + renderText(frames[i], f2); + } + + // try to force strike disposal (note that we have to use + // -Dsun.java2d.font.reftype=weak to facilitate the disposal) + + System.gc(); + System.runFinalization(); + System.gc(); + System.runFinalization(); + + for (Frame f : frames) { + f.dispose(); + } + + System.err.println("Exiting. If the test crashed after this it FAILED"); + } + + private static final String text = + "The quick brown fox jumps over the lazy dog 1234567890"; + private static void renderText(Frame frame, Font f1) { + VolatileImage vi = frame.createVolatileImage(256, 32); + vi.validate(frame.getGraphicsConfiguration()); + + Graphics2D g = vi.createGraphics(); + g.setFont(f1); + g.drawString(text, 0, vi.getHeight()/2); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.drawString(text, 0, vi.getHeight()/2); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); + g.drawString(text, 0, vi.getHeight()/2); + Toolkit.getDefaultToolkit().sync(); + } +} diff --git a/test/sun/java2d/DirectX/SwingOnScreenScrollingTest/SwingOnScreenScrollingTest.java b/test/sun/java2d/DirectX/SwingOnScreenScrollingTest/SwingOnScreenScrollingTest.java new file mode 100644 index 000000000..5f2d5cb05 --- /dev/null +++ b/test/sun/java2d/DirectX/SwingOnScreenScrollingTest/SwingOnScreenScrollingTest.java @@ -0,0 +1,146 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6630702 + * @summary Tests that scrolling after paint() is performed correctly. + * This is really only applicable to Vista + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm SwingOnScreenScrollingTest + * run main/othervm -Dsun.java2d.opengl=True SwingOnScreenScrollingTest + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +public class SwingOnScreenScrollingTest extends JPanel { + + static JScrollPane pane; + static SwingOnScreenScrollingTest test; + + public SwingOnScreenScrollingTest() { + } + + public static void main(String[] args) { + int size = GraphicsEnvironment. + getLocalGraphicsEnvironment(). + getDefaultScreenDevice(). + getDefaultConfiguration().getColorModel().getPixelSize(); + if (size < 16) { + System.err.println("<16 bit display mode detected. Test PASSED"); + return; + } + + final JFrame f = new JFrame("SwingOnScreenScrollingTest"); + try { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + test = new SwingOnScreenScrollingTest(); + pane = new JScrollPane(test); + f.add(pane); + f.pack(); + f.setSize(100, 200); + f.setVisible(true); + } + }); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + EventQueue.invokeLater(new Runnable() { + public void run() { + BufferedImage bi; + bi = new BufferedImage(100, 300, + BufferedImage.TYPE_INT_RGB); + Graphics gg = bi.getGraphics(); + test.paint(gg); + for (int y = 80; y < 200; y +=10) { + test.scrollRectToVisible(new Rectangle(0, y, 100, 100)); + try { + Thread.sleep(200); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + Point p = pane.getViewport().getLocationOnScreen(); + Robot r = null; + try { + r = new Robot(); + } catch (AWTException ex) { + throw new RuntimeException(ex); + } + bi = r.createScreenCapture(new Rectangle(p.x+5, p.y+5, 30, 30)); + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getHeight(); x++) { + int rgb = bi.getRGB(x, y); + if (bi.getRGB(x, y) != Color.red.getRGB()) { + System.err.printf("Test Failed at (%d,%d) c=0x%x\n", + x, y, rgb); + try { + String name = + "SwingOnScreenScrollingTest_out.png"; + ImageIO.write(bi, "png", new File(name)); + System.err.println("Wrote grabbed image to "+ + name); + } catch (Throwable ex) {} + throw new RuntimeException("Test failed"); + } + } + } + System.out.println("Test PASSED."); + f.dispose(); + } + }); + } + + protected void paintComponent(Graphics g) { + g.setColor(Color.green); + g.fillRect(0, 0, getWidth(), 100); + g.setColor(Color.red); + g.fillRect(0, 100, getWidth(), getHeight()-100); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 300); + } +} diff --git a/test/sun/java2d/DirectX/TransformedPaintTest/TransformedPaintTest.java b/test/sun/java2d/DirectX/TransformedPaintTest/TransformedPaintTest.java new file mode 100644 index 000000000..3929a59c8 --- /dev/null +++ b/test/sun/java2d/DirectX/TransformedPaintTest/TransformedPaintTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6689025 + * @summary Tests that transformed Paints are rendered correctly + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @run main/othervm TransformedPaintTest + * @run main/othervm -Dsun.java2d.opengl=True TransformedPaintTest + */ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.LinearGradientPaint; +import java.awt.MultipleGradientPaint.CycleMethod; +import java.awt.Paint; +import java.awt.RadialGradientPaint; +import java.awt.TexturePaint; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class TransformedPaintTest { + + private static enum PaintType { + COLOR, + GRADIENT, + LINEAR_GRADIENT, + RADIAL_GRADIENT, + TEXTURE + }; + + private static final int CELL_SIZE = 100; + private static final int R_WIDTH = 3 * CELL_SIZE; + private static final int R_HEIGHT = PaintType.values().length * CELL_SIZE; + + private Paint createPaint(PaintType type, int startx, int starty, + int w, int h) + { + // make sure that the blue color doesn't show up when filling a + // w by h rect + w++; h++; + + int endx = startx + w; + int endy = starty + h; + Rectangle2D.Float r = new Rectangle2D.Float(startx, starty, w, h); + switch (type) { + case COLOR: return Color.red; + case GRADIENT: return + new GradientPaint(startx, starty, Color.red, + endx, endy, Color.green); + case LINEAR_GRADIENT: return + new LinearGradientPaint(startx, starty, endx, endy, + new float[] { 0.0f, 0.999f, 1.0f }, + new Color[] { Color.red, Color.green, Color.blue }); + case RADIAL_GRADIENT: return + new RadialGradientPaint(startx, starty, + (float)Math.sqrt(w * w + h * h), + new float[] { 0.0f, 0.999f, 1.0f }, + new Color[] { Color.red, Color.green, Color.blue }, + CycleMethod.NO_CYCLE); + case TEXTURE: { + BufferedImage bi = + new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D) bi.getGraphics(); + g.setPaint(createPaint(PaintType.LINEAR_GRADIENT, 0, 0, w, h)); + g.fillRect(0, 0, w, h); + return new TexturePaint(bi, r); + } + } + return Color.green; + } + + private void renderLine(PaintType type, Graphics2D g, + int startx, int starty, int w, int h) + { + Paint p = createPaint(type, startx, starty, w, h); + g.setPaint(p); + + // first, no transform + g.fillRect(startx, starty, w, h); + + // translation only + g.translate(w, 0); + g.fillRect(startx, starty, w, h); + g.translate(-w, 0); + + // complex transform + g.translate(startx + w*2, starty); + g.rotate(Math.toRadians(90), w/2, h/2); + g.translate(-startx, -starty); + g.fillRect(startx, starty, w, h); + } + + private void render(Graphics2D g, int w, int h) { + int paintTypes = PaintType.values().length; + int ystep = h / paintTypes; + int y = 0; + + for (PaintType type : PaintType.values()) { + renderLine(type, (Graphics2D)g.create(), + 0, y, h / paintTypes, h / paintTypes); + y += ystep; + } + } + + private void checkBI(BufferedImage bi) { + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getWidth(); x++) { + if (bi.getRGB(x, y) == Color.blue.getRGB()) { + try { + String fileName = "TransformedPaintTest_res.png"; + ImageIO.write(bi, "png", new File(fileName)); + System.err.println("Dumped image to: " + fileName); + } catch (IOException ex) {} + throw new RuntimeException("Test failed, blue color found"); + } + } + } + } + + private void runTest() { + GraphicsConfiguration gc = GraphicsEnvironment. + getLocalGraphicsEnvironment().getDefaultScreenDevice(). + getDefaultConfiguration(); + + if (gc.getColorModel().getPixelSize() < 16) { + System.out.println("8-bit desktop depth found, test passed"); + return; + } + + VolatileImage vi = gc.createCompatibleVolatileImage(R_WIDTH, R_HEIGHT); + BufferedImage bi = null; + do { + vi.validate(gc); + Graphics2D g = vi.createGraphics(); + render(g, vi.getWidth(), vi.getHeight()); + bi = vi.getSnapshot(); + } while (vi.contentsLost()); + + checkBI(bi); + System.out.println("Test PASSED."); + } + + private static void showFrame(final TransformedPaintTest t) { + JFrame f = new JFrame("TransformedPaintTest"); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + final BufferedImage bi = + new BufferedImage(R_WIDTH, R_HEIGHT, BufferedImage.TYPE_INT_RGB); + JPanel p = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; + t.render(g2d, R_WIDTH, R_HEIGHT); + t.render(bi.createGraphics(), R_WIDTH, R_HEIGHT); + g2d.drawImage(bi, R_WIDTH + 5, 0, null); + + g.setColor(Color.black); + g.drawString("Rendered to Back Buffer", 10, 20); + g.drawString("Rendered to BufferedImage", R_WIDTH + 15, 20); + } + }; + p.setPreferredSize(new Dimension(2 * R_WIDTH + 5, R_HEIGHT)); + f.add(p); + f.pack(); + f.setVisible(true); + } + + public static void main(String[] args) throws + InterruptedException, InvocationTargetException + { + boolean show = (args.length > 0 && "-show".equals(args[0])); + + final TransformedPaintTest t = new TransformedPaintTest(); + if (show) { + EventQueue.invokeAndWait(new Runnable() { + public void run() { + showFrame(t); + } + }); + } else { + t.runTest(); + } + } +} diff --git a/test/sun/java2d/GdiRendering/InsetClipping.java b/test/sun/java2d/GdiRendering/InsetClipping.java new file mode 100644 index 000000000..fbaf71956 --- /dev/null +++ b/test/sun/java2d/GdiRendering/InsetClipping.java @@ -0,0 +1,112 @@ +/* + * Copyright 2003-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 4873505 6588884 + * @author cheth + * @summary verifies that drawImage behaves the bounds of a complex + * clip shape. This was a problem with our GDI renderer on Windows, where + * we would ignore the window insets. + * @run main InsetClipping +*/ + +/** + * This test works by setting up a clip area that equals the visible area + * of the Frame. When we perform any rendering operation to that window, + * we should not see the results of the operation because they should be + * clipped out. We create an Image with one color (red) and use a + * different background fill color (blue). We fill the area with the + * background color, then set the clip, then draw the image; if we detect + * the image color at pixel (0, 0) then we did not clip correctly and the + * test fails. + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; + + +public class InsetClipping extends Frame { + BufferedImage image; + Area area; + static boolean painted = false; + static Color imageColor = Color.red; + static Color fillColor = Color.blue; + + public InsetClipping() { + + image = new BufferedImage( 300, 300,BufferedImage.TYPE_INT_RGB); + Graphics g2 = image.createGraphics(); + g2.setColor(imageColor); + g2.fillRect(0,0, 300,300); + } + + public void paint(Graphics g) { + Insets insets = getInsets(); + area = new Area( new Rectangle(0,0, getWidth(), getHeight())); + area.subtract(new Area(new Rectangle(insets.left, insets.top, + getWidth() - insets.right, + getHeight() - insets.bottom))); + g.setColor(fillColor); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setClip(area); + g.drawImage(image, 0, 0, null); + painted = true; + } + + public static void main(String args[]) { + InsetClipping clipTest = new InsetClipping(); + clipTest.setSize(300, 300); + clipTest.setVisible(true); + while (!painted) { + try { + Thread.sleep(100); + } catch (Exception e) {} + } + try { + Robot robot = new Robot(); + Point clientLoc = clipTest.getLocationOnScreen(); + Insets insets = clipTest.getInsets(); + clientLoc.x += insets.left; + clientLoc.y += insets.top; + BufferedImage clientPixels = + robot.createScreenCapture(new Rectangle(clientLoc.x, + clientLoc.y, + clientLoc.x + 2, + clientLoc.y + 2)); + try { + Thread.sleep(2000); + } catch (Exception e) {} + int pixelVal = clientPixels.getRGB(0, 0); + clipTest.dispose(); + if ((new Color(pixelVal)).equals(fillColor)) { + System.out.println("Passed"); + } else { + throw new Error("Failed: incorrect color in pixel (0, 0)"); + } + } catch (Exception e) { + System.out.println("Problems creating Robot"); + } + } +} diff --git a/test/sun/java2d/OpenGL/DrawBufImgOp.java b/test/sun/java2d/OpenGL/DrawBufImgOp.java new file mode 100644 index 000000000..321d8c0a5 --- /dev/null +++ b/test/sun/java2d/OpenGL/DrawBufImgOp.java @@ -0,0 +1,483 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6514990 + * @summary Verifies that calling + * Graphics2D.drawImage(BufferedImage, BufferedImageOp, x, y) to an + * OpenGL-accelerated destination produces the same results when performed + * in software via BufferedImageOp.filter(). + * @run main/othervm -Dsun.java2d.opengl=True DrawBufImgOp -ignore + * @author campbelc + */ + +import java.awt.*; +import java.awt.image.*; +import java.io.File; +import javax.imageio.ImageIO; + +/** + * REMIND: This testcase was originally intended to automatically compare + * the results of the software BufferedImageOp implementations against + * the OGL-accelerated codepaths. However, there are just too many open + * bugs in the mediaLib-based codepaths (see below), which means that + * creating the reference image may cause crashes or exceptions, + * and even if we work around those cases using the "-ignore" flag, + * the visual results of the reference image are often buggy as well + * (so the comparison will fail even though the OGL results are correct). + * Therefore, for now we will run the testcase with the "-ignore" flag + * but without the "-compare" flag, so at least it will be checking for + * any exceptions/crashes in the OGL code. When we fix all of the + * outstanding bugs with the software codepaths, we can remove the + * "-ignore" flag and maybe even restore the "-compare" flag. In the + * meantime, it stil functions well as a manual testcase (with either + * the "-show" or "-dump" options). + */ +public class DrawBufImgOp extends Canvas { + + private static final int TESTW = 600; + private static final int TESTH = 500; + private static boolean done; + + /* + * If true, skips tests that are known to trigger bugs (which in + * turn may cause crashes, exceptions, or other artifacts). + */ + private static boolean ignore; + + // Test both pow2 and non-pow2 sized images + private static final int[] srcSizes = { 32, 17 }; + private static final int[] srcTypes = { + BufferedImage.TYPE_INT_RGB, + BufferedImage.TYPE_INT_ARGB, + BufferedImage.TYPE_INT_ARGB_PRE, + BufferedImage.TYPE_INT_BGR, + BufferedImage.TYPE_3BYTE_BGR, + BufferedImage.TYPE_4BYTE_ABGR, + BufferedImage.TYPE_USHORT_565_RGB, + BufferedImage.TYPE_BYTE_GRAY, + BufferedImage.TYPE_USHORT_GRAY, + }; + + private static final RescaleOp + rescale1band, rescale3band, rescale4band; + private static final LookupOp + lookup1bandbyte, lookup3bandbyte, lookup4bandbyte; + private static final LookupOp + lookup1bandshort, lookup3bandshort, lookup4bandshort; + private static final ConvolveOp + convolve3x3zero, convolve5x5zero, convolve7x7zero; + private static final ConvolveOp + convolve3x3noop, convolve5x5noop, convolve7x7noop; + + static { + rescale1band = new RescaleOp(0.5f, 10.0f, null); + rescale3band = new RescaleOp( + new float[] { 0.6f, 0.4f, 0.6f }, + new float[] { 10.0f, -3.0f, 5.0f }, + null); + rescale4band = new RescaleOp( + new float[] { 0.6f, 0.4f, 0.6f, 0.9f }, + new float[] { -1.0f, 5.0f, 3.0f, 1.0f }, + null); + + // REMIND: we should probably test non-zero offsets, but that + // would require massaging the source image data to avoid going + // outside the lookup table array bounds + int offset = 0; + { + byte invert[] = new byte[256]; + byte halved[] = new byte[256]; + for (int j = 0; j < 256 ; j++) { + invert[j] = (byte) (255-j); + halved[j] = (byte) (j / 2); + } + ByteLookupTable lut1 = new ByteLookupTable(offset, invert); + lookup1bandbyte = new LookupOp(lut1, null); + ByteLookupTable lut3 = + new ByteLookupTable(offset, + new byte[][] {invert, halved, invert}); + lookup3bandbyte = new LookupOp(lut3, null); + ByteLookupTable lut4 = + new ByteLookupTable(offset, + new byte[][] {invert, halved, invert, halved}); + lookup4bandbyte = new LookupOp(lut4, null); + } + + { + short invert[] = new short[256]; + short halved[] = new short[256]; + for (int j = 0; j < 256 ; j++) { + invert[j] = (short) ((255-j) * 255); + halved[j] = (short) ((j / 2) * 255); + } + ShortLookupTable lut1 = new ShortLookupTable(offset, invert); + lookup1bandshort = new LookupOp(lut1, null); + ShortLookupTable lut3 = + new ShortLookupTable(offset, + new short[][] {invert, halved, invert}); + lookup3bandshort = new LookupOp(lut3, null); + ShortLookupTable lut4 = + new ShortLookupTable(offset, + new short[][] {invert, halved, invert, halved}); + lookup4bandshort = new LookupOp(lut4, null); + } + + // 3x3 blur + float[] data3 = { + 0.1f, 0.1f, 0.1f, + 0.1f, 0.2f, 0.1f, + 0.1f, 0.1f, 0.1f, + }; + Kernel k3 = new Kernel(3, 3, data3); + + // 5x5 edge + float[] data5 = { + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, 24.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + }; + Kernel k5 = new Kernel(5, 5, data5); + + // 7x7 blur + float[] data7 = { + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, + }; + Kernel k7 = new Kernel(7, 7, data7); + + convolve3x3zero = new ConvolveOp(k3, ConvolveOp.EDGE_ZERO_FILL, null); + convolve5x5zero = new ConvolveOp(k5, ConvolveOp.EDGE_ZERO_FILL, null); + convolve7x7zero = new ConvolveOp(k7, ConvolveOp.EDGE_ZERO_FILL, null); + + convolve3x3noop = new ConvolveOp(k3, ConvolveOp.EDGE_NO_OP, null); + convolve5x5noop = new ConvolveOp(k5, ConvolveOp.EDGE_NO_OP, null); + convolve7x7noop = new ConvolveOp(k7, ConvolveOp.EDGE_NO_OP, null); + } + + public void paint(Graphics g) { + synchronized (this) { + if (done) { + return; + } + } + + VolatileImage vimg = createVolatileImage(TESTW, TESTH); + vimg.validate(getGraphicsConfiguration()); + + Graphics2D g2d = vimg.createGraphics(); + renderTest(g2d); + g2d.dispose(); + + g.drawImage(vimg, 0, 0, null); + + Toolkit.getDefaultToolkit().sync(); + + synchronized (this) { + done = true; + notifyAll(); + } + } + + /* + * foreach source image size (once with pow2, once with non-pow2) + * + * foreach BufferedImage type + * + * RescaleOp (1 band) + * RescaleOp (3 bands, if src has 3 bands) + * RescaleOp (4 bands, if src has 4 bands) + * + * foreach LookupTable type (once with ByteLUT, once with ShortLUT) + * LookupOp (1 band) + * LookupOp (3 bands, if src has 3 bands) + * LookupOp (4 bands, if src has 4 bands) + * + * foreach edge condition (once with ZERO_FILL, once with EDGE_NO_OP) + * ConvolveOp (3x3) + * ConvolveOp (5x5) + * ConvolveOp (7x7) + */ + private void renderTest(Graphics2D g2d) { + g2d.setColor(Color.white); + g2d.fillRect(0, 0, TESTW, TESTH); + + int yorig = 2; + int xinc = 34; + int yinc = srcSizes[0] + srcSizes[1] + 2 + 2; + + for (int srcType : srcTypes) { + int y = yorig; + + for (int srcSize : srcSizes) { + int x = 2; + System.out.printf("type=%d size=%d\n", srcType, srcSize); + + BufferedImage srcImg = makeSourceImage(srcSize, srcType); + ColorModel srcCM = srcImg.getColorModel(); + + // RescaleOp + g2d.drawImage(srcImg, rescale1band, x, y); + x += xinc; + // REMIND: 3-band RescaleOp.filter() throws IAE for images + // that contain an alpha channel (bug to be filed) + if (srcCM.getNumColorComponents() == 3 && + !(ignore && srcCM.hasAlpha())) + { + g2d.drawImage(srcImg, rescale3band, x, y); + } + x += xinc; + if (srcCM.getNumComponents() == 4) { + g2d.drawImage(srcImg, rescale4band, x, y); + } + x += xinc; + + // LookupOp + // REMIND: Our LUTs are only 256 elements long, so won't + // currently work with USHORT_GRAY data + if (srcType != BufferedImage.TYPE_USHORT_GRAY) { + g2d.drawImage(srcImg, lookup1bandbyte, x, y); + x += xinc; + if (srcCM.getNumColorComponents() == 3) { + g2d.drawImage(srcImg, lookup3bandbyte, x, y); + } + x += xinc; + if (srcCM.getNumComponents() == 4) { + g2d.drawImage(srcImg, lookup4bandbyte, x, y); + } + x += xinc; + + // REMIND: LookupOp.createCompatibleDestImage() throws + // IAE for 3BYTE_BGR/4BYTE_ABGR (bug to be filed) + if (!(ignore && + (srcType == BufferedImage.TYPE_3BYTE_BGR || + srcType == BufferedImage.TYPE_4BYTE_ABGR))) + { + g2d.drawImage(srcImg, lookup1bandshort, x, y); + x += xinc; + // REMIND: 3-band LookupOp.filter() throws IAE for + // images that contain an alpha channel + // (bug to be filed) + if (srcCM.getNumColorComponents() == 3 && + !(ignore && srcCM.hasAlpha())) + { + g2d.drawImage(srcImg, lookup3bandshort, x, y); + } + x += xinc; + if (srcCM.getNumComponents() == 4) { + g2d.drawImage(srcImg, lookup4bandshort, x, y); + } + x += xinc; + } else { + x += 3*xinc; + } + } else { + x += 6*xinc; + } + + // ConvolveOp + // REMIND: ConvolveOp.filter() throws ImagingOpException + // for 3BYTE_BGR (see 4957775) + if (srcType != BufferedImage.TYPE_3BYTE_BGR) { + g2d.drawImage(srcImg, convolve3x3zero, x, y); + x += xinc; + g2d.drawImage(srcImg, convolve5x5zero, x, y); + x += xinc; + g2d.drawImage(srcImg, convolve7x7zero, x, y); + x += xinc; + + g2d.drawImage(srcImg, convolve3x3noop, x, y); + x += xinc; + g2d.drawImage(srcImg, convolve5x5noop, x, y); + x += xinc; + g2d.drawImage(srcImg, convolve7x7noop, x, y); + x += xinc; + } else { + x += 6*xinc; + } + + y += srcSize + 2; + } + + yorig += yinc; + } + } + + private BufferedImage makeSourceImage(int size, int type) { + int s2 = size/2; + BufferedImage img = new BufferedImage(size, size, type); + Graphics2D g2d = img.createGraphics(); + g2d.setComposite(AlphaComposite.Src); + g2d.setColor(Color.orange); + g2d.fillRect(0, 0, size, size); + g2d.setColor(Color.red); + g2d.fillRect(0, 0, s2, s2); + g2d.setColor(Color.green); + g2d.fillRect(s2, 0, s2, s2); + g2d.setColor(Color.blue); + g2d.fillRect(0, s2, s2, s2); + g2d.setColor(new Color(255, 255, 0, 128)); + g2d.fillRect(s2, s2, s2, s2); + g2d.setColor(Color.pink); + g2d.fillOval(s2-3, s2-3, 6, 6); + g2d.dispose(); + return img; + } + + public BufferedImage makeReferenceImage() { + BufferedImage img = new BufferedImage(TESTW, TESTH, + BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = img.createGraphics(); + renderTest(g2d); + g2d.dispose(); + return img; + } + + public Dimension getPreferredSize() { + return new Dimension(TESTW, TESTH); + } + + private static void compareImages(BufferedImage refImg, + BufferedImage testImg, + int tolerance) + { + 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)) { + throw new RuntimeException("Test failed at x="+x+" y="+y+ + " (expected="+expected+ + " actual="+actual+ + ")"); + } + } + } + } + + 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) throws Exception { + boolean show = false; + boolean dump = false; + boolean compare = false; + + for (String arg : args) { + if (arg.equals("-show")) { + show = true; + } else if (arg.equals("-dump")) { + dump = true; + } else if (arg.equals("-compare")) { + compare = true; + } else if (arg.equals("-ignore")) { + ignore = true; + } + } + + DrawBufImgOp test = new DrawBufImgOp(); + 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; + } + + // Grab the screen region + BufferedImage capture = null; + try { + Robot robot = new Robot(); + Point pt1 = test.getLocationOnScreen(); + Rectangle rect = new Rectangle(pt1.x, pt1.y, TESTW, TESTH); + capture = robot.createScreenCapture(rect); + } catch (Exception e) { + throw new RuntimeException("Problems creating Robot"); + } finally { + if (!show) { + frame.dispose(); + } + } + + // Compare the images (allow for +/- 1 bit differences in color comps) + if (dump || compare) { + BufferedImage ref = test.makeReferenceImage(); + if (dump) { + ImageIO.write(ref, "png", + new File("DrawBufImgOp.ref.png")); + ImageIO.write(capture, "png", + new File("DrawBufImgOp.cap.png")); + } + if (compare) { + test.compareImages(ref, capture, 1); + } + } + } +} diff --git a/test/sun/java2d/SunGraphics2D/DrawImageBilinear.java b/test/sun/java2d/SunGraphics2D/DrawImageBilinear.java new file mode 100644 index 000000000..5e8831862 --- /dev/null +++ b/test/sun/java2d/SunGraphics2D/DrawImageBilinear.java @@ -0,0 +1,205 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 5009033 6603000 6666362 + * @summary Verifies that images transformed with bilinear filtering do not + * leave artifacts at the edges. + * @run main/othervm DrawImageBilinear + * @run main/othervm -Dsun.java2d.opengl=True DrawImageBilinear + * @author campbelc + */ + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.VolatileImage; + +public class DrawImageBilinear extends Canvas { + + private static final int SIZE = 5; + + private static boolean done; + private BufferedImage bimg1, bimg2; + private VolatileImage vimg; + private static volatile BufferedImage capture; + private static void doCapture(Component test) { + // Grab the screen region + try { + Robot robot = new Robot(); + Point pt1 = test.getLocationOnScreen(); + Rectangle rect = + new Rectangle(pt1.x, pt1.y, test.getWidth(), test.getHeight()); + capture = robot.createScreenCapture(rect); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void renderPattern(Graphics g) { + g.setColor(Color.red); + g.fillRect(0, 0, SIZE, SIZE); + //g.setColor(Color.green); + //g.drawRect(0, 0, SIZE-1, SIZE-1); + g.dispose(); + } + + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D)g; + + if (bimg1 == null) { + bimg1 = (BufferedImage)createImage(SIZE, SIZE); + bimg1.setAccelerationPriority(0.0f); + renderPattern(bimg1.createGraphics()); + + bimg2 = (BufferedImage)createImage(SIZE, SIZE); + renderPattern(bimg2.createGraphics()); + + vimg = createVolatileImage(SIZE, SIZE); + vimg.validate(getGraphicsConfiguration()); + renderPattern(vimg.createGraphics()); + } + + do { + g2d.setColor(Color.white); + g2d.fillRect(0, 0, getWidth(), getHeight()); + + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + // first time will be a sw->surface blit + g2d.drawImage(bimg1, 10, 10, 40, 40, null); + + // second time will be a texture->surface blit + g2d.drawImage(bimg2, 80, 10, 40, 40, null); + g2d.drawImage(bimg2, 80, 10, 40, 40, null); + + // third time will be a pbuffer->surface blit + if (vimg.validate(getGraphicsConfiguration()) != VolatileImage.IMAGE_OK) { + renderPattern(vimg.createGraphics()); + } + g2d.drawImage(vimg, 150, 10, 40, 40, null); + + Toolkit.getDefaultToolkit().sync(); + } while (vimg.contentsLost()); + + synchronized (this) { + if (!done) { + doCapture(this); + done = true; + } + notifyAll(); + } + } + + public Dimension getPreferredSize() { + return new Dimension(200, 100); + } + + private static void testRegion(BufferedImage bi, + Rectangle affectedRegion) + { + int x1 = affectedRegion.x; + int y1 = affectedRegion.y; + int x2 = x1 + affectedRegion.width; + int y2 = y1 + affectedRegion.height; + + for (int y = y1; y < y2; y++) { + for (int x = x1; x < x2; x++) { + int actual = bi.getRGB(x, y); + if ((actual != 0xfffe0000) && (actual != 0xffff0000)) { + throw new RuntimeException("Test failed at x="+x+" y="+y+ + " (expected=0xffff0000"+ + " actual=0x"+ + Integer.toHexString(actual) + + ")"); + } + } + } + } + + public static void main(String[] args) { + boolean show = false; + for (String arg : args) { + if ("-show".equals(arg)) { + show = true; + } + } + + DrawImageBilinear test = new DrawImageBilinear(); + 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; + } + + if (!show) { + frame.dispose(); + } + if (capture == null) { + throw new RuntimeException("Failed: capture is null"); + } + + // Test background color + int pixel = capture.getRGB(5, 5); + if (pixel != 0xffffffff) { + throw new RuntimeException("Failed: Incorrect color for " + + "background"); + } + + // Test pixels + testRegion(capture, new Rectangle(10, 10, 40, 40)); + testRegion(capture, new Rectangle(80, 10, 40, 40)); + testRegion(capture, new Rectangle(150, 10, 40, 40)); + } +} diff --git a/test/sun/java2d/SunGraphics2D/PolyVertTest.java b/test/sun/java2d/SunGraphics2D/PolyVertTest.java new file mode 100644 index 000000000..73138973b --- /dev/null +++ b/test/sun/java2d/SunGraphics2D/PolyVertTest.java @@ -0,0 +1,661 @@ +/* + * Copyright 2002-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4678208 4771101 6328481 6588884 + * @summary verify the pixelization of degenerate polylines and polygons + * @run main PolyVertTest + * @run main/othervm -Dsun.java2d.d3d=True PolyVertTest -hwonly + * @run main/othervm -Dsun.java2d.opengl=True PolyVertTest -hwonly + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.image.*; + +public class PolyVertTest { + static int TESTWIDTH; + static int TESTHEIGHT; + static final int REG_TEST_WIDTH = 10; + static final int REG_TEST_HEIGHT = 10; + static final int FULL_TEST_WIDTH = 50; + static final int FULL_TEST_HEIGHT = 200; + + static final int FRINGE = 2; + static final int GREEN = Color.green.getRGB(); + static final int RED = Color.red.getRGB(); + + static BufferedImage refImg; + static BufferedImage errorImg; + static Graphics errorG; + static Component testCanvas; + + static int totalbadpixels; + static int totalfuzzypixels; + static int numbadtests; + static int numfuzzytests; + static int numframes; + static int fuzzystarty; + + static boolean counting; + static boolean showerrors; + static boolean showresults; + static boolean fringe; + static boolean forceerror; + static boolean fulltest = true; + static boolean hwonly; + + static WindowListener windowCloser = new WindowAdapter() { + public void windowClosing(WindowEvent e) { + e.getWindow().hide(); + if (--numframes <= 0) { + System.exit(0); + } + } + }; + + public PolyVertTest() { + /* + setBackground(Color.white); + setForeground(Color.black); + */ + } + + static int polypts[][][] = { + { + // void polygon (no points) + {}, {}, + }, + { + // one point + { 0 }, { 0 }, + }, + { + // two points + { 0, 5 }, { 0, 0 }, + { 0, 0, 6, 1, + 10, 0, 6, 1, + 20, 0, 6, 1 }, + { 0, 0, 6, 1, + 10, 0, 1, 1, 15, 0, 1, 1, + 20, 0, 1, 1, 25, 0, 1, 1 }, + { 10, 0, 1, 1, + 20, 0, 1, 1 }, + }, + { + // open triangle + { 0, 5, 5 }, { 0, 0, 5 }, + + { 0, 0, 6, 1, 5, 1, 1, 5, + + 10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1, + 12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1, + + 20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1, + 22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 }, + + { 0, 0, 6, 1, 5, 1, 1, 5, + + 10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1, + 12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1, + + 20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1, + 22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 }, + + { 10, 0, 1, 1, + 20, 0, 1, 1 }, + }, + { + // closed triangle + { 0, 5, 5, 0 }, { 0, 0, 5, 0 }, + + { 0, 0, 6, 1, 5, 1, 1, 5, 1, 1, 1, 1, + 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, + + 10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1, + 12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1, + + 20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1, + 22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 }, + + { 1, 0, 5, 1, 5, 1, 1, 5, 1, 1, 1, 1, + 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, + + 10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1, + 12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1, + + 20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1, + 22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 }, + + { 0, 0, 1, 1, + 10, 0, 1, 1, + 20, 0, 1, 1 }, + }, + { + // empty line + { 0, 0 }, { 0, 0 }, + { 0, 0, 1, 1, + 10, 0, 1, 1, + 20, 0, 1, 1 }, + }, + { + // empty triangle + { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 1, 1, + 10, 0, 1, 1, + 20, 0, 1, 1 }, + }, + }; + + public static void render(Graphics2D g2d) { + g2d.setColor(Color.white); + g2d.fillRect(0, 0, TESTWIDTH, TESTHEIGHT); + g2d.setColor(Color.black); + + if (forceerror) { + g2d.fillRect(2, 2, 2, 2); + g2d.fillRect(15, 5, 1, 1); + } + + if (!fulltest) { + g2d.draw(new Rectangle2D.Double(5, 5, 0, 0)); + return; + } + + g2d.drawLine(10, 10, 10, 10); + g2d.draw(new Line2D.Double(20, 10, 20, 10)); + + g2d.drawRect(10, 20, 0, 0); + g2d.draw(new Rectangle2D.Double(20, 20, 0, 0)); + + g2d.setXORMode(Color.white); + + g2d.drawLine(10, 30, 10, 30); + g2d.draw(new Line2D.Double(20, 30, 20, 30)); + + g2d.drawRect(10, 40, 0, 0); + g2d.draw(new Rectangle2D.Double(20, 40, 0, 0)); + + g2d.setPaintMode(); + + int y = 50; + for (int i = 0; i < polypts.length; i++) { + int data[][] = polypts[i]; + int xpoints[] = data[0]; + int ypoints[] = data[1]; + int npoints = xpoints.length; + g2d.translate(10, y); + g2d.drawPolyline(xpoints, ypoints, npoints); + g2d.translate(10, 0); + g2d.drawPolygon(xpoints, ypoints, npoints); + g2d.translate(10, 0); + g2d.draw(new Polygon(xpoints, ypoints, npoints)); + g2d.translate(-30, -y); + y += 10; + } + g2d.setXORMode(Color.white); + for (int i = 0; i < polypts.length; i++) { + int data[][] = polypts[i]; + int xpoints[] = data[0]; + int ypoints[] = data[1]; + int npoints = xpoints.length; + g2d.translate(10, y); + g2d.drawPolyline(xpoints, ypoints, npoints); + g2d.translate(10, 0); + g2d.drawPolygon(xpoints, ypoints, npoints); + g2d.translate(10, 0); + g2d.draw(new Polygon(xpoints, ypoints, npoints)); + g2d.translate(-30, -y); + y += 10; + } + g2d.setPaintMode(); + } + + public Dimension getPreferredSize() { + return new Dimension(500, 500); + } + + public static void usage(int exitcode) { + System.err.println("usage: java PolyVertTest [<option>]*"); + System.err.println(" -usage "+ + "print this usage summary"); + System.err.println(" -count "+ + "run all tests and accumulate error counts"); + System.err.println(" -forceerror "+ + "force at least one error in each test"); + System.err.println(" -fringe "+ + "draw a yellow fringe around problems"); + System.err.println(" -showerrors "+ + "display results window for tests with problems"); + System.err.println(" -showresults "+ + "display results window for all tests"); + System.err.println(" -quicktest "+ + "only run test cases reported in bug reports"); + System.err.println(" -fulltest "+ + "run full suite of test cases for a 'unit test'"); + System.err.println(" -hwonly "+ + "only run tests for screen and VolatileImage"); + System.exit(exitcode); + } + + public static void main(String argv[]) { + for (int i = 0; i < argv.length; i++) { + String arg = argv[i]; + if (arg.equalsIgnoreCase("-count")) { + counting = true; + } else if (arg.equalsIgnoreCase("-forceerror")) { + forceerror = true; + } else if (arg.equalsIgnoreCase("-fringe")) { + fringe = true; + } else if (arg.equalsIgnoreCase("-showerrors")) { + showerrors = true; + } else if (arg.equalsIgnoreCase("-showresults")) { + showresults = true; + } else if (arg.equalsIgnoreCase("-quicktest")) { + fulltest = false; + } else if (arg.equalsIgnoreCase("-fulltest")) { + fulltest = true; + } else if (arg.equalsIgnoreCase("-hwonly")) { + hwonly = true; + } else if (arg.equalsIgnoreCase("-usage")) { + usage(0); + } else { + System.err.println("unknown option: "+arg); + usage(1); + } + } + + if (fulltest) { + TESTWIDTH = FULL_TEST_WIDTH; + TESTHEIGHT = FULL_TEST_HEIGHT; + } else { + TESTWIDTH = REG_TEST_WIDTH; + TESTHEIGHT = REG_TEST_HEIGHT; + } + + // Prevents premature exit by the WindowAdapter if the user + // closes the last visible results window before we've + // finished our tests. + numframes++; + + makeReferenceImage(); + testScreen(); + testVolatileImage(); + if (!hwonly) { + testBufferedImage(); + testOffscreen(); + testCompatibleImages(); + } + if (totalfuzzypixels > 0) { + System.err.println(totalfuzzypixels+" fuzzy pixels found in "+ + numfuzzytests+" tests"); + } + if (totalbadpixels > 0) { + throw new RuntimeException(totalbadpixels+" bad pixels found in "+ + numbadtests+" tests"); + } + System.out.println("Test done - no bad pixels found"); + + --numframes; + + if (counting || ((showresults || showerrors) && numframes == 0)) { + System.exit(0); + } + } + + public static void makeReferenceImage() { + refImg = new BufferedImage(TESTWIDTH, TESTHEIGHT, + BufferedImage.TYPE_INT_RGB); + Graphics g = refImg.getGraphics(); + + g.setColor(Color.white); + g.fillRect(0, 0, TESTWIDTH, TESTHEIGHT); + + g.setColor(Color.black); + + if (!fulltest) { + g.fillRect(5, 5, 1, 1); + g.dispose(); + return; + } + + for (int y = 10; y < 50; y += 10) { + g.fillRect(10, y, 1, 1); + g.fillRect(20, y, 1, 1); + } + int y = 50; + for (int i = 0; i < polypts.length; i++) { + int data[][] = polypts[i]; + g.translate(10, y); + if (data.length > 2) { + int rectvals[] = data[2]; + for (int j = 0; j < rectvals.length; j += 4) { + g.fillRect(rectvals[j+0], rectvals[j+1], + rectvals[j+2], rectvals[j+3]); + } + } + g.translate(-10, -y); + y += 10; + } + fuzzystarty = y; + for (int i = 0; i < polypts.length; i++) { + int data[][] = polypts[i]; + g.translate(10, y); + if (data.length > 2) { + int rectvals[] = data.length > 3 ? data[3] : data[2]; + for (int j = 0; j < rectvals.length; j += 4) { + g.fillRect(rectvals[j+0], rectvals[j+1], + rectvals[j+2], rectvals[j+3]); + } + } + g.translate(-10, -y); + y += 10; + } + g.dispose(); + } + + public static void initerrorbuf() { + if (errorImg == null) { + droperrorbuf(); + errorImg = new BufferedImage(TESTWIDTH, TESTHEIGHT, + BufferedImage.TYPE_INT_RGB); + } + if (errorG == null) { + errorG = errorImg.getGraphics(); + } + errorG.setColor(Color.green); + errorG.fillRect(0, 0, TESTWIDTH, TESTHEIGHT); + errorG.setColor(Color.red); + } + + public static void droperrorbuf() { + errorImg = null; + if (errorG != null) { + errorG.dispose(); + } + errorG = null; + } + + public static void test(Image img, String name) { + Graphics2D g2d = (Graphics2D) img.getGraphics(); + render(g2d); + g2d.dispose(); + verify(img, name); + } + + public static void test(BufferedImage bimg, String name) { + Graphics2D g2d = bimg.createGraphics(); + render(g2d); + g2d.dispose(); + verify(bimg, name); + } + + public static void verify(Image img, String name) { + BufferedImage bimg; + if (img instanceof BufferedImage) { + bimg = (BufferedImage) img; + } else { + bimg = new BufferedImage(TESTWIDTH, TESTHEIGHT, + BufferedImage.TYPE_INT_RGB); + Graphics g = bimg.getGraphics(); + g.drawImage(img, 0, 0, null); + g.dispose(); + } + verify(bimg, name); + } + + public static boolean isFuzzyPixel(int X, int Y) { + int ytrans = fuzzystarty; + if (!fulltest || Y < ytrans) { + return false; + } + for (int i = 0; i < polypts.length; i++) { + int data[][] = polypts[i]; + if (data.length > 4) { + int rectvals[] = data[4]; + for (int j = 0; j < rectvals.length; j += 4) { + int rectx = rectvals[j+0] + 10; + int recty = rectvals[j+1] + ytrans; + int rectw = rectvals[j+2]; + int recth = rectvals[j+3]; + if (X >= rectx && Y >= recty && + X < rectx + rectw && Y < recty + recth) + { + return true; + } + } + } + ytrans += 10; + } + return false; + } + + public static void verify(BufferedImage bimg, String name) { + int numbadpixels = 0; + int numfuzzypixels = 0; + for (int y = 0; y < TESTHEIGHT; y++) { + for (int x = 0; x < TESTWIDTH; x++) { + if (refImg.getRGB(x, y) != bimg.getRGB(x, y)) { + boolean isfuzzy = isFuzzyPixel(x, y); + if (showerrors || showresults) { + if (errorG == null) { + initerrorbuf(); + } + errorG.setColor(isfuzzy ? Color.blue : Color.red); + errorG.fillRect(x, y, 1, 1); + } else if (!counting && !isfuzzy) { + throw new RuntimeException("Error at "+x+", "+y+ + " while testing: "+name); + } + if (isfuzzy) { + numfuzzypixels++; + } else { + numbadpixels++; + } + } + } + } + if (numbadpixels > 0 || numfuzzypixels > 0) { + if (numbadpixels > 0) { + totalbadpixels += numbadpixels; + numbadtests++; + } + if (numfuzzypixels > 0) { + totalfuzzypixels += numfuzzypixels; + numfuzzytests++; + } + System.out.println(numbadpixels+" bad pixels and "+ + numfuzzypixels+" questionable pixels "+ + "found while testing "+name); + if (showerrors || showresults) { + displaydiffs(bimg, name); + } + } else if (showresults) { + if (errorG == null) { + initerrorbuf(); + } + displaydiffs(bimg, name); + } + } + + public static void displaydiffs(BufferedImage bimg, String name) { + if (fringe) { + errorG.setColor(Color.yellow); + for (int y = 0; y < TESTHEIGHT; y++) { + for (int x = 0; x < TESTWIDTH; x++) { + if (errorImg.getRGB(x, y) == RED) { + for (int iy = y-FRINGE; iy <= y+FRINGE; iy++) { + for (int ix = x-FRINGE; ix <= x+FRINGE; ix++) { + if (ix >= 0 && ix < TESTWIDTH && + iy >= 0 && iy < TESTHEIGHT && + errorImg.getRGB(ix, iy) == GREEN) + { + errorG.fillRect(ix, iy, 1, 1); + } + } + } + } + } + } + } + Frame f = new Frame("Results for "+name); + f.setLayout(new BorderLayout()); + f.addWindowListener(windowCloser); + ++numframes; + Panel p = new Panel(); + p.add(new ImageCanvas(bimg)); + p.add(new ImageCanvas(errorImg)); + p.add(new ImageCanvas(refImg)); + f.add(p, "Center"); + droperrorbuf(); + f.pack(); + f.show(); + } + + public static void testBufferedImage() { + testBufferedImage(BufferedImage.TYPE_INT_RGB, "IntXrgb"); + testBufferedImage(BufferedImage.TYPE_INT_ARGB, "IntArgb"); + testBufferedImage(BufferedImage.TYPE_3BYTE_BGR, "ThreeByte"); + testBufferedImage(BufferedImage.TYPE_4BYTE_ABGR, "FourByte"); + testBufferedImage(BufferedImage.TYPE_USHORT_555_RGB, "UShort555"); + testBufferedImage(BufferedImage.TYPE_BYTE_GRAY, "ByteGray"); + testBufferedImage(BufferedImage.TYPE_BYTE_INDEXED, "Indexed"); + } + + public static void testBufferedImage(int type, String name) { + BufferedImage bimg = new BufferedImage(TESTWIDTH, TESTHEIGHT, type); + test(bimg, name); + } + + public static void testScreen() { + Frame f = new Frame("PolyVertTest"); + TestCanvas child = new TestCanvas(); + testCanvas = child; + f.add(child); + f.pack(); + f.show(); + BufferedImage bimg = child.getImage(); + f.hide(); + verify(bimg, "Screen"); + } + + public static void testOffscreen() { + Image img = testCanvas.createImage(TESTWIDTH, TESTHEIGHT); + test(img, "Offscreen"); + } + + public static void testCompatibleImages() { + GraphicsEnvironment genv = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gdevs[] = genv.getScreenDevices(); + for (int i = 0; i < gdevs.length; i++) { + testCompatibleImages(gdevs[i]); + } + } + + public static void testCompatibleImages(GraphicsDevice gdev) { + GraphicsConfiguration gconfigs[] = gdev.getConfigurations(); + for (int i = 0; i < gconfigs.length; i++) { + testCompatibleImages(gconfigs[i]); + } + } + + public static void testCompatibleImages(GraphicsConfiguration gconfig) { + test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT), + gconfig+".createCompat()"); + test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT, + Transparency.OPAQUE), + gconfig+".createCompat(OPAQUE)"); + test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT, + Transparency.BITMASK), + gconfig+".createCompat(BITMASK)"); + test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT, + Transparency.TRANSLUCENT), + gconfig+".createCompat(TRANSLUCENT)"); + test(gconfig.createCompatibleVolatileImage(TESTWIDTH, TESTHEIGHT), + gconfig+".createCompatVolatile()"); + } + + public static void testVolatileImage() { + Image img = testCanvas.createVolatileImage(TESTWIDTH, TESTHEIGHT); + test(img, "Volatile"); + } + + public static class ImageCanvas extends Canvas { + BufferedImage bimg; + + public ImageCanvas(BufferedImage bimg) { + this.bimg = bimg; + } + + public Dimension getPreferredSize() { + return new Dimension(bimg.getWidth(), bimg.getHeight()); + } + + public void paint(Graphics g) { + g.drawImage(bimg, 0, 0, null); + } + } + + public static class TestCanvas extends Canvas { + BufferedImage bimg; + + public Dimension getPreferredSize() { + return new Dimension(TESTWIDTH, TESTHEIGHT); + } + + public void paint(Graphics g) { + if (bimg != null || + getWidth() < TESTWIDTH || + getHeight() < TESTHEIGHT) + { + return; + } + render((Graphics2D) g); + Toolkit.getDefaultToolkit().sync(); + Point p = getLocationOnScreen(); + Rectangle r = new Rectangle(p.x, p.y, TESTWIDTH, TESTHEIGHT); + try { + bimg = new Robot().createScreenCapture(r); + } catch (AWTException e) { + e.printStackTrace(); + } + synchronized (this) { + notifyAll(); + } + } + + public synchronized BufferedImage getImage() { + while (bimg == null) { + try { + wait(); + } catch (InterruptedException e) { + return null; + } + } + return bimg; + } + } +} diff --git a/test/sun/java2d/SunGraphics2D/SimplePrimQuality.java b/test/sun/java2d/SunGraphics2D/SimplePrimQuality.java new file mode 100644 index 000000000..8b7b11b25 --- /dev/null +++ b/test/sun/java2d/SunGraphics2D/SimplePrimQuality.java @@ -0,0 +1,281 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4832224 6322584 6328478 6328481 6322580 6588884 6587863 + * @summary Verifies that the pixelization of simple primitives (drawLine, + * fillRect, drawRect, fill, draw) with the OGL pipeline enabled + * matches that produced by our software loops. (The primitives tested here + * are simple enough that the OGL results should match the software results + * exactly.) There is some overlap with PolyVertTest as we test both + * solid and XOR rendering here, but this testcase is a bit simpler and + * more appropriate for quick OGL testing. This test is also useful for + * comparing quality between our X11/GDI and software pipelines. + * @run main/othervm SimplePrimQuality + * @run main/othervm -Dsun.java2d.opengl=True SimplePrimQuality + * @author campbelc + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class SimplePrimQuality extends Canvas { + + private static final int SIZE = 300; + private static boolean done; + private static boolean testVI; + private static volatile BufferedImage capture; + private static void doCapture(Component test) { + // Grab the screen region + try { + Robot robot = new Robot(); + Point pt1 = test.getLocationOnScreen(); + Rectangle rect = + new Rectangle(pt1.x, pt1.y, test.getWidth(), test.getHeight()); + capture = robot.createScreenCapture(rect); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static final int[][] rpts = { + {2, 0, 0, 0}, + {12, 0, 1, 0}, + {22, 0, 0, 1}, + {32, 0, 1, 1}, + {42, 0, 2, 1}, + {52, 0, 1, 2}, + {62, 0, 2, 2}, + {72, 0, 5, 5}, + {82, 0, 10, 10}, + {97, 0, 15, 15}, + }; + + private void drawLine(Graphics2D g, int x, int y, int dx, int dy) { + g.drawLine(x, y, x + dx, y + dy); + } + + private void drawLines(Graphics2D g, int s) { + drawLine(g, 2, 0, 0, 0); + drawLine(g, 12, 0, 0, s); + drawLine(g, 22, 0, s, 0); + drawLine(g, 32, 0, s, s); + drawLine(g, 42, 0, 0, -s); + drawLine(g, 52, 0, -s, 0); + drawLine(g, 62, 0, -s, -s); + drawLine(g, 72, 0, -s, s); + drawLine(g, 82, 0, s, -s); + } + + private void fillRects(Graphics2D g) { + for (int i = 0; i < rpts.length; i++) { + g.fillRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]); + } + } + + private void drawRects(Graphics2D g) { + for (int i = 0; i < rpts.length; i++) { + g.drawRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]); + } + } + + private void fillOvals(Graphics2D g) { + for (int i = 0; i < rpts.length; i++) { + // use fill() instead of fillOval(), since the former is more + // likely to be consistent with our software loops when the + // OGL pipeline cannot be enabled + g.fill(new Ellipse2D.Float(rpts[i][0], rpts[i][1], + rpts[i][2], rpts[i][3])); + } + } + + private void drawOvals(Graphics2D g) { + for (int i = 0; i < rpts.length; i++) { + // use draw() instead of drawOval(), since the former is more + // likely to be consistent with our software loops when the + // OGL pipeline cannot be enabled + g.draw(new Ellipse2D.Float(rpts[i][0], rpts[i][1], + rpts[i][2], rpts[i][3])); + } + } + + private void renderShapes(Graphics2D g) { + // drawLine tests... + g.translate(0, 5); + drawLines(g, 1); + g.translate(0, 10); + drawLines(g, 4); + + // fillRect tests... + g.translate(0, 10); + fillRects(g); + + // drawRect tests... + g.translate(0, 20); + drawRects(g); + + // fillOval tests... + g.translate(0, 20); + fillOvals(g); + + // drawOval tests... + g.translate(0, 20); + drawOvals(g); + } + + private void renderTest(Graphics2D g, int w, int h) { + // on the left side, render the shapes in solid mode + g.setColor(Color.black); + g.fillRect(0, 0, w, h); + g.setColor(Color.green); + renderShapes(g); + + // on the right side, render the shapes in XOR mode + g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0)); + g.setXORMode(Color.black); + renderShapes(g); + g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0)); + renderShapes(g); + } + + public void paint(Graphics g) { + + Graphics2D g2d = (Graphics2D)g; + renderTest(g2d, SIZE, SIZE); + + Toolkit.getDefaultToolkit().sync(); + + synchronized (this) { + if (!done) { + doCapture(this); + done = true; + } + notifyAll(); + } + } + + public Dimension getPreferredSize() { + return new Dimension(SIZE, SIZE); + } + + public static void main(String[] args) { + boolean show = false; + for (String arg : args) { + if (arg.equals("-testvi")) { + System.out.println("Testing VolatileImage, not screen"); + testVI = true; + } else if (arg.equals("-show")) { + show = true; + } + } + + SimplePrimQuality test = new SimplePrimQuality(); + 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"); + } + } + } + + // REMIND: We will allow this test to pass silently on Windows + // (when OGL is not enabled) until we fix the GDI pipeline so that + // its stroked/filled GeneralPaths match our software loops (see + // 6322554). This check should be removed when 6322554 is fixed. + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + if (gc.getClass().getSimpleName().startsWith("Win")) { + System.out.println("GDI pipeline detected: " + + "test considered PASSED"); + frame.dispose(); + return; + } + + + if (testVI) { + // render to a VI instead of the screen + VolatileImage vi = frame.createVolatileImage(SIZE, SIZE); + do { + vi.validate(frame.getGraphicsConfiguration()); + Graphics2D g1 = vi.createGraphics(); + test.renderTest(g1, SIZE, SIZE); + g1.dispose(); + capture = vi.getSnapshot(); + } while (vi.contentsLost()); + frame.dispose(); + } + + if (!show) { + frame.dispose(); + } + if (capture == null) { + throw new RuntimeException("Error capturing the rendering"); + } + + // Create reference image + int w = SIZE, h = SIZE; + BufferedImage refimg = new BufferedImage(w, h, + BufferedImage.TYPE_INT_RGB); + Graphics2D g = refimg.createGraphics(); + test.renderTest(g, w, h); + g.dispose(); + + // Test pixels + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int actual = capture.getRGB(x, y); + int expected = refimg.getRGB(x, y); + if (actual != expected) { + String expectedName = "SimplePrimQuality_expected.png"; + String actualName = "SimplePrimQuality_actual.png"; + try { + System.out.println("Writing expected image to: "+ + expectedName); + ImageIO.write(refimg, "png", new File(expectedName)); + System.out.println("Writing actual image to: "+ + actualName); + ImageIO.write(capture, "png", new File(actualName)); + } catch (IOException ex) {} + throw new RuntimeException("Test failed at x="+x+" y="+y+ + " (expected="+ + Integer.toHexString(expected) + + " actual="+ + Integer.toHexString(actual) + + ")"); + } + } + } + } +} diff --git a/test/sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java b/test/sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java new file mode 100644 index 000000000..3bd1109bb --- /dev/null +++ b/test/sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java @@ -0,0 +1,295 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test + @bug 6244574 + @bug 6258142 + @bug 6395165 + @bug 6588884 + @summary Tests that source is clipped correctly when blitting + different types of images to the screen + @author Dmitri.Trembovetski: area=Graphics2D + @run main SourceClippingBlitTest +*/ + +import java.awt.AWTException; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Transparency; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; + +public class SourceClippingBlitTest extends Canvas { + static final int TESTW = 300; + static final int TESTH = 300; + static final int IMAGEW = 50; + static final int IMAGEH = 50; + + static final Rectangle IMAGE_BOUNDS = new Rectangle(0, 0, IMAGEW, IMAGEH); + static Robot robot; + static private boolean showErrors; + + private static final Object lock = new Object(); + private static volatile boolean done = false; + + BufferedImage grabbedBI; + + public static void main(String[] args) { + // allow user to override the properties if needed + if (System.getProperty("sun.java2d.pmoffscreen") == null) { + System.setProperty("sun.java2d.pmoffscreen", "true"); + } + + if (args.length > 0 && args[0].equals("-showerrors")) { + showErrors = true; + } + + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException(e); + } + + Frame f = new Frame(SourceClippingBlitTest.class.getName()); + final SourceClippingBlitTest test = new SourceClippingBlitTest(); + f.add(test); + f.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + if (!done) { + test.runTests(); + } + } + + }); + f.pack(); + f.setLocation(100, 100); + f.setVisible(true); + synchronized (lock) { + while (!done) { + try { + lock.wait(); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + } + if (!showErrors) { + f.dispose(); + } + } + + public Dimension getPreferredSize() { + return new Dimension(TESTW, TESTH); + } + + public void paint(Graphics g) { + if (showErrors && done && grabbedBI != null) { + g.drawImage(grabbedBI, 0, 0, null); + } + } + + public void runTests() { + GraphicsConfiguration gc = getGraphicsConfiguration(); + for (Image srcIm : + new Image[] { + getBufferedImage(gc, IMAGEW, IMAGEH, + BufferedImage.TYPE_INT_RGB, true), + getBufferedImage(gc, IMAGEW, IMAGEH, + BufferedImage.TYPE_INT_RGB, false), + // commented out due to 6593406 +// getBMImage(gc, IMAGEW, IMAGEH), +// getBufferedImage(gc, IMAGEW, IMAGEH, +// BufferedImage.TYPE_INT_ARGB, true), +// getBufferedImage(gc, IMAGEW, IMAGEH, +// BufferedImage.TYPE_INT_ARGB, false), + getVImage(gc, IMAGEW, IMAGEH), + }) + { + System.out.println("Testing source: " + srcIm); + // wiggle the source and dest rectangles + try { + for (int locationVar = -10; locationVar < 20; locationVar += 10) + { + for (int sizeVar = -10; sizeVar < 20; sizeVar += 10) { + Rectangle srcRect = (Rectangle)IMAGE_BOUNDS.clone(); + srcRect.translate(locationVar, locationVar); + srcRect.grow(sizeVar, sizeVar); + + Rectangle dstRect = + new Rectangle(sizeVar, sizeVar, + srcRect.width, srcRect.height); + System.out.println("testing blit rect src: " + srcRect); + System.out.println(" dst: " + dstRect); + render(getGraphics(), srcIm, srcRect, dstRect); + test(srcRect, dstRect); + } + } + System.out.println("Test passed."); + } finally { + synchronized (lock) { + done = true; + lock.notifyAll(); + } + } + } + } + + public void render(Graphics g, Image image, + Rectangle srcRect, Rectangle dstRect) + { + int w = getWidth(); + int h = getHeight(); + g.setColor(Color.green); + g.fillRect(0, 0, w, h); + + int bltWidth = srcRect.width; + int bltHeight = srcRect.height; + VolatileImage vi = null; + if (image instanceof VolatileImage) { + vi = (VolatileImage)image; + } + do { + if (vi != null) { + GraphicsConfiguration gc = getGraphicsConfiguration(); + if (vi.validate(gc) != VolatileImage.IMAGE_OK) { + initImage(gc, vi); + } + } + g.drawImage(image, + dstRect.x, dstRect.y, + dstRect.x + bltWidth, dstRect.y + bltHeight, + srcRect.x, srcRect.y, + srcRect.x + bltWidth, srcRect.y + bltHeight, + Color.red, + null); + } while (vi != null && vi.contentsLost()); + } + + + public void test(Rectangle srcRect, Rectangle dstRect) { + int w = getWidth(); + int h = getHeight(); + Toolkit.getDefaultToolkit().sync(); + Point p = getLocationOnScreen(); + grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h)); + + // calculate the destination rectangle + Rectangle srcBounds = srcRect.intersection(IMAGE_BOUNDS); + int trX = dstRect.x - srcRect.x; + int trY = dstRect.y - srcRect.y; + Rectangle newDstRect = (Rectangle)dstRect.clone(); + newDstRect.translate(-trX, -trY); + Rectangle.intersect(newDstRect, srcBounds, newDstRect); + newDstRect.translate(trX, trY); + Rectangle.intersect(newDstRect, new Rectangle(0, 0, w, h), newDstRect); + + System.out.println("calculated dest rect:" + newDstRect); + + // we do implicit clipping of the destination surface + // by only checking pixels within its bounds + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int rgb = 0; + if (newDstRect.contains(x, y)) { + rgb = Color.red.getRGB(); + } else { + rgb = Color.green.getRGB(); + } + if (grabbedBI.getRGB(x, y) != rgb) { + String msg1 = "Test failed at x="+x+" y="+y; + System.out.println(msg1); + System.out.println(" expected: "+Integer.toHexString(rgb)+ + " got:"+Integer.toHexString(grabbedBI.getRGB(x, y))); + throw new RuntimeException(msg1); + } + } + } + System.out.println("subtest passed"); + } + + static VolatileImage dstImage; + static void initImage(GraphicsConfiguration gc, Image image) { + Graphics g = image.getGraphics(); + g.setColor(Color.RED); + int w = image.getWidth(null); + int h = image.getHeight(null); + g.fillRect(0, 0, w, h); + g.dispose(); + + // need to 'accelerate' the image + if (dstImage == null) { + dstImage = + gc.createCompatibleVolatileImage(TESTW, TESTH, + Transparency.OPAQUE); + } + dstImage.validate(gc); + g = dstImage.getGraphics(); + g.drawImage(image, 0, 0, null); + g.drawImage(image, 0, 0, null); + g.drawImage(image, 0, 0, null); + } + + static VolatileImage getVImage(GraphicsConfiguration gc, + int w, int h) + { + VolatileImage image = + gc.createCompatibleVolatileImage(w, h, Transparency.OPAQUE); + image.validate(gc); + initImage(gc, image); + return image; + } + + static Image getBMImage(GraphicsConfiguration gc, + int w, int h) + { + Image image = + gc.createCompatibleImage(w, h, Transparency.BITMASK); + initImage(gc, image); + return image; + } + + static Image getBufferedImage(GraphicsConfiguration gc, + int w, int h, int type, boolean acceleratable) + { + BufferedImage image = new BufferedImage(w, h, type); + if (!acceleratable) { + image.setAccelerationPriority(0.0f); + } + initImage(gc, image); + return image; + } +} diff --git a/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.java b/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.java new file mode 100644 index 000000000..0b85955a2 --- /dev/null +++ b/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.java @@ -0,0 +1,156 @@ +/* + * Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; + +/* + * + * + * Tests that the use of shared memory pixmaps isn't broken: + * create a VolatileImage, fill it with red color, copy it to the screen + * make sure the pixels on the screen are red. + * + * Note that we force the use of shared memory pixmaps in the shell script. + * + * @author Dmitri.Trembovetski + */ + +public class SharedMemoryPixmapsTest { + static final int IMAGE_SIZE = 100; + static boolean show = false; + final Frame testFrame; + /** Creates a new instance of SharedMemoryPixmapsTest */ + public SharedMemoryPixmapsTest() { + testFrame = new Frame("SharedMemoryPixmapsTest"); + testFrame.add(new TestComponent()); + testFrame.pack(); + testFrame.setVisible(true); + } + + public static void main(String[] args) { + for (String s : args) { + if ("-show".equals(s)) { + show = true; + } else { + System.err.println("Usage: SharedMemoryPixmapsTest [-show]"); + } + } + new SharedMemoryPixmapsTest(); + } + + private class TestComponent extends Component { + VolatileImage vi = null; + boolean tested = false; + + void initVI() { + int res; + if (vi == null) { + res = VolatileImage.IMAGE_INCOMPATIBLE; + } else { + res = vi.validate(getGraphicsConfiguration()); + } + if (res == VolatileImage.IMAGE_INCOMPATIBLE) { + if (vi != null) vi.flush(); + vi = createVolatileImage(IMAGE_SIZE, IMAGE_SIZE); + vi.validate(getGraphicsConfiguration()); + res = VolatileImage.IMAGE_RESTORED; + } + if (res == VolatileImage.IMAGE_RESTORED) { + Graphics vig = vi.getGraphics(); + vig.setColor(Color.red); + vig.fillRect(0, 0, vi.getWidth(), vi.getHeight()); + vig.dispose(); + } + } + + @Override + public synchronized void paint(Graphics g) { + do { + g.setColor(Color.green); + g.fillRect(0, 0, getWidth(), getHeight()); + + initVI(); + g.drawImage(vi, 0, 0, null); + } while (vi.contentsLost()); + + Toolkit.getDefaultToolkit().sync(); + if (!tested) { + if (testRendering()) { + System.err.println("Test Passed"); + } else { + System.err.println("Test Failed"); + } + tested = true; + } + if (!show) { + testFrame.setVisible(false); + testFrame.dispose(); + } + } + + private boolean testRendering() throws RuntimeException { + Robot r = null; + try { + r = new Robot(); + } catch (AWTException ex) { + ex.printStackTrace(); + throw new RuntimeException("Can't create Robot"); + } + Point p = getLocationOnScreen(); + BufferedImage b = + r.createScreenCapture(new Rectangle(p, getPreferredSize())); + for (int y = 0; y < b.getHeight(); y++) { + for (int x = 0; x < b.getWidth(); x++) { + if (b.getRGB(x, y) != Color.red.getRGB()) { + System.err.println("Incorrect pixel" + " at " + + x + "x" + y + " : " + + Integer.toHexString(b.getRGB(x, y))); + if (show) { + return false; + } + System.err.println("Test Failed"); + System.exit(1); + } + } + } + return true; + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(IMAGE_SIZE, IMAGE_SIZE); + } + } + +} diff --git a/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.sh b/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.sh new file mode 100644 index 000000000..2bc9fd10c --- /dev/null +++ b/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.sh @@ -0,0 +1,51 @@ +# +# Copyright 2005-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +#!/bin/sh +# @test +# @bug 6363434 6588884 +# @summary Verify that shared memory pixmaps are not broken +# by filling a VolatileImage with red color and copying it +# to the screen. +# Note that we force the use of shared memory pixmaps. +# @author Dmitri.Trembovetski + +echo "TESTJAVA=${TESTJAVA}" +echo "TESTSRC=${TESTSRC}" +echo "TESTCLASSES=${TESTCLASSES}" +cd ${TESTSRC} +${TESTJAVA}/bin/javac -d ${TESTCLASSES} SharedMemoryPixmapsTest.java +cd ${TESTCLASSES} + +NO_J2D_DGA=true +J2D_PIXMAPS=shared +export NO_J2D_DGA J2D_PIXMAPS + +${TESTJAVA}/bin/java SharedMemoryPixmapsTest + +if [ $? -ne 0 ]; then + echo "Test failed!" + exit 1 +fi + +exit 0 diff --git a/test/sun/java2d/pipe/MutableColorTest/MutableColorTest.java b/test/sun/java2d/pipe/MutableColorTest/MutableColorTest.java new file mode 100644 index 000000000..30e7f949f --- /dev/null +++ b/test/sun/java2d/pipe/MutableColorTest/MutableColorTest.java @@ -0,0 +1,169 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6613860 6691934 + * @summary Tests that the pipelines can handle (in somewhat limited + * manner) mutable Colors + * + * @run main/othervm MutableColorTest + * @run main/othervm -Dsun.java2d.noddraw=true MutableColorTest + * @run main/othervm -Dsun.java2d.opengl=True MutableColorTest + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Transparency; +import java.awt.geom.Ellipse2D; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class MutableColorTest { + + static Image bmImage; + static Image argbImage; + + static class EvilColor extends Color { + Color colors[] = { Color.red, Color.green, Color.blue }; + int currentIndex = 0; + EvilColor() { + super(Color.red.getRGB()); + } + + @Override + public int getRGB() { + return colors[currentIndex].getRGB(); + } + void nextColor() { + currentIndex++; + } + } + + private static int testImage(Image im, + boolean doClip, boolean doTx) + { + int w = im.getWidth(null); + int h = im.getHeight(null); + Graphics2D g = (Graphics2D)im.getGraphics(); + EvilColor evilColor = new EvilColor(); + g.setColor(evilColor); + g.fillRect(0, 0, w, h); + g.dispose(); + + evilColor.nextColor(); + + g = (Graphics2D)im.getGraphics(); + + if (doTx) { + g.rotate(Math.PI/2.0, w/2, h/2); + } + g.setColor(evilColor); + g.fillRect(0, 0, w, h); + if (doClip) { + g.clip(new Ellipse2D.Float(0, 0, w, h)); + } + g.fillRect(0, h/3, w, h/3); + + // tests native BlitBg loop + g.drawImage(bmImage, 0, 2*h/3, evilColor, null); + // tests General BlitBg loop + g.drawImage(argbImage, 0, 2*h/3+h/3/2, evilColor, null); + + return evilColor.getRGB(); + } + + private static void testResult(final String desc, + final BufferedImage snapshot, + final int evilColor) { + for (int y = 0; y < snapshot.getHeight(); y++) { + for (int x = 0; x < snapshot.getWidth(); x++) { + int snapRGB = snapshot.getRGB(x, y); + if (snapRGB != evilColor) { + System.err.printf("Wrong RGB for %s at (%d,%d): 0x%x " + + "instead of 0x%x\n", desc, x, y, snapRGB, evilColor); + String fileName = "MutableColorTest_"+desc+".png"; + try { + ImageIO.write(snapshot, "png", new File(fileName)); + System.err.println("Dumped snapshot to "+fileName); + } catch (IOException ex) {} + throw new RuntimeException("Test FAILED."); + } + } + } + } + + public static void main(String[] args) { + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + + bmImage = gc.createCompatibleImage(64, 64, Transparency.BITMASK); + argbImage = gc.createCompatibleImage(64, 64, Transparency.TRANSLUCENT); + + if (gc.getColorModel().getPixelSize() > 8) { + VolatileImage vi = + gc.createCompatibleVolatileImage(64, 64, Transparency.OPAQUE); + do { + if (vi.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) { + vi = gc.createCompatibleVolatileImage(64, 64, + Transparency.OPAQUE); + vi.validate(gc); + } + + int color = testImage(vi, false, false); + testResult("vi_noclip_notx", vi.getSnapshot(), color); + + color = testImage(vi, true, true); + testResult("vi_clip_tx", vi.getSnapshot(), color); + + color = testImage(vi, true, false); + testResult("vi_clip_notx", vi.getSnapshot(), color); + + color = testImage(vi, false, true); + testResult("vi_noclip_tx", vi.getSnapshot(), color); + } while (vi.contentsLost()); + } + + BufferedImage bi = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB); + int color = testImage(bi, false, false); + testResult("bi_noclip_notx", bi, color); + + color = testImage(bi, true, true); + testResult("bi_clip_tx", bi, color); + + color = testImage(bi, true, false); + testResult("bi_clip_notx", bi, color); + + color = testImage(bi, false, true); + testResult("bi_noclip_tx", bi, color); + + System.err.println("Test passed."); + } +} diff --git a/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java b/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java new file mode 100644 index 000000000..52ddd3b21 --- /dev/null +++ b/test/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java @@ -0,0 +1,308 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6635805 6653780 6667607 + * @summary Tests that the resource sharing layer API is not broken + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @compile -XDignore.symbol.file=true RSLAPITest.java + * @run main/othervm RSLAPITest + * @run main/othervm -Dsun.java2d.noddraw=true RSLAPITest + * @run main/othervm -Dsun.java2d.opengl=True RSLAPITest + */ + +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; +import java.awt.Transparency; +import java.awt.image.VolatileImage; +import java.util.HashSet; +import sun.java2d.DestSurfaceProvider; +import sun.java2d.Surface; +import sun.java2d.pipe.BufferedContext; +import sun.java2d.pipe.RenderQueue; +import sun.java2d.pipe.hw.AccelDeviceEventListener; +import sun.java2d.pipe.hw.AccelGraphicsConfig; +import sun.java2d.pipe.hw.AccelSurface; +import static java.awt.Transparency.*; +import java.lang.reflect.Field; +import static sun.java2d.pipe.hw.AccelSurface.*; +import static sun.java2d.pipe.hw.ContextCapabilities.*; + +public class RSLAPITest { + private static volatile boolean failed = false; + + public static void main(String[] args) { + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + testGC(gc); + + if (failed) { + throw new RuntimeException("Test FAILED. See err output for more"); + } + + System.out.println("Test PASSED."); + } + + private static void testInvalidType(AccelSurface surface, int type) { + long ret = surface.getNativeResource(type); + System.out.printf(" getNativeResource(%d)=0x%x\n", type, ret); + if (ret != 0l) { + System.err.printf( + "FAILED: surface.getNativeResource(%d) returned" + + " 0x%s. It should have have returned 0L\n", + type, ret); + failed = true; + } + } + + private static void testD3DDeviceResourceField(final AccelSurface surface) { + try { + Class d3dc = Class.forName("sun.java2d.d3d.D3DSurfaceData"); + if (d3dc.isInstance(surface)) { + Field f = d3dc.getDeclaredField("D3D_DEVICE_RESOURCE"); + f.setAccessible(true); + int d3dDR = (Integer)f.get(null); + + System.out.printf( + " getNativeResource(D3D_DEVICE_RESOURCE)=0x%x\n", + surface.getNativeResource(d3dDR)); + } + } catch (ClassNotFoundException e) {} + catch (IllegalAccessException e) {} + catch (NoSuchFieldException e) { + System.err.println("Failed: D3DSurfaceData.D3D_DEVICE_RESOURCE" + + " field not found!"); + failed = true; + } + } + + private static void printSurface(Surface s) { + if (s instanceof AccelSurface) { + final AccelSurface surface = (AccelSurface) s; + System.out.println(" Accel Surface: "); + System.out.println(" type=" + surface.getType()); + System.out.println(" bounds=" + surface.getBounds()); + System.out.println(" nativeBounds=" + surface.getNativeBounds()); + System.out.println(" isSurfaceLost=" + surface.isSurfaceLost()); + System.out.println(" isValid=" + surface.isValid()); + RenderQueue rq = surface.getContext().getRenderQueue(); + rq.lock(); + try { + rq.flushAndInvokeNow(new Runnable() { + public void run() { + System.out.printf(" getNativeResource(TEXTURE)=0x%x\n", + surface.getNativeResource(TEXTURE)); + System.out.printf(" getNativeResource(RT_TEXTURE)=0x%x\n", + surface.getNativeResource(RT_TEXTURE)); + System.out.printf(" getNativeResource(RT_PLAIN)=0x%x\n", + surface.getNativeResource(RT_PLAIN)); + System.out.printf( + " getNativeResource(FLIP_BACKBUFFER)=0x%x\n", + surface.getNativeResource(FLIP_BACKBUFFER)); + + testD3DDeviceResourceField(surface); + + testInvalidType(surface, -1); + testInvalidType(surface, -150); + testInvalidType(surface, 300); + testInvalidType(surface, Integer.MAX_VALUE); + testInvalidType(surface, Integer.MIN_VALUE); + } + }); + } finally { + rq.unlock(); + } + } else { + System.out.println("null accelerated surface"); + } + } + + private static void printAGC(AccelGraphicsConfig agc) { + System.out.println("Accelerated Graphics Config: " + agc); + System.out.println("Capabilities:"); + System.out.printf("AGC caps: 0x%x\n", + agc.getContextCapabilities().getCaps()); + System.out.println(agc.getContextCapabilities()); + } + + private static void testGC(GraphicsConfiguration gc) { + if (!(gc instanceof AccelGraphicsConfig)) { + System.out.println("Test passed: no hw accelerated configs found."); + return; + } + System.out.println("AccelGraphicsConfig exists, testing."); + AccelGraphicsConfig agc = (AccelGraphicsConfig) gc; + printAGC(agc); + + testContext(agc); + + VolatileImage vi = gc.createCompatibleVolatileImage(10, 10); + vi.validate(gc); + if (vi instanceof DestSurfaceProvider) { + System.out.println("Passed: VI is DestSurfaceProvider"); + Surface s = ((DestSurfaceProvider) vi).getDestSurface(); + if (s instanceof AccelSurface) { + System.out.println("Passed: Obtained Accel Surface"); + printSurface((AccelSurface) s); + } + Graphics g = vi.getGraphics(); + if (g instanceof DestSurfaceProvider) { + System.out.println("Passed: VI graphics is " + + "DestSurfaceProvider"); + printSurface(((DestSurfaceProvider) g).getDestSurface()); + } + } else { + System.out.println("VI is not DestSurfaceProvider"); + } + testVICreation(agc, CAPS_RT_TEXTURE_ALPHA, TRANSLUCENT, RT_TEXTURE); + testVICreation(agc, CAPS_RT_TEXTURE_OPAQUE, OPAQUE, RT_TEXTURE); + testVICreation(agc, CAPS_RT_PLAIN_ALPHA, TRANSLUCENT, RT_PLAIN); + testVICreation(agc, agc.getContextCapabilities().getCaps(), OPAQUE, + TEXTURE); + testForNPEDuringCreation(agc); + } + + private static void testVICreation(AccelGraphicsConfig agc, int cap, + int transparency, int type) + { + int caps = agc.getContextCapabilities().getCaps(); + int w = 11, h = 17; + + VolatileImage vi = + agc.createCompatibleVolatileImage(w, h, transparency, type); + if ((cap & caps) != 0) { + if (vi == null) { + System.out.printf("Failed: cap=%d is supported but " + + "image wasn't created\n", cap); + throw new RuntimeException("Failed: image wasn't created " + + "for supported cap"); + } else { + if (!(vi instanceof DestSurfaceProvider)) { + throw new RuntimeException("Failed: created VI is not " + + "DestSurfaceProvider"); + } + Surface s = ((DestSurfaceProvider) vi).getDestSurface(); + if (s instanceof AccelSurface) { + AccelSurface as = (AccelSurface) s; + printSurface(as); + if (as.getType() != type) { + throw new RuntimeException("Failed: returned VI is" + + " of incorrect type: " + as.getType() + + " requested type=" + type); + } else { + System.out.printf("Passed: VI of type %d was " + + "created for cap=%d\n", type, cap); + } + if (as.getType() == TEXTURE) { + boolean ex = false; + try { + Graphics g = vi.getGraphics(); + g.dispose(); + } catch (UnsupportedOperationException e) { + ex = true; + } + if (!ex) { + throw new RuntimeException("Failed: " + + "texture.getGraphics() didn't throw exception"); + } else { + System.out.println("Passed: VI.getGraphics()" + + " threw exception for texture-based VI"); + } + } + } else { + System.out.printf("Passed: VI of type %d was " + + "created for cap=%d but accel surface is null\n", + type, cap); + } + } + } else { + if (vi != null) { + throw new RuntimeException("Failed: created VI for " + + "unsupported cap=" + cap); + } + } + } + + private static void testContext(final AccelGraphicsConfig agc) { + BufferedContext c = agc.getContext(); + final AccelDeviceEventListener l = new AccelDeviceEventListener() { + public void onDeviceDispose() { + System.out.println("onDeviceDispose invoked"); + agc.removeDeviceEventListener(this); + } + public void onDeviceReset() { + System.out.println("onDeviceReset invoked"); + } + }; + agc.addDeviceEventListener(l); + + RenderQueue rq = c.getRenderQueue(); + rq.lock(); + try { + c.saveState(); + rq.flushNow(); + c.restoreState(); + rq.flushNow(); + System.out.println("Passed: Save/Restore"); + } finally { + rq.unlock(); + } + } + + private static void testForNPEDuringCreation(AccelGraphicsConfig agc) { + int iterations = 100; + HashSet<VolatileImage> vis = new HashSet<VolatileImage>(); + GraphicsConfiguration gc = (GraphicsConfiguration)agc; + Rectangle r = gc.getBounds(); + long ram = gc.getDevice().getAvailableAcceleratedMemory(); + if (ram > 0) { + // guesstimate the number of iterations needed to exhaust vram + int i = 2 * + (int)(ram / (r.width * r.height * gc.getColorModel().getPixelSize()/8)); + iterations = Math.max(iterations, i); + System.err.println("iterations="+iterations); + } + for (int i = 0; i < iterations; i++) { + VolatileImage vi = + agc.createCompatibleVolatileImage(r.width, r.height, + Transparency.OPAQUE, + AccelSurface.RT_PLAIN); + if (vi == null) { + break; + } + vis.add(vi); + } + for (VolatileImage vi : vis) { + vi.flush(); + } + vis = null; + + System.out.println("Passed: testing for possible NPEs " + + "during VI creation"); + } +} diff --git a/test/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java b/test/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java new file mode 100644 index 000000000..cec37046c --- /dev/null +++ b/test/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java @@ -0,0 +1,338 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6678218 6681745 6691737 + * @summary Tests that v-synced BufferStrategies works (if vsync is supported) + * @author Dmitri.Trembovetski@sun.com: area=Graphics + * @compile -XDignore.symbol.file=true VSyncedBufferStrategyTest.java + * @run main/manual/othervm VSyncedBufferStrategyTest + * @run main/manual/othervm -Dsun.java2d.opengl=True VSyncedBufferStrategyTest + */ + +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.BufferCapabilities.FlipContents; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.HeadlessException; +import java.awt.ImageCapabilities; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferStrategy; +import java.util.concurrent.CountDownLatch; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class VSyncedBufferStrategyTest extends Canvas implements Runnable { + + private static final int BLOCK_W = 50; + private static final int BLOCK_H = 200; + + BufferStrategy bs; + Thread renderThread; + + int blockX = 10; + int blockY = 10; + + private volatile boolean done = false; + private volatile boolean requestVSync; + private boolean currentBSVSynced; + + public VSyncedBufferStrategyTest(boolean requestVSync) { + this.requestVSync = requestVSync; + this.currentBSVSynced = !requestVSync; + renderThread = new Thread(this); + renderThread.start(); + } + + private static final BufferCapabilities defaultBC = + new BufferCapabilities( + new ImageCapabilities(true), + new ImageCapabilities(true), + null); + + private void createBS(boolean requestVSync) { + if (bs != null && requestVSync == currentBSVSynced) { + return; + } + + BufferCapabilities bc = defaultBC; + if (requestVSync) { + bc = new sun.java2d.pipe.hw.ExtendedBufferCapabilities( + new ImageCapabilities(true), + new ImageCapabilities(true), + FlipContents.COPIED, + sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON); + } + try { + createBufferStrategy(2, bc); + } catch (AWTException e) { + System.err.println("Warning: cap is not supported: "+bc); + e.printStackTrace(); + createBufferStrategy(2); + } + currentBSVSynced = requestVSync; + bs = getBufferStrategy(); + String s = + getParent() instanceof Frame ? + ((Frame)getParent()).getTitle() : "parent"; + System.out.println("Created BS for \"" + s + "\" frame, bs="+bs); + } + + @Override + public void paint(Graphics g) { + } + @Override + public void update(Graphics g) { + } + + @Override + public void run() { + while (!isShowing()) { + try { Thread.sleep(5); } catch (InterruptedException e) {} + } + try { Thread.sleep(2000); } catch (InterruptedException e) {} + + try { + while (!done && isShowing()) { + createBS(requestVSync); + do { + step(); + Graphics g = bs.getDrawGraphics(); + render(g); + if (!bs.contentsRestored()) { + bs.show(); + } + } while (bs.contentsLost()); + Thread.yield(); + } + } catch (Throwable e) { + // since we're not bothering with proper synchronization, exceptions + // may be thrown when the frame is closed + if (isShowing()) { + throw new RuntimeException(e); + } + } + } + + int inc = 5; + private void step() { + blockX += inc; + if (blockX > getWidth() - BLOCK_W - 10) { + inc = -inc; + blockX += inc; + } + if (blockX < 10) { + inc = -inc; + blockX += inc; + } + } + + private void render(Graphics g) { + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + + g.setColor(Color.black); + g.fillRect(blockX, blockY, BLOCK_W, BLOCK_H); + } + + private void setRequestVSync(boolean reqVSync) { + requestVSync = reqVSync; + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(BLOCK_W*10+20, BLOCK_H+20); + } + + private static int frameNum = 0; + private static Frame createAndShowBSFrame() { + final Frame f = new Frame("Not V-Synced"); + + int myNum; + synchronized (VSyncedBufferStrategyTest.class) { + myNum = frameNum++; + } + + final VSyncedBufferStrategyTest component = + new VSyncedBufferStrategyTest(false); + f.setIgnoreRepaint(true); + f.add("Center", component); + + Panel p = new Panel(); + + Button b = new Button("Request VSync"); + b.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + f.setTitle("Possibly V-Synced"); + component.setRequestVSync(true); + } + }); + p.add(b); + + b = new Button("Relinquish VSync"); + b.addActionListener(new ActionListener() { + int inc = 1; + public void actionPerformed(ActionEvent e) { + f.setTitle("Not V-Synced"); + component.setRequestVSync(false); + f.setSize(f.getWidth()+inc, f.getHeight()); + inc = -inc; + } + }); + p.add(b); + + f.add("South", p); + + f.pack(); + f.setLocation(10, myNum * f.getHeight()); + f.setVisible(true); + f.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + component.done = true; + f.dispose(); + } + @Override + public void windowClosed(WindowEvent e) { + component.done = true; + } + }); + + return f; + } + + private static final String description = + "Tests that v-synced BufferStrategy works. Note that it in some\n" + + "cases the v-sync can not be enabled, and it is accepted.\n" + + "The following however is true: only one buffer strategy at a time can\n"+ + "be created v-synced. In order for other BS to become v-synced, the one\n"+ + "that currently is v-synched (or its window) needs to be disposed.\n" + + "Try the following scenarios:\n" + + " - click the \"Request VSync\" button in one of the frames. If the\n"+ + " behavior of the animation changes - the animation becomes smooth\n" + + " it had successfully created a v-synced BS. Note that the animation\n" + + " in other frames may also become smoother - this is a side-effect\n"+ + " of one of the BS-es becoming v-synched\n" + + " - click the \"Relinquish VSync\" button on the same frame. If the\n"+ + " behavior changes to the original (tearing)- it had successfully\n" + + " created a non-vsynced strategy.\n" + + " - next, try making another one v-synced. It should succeed.\n" + + " - next, try making another one v-synced - while there's already\n" + + " a v-synced frame. It should not succeed - meaning, it shouldn't\n" + + " appear to become smoother, and the behavior of the current v-synced\n" + + " frame shouldn't change.\n" + + "\n" + + "If there aren't any BufferStrategy-related exceptions or other\n" + + "issues, and the scenarios worked, the test passed, otherwise it\n"+ + "failed.\n"; + + private static void createAndShowDescGUI(final Frame f3, final Frame f1, + final Frame f2) + throws HeadlessException, RuntimeException + { + final JFrame desc = + new JFrame("VSyncedBufferStrategyTest - Description"); + desc.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + f1.dispose(); + f2.dispose(); + f3.dispose(); + l.countDown(); + } + }); + JPanel p = new JPanel(); + JButton bPassed = new JButton("Passed"); + bPassed.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + desc.dispose(); + f1.dispose(); + f2.dispose(); + f3.dispose(); + l.countDown(); + } + }); + JButton bFailed = new JButton("Failed"); + bFailed.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + failed = true; + desc.dispose(); + f1.dispose(); + f2.dispose(); + f3.dispose(); + l.countDown(); + } + }); + p.setLayout(new FlowLayout()); + p.add(bPassed); + p.add(bFailed); + JTextArea ta = new JTextArea(24, 75); + ta.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + ta.setEditable(false); + ta.setText(description); + desc.add("Center", new JScrollPane(ta)); + desc.add("South", p); + desc.pack(); + desc.setLocation(BLOCK_W*10+50, 0); + desc.setVisible(true); + } + + private static void createTestFrames() { + Frame f1 = createAndShowBSFrame(); + Frame f2 = createAndShowBSFrame(); + Frame f3 = createAndShowBSFrame(); + createAndShowDescGUI(f1, f2, f3); + } + + static boolean failed = false; + static CountDownLatch l = new CountDownLatch(1); + public static void main(String[] args) throws Exception { + EventQueue.invokeLater(new Runnable() { + public void run() { + createTestFrames(); + } + }); + l.await(); + if (failed) { + throw new RuntimeException("Test FAILED"); + } + System.out.println("Test PASSED"); + } + +} |