summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-12-19 00:45:18 +0100
committerSven Gothel <[email protected]>2010-12-19 00:45:18 +0100
commit5166d6a6b617ccb15c40fcb8d4eac2800527aa7b (patch)
tree7a9debae4db5929e4e9e8351e2c5cd778c40c64c
parent5f67805a1cba7390cde0f862cbe4d4fcce3396ee (diff)
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.
-rw-r--r--make/stub_includes/win32/windows.h5
-rw-r--r--make/stub_includes/win32/wingdi.h5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java37
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java3
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java9
5 files changed, 58 insertions, 1 deletions
diff --git a/make/stub_includes/win32/windows.h b/make/stub_includes/win32/windows.h
index 5abf792d1..ddee94c06 100644
--- a/make/stub_includes/win32/windows.h
+++ b/make/stub_includes/win32/windows.h
@@ -12,7 +12,7 @@
typedef int BOOL;
typedef unsigned char BYTE;
typedef char CHAR;
-typedef unsigned int DWORD;
+typedef unsigned __int32 DWORD;
typedef int INT;
typedef __int32 INT32;
typedef __int64 INT64;
@@ -29,12 +29,15 @@ typedef HANDLE HWND;
typedef __int32 LONG;
typedef const char* LPCSTR;
typedef void* LPVOID;
+typedef unsigned __int64 ULONG_PTR;
typedef struct _proc* PROC;
typedef unsigned int* PUINT;
typedef unsigned int UINT;
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned short ATOM;
+typedef intptr_t DWORD_PTR;
+typedef intptr_t* PDWORD_PTR;
/* Necessary handle typedefs for parsing wglext.h */
diff --git a/make/stub_includes/win32/wingdi.h b/make/stub_includes/win32/wingdi.h
index 7862b5533..b169621f5 100644
--- a/make/stub_includes/win32/wingdi.h
+++ b/make/stub_includes/win32/wingdi.h
@@ -194,6 +194,11 @@ WINUSERAPI int WINAPI ReleaseDC(HWND hWnd, HDC hDC);
WINUSERAPI BOOL WINAPI DestroyWindow(HWND hWnd);
WINUSERAPI DWORD WINAPI GetObjectType(HGDIOBJ h);
+WINUSERAPI HANDLE WINAPI GetCurrentProcess(void);
+WINUSERAPI BOOL WINAPI GetProcessAffinityMask(HANDLE hProcess,PDWORD_PTR lpProcessAffinityMask,PDWORD_PTR lpSystemAffinityMask);
+WINUSERAPI BOOL WINAPI SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR dwProcessAffinityMask);
+
+
// Routines for changing gamma ramp of display device
WINGDIAPI BOOL WINAPI GetDeviceGammaRamp(HDC,LPVOID);
WINGDIAPI BOOL WINAPI SetDeviceGammaRamp(HDC,LPVOID);
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/*<connection, SharedResource>*/ 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) {