BufferStrategy and Alt-Tab

I’m somewhat new to High Performance Entertainment programming in java and i’ve hit a minor snag that i wanted to ask about.

My renderer thread seems to be working fine and is all happy until I Alt-Tab to windows and then back to my game. I’ve read the api docs and it really does seem like buffers might be getting lost but since i’m actually completely redrawing each frame(perhaps not the most optimal solution but enough atm) what i’m reading seems to say that shouldn’t be a problem.

While i can simply say “don’t alt-tab cos it ain’t supported” i’d rather find out whats going wrong and fix it(obviously)… I’d be uber grateful if anyone came up with anything. The code for my renderer follows


      public void run() {
            BufferStrategy bs = this.getBufferStrategy();

            Image bgImage = getToolkit().createImage("bg.jpg");

            while (t != null) {
                  Graphics g = bs.getDrawGraphics();

                  g.drawImage(bgImage, 0, 0, this);

                  bs.show();
                  g.dispose();

                  t.yield();
            }
      }


Theres nothing wrong with that render loop.

The Alt+Tab problem is a hardware specific problem, and is cased by a bug[s] in Suns code, so isn’t realy fixable by us :frowning:

what gfx card have u got?

p.s. what createBufferStrategy() method are you using?

GEForce 2 Ultra

just the simple bs.createBufferStrategy(2);

have u got the latest drivers?

i’ve got a gf2 gts, and it alt+tabs back and forth fine.

I get the same problem as well actually with a Geforce 4 Ti 4400 and I think not the latest but the previous release of the Detonator drivers. Are you using Detonators as well?

I believe i’m using detonator 40.72 tho it could be 30.82 (i’m not totally sure which i installed).

To add fuel to the fire i’ve realised that the Java MultiBufferTest (at http://java.sun.com/docs/books/tutorial/extra/fullscreen/example-1dot4/MultiBufferTest.java)
works fine and happily without any problems.

Looking at the code the only thing that i can see that i’m doing differently seems to be that i’m using threads (and when i tried it without using threads it still has the problem)

This is weird.

Dante,

Can you post a complete test app that demos the problems you’re seeing? Also, describe exactly what the problem is (crash? hang? slowdown? white-screen of death?). We fixed major alt-tab fullscreen problems in release 1.4.1_02 and 1.4.2-beta, but I have heard of possible issues related to BufferStrategy and alt-tab. I have not yet reproduced these problems, so if you have anything easy and tangible that i can work with, that would help me narrow down the problem.

Thanks,
Chet.
(Java2D)

OK i tried to create something smaller and easier to work with and it didn’t have any problems(I’m starting to think that Java has a well defined sense of humour :P). This however also leads me to think the problem is me doing something bad.

This thing consists of 2 items of code the main function and the window class. To use these 2 bits of code you need a jpeg called bg.jpg in the working directory. mines 800x600 but anything should in theory work. this however is all the code being used.

What actually happens is that when i alt-tab back to the app it fails to redraw the image leaving me with a blank screen. I’m also using java 1.4.1_01 so that might be part of the problem too.

(sorry for the spammage… would have linked to a website but realised that atm i don’t actually have one)

Main function isn’t anything truly special


import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

public class InfiltratorMain {
      static GraphicsEnvironment ge;
      static GraphicsDevice gs;
      static DisplayMode oldDisplay;

      public static void main(String[] args) {
            // Determine if full-screen mode is supported directly
            ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            gs = ge.getDefaultScreenDevice();

            // Create a window for full-screen mode; add a button to leave full-screen mode
            BufferStrategyTest win = new BufferStrategyTest(gs.getDefaultConfiguration());

            // If full screen is possible go full screen 800x600
            if (gs.isFullScreenSupported()) {
                  gs.setFullScreenWindow(win);
                  if (gs.isDisplayChangeSupported()) {
                        oldDisplay = gs.getDisplayMode();
                gs.setDisplayMode(new DisplayMode(800, 600, 16, oldDisplay.getRefreshRate()));
                  }
            } else {
                  System.out.println("Full Screen Mode unavailable. emulation engaged");
                  gs.setFullScreenWindow(win);
            }
            win.resize();
            win.createBufferStrategy(2);
            win.start();
      }

}

The window class is (in theory) responsible for handling input and output with the user.


import javax.swing.JWindow;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;

public class BufferStrategyTest extends JWindow implements Runnable, MouseListener {
      Thread t;
      int width;
      int height;
      Image bgImage;

      public BufferStrategyTest(GraphicsConfiguration gc) {
            super(gc);
            t = null;
              bgImage = getToolkit().createImage("bg.jpg");

            addMouseListener(this);
            setIgnoreRepaint(true);
      }

      public void paint(Graphics g) {
            // This function does nothing.. for painting see run()
      }

      // This tells the DrawnPanel that it has been resized so it needs to reset its size variables
      public void resize() {
            GraphicsDevice gs = getGraphicsConfiguration().getDevice();
            width = gs.getDisplayMode().getWidth();
            height = gs.getDisplayMode().getHeight();
      }

      public void start() {
            resize();
            if (t == null) {
                  t = new Thread(this);
                  t.setPriority(Thread.MIN_PRIORITY);
                  t.start();
            }
      }

      public void stop() {
            t = null;
      }

      // MouseListener Implementation
      public void mouseClicked(MouseEvent e) {
            this.stop();
            System.exit(0);
      }

      public void mousePressed(MouseEvent e) {}

      public void mouseReleased(MouseEvent e) {}
      public void mouseExited(MouseEvent e) {}
      public void mouseEntered(MouseEvent e) {}

      public void run() {
            BufferStrategy bs = this.getBufferStrategy();

            while (t != null) {
                  Graphics g = bs.getDrawGraphics();
                  if (!bs.contentsLost()) {

                        g.drawImage(bgImage, 0, 0, width, height, this);

                        bs.show();
                        g.dispose();
                  }
                  t.yield();
            }
      }
}

You realy should get the latest version of Java & your drivers b4 posting potencial bugs :smiley:

(btw, the latest Detonator drivers are 43.45)

to be honest i thought i was using revision 2 jdk :confused: