Double Buffering with Passive or Active Rendering in Java


My articles and tutorials and code examples:

Double Buffering and Active Rendering in Java with Swing Integration
This is a guide to active rendering and double buffering with Swing integration. The tutorial shows how to actively render your applications graphics while still using Swing components that can appear alongside and on top of your graphics. It's a bit tricky, and not the recommended way to use Swing, but it works to some extent.
Double Buffering and Passive Rendering in Java using a Timer Object
This is a guide to passive rendering and double buffering via the paintComponent(Graphics g) method, where your application or game's graphics are represented as a Swing component, and rendered by the Event Dispatch Thread like any other normal Swing component. Repainting of graphics in this guide occur at a constant rate through the use of a Timer and TimerTasks.

Frequently Asked Questions

Some questions or issues people have emailed me about:

What is the difference between passive and active rendering?

Passive rendering is when the next render (repaint) of graphics is unknown. In Java with Swing, this is because the Event Dispatch Thread (EDT) controls every repaint's schedule (The EDT is a separate thread that queues GUI related tasks your application needs to accomplish and completes them one after another). Active rendering is when you render the graphics over and over again in a tightly controlled loop, where the developer has complete control over every repaint's schedule. Active rendering has the advantage of being able to squeeze out more frames per second, which can help with smoother animations and sprite movements.

When should I use active rendering instead of passive rendering?

You usually only want to use active rendering when your application needs to achieve a good frame rate performance that passive rendering won't get you. This is because active rendering techniques allow you to precisely control the speed, style, and occurrence of updates and drawing. If you have an application that needs to show some animations, but the graphics will update in a timely manner no matter what machine your application is running on, then passive rendering techniques should suffice.

How could my application's update speed matter?

One possible scenario explaining why a high rate might be important is if your animation and movement depends on how much time has elapsed between updates. If too much time has passed, an animation could be skipped over, or moving sprite could miss its relative collision zone. For example, imagine if you had a sprite, traveling at a speed of so many pixels per millisecond, but just enough milliseconds past that by the time the next update comes around, the sprite is updated over and past the wall that it should have collided with.

Is active rendering is faster than passive rendering?

Yes, active rendering techniques should allow your application to achieve greater frames and updates per second if you scale your application to do so, such as using multiple threads (or a single thread for a single CPU machine), a better tuned drawing thread, or your own cheap and fast GUI components. In Swing, passive rendering gives you by default a multithreaded environment with the EDT doing the draws, and whatever other thread your application has doing the updates, so it's probably needed to mimic those basics with an active rendering solution to match the possible better speed from a passive rendering solution.

How is passive rendering in Swing slower than Active rendering?

In Swing when exactly something is repainted or even if it is repainted, is unknown. In Swing, a repaint request is handled by the EDT, where a few things can hamper the speed of the drawing and help make it unknown how fast your application will be:

  • The EDT can have some number of tasks it needs to complete ahead of the repaint request, and perhaps long lasting ones from some other portion of the codebase
  • The EDT is a separate thread, you have to wait for it to be scheduled onto the processor which may not be desirable, such as when running on a single CPU machine
  • EDT will not schedule a repaint if there's a repaint already queued in the EDT. So let's say you were scheduling repaints with a timer every 5 milliseconds, and when you call for the second repaint and the first one hasn't happened yet, then the second request is ignored and 10 milliseconds later (when you expected 5 milliseconds), the third repaint acting as the second finally updates your application.
  • How often your application requests a repaint

If you're using a java.util.Timer, the different scheduling approaches, fixed delay, and fixed rate can influence how often a repaint occurs. Fixed delay tries to create an event every x amount of milliseconds, longer if the prior task did not finish in x milliseconds. Fixed rate does the same but with a small difference where if one event takes too long to finish, it will speed up the next few events to maintain an overall average speed. The fastest you can schedule an event on a java.util.Timer is 1 ms, so repainting with that timer would limit you to 1000 fps. You don't need to use a Timer for updates though, you can just create a loop on the some thread to update state over and over with a call to repaint somewhere, that would tie your frame rate to however fast the EDT can handle your paint calls.

How should I go about programming a good multithreaded active rendering (game) engine?

Scaling your application with useful measurements is the best way I know of. If your game has an update then draw cycle, you can try splitting the updating of your data across N to N+1 threads (N = number of CPUs available) in a thread pool, blocking until it's done then drawing. It may be helpful to store a copy of the last computed update, so while your draw thread draws the last computed update's data, your update thread can be working on the next set of updated data. This would also remove the need for the threads to block each other when accessing shared data on the state of the application if the application at the time was already okay with drawing and updating a set of data at the same time.

Caching graphics is another way to improve performance. Caching graphics that are used often to an image (BufferedImage created by createCompatibleImage) to draw again later lets you skip the time it takes to compute certain data about what you are drawing (such as the arcs of the circles drawn in this code), and also enables the image to be hardware accelerated after you draw it a few times. A BufferedImage created this way that isn't changed and drawn a few times will be cached to VRAM, creating what is known as a managed image. A managed image is a lot faster to render to the screen because it's transferring pixel data from VRAM to VRAM, leaving out the CPU, the bus, and main memory. This also allows the GPU to handle the task of drawing the image, freeing up the CPU to handle other tasks. Also another good time to cache graphics is when the rendering actions we do cannot be handled directly by the underlying native graphics API such as antialiasing, so caching graphics that use those techniques is a great thing to do. Check out section 3.2.2. of Troubleshooting Guide for Java SE6 Desktop Technologies for a list of actions that will be bound to the CPU.

If you want some really nice engine to help run what you're trying to create, it may be more efficient to put time and energy into learning and using some of the already existing engines available (that may take the fun out of it though!). These engines are written by the experts and have huge communities willing to help.

Since my tutorials on these subjects are Java centric, these are some links to some well-known Java game engines or useful libraries.

Primarily used for 3D applications:
JMonkeyEngine
Java OpenGL Game Engine... jMonkeyEngine 3.0 was rewritten from the ground up to accommodate modern standards in game development... a game engine, made especially for game developers who want to create 3D games with modern technology standards. The software is programmed entirely in Java, intended for wide accessibility and quick deployment.
Primarily used for 2D applications:
Slick, if not working, Slick
Slick2D is a simple set of tools wrapped around the LWJGL OpenGL binding for Java. It's aims are as follows:
* Provide a simple 2D API
* Make transition from Java2D to OpenGL easier
* Enable distribution via WebStart without the complexity
* Provide the tools required for most simple games out of the box
* Extensible framework for flexibility
* Mix and Match - you use what you want, nothing is enforced.
* Help with rendering, sound, input, collision and anything else we can think of.

Essentially, it's a 2D game engine using the Lightweight Java Game Library (listed below), so by nature that extra layer of abstraction to it probably helps it be user friendly, and with more libraries already written (which you might have reinvented yourself if you used LWJGL for a 2D application), this engine seems to be a good and popular pick on the internet.
Used for either 3D or 2D applications:
Lightweight Java Game Library (LWJGL)
The Lightweight Java Game Library (LWJGL) is a solution aimed directly at professional and amateur Java programmers alike to enable commercial quality games to be written in Java. LWJGL provides developers access to high performance crossplatform libraries such as OpenGL (Open Graphics Library), OpenCL (Open Computing Language) and OpenAL (Open Audio Library) allowing for state of the art 3D games and 3D sound. Additionally LWJGL provides access to controllers such as Gamepads, Steering wheel and Joysticks. All in a simple and straight forward API.
What is page flipping?

Page flipping is a double buffering technique that uses two buffers, a display buffer, and a back end buffer that's being drawn too. These two buffers work together by simply switching pointers to switch roles between frame renders. Page flipping is usually more efficient than the historic notion of double buffering in Java (in Java, that was the act of drawing a set of graphics to an image in the background, and then drawing the image at once onto the screen with drawImage), and luckily the BufferStrategy class decides for us what technique we should use, by first trying to use page flipping, and if that doesn't work out, then it tries double buffering. To the Java developer using a BufferStrategy (you can find query to find out what strategy is being used) and user, the technique used is abstracted. People from what I've seen use the word double buffering to refer to any type of double buffer rendering technique. Also, page flipping is only available in full-screen mode.

Are there any other places I can learn about active rendering and double buffering?
Picture of the books recommended below

Yes, here are some web links for Java:

Some good books I would recommend on learning about Swing and programming games or game engines:

  • Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java Applications
    This book goes into great detail on the underlying details of how Swing works, from creating your own custom components, to performance, animations, and graphical effects.
    Homepage for Filthy Rich Clients
  • Java Concurrency in Practice
    This book is great for learning how to create thread safe objects, achieve better performance through concurrency, and make good use out of the already existing concurrent tools that come with Java.
    Homepage for Java Concurrency in Practice
  • Developing Games in Java
    This book shows how to make a game from the ground up. The first half of the book it takes the approach of showing how to create a reusable game engine (sound, music, graphics, sprites and animation), and then walks you through making a simple game 2D platformer game with those libraries. The second half shows you how to implement your own 3d graphics library using Java 2D, with a 3D first person shooter game that slowly evolves. The book is rather old (Java 1.4), but recognizing where you can replace and apply modern Java will go a long way in making pretty good use out of this book.
    Homepage for Developing Games in Java
  • Killer Game Programming in Java
    I don't really like this book that much, especially reading Developing Games in Java first, but a lot of people online seem to reference this book a lot and seem to enjoy it. The first half of the book goes over various ways to load images, sounds, and graphical effects, and a goes over how to program a few small games. However, I find that the techniques used to update the game or animation are not as elegant, or reusable compared to Developing Games in Java. I do find the book to have a lot of information which can be found rather interesting such as the graphical effects, but a lot of the information in the book is out of date for today's Java, and some of it, such as the graphical effects, is more approachable in a book such as Filthy Rich Clients. The second half of the book shows you how to program 3D games using Java 3D, a now dead technology, but also requires you to go read a secondary source on how to use Java 3D before continuing on through the second half. I find that Developing Games in Java's second half is much more approachable and usable today, and fun given how you get to create the 3D engine yourself. I would only recommend this book, after obtaining Developing Games in Java for game programming, and after obtaining Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java Applications for general know-how of programming graphics.
    Homepage for Killer Game Programming in Java
Site Smith badge icon