Our Java 2D application exhibits screen tearing when run on Linux. It does not exhibit any tearing when running on Wind开发者_运维百科ows. We've spent significant time analyzing our code, and haven't yet found a cause there. While I'm never one to decide that it must not be my code at fault, I'm also entertaining the possibility that the issue is with the Java 2D rendering pipeline on Linux. By the way, please note that we see the tearing with both Java 6 and Java 7. When running on Java 7, we see the tearing regardless of whether we enable the XRender pipeline or not.
We are of course using double-buffering via a BufferStrategy
. The BufferStrategy
implementation we get when we call Frame.createBufferStrategy(2)
is a java.awt.Component$FlipSubRegionBufferStrategy
. In addition, calling isPageFlipping()
on the BufferStrategy
's BufferCapabilities
returns true, and calling isFullScreenRequired()
on the capabilities returns false. We are not running in full-screen exclusive mode, though we have tried doing so and it did not resolve the issue. BufferCapabilities.getFlipContents()
returns FlipContents.UNDEFINED
(but I suspect that is not relevant).
Since page-flipping is supposedly supported and we're getting a page-flipping BufferStrategy
(rather than a blitting strategy), I would not expect the rendering pipeline to be causing the tearing. However, I found a mailing list message written by Chet Haase back in 2006 addressing a screen tearing problem which states, "It's possible that the Flip strategy on your particular platform is actually doing a copy behind the scenes, which would be the same as the BltBufferStrategy, which runs smack into the refresh artifact."
How can I determine if the flip strategy we're getting is not actually page-flipping?
Chet also states, "Running fullscreen with a BufferStrategy is a decent way to work around this; depending on the platform and the situation, we will usually give you a Flip strategy, which is (usually) synchronized with the vertical refresh of the display to avoid tearing."
How can I determine if the strategy is synchronized with the display's vertical refresh?
(See http://www.mail-archive.com/java2d-interest@capra.eng.sun.com/msg03743.html for the full message from Chet Haase referenced above)
Depending on the distro, many Linux systems are now shipping desktops that are 3d rendered by default. If you have one of the graphics cards which has poor (or missing) 3d acceleration with open-source drivers, you may need to install a proprietary 3d driver to get the desktop rendering within the acceptance tolerances for normal desktop use.
Remember that if your code looks right on other platforms, and performs admirably there; odds are it is right on Linux. It's just that Linux has a lot more "rendering architecture" variance, as would be expected considering X's history and design goals. Chances are your graphics information is being sent in a timely manner, but the config pipeline just can't keep up (so it drops a little, resulting in tearing).
Now for the specific questions
How can I determine if the flip strategy we're getting is not actually page-flipping?
By calling the methods you have already called.
How can I determine if the strategy is synchronized with the display's vertical refresh?
Hard to say, because the entire point of the strategy is to hide the nasty details from the API user. I'm not the right person to dive under these covers; but, I do have a good view of things from the X side.
My question to you, "Does this tearing exhibit in any other application besides your own?"
have you considered that the issue may be that on windows you are using oracle jdk and on linux you are using open jdk?
Its easy to find out. Install oracle jdk on your linux machine and run against the oracle jre.
Instructions on how to install here
Details on how to switch between installed versions of jre here
精彩评论