Ultra-fast drawImage() slideshow

I need to develop a slide-show routine which displays 64 full screen images as fast as possible. i.e.

  1. Load image from disk to an image array
  2. Switch to full screen mode
  3. drawImage()
  4. delay and draw next image

As I need very little delay (about 15ms, that is 64 fps) between each image, I have done the following to optimize the slideshow:

  • switch to full-screen exclusive mode
  • use multi-buffering and flipping in JDK 1.4
  • use 640x480x32 resolution instead of 1024x768

But the result is still unsatisfactory. Even though there is no flickering, the delay between images is unpredictable (I use sleep(15) but the delay is sometime several seconds!) and sometimes the screen just blanks out without displaying any images. I seem to recall there are alternatives to drawImage() method, does anyone know how to use them, or have better way to optimize the display?

p.s. Slideshow is not allowed to skip any images, all images must be displayed once within the time frame.

What format are the images in? I’ve found the JPEG decoder in the JRE to be relatively slow.

I would keep one thread reading images into a buffer and another thread drawing them to the screen. You want to make sure there is an I/O operation in progress while you are drawing and flipping pages etc.

I’ve got 30fps at 720x480 using a method like this with JPEG… WITHOUT the extra buffering, threads, or fullscreen mode… just decoding and calling repaint(). I was reading the images over a socket.

With images coming directly from a local disk and JPEG compression 30fps should be easy… 64 fps should also be possible, but I’ve never tried to go that fast.

Why do you need 64 fps? Anything over 30 is pretty much undetectable by the human eye, isn’t it? Or is it more like 72 fps that is undetectable…?

Or are my eyes just old and slow?

[quote]Why do you need 64 fps? Anything over 30 is pretty much undetectable by the human eye, isn’t it? Or is it more like 72 fps that is undetectable…?

Or are my eyes just old and slow?
[/quote]
This has been dicussed before.

To the original poster, if you are in fullscreen mode with a bufferstrategy, you don’t need to sleep. The program will already be locked with the VSync. If you want to “proof” your application against loss of VSync (i.e. VSync is not available under Unix), then you should use an algorithm like this:


int fps = 60; //60 frames per second
int time = 0;
int sleepTime = 1000/fps; //Divide one second by fps

while(true)
{
    ...
    //draw stuff
    ...

    bufferStrategy.show();

    while(time+sleepTime < System.currentTimeMillis();
    {
        try{Thread.sleep(1);}catch(Exception e) {}
    }

    time += sleepTime;
}

The algorithm above will automatically adjust to any timing errors and attempt to produce a smooth 60 fps. Note that the above algo won’t work right under windows due to Window’s poor timer. You can use a timer like GAGETimer to give a more consistent result across all OSes. If you still have problems with smoothness, profile your code. If you regularily have less than 3 ms left after rendering each frame, you should try using the GAGETimer “sleepUntil” method. This will force the machine to give your program all the idle time so that other programs can run, but you won’t miss the deadline to generate another frame.

Good luck!