diff options
Diffstat (limited to 'test/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java')
-rw-r--r-- | test/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java | 338 |
1 files changed, 338 insertions, 0 deletions
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"); + } + +} |