diff options
3 files changed, 71 insertions, 2 deletions
diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java index 2aa8e9640..4fd00dcd5 100644 --- a/src/net/java/games/jogl/impl/GLContext.java +++ b/src/net/java/games/jogl/impl/GLContext.java @@ -620,6 +620,9 @@ public abstract class GLContext { from within the destroy() implementation. */ protected synchronized void setRealized(boolean realized) { this.realized = realized; + if (DEBUG) { + System.err.println("GLContext.setRealized(" + realized + ") for context " + this); + } } /** Indicates whether the component associated with this context has diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java index 86f6debfb..f80b2a107 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java @@ -141,6 +141,11 @@ public abstract class WindowsGLContext extends GLContext { if (!WGL.wglMakeCurrent(hdc, hglrc)) { throw new GLException("Error making context current: " + WGL.GetLastError()); + } else { + if (DEBUG) { + System.err.println("wglMakeCurrent(hdc " + hdcToString(hdc) + + ", hglrc " + hdcToString(hglrc) + ") succeeded"); + } } if (created) { @@ -501,11 +506,17 @@ public abstract class WindowsGLContext extends GLContext { pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); } if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { - throw new GLException("Unable to set pixel format"); + int lastError = WGL.GetLastError(); + if (DEBUG) { + System.err.println("SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + + ", current DC = " + WGL.wglGetCurrentDC()); + System.err.println("GetPixelFormat(hdc " + hdcToString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); + } + throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + hdcToString(hdc) + ": error code " + lastError); } hglrc = WGL.wglCreateContext(hdc); if (DEBUG) { - System.err.println("!!! Created OpenGL context " + hglrc); + System.err.println("!!! Created OpenGL context " + hglrc + " for device context " + hdcToString(hdc) + " using pixel format " + pixelFormat); } if (hglrc == 0) { throw new GLException("Unable to create OpenGL context"); @@ -665,4 +676,8 @@ public abstract class WindowsGLContext extends GLContext { } return res; } + + protected static String hdcToString(long hdc) { + return "0x" + Long.toHexString(hdc); + } } diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java index 726091bf1..1c976c355 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java @@ -43,6 +43,7 @@ import java.awt.Component; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.Rectangle; +import java.io.File; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; @@ -74,6 +75,56 @@ public class WindowsGLContextFactory extends GLContextFactory { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { Runtime.getRuntime().addShutdownHook( new ShutdownHook() ); + + // Test for whether we should enable the single-threaded + // workaround for ATI cards. It appears that if we make any + // OpenGL context current on more than one thread on ATI cards + // on Windows then we see random failures like the inability + // to create more OpenGL contexts, or having just the next + // OpenGL SetPixelFormat operation fail with a GetNextError() + // code of 0 (but subsequent ones on subsequently-created + // windows succeed). These kinds of failures are obviously due + // to bugs in ATI's OpenGL drivers. Through trial and error it + // was found that specifying + // -DJOGL_SINGLE_THREADED_WORKAROUND=true on the command line + // caused these problems to completely disappear. Therefore at + // least on Windows we try to enable the single-threaded + // workaround before creating any OpenGL contexts. In the + // future, if problems are encountered on other platforms and + // -DJOGL_SINGLE_THREADED_WORKAROUND=true works around them, + // we may want to implement a workaround like this on other + // platforms. + + // The algorithm here is to try to find the system directory + // (assuming it is on the same drive as TMPDIR, exposed + // through the system property java.io.tmpdir) and see whether + // a known file in the ATI drivers is present; if it is, we + // enable the single-threaded workaround. + + // If any path down this code fails, we simply bail out -- we + // don't go to great lengths to figure out if the ATI drivers + // are present. We could add more checks here in the future if + // these appear to be insufficient. + + String tmpDirProp = System.getProperty("java.io.tmpdir"); + if (tmpDirProp != null) { + File file = new File(tmpDirProp); + if (file.isAbsolute()) { + File parent = null; + do { + parent = file.getParentFile(); + if (parent != null) { + file = parent; + } + } while (parent != null); + // Now the file contains just the drive letter + file = new File(new File(new File(file, "windows"), "system32"), "atioglxx.dll"); + if (file.exists()) { + SingleThreadedWorkaround.shouldDoWorkaround(); + } + } + } + return( null ); } }); |