Package

Source Code of VSyncedBufferStrategyTest

/*
* 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");
    }

}
TOP

Related Classes of VSyncedBufferStrategyTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.