Heh, thanks. Good enough to get asked repeatedly, it appears. 8)
[quote]As far as I know, If you use BufferStrategy you’ll get V-sync enabled if it’s available. There’s no explicit control for it AFAIK.
[/quote]
That is definitely the case when it’s available and your app is in full-screen mode. That fact is, rather remarkably, not addressed in any way in the API javadoc. The only authoritative confirmation of this I’ve ever found was in Andrew Davison’s, “Killer Game Programming in Java,” where he says this:
[quote=Davison]In FSEM, show() blocks until the next vsync signal.
[/quote]
Which is nice to know, but I would like to see something from Oracle that says the same thing, and I can’t find it. My experiments confirm that Davison is correct: using System.nanoTime(), it is easy to see that the time between two calls to show() matches the frame-rate of the associated monitor (changing to match it when the monitor’s frame-rate is changed). However, those same experiments confirm that show() does not match the frame-rate of the associated monitor when in window mode. The JDK source code for the Component class shows that use of vsync depends on whether or not your BufferStrategy was created with a BufferCapabilities object, or with the (undocumented and unsupported) ExtendedBufferCapabilities class. Here’s the code from Component.java:
if (caps instanceof ExtendedBufferCapabilities) {
ExtendedBufferCapabilities ebc =
(ExtendedBufferCapabilities)caps;
if (ebc.getVSync() == VSYNC_ON) {
// if this buffer strategy is not allowed to be v-synced,
// change the caps that we pass to the peer but keep on
// trying to create v-synced buffers;
// do not throw IAE here in case it is disallowed, see
// ExtendedBufferCapabilities for more info
if (!VSyncedBSManager.vsyncAllowed(this)) {
caps = ebc.derive(VSYNC_DEFAULT);
}
}
}
I’m no expert on the sun.* packages, but it does look to me like the Windows implementation is, indeed, specific to Windows, relying on Direct3D for much of its low-level functionality. There may be something comparable in other implementations, but I only have Windows, so I wouldn’t know.
Now, a few lines of Windows code (again, using Direct3D calls) gets me access to a native method that will do what I want, blocking until the next vsync on a specified monitor. But, that’s kind of why I’m curious about the way this is treated in Java. That is, it’s so easy that I’m puzzled by its absence. Could it be that, while it’s easy in Windows, it’s not so easy on other platforms, and would conflict with the “write once, run anywhere” Java ideology? Or, is it not even all that reliable on Windows, so they don’t want to guarantee it? Even more puzzling is the API javadoc’s silence regarding Davison’s observation, that show() does block on vsync in full-screen mode. That seems like a major operational characteristic, one that I would have expected to see described in that javadoc.
I suppose the ultimate solution to all of my confusion will be to learn OpenGL, thereby avoiding Java2D. A few folks have told me that OpenGL is the preferred choice over Java2D for games in general. If that’s true, it’s probably where my future lies.
I’d still like to know what the best option in Java2D for vsync in window mode is, though (and why the blocking behavior of show() in full-screen mode is not documented).
But I tend to get obsessed over things like that. I should probably just chill…