How to leave fullscreen mode and not crash?

Greetings.

Okay, using BufferStrategy and rendering nicely to the screen. When a user decides to quit, I can pretty much guarantee that the system will throw an exception upon leaving because of the BufferStrategy. I think it is nulled at some point, and before anyone starts suggesting I debug the code, that’s not the point of this post.

The point is to ask (and hopefully others will benefit from the question) what other developers are doing to exit their game without throwing an exception? I am not sure what should be done when, that’s what I’m examining now, but some guidance would be very appreciated.

Code:


                  fsf.startRenderThread();
                  fsf.setDisplayFPS( true );
                  while( !fsf.bEnd )
                  {
                        // Wait
                  }
                  fsf.stopRenderThread();
                  fsf.initFromScreen();



      public void startRenderThread()
      {
            timer.start();

            if ( doRender == false )
            {
                  timeLastFrame = timer.getClockTicks();
                  pauseRender = false;
                  doRender = true;
                  renderThread = new Thread( this, "Render Thread" );
                  renderThread.start();
            }
      }


      public void stopRenderThread()
      {
            doRender = false;
            pauseRender = false;
      }



      public void run()
      {
            boolean contentsLost = false;
            try
            {
                  while ( doRender )
                  {
                        if ( !pauseRender )
                        {
                              if ( doRender( null ) )
                              {
                                    bufferStrategy.show();
                              }

                              timer.sleep( renderLoopSpeed );
                        }
                  }
            }
            catch ( Exception x )
            {
            }
      }


      public void initFromScreen()
      {
            if ( !windowed )
            {
                  graphicsDevice.setDisplayMode( oldDisplayMode );
                  graphicsDevice.setFullScreenWindow( null );
            }
      }

Thanks.

stopRenderThread() doesn’t wait for the renderer to actually stop before you go on to return to window mode. You also need some synchronization (or use of volatile) to ensure that the rendering thread actually sees the changes to the doRender/pauseRender flags.

Thanks for the reply, Mark.

After rereading your post a few times… I think I’m seeing the point. We ask the thread to stop rendering, but do not wait for it to actually do so… thus causing problems since things are largely unsynchronized. Back to multithreading school I go.

That’s it. The second point was that due to the lack of synchronization the rendering thread may never see the request to stop unless the flag fields were declared volatile.

Your suggestion seems to mean that simply declaring doRender and pauseRender as:

protected static volatile boolean

should do the job nicely, as it GUARANTEES that the shared copies will be updated correctly when the main thread alters those values in stopRenderThread()

Probably a delay of one or two ms between calling stopRenderThread and initFromScreen is in order, to guarantee the thread has died.

Yes using volatile is the simplest way to ensure the message is received. Instead of using sleep, try

try {
   renderThread.join();
}
catch (InterruptedException ex) {}

Pass a timeout value to join if you don’t want to wait forever (only needed if your render thread might be broken and not watching for the stop request).