Path: blob/master/test/jdk/sun/java2d/pipe/hw/VSyncedBufferStrategyTest/VSyncedBufferStrategyTest.java
41159 views
/*1* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22/*23* @test24* @bug 6678218 6681745 6691737 819861325* @summary Tests that v-synced BufferStrategies works (if vsync is supported)26* @author [email protected]: area=Graphics27* @modules java.desktop/sun.java2d.pipe.hw28* @compile -XDignore.symbol.file=true VSyncedBufferStrategyTest.java29* @run main/manual/othervm VSyncedBufferStrategyTest30*/3132import java.awt.AWTException;33import java.awt.BufferCapabilities;34import java.awt.BufferCapabilities.FlipContents;35import java.awt.Button;36import java.awt.Canvas;37import java.awt.Color;38import java.awt.Dimension;39import java.awt.EventQueue;40import java.awt.FlowLayout;41import java.awt.Font;42import java.awt.Frame;43import java.awt.Graphics;44import java.awt.HeadlessException;45import java.awt.ImageCapabilities;46import java.awt.Panel;47import java.awt.event.ActionEvent;48import java.awt.event.ActionListener;49import java.awt.event.WindowAdapter;50import java.awt.event.WindowEvent;51import java.awt.image.BufferStrategy;52import java.util.concurrent.CountDownLatch;53import javax.swing.JButton;54import javax.swing.JFrame;55import javax.swing.JPanel;56import javax.swing.JScrollPane;57import javax.swing.JTextArea;5859public class VSyncedBufferStrategyTest extends Canvas implements Runnable {6061private static final int BLOCK_W = 50;62private static final int BLOCK_H = 200;6364BufferStrategy bs;65Thread renderThread;6667int blockX = 10;68int blockY = 10;6970private volatile boolean done = false;71private volatile boolean requestVSync;72private boolean currentBSVSynced;7374public VSyncedBufferStrategyTest(boolean requestVSync) {75this.requestVSync = requestVSync;76this.currentBSVSynced = !requestVSync;77renderThread = new Thread(this);78renderThread.start();79}8081private static final BufferCapabilities defaultBC =82new BufferCapabilities(83new ImageCapabilities(true),84new ImageCapabilities(true),85null);8687private void createBS(boolean requestVSync) {88if (bs != null && requestVSync == currentBSVSynced) {89return;90}9192BufferCapabilities bc = defaultBC;93if (requestVSync) {94bc = new sun.java2d.pipe.hw.ExtendedBufferCapabilities(95new ImageCapabilities(true),96new ImageCapabilities(true),97FlipContents.COPIED,98sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON);99}100try {101createBufferStrategy(2, bc);102} catch (AWTException e) {103System.err.println("Warning: cap is not supported: "+bc);104e.printStackTrace();105createBufferStrategy(2);106}107currentBSVSynced = requestVSync;108bs = getBufferStrategy();109String s =110getParent() instanceof Frame ?111((Frame)getParent()).getTitle() : "parent";112System.out.println("Created BS for \"" + s + "\" frame, bs="+bs);113}114115@Override116public void paint(Graphics g) {117}118@Override119public void update(Graphics g) {120}121122@Override123public void run() {124while (!isShowing()) {125try { Thread.sleep(5); } catch (InterruptedException e) {}126}127try { Thread.sleep(2000); } catch (InterruptedException e) {}128129try {130while (!done && isShowing()) {131createBS(requestVSync);132do {133step();134Graphics g = bs.getDrawGraphics();135render(g);136if (!bs.contentsRestored()) {137bs.show();138}139} while (bs.contentsLost());140Thread.yield();141}142} catch (Throwable e) {143// since we're not bothering with proper synchronization, exceptions144// may be thrown when the frame is closed145if (isShowing()) {146throw new RuntimeException(e);147}148}149}150151int inc = 5;152private void step() {153blockX += inc;154if (blockX > getWidth() - BLOCK_W - 10) {155inc = -inc;156blockX += inc;157}158if (blockX < 10) {159inc = -inc;160blockX += inc;161}162}163164private void render(Graphics g) {165g.setColor(Color.white);166g.fillRect(0, 0, getWidth(), getHeight());167168g.setColor(Color.black);169g.fillRect(blockX, blockY, BLOCK_W, BLOCK_H);170}171172private void setRequestVSync(boolean reqVSync) {173requestVSync = reqVSync;174}175176@Override177public Dimension getPreferredSize() {178return new Dimension(BLOCK_W*10+20, BLOCK_H+20);179}180181private static int frameNum = 0;182private static Frame createAndShowBSFrame() {183final Frame f = new Frame("Not V-Synced");184185int myNum;186synchronized (VSyncedBufferStrategyTest.class) {187myNum = frameNum++;188}189190final VSyncedBufferStrategyTest component =191new VSyncedBufferStrategyTest(false);192f.setIgnoreRepaint(true);193f.add("Center", component);194195Panel p = new Panel();196197Button b = new Button("Request VSync");198b.addActionListener(new ActionListener() {199public void actionPerformed(ActionEvent e) {200f.setTitle("Possibly V-Synced");201component.setRequestVSync(true);202}203});204p.add(b);205206b = new Button("Relinquish VSync");207b.addActionListener(new ActionListener() {208int inc = 1;209public void actionPerformed(ActionEvent e) {210f.setTitle("Not V-Synced");211component.setRequestVSync(false);212f.setSize(f.getWidth()+inc, f.getHeight());213inc = -inc;214}215});216p.add(b);217218f.add("South", p);219220f.pack();221f.setLocation(10, myNum * f.getHeight());222f.setVisible(true);223f.addWindowListener(new WindowAdapter() {224@Override225public void windowClosing(WindowEvent e) {226component.done = true;227f.dispose();228}229@Override230public void windowClosed(WindowEvent e) {231component.done = true;232}233});234235return f;236}237238private static final String description =239"Tests that v-synced BufferStrategy works. Note that it in some\n" +240"cases the v-sync can not be enabled, and it is accepted.\n" +241"The following however is true: only one buffer strategy at a time can\n"+242"be created v-synced. In order for other BS to become v-synced, the one\n"+243"that currently is v-synched (or its window) needs to be disposed.\n" +244"Try the following scenarios:\n" +245" - click the \"Request VSync\" button in one of the frames. If the\n"+246" behavior of the animation changes - the animation becomes smooth\n" +247" it had successfully created a v-synced BS. Note that the animation\n" +248" in other frames may also become smoother - this is a side-effect\n"+249" of one of the BS-es becoming v-synched\n" +250" - click the \"Relinquish VSync\" button on the same frame. If the\n"+251" behavior changes to the original (tearing)- it had successfully\n" +252" created a non-vsynced strategy.\n" +253" - next, try making another one v-synced. It should succeed.\n" +254" - next, try making another one v-synced - while there's already\n" +255" a v-synced frame. It should not succeed - meaning, it shouldn't\n" +256" appear to become smoother, and the behavior of the current v-synced\n" +257" frame shouldn't change.\n" +258"\n" +259"If there aren't any BufferStrategy-related exceptions or other\n" +260"issues, and the scenarios worked, the test passed, otherwise it\n"+261"failed.\n";262263private static void createAndShowDescGUI(final Frame f3, final Frame f1,264final Frame f2)265throws HeadlessException, RuntimeException266{267final JFrame desc =268new JFrame("VSyncedBufferStrategyTest - Description");269desc.addWindowListener(new WindowAdapter() {270271@Override272public void windowClosing(WindowEvent e) {273f1.dispose();274f2.dispose();275f3.dispose();276l.countDown();277}278});279JPanel p = new JPanel();280JButton bPassed = new JButton("Passed");281bPassed.addActionListener(new ActionListener() {282public void actionPerformed(ActionEvent e) {283desc.dispose();284f1.dispose();285f2.dispose();286f3.dispose();287l.countDown();288}289});290JButton bFailed = new JButton("Failed");291bFailed.addActionListener(new ActionListener() {292public void actionPerformed(ActionEvent e) {293failed = true;294desc.dispose();295f1.dispose();296f2.dispose();297f3.dispose();298l.countDown();299}300});301p.setLayout(new FlowLayout());302p.add(bPassed);303p.add(bFailed);304JTextArea ta = new JTextArea(24, 75);305ta.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));306ta.setEditable(false);307ta.setText(description);308desc.add("Center", new JScrollPane(ta));309desc.add("South", p);310desc.pack();311desc.setLocation(BLOCK_W*10+50, 0);312desc.setVisible(true);313}314315private static void createTestFrames() {316Frame f1 = createAndShowBSFrame();317Frame f2 = createAndShowBSFrame();318Frame f3 = createAndShowBSFrame();319createAndShowDescGUI(f1, f2, f3);320}321322static boolean failed = false;323static CountDownLatch l = new CountDownLatch(1);324public static void main(String[] args) throws Exception {325EventQueue.invokeLater(new Runnable() {326public void run() {327createTestFrames();328}329});330l.await();331if (failed) {332throw new RuntimeException("Test FAILED");333}334System.out.println("Test PASSED");335}336337}338339340