Anything new on vsync in window mode?

Hi all. I’m new here so please forgive any ignorance I put on display. I’m looking for options to achieve synchronization between my frame updates and my monitor’s refresh while in window mode using Java2D. Searching on “vsync,” I found a number of postings, but almost all are too old to reply to them. So, I’m asking here if there’s recent information that changes the state of affairs. This discussion made me aware of the ExtendedBufferCapabilties class, which appears to offer some access to vsync in window mode. However, the ExtendedBufferCapabilities class is in one of the sun.* packages, which this FAQ entry warns are not supported and can change at any time (nor are they likely to be on non-Oracle implementations Java).

If one is willing to be platform-specific (I’m on Windows), a native method could get the job done. But who wants to be platform-specific? My prior research tells me that OpenGL, among other alternatives, provides vsync support. But I like Java2D and would be interested in knowing what solutions, if any, there are to syncing with monitor refresh in the Java2D context.

Hope I’m not overtreading an already beaten path with this question, and thank in advance for any replies.

Chill, it’s a good question.

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.

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… :wink: