Fullscreen switching causing major problems

Just to be clear from the start, I’m using XP & Java 1.6.0-beta2, with the flag " -Dsun.java2d.opengl=True"
I have a frame that starts a thread to do the game loop (which I only use for painting).
I’m using a custom repaint manager that does nothing (null).
I’m developing on a system with dual monitors. ATI graphics card.

Now on to the problems. ::slight_smile:

I’m working on a toggle to switch from window mode to fullscreen mode. I don’t want to use exclusive fullscreen, just undecorated.
Here’s how I currently make the switch to fullscreen:


               GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
               GraphicsDevice dev = env.getDefaultScreenDevice();
		bufferStrategy.dispose();
		bufferStrategy = null;

		origBounds = this.getBounds();
			
		Rectangle screenSize = dev.getDefaultConfiguration().getBounds();
		screenSize.width -= 1;

		this.dispose();
		this.setResizable(false);
		this.setUndecorated(true);
		this.pack();

		this.setBounds(screenSize);

		this.createBufferStrategy(2);
		this.bufferStrategy = getBufferStrategy();
		
		this.setVisible(true);
		this.validate();

Note the screenSize.width -= 1. Without this, the other monitor (extended desktop) will distort and half mimic whatever is happening on the first. However, with the width reduced by 1, there is no distortion or strange behavior on the second monitor, but the windows taskbar now shows on top of the frame. :stuck_out_tongue:
That’s the first weird thing I can’t figure out. I’ve noted that this does not happen when I’m just using a standard JFrame, nor does the next problem- which makes me think these two might be related somehow.

The second problem is this: When switching between fullscreen and windowed mode, the 6th attempt (after 5 switches to fullscreen, and 5 switches back to windowed) to change from windowed mode to fullscreen mode causes the game to stop. It dosen’t crash visibly and no exceptions get thrown, it just stops. The game loop never gets past bufferStrategy.show(). This always happens on exactly the 6th attempt to fullscreen. If I minimize, the loop runs again until I restore it, where it stops when it hits bufferStrategy.show().

Here’s the code for coming out of fullscreen mode back to windowed:


		GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice dev = env.getDefaultScreenDevice();

		bufferStrategy.dispose();
		bufferStrategy = null;
		this.dispose();
		this.setResizable(true);
		this.setUndecorated(false);
		this.pack();
		this.setBounds(origBounds);
		this.createBufferStrategy(2);
		this.bufferStrategy = getBufferStrategy();
		
		this.setVisible(true);
		this.validate();

Here’s the game loop:


while (!stopFlag) {
        	if(displayChangeRequested) {
        		toggleFullscreenCallback();
        		displayChangeRequested = false;
        	}
        		
        	if(bufferStrategy != null) {
	            Graphics2D g2d = (Graphics2D)bufferStrategy.getDrawGraphics();
	            paint(g2d);

	            g2d.setColor(Color.black);
	            g2d.drawString("FPS : "+fpsCounter.getFPS(), getWidth() - 150, 50);
	            bufferStrategy.show();

	            g2d.dispose();
	            Thread.yield();
	
	            fpsCounter.frameDone();
	            System.out.flush();
        	} else {
        		try{
        			System.out.println("   waiting for bufferStrategy");
        			Thread.sleep(10);
        		} catch(Exception e) {
        			e.printStackTrace();
        		}
        	}
        }

I’d be most grateful if someone could tell me what’s going wrong. ;D

Here’s the whole class:


import ...

public class J2dGameFrame extends JFrame implements Runnable {


    private boolean stopFlag = false;

    private final JPanel mainContentPane = new JPanel();
    private BufferStrategy bufferStrategy;
    private FPSCounter fpsCounter = new FPSCounter();
    
    boolean displayChangeRequested = false;
	Rectangle origBounds;
	boolean isFullscreen = false;


    public J2dGameFrame() {
        setLayout(null);

        mainContentPane.setLayout(new BorderLayout());
        setContentPane(mainContentPane);

        RepaintManager.setCurrentManager(new NullRepaintManager());
    }

    public void addComponent(JComponent c) {
        mainContentPane.add(c);
        validate();
    }
    
    public void addComponent(Component comp, Object constraints) {
        mainContentPane.add(comp, constraints);
        validate();
    }

    public void start() {
        Thread thread = new Thread(this);
        thread.setName("J2dGameFrame rendering Thread");
        thread.start();
    }

    public void stopRunning() {
        stopFlag = true;
    }
    
    public void run() {

        System.out.println("  J2dGameFrame run()");
        while (bufferStrategy == null) {
            try {
                if (isDisplayable())  {
                    createBufferStrategy(2);
                    bufferStrategy = getBufferStrategy();
                }
                System.out.println("   waiting for bufferStrategy");
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        while (!stopFlag) {
        	if(displayChangeRequested) {
        		
        		toggleFullscreenCallback();
        		displayChangeRequested = false;
        	}
        		
        	if(bufferStrategy != null) {
	            Graphics2D g2d = (Graphics2D)bufferStrategy.getDrawGraphics();
	            paint(g2d);
	            g2d.setColor(Color.black);
	            g2d.drawString("FPS : "+fpsCounter.getFPS(), getWidth() - 150, 50);
	            bufferStrategy.show();
	            g2d.dispose();
	            Thread.yield();
	
	            fpsCounter.frameDone();
        	} else {
        		try{
        			System.out.println("   waiting for bufferStrategy");
        			Thread.sleep(10);
        		} catch(Exception e) {
        			e.printStackTrace();
        		}
        	}
        }
    }

    public void toggleFullscreen() {
    	displayChangeRequested = true;
    	System.out.println("Toggle requested");
    }
    
	public void toggleFullscreenCallback() {
		GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice dev = env.getDefaultScreenDevice();

		bufferStrategy.dispose();
		bufferStrategy = null;
		if(isFullscreen) {
			System.out.println("Exit fullscreen. size: "+origBounds);
			
			this.dispose();
			this.setResizable(true);
			this.setUndecorated(false);
			this.pack();

			this.setBounds(origBounds);
			
			isFullscreen = false;
		} else {
			origBounds = this.getBounds();
			origDisplayMode = dev.getDisplayMode();
			
			Rectangle screenSize = dev.getDefaultConfiguration().getBounds();
			screenSize.width -= 1;
			System.out.println("Enter fullscreen. size: "+screenSize);
			
			this.dispose();
			this.setResizable(false);
			this.setUndecorated(true);
			this.pack();
			
			this.setBounds(screenSize);
			
			isFullscreen = true;
		}
		this.createBufferStrategy(2);
		this.bufferStrategy = getBufferStrategy();
		
		this.setVisible(true);
		this.validate();
	}
}

I should also mention that after the program dies, explorer.exe loses its acceleration. Things like scrolling and moving windows turns into a chore (like X with no acceleration)

Last addition, I swear!

If I disable opengl, all my problems go away.
ie. -Dsun.java2d.opengl=False

I read about someone else having problems with the ATI Raedon X600, but with Direct3D:
http://forums.java.net/jive/thread.jspa?threadID=18088&messageID=150502

::slight_smile:

Doing this causes my framerate to drop from 160+ to around 30+, which wouldn’t be a problem if there still wasn’t a lot of things to be added. :’(

Hi,

I have had this problem myself - Chris Campbell has told me it is a bug specific to Windows with the OGL pipeline. He said he’d try and get a fix out in an update to Mustang sometime after its release.

Bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6432096

Chris’s reply to the problem, see last posts:
http://forums.java.net/jive/thread.jspa?threadID=17494&tstart=0

I hope you can work around it. The D3D, noddraw & the default pipelines still work for me when switching between screen modes by the way - I use the same NullReapintManager.

Keith

Thanks for the reply. I poked around in the bug database a bit and found this tidbit, which fixed another problem I was having where java would crash and blame the video drivers:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6458746

I guess all I can really do for now is wait for the fixes to come along. Thanks again!