From 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 19 Dec 2010 00:45:18 +0100 Subject: Adding NVIDIA 'Threaded optimization' workaround/fix at initialization on Windows for javaws/applets. It has been observed that for some combinations, eg: - Windows 7 64bit (other variants may apply too) - NVIDIA 8600M GT - 260.99 the NVIDIA setting of 'Threaded optimization' := 'auto' (default) causes the JVM to simply crash in case of javaws and [jnlp] applets. 'Threaded Optimization' := 'off' works reliable 'Threaded Optimization' := 'on' never works with javaws and applets on the above configuration A user could workaround this by setting 'Threaded Optimization' := 'off', however, this would disable many users on the spot, since you cannot ask the average user for such a task, if she only wants to see a web page. This patch 'fixes' the 'auto' mode by running the eager GL profile initialization within a block of single CPU affinity: SetProcessAffinityMask(pid, 1); try { initProfilesForDeviceImpl(device); } finally { SetProcessAffinityMask(pid, sysValue); } Hopefully we can remove this hack with a driver fix. However this workaround is as little invasive as possible. --- .../windows/wgl/WindowsWGLDrawableFactory.java | 37 ++++++++++++++++++++++ .../javax/media/opengl/GLDrawableFactory.java | 3 ++ src/jogl/classes/javax/media/opengl/GLProfile.java | 9 ++++++ 3 files changed, 49 insertions(+) (limited to 'src/jogl/classes') diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index cd39ddc15..ac71d6e9c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -60,6 +60,7 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.windows.GDI; @@ -125,6 +126,42 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { Thread sharedResourceThread; HashMap/**/ sharedMap = new HashMap(); + long processAffinityChanges = 0; + PointerBuffer procMask = PointerBuffer.allocateDirect(1); + PointerBuffer sysMask = PointerBuffer.allocateDirect(1); + + protected void enterThreadCriticalZone() { + synchronized (sysMask) { + if( 0 == processAffinityChanges) { + long pid = GDI.GetCurrentProcess(); + if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) { + if(DEBUG) { + System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + Thread.dumpStack(); + } + processAffinityChanges = pid; + GDI.SetProcessAffinityMask(pid, 1); + } + } + } + } + + protected void leaveThreadCriticalZone() { + synchronized (sysMask) { + if( 0 != processAffinityChanges) { + long pid = GDI.GetCurrentProcess(); + if( pid != processAffinityChanges) { + throw new GLException("PID doesn't match: set PID 0x" + Long.toHexString(processAffinityChanges) + + " this PID 0x" + Long.toHexString(pid) ); + } + if(DEBUG) { + System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + } + GDI.SetProcessAffinityMask(pid, sysMask.get(0)); + } + } + } + static class SharedResource implements SharedResourceRunner.Resource { private WindowsGraphicsDevice device; private AbstractGraphicsScreen screen; diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 78ca24be0..fe591c9fc 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -220,6 +220,9 @@ public abstract class GLDrawableFactory { } } + protected void enterThreadCriticalZone() {}; + protected void leaveThreadCriticalZone() {}; + protected abstract void shutdownInstance(); /** diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index 378d3df9c..3e1727f50 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -1218,6 +1218,15 @@ public class GLProfile { if(null == device) { return false; } + GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device); + factory.enterThreadCriticalZone(); + try { + return initProfilesForDeviceImpl(device); + } finally { + factory.leaveThreadCriticalZone(); + } + } + private static synchronized boolean initProfilesForDeviceImpl(AbstractGraphicsDevice device) { boolean isSet = GLContext.getAvailableGLVersionsSet(device); if(DEBUG) { -- cgit v1.2.3