summaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-11-29 02:24:01 +0100
committerSven Gothel <[email protected]>2013-11-29 02:24:01 +0100
commit586446311ea1ba87f98236d5347955bf99b465d6 (patch)
tree2bba93f117ec08bbb3ea96ee6cd2c44d97b04421 /src/nativewindow/classes
parentcb0afe743d21a3480e2d41744a904ac7d404612d (diff)
Bug 907 - Refine DummyDispatchThread (DDT) Handling: Proper OO integration in RegisteredClass; Safe DDT Post/WaitForReady handling and error cases ; ...
Proper OO integration of DDT in RegisteredClass - DDT is optional to RegisteredClass[Factory], i.e. NEWT without DDT and DummyWindow with DDT. - Using native type DummyThreadContext per DDT passed as DDT handle to java referenced in RegisteredClass - Passing DDT handle to related native methods, if not null use DDT - otherwise work on current thread. The latter impacts CreateDummyWindow0 and DestroyWindow0. Safe DDT Post/WaitForReady handling and error cases ; ... - Wait until command it complete using a 3s timeout - Terminate thread if errors occur and throw an exception +++ Discussion: DDT Native Implementation Due to original code, the DDT is implemented in native code. Usually we should favor running the DDT from a java thread. However, since it's main purpose is _not_ to interact w/ java and the native implementation has less footprint (performance and memory) we shall be OK w/ it for now - as long the implementation IS SAFE.
Diffstat (limited to 'src/nativewindow/classes')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java21
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java17
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java30
3 files changed, 44 insertions, 24 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index bab4b5c6e..a872e63d8 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -59,7 +59,7 @@ public class GDIUtil implements ToolkitProperties {
if( !initIDs0() ) {
throw new NativeWindowException("GDI: Could not initialized native stub");
}
- dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0(), true /* useDummyDispatchThread */);
if(DEBUG) {
System.out.println("GDI.initSingleton() dummyWindowClassFactory "+dummyWindowClassFactory);
}
@@ -98,8 +98,7 @@ public class GDIUtil implements ToolkitProperties {
System.out.println("GDI.CreateDummyWindow() dummyWindowClassFactory "+dummyWindowClassFactory);
System.out.println("GDI.CreateDummyWindow() dummyWindowClass "+dummyWindowClass);
}
- // FIXME return CreateDummyWindow0(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height);
- return CreateDummyWindowAndMessageLoop(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height);
+ return CreateDummyWindow0(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getHDispThreadContext(), dummyWindowClass.getName(), x, y, width, height);
}
}
@@ -109,8 +108,7 @@ public class GDIUtil implements ToolkitProperties {
if( null == dummyWindowClass ) {
throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null");
}
- // FIXME res = GDI.DestroyWindow(hwnd);
- res = SendCloseMessage(hwnd);
+ res = DestroyWindow0(dummyWindowClass.getHDispThreadContext(), hwnd);
dummyWindowClassFactory.releaseSharedClass();
}
return res;
@@ -128,8 +126,11 @@ public class GDIUtil implements ToolkitProperties {
return IsChild0(win);
}
- public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc);
- public static native boolean DestroyWindowClass(long hInstance, String className);
+ private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
+
+ static native boolean CreateWindowClass0(long hInstance, String clazzName, long wndProc);
+ static native boolean DestroyWindowClass0(long hInstance, String className, long dispThreadCtx);
+ static native long CreateDummyDispatchThread0();
private static native boolean initIDs0();
private static native long getDummyWndProc0();
@@ -137,8 +138,6 @@ public class GDIUtil implements ToolkitProperties {
private static native boolean IsChild0(long win);
private static native boolean IsUndecorated0(long win);
- private static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height);
-
- private static native long CreateDummyWindowAndMessageLoop(long hInstance, String className, String windowName, int x, int y, int width, int height);
- private static native boolean SendCloseMessage(long win);
+ private static native long CreateDummyWindow0(long hInstance, String className, long dispThreadCtx, String windowName, int x, int y, int width, int height);
+ private static native boolean DestroyWindow0(long dispThreadCtx, long win);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java
index 976693e3a..1f6cb7c05 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java
@@ -29,12 +29,14 @@
package jogamp.nativewindow.windows;
public class RegisteredClass {
- long hInstance;
- String className;
+ private final long hInstance;
+ private final String className;
+ private final long hDDTCtx;
- RegisteredClass(long hInst, String name) {
- hInstance = hInst;
- className = name;
+ RegisteredClass(long hInst, String name, long hDispatchThreadCtx) {
+ this.hInstance = hInst;
+ this.className = name;
+ this.hDDTCtx = hDispatchThreadCtx;
}
/** Application handle, same as {@link RegisteredClassFactory#getHInstance()}. */
@@ -43,6 +45,9 @@ public class RegisteredClass {
/** Unique Window Class Name */
public final String getName() { return className; }
+ /** Unique associated dispatch thread context for this Window Class, or 0 for none. */
+ public final long getHDispThreadContext() { return hDDTCtx; }
+
@Override
- public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+"]"; }
+ public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+", dtx 0x"+Long.toHexString(hDDTCtx)+"]"; }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
index 19a48d3bf..ee41fe192 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
@@ -49,6 +49,7 @@ public class RegisteredClassFactory {
private final String classBaseName;
private final long wndProc;
+ private final boolean useDummyDispatchThread;
private RegisteredClass sharedClass = null;
private int classIter = 0;
@@ -59,24 +60,29 @@ public class RegisteredClassFactory {
@Override
public final String toString() { return "RegisteredClassFactory[moduleHandle "+toHexString(hInstance)+", "+classBaseName+
- ", wndProc "+toHexString(wndProc)+", shared[refCount "+sharedRefCount+", class "+sharedClass+"]]"; }
+ ", wndProc "+toHexString(wndProc)+", useDDT "+useDummyDispatchThread+", shared[refCount "+sharedRefCount+", class "+sharedClass+"]]"; }
/**
* Release the {@link RegisteredClass} of all {@link RegisteredClassFactory}.
*/
public static void shutdownSharedClasses() {
synchronized(registeredFactories) {
+ if( DEBUG ) {
+ System.err.println("RegisteredClassFactory.shutdownSharedClasses: "+registeredFactories.size());
+ }
for(int j=0; j<registeredFactories.size(); j++) {
final RegisteredClassFactory rcf = registeredFactories.get(j);
synchronized(rcf.sync) {
if(null != rcf.sharedClass) {
- GDIUtil.DestroyWindowClass(rcf.sharedClass.getHInstance(), rcf.sharedClass.getName());
+ GDIUtil.DestroyWindowClass0(rcf.sharedClass.getHInstance(), rcf.sharedClass.getName(), rcf.sharedClass.getHDispThreadContext());
rcf.sharedClass = null;
rcf.sharedRefCount = 0;
rcf.classIter = 0;
if(DEBUG) {
- System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+" shutdownSharedClasses : "+rcf.sharedClass);
+ System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+": shutdownSharedClasses : "+rcf.sharedClass);
}
+ } else if(DEBUG) {
+ System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+": null");
}
}
}
@@ -86,9 +92,10 @@ public class RegisteredClassFactory {
/** Application handle. */
public static long getHInstance() { return hInstance; }
- public RegisteredClassFactory(String classBaseName, long wndProc) {
+ public RegisteredClassFactory(String classBaseName, long wndProc, boolean useDummyDispatchThread) {
this.classBaseName = classBaseName;
this.wndProc = wndProc;
+ this.useDummyDispatchThread = useDummyDispatchThread;
synchronized(registeredFactories) {
registeredFactories.add(this);
}
@@ -107,12 +114,21 @@ public class RegisteredClassFactory {
// Retry with next clazz name, this could happen if more than one JVM is running
clazzName = classBaseName + classIter;
classIter++;
- registered = GDIUtil.CreateWindowClass(hInstance, clazzName, wndProc);
+ registered = GDIUtil.CreateWindowClass0(hInstance, clazzName, wndProc);
}
if( !registered ) {
throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName);
}
- sharedClass = new RegisteredClass(hInstance, clazzName);
+ final long hDispatchThread;
+ if( useDummyDispatchThread ) {
+ hDispatchThread = GDIUtil.CreateDummyDispatchThread0();
+ if( 0 == hDispatchThread ) {
+ throw new NativeWindowException("Error: Could not create DDT "+clazzName);
+ }
+ } else {
+ hDispatchThread = 0;
+ }
+ sharedClass = new RegisteredClass(hInstance, clazzName, hDispatchThread);
if(DEBUG) {
System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass);
}
@@ -137,7 +153,7 @@ public class RegisteredClassFactory {
throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null");
}
if( 0 == sharedRefCount ) {
- GDIUtil.DestroyWindowClass(sharedClass.getHInstance(), sharedClass.getName());
+ GDIUtil.DestroyWindowClass0(sharedClass.getHInstance(), sharedClass.getName(), sharedClass.getHDispThreadContext());
if(DEBUG) {
System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass);
}