Toolkit.sync() ?

Hi,

I was reading Guy Romain’s article http://weblogs.java.net/blog/gfx/archive/2006/09/java2d_gradient.html about gradient paint performance and in the comments he mentioned java.awt.Toolkit.sync(), a method I haven’t come across. What does it do & where should I use it? The docs say it:

[quote]Synchronizes this toolkit’s graphics state. Some window systems may do buffering of graphics events.
This method ensures that the display is up-to-date. It is useful for animation.
[/quote]
and Romain said

[quote]Chris Campbell, from the Java2D team, kindly reminded me that timing the painting operation should be performed by calling Toolkit.sync() after each paint to ensure the drawing commands are flushed to the graphics card.
[/quote]
So does everyone call toolkit.sync() after rendering?

Thanks :),
Keith

There are few circumstances that you need to explicitly call sync().
Synthetic benchmarks is one of them.

Under normal operation, any caching of rendering operations is implicitly flushed at the end of a paint cycle.
When using BufferStrategy, this occurs when you call BufferStrategy.show().
When not using BufferStrategy, it occurs when the top level components paint(Graphics) method returns control back to the event dispatch thread.

If you were to use Component.getGraphics() however, I believe you should explicitly call Toolkit.sync() at the end of your paint cycle. (as the application has no idea when you want your changes to be flushed through to the display.)

All that siad, I’ve yet to see Toolkit.sync() have any effect, ever.

I’ve always understood it to be that Graphics sets the pixels as soon as you call the drawing command, thus the flicker that is introduced if you do not use a buffer.

I guess the exact behaviour of the Graphics drawing methods is upto the implementation.
Suns Windows implementation behaving one way, does not preclude the possibility that a future VM may behave differently.

Thanks a lot for that.

I’m using BufferStrategy.show() so I should be OK then.

Cheers,
Keith

[quote]Under normal operation, any caching of rendering operations is implicitly flushed at the end of a paint cycle.
[/quote]
Well, that depends - even if we (Java2D) issue our rendering commands immediately the video
driver may chose not to execute them right away.

Classic example is X11 - try timing a loop of Graphics.fillRects - see how many you can issue
in a couple of seconds. Without toolkit.sync() (which in case of X11 pipeline does XFlush())
after each call or at the end of the loop what you actually measure is how fast Java2D can
call X11 lib’s XFillRect method, which just batches up those calls until it’s command
buffer is full, only then they’re sent to the X server for execution.

Even calling BufferStrategy.show() doesn’t guarantee that the commands
buffer will be flushed -the call may be put in X11 queue just as well as
XFillRect.

Pretty much the same stuff happens on Windows - DirectDraw/Direct3D’s driver
does its own batching up before sending the commands over the wall
to the kernel part of the driver. There’s a list of conditions which could trigger
the queue flush (like if you request pixels from a surface, and certain
device state changes could also cause a command buffer flush).

So, in short, do Toolkit.sync() if you need to be sure that your pixels appear
on the screen.

Thanks,
Dmitri

Thanks for explaining this. Then I’ll call Toolkit.sync() after each call to BufferStrategy.show().

Keith