diff options
Diffstat (limited to 'src/nativewindow')
4 files changed, 126 insertions, 72 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java index 36bf646d5..02cec5bbf 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java @@ -480,7 +480,7 @@ public class SWTAccessor { public static void invoke(boolean wait, Runnable runnable) { if( isOSX ) { // Use SWT main thread! Only reliable config w/ -XStartOnMainThread !? - OSXUtil.RunOnMainThread(wait, runnable); + OSXUtil.RunOnMainThread(wait, false, runnable); } else { runnable.run(); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 3728bfb59..e64525fbe 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -96,7 +96,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { if(0 != windowHandle) { OSXUtil.DestroyNSWindow(windowHandle); } - OSXUtil.RunOnMainThread(false, new Runnable() { + OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() { @Override public void run() { if( 0 != rootSurfaceLayer ) { @@ -121,7 +121,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { updatePixelScale(); if( hadPixelScaleX != getPixelScaleX() && 0 != getAttachedSurfaceLayer() ) { - OSXUtil.RunOnMainThread(false, new Runnable() { + OSXUtil.RunOnMainThread(false, false, new Runnable() { @Override public void run() { final long osl = getAttachedSurfaceLayer(); @@ -136,37 +136,37 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { @Override protected void attachSurfaceLayerImpl(final long layerHandle) { - OSXUtil.RunOnMainThread(false, new Runnable() { - @Override - public void run() { - // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. - // Determine p0: components location on screen w/o insets. - // CALayer position will be determined in native code. - // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} - final Point p0 = new Point(); - final Component outterComp = getLocationOnScreenNonBlocking(p0, component); - final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); - final Point p1 = (Point)p0.cloneMutable(); - p1.translate(-outterComp.getX(), -outterComp.getY()); - if( null != outterInsets ) { - p1.translate(-outterInsets.left, -outterInsets.top); - } - - if( DEBUG_CALAYER_POS_CRITICAL ) { - final java.awt.Point pA0 = component.getLocationOnScreen(); - final Point pA1 = new Point(pA0.x, pA0.y); - pA1.translate(-outterComp.getX(), -outterComp.getY()); + OSXUtil.RunOnMainThread(false, false /* kickNSApp */, new Runnable() { + @Override + public void run() { + // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. + // Determine p0: components location on screen w/o insets. + // CALayer position will be determined in native code. + // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} + final Point p0 = new Point(); + final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); + final Point p1 = (Point)p0.cloneMutable(); + p1.translate(-outterComp.getX(), -outterComp.getY()); if( null != outterInsets ) { - pA1.translate(-outterInsets.left, -outterInsets.top); + p1.translate(-outterInsets.left, -outterInsets.top); } - System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], pA "+pA0+" -> "+pA1+ - ", p0 "+p0+" -> "+p1+", bounds "+bounds); - } else if( DEBUG ) { - System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], p0 "+p0+" -> "+p1+", bounds "+bounds); - } - // HiDPI: uniform pixel scale - OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, p1.getX(), p1.getY(), getWidth(), getHeight(), getPixelScaleX(), JAWTUtil.getOSXCALayerQuirks()); - } } ); + + if( DEBUG_CALAYER_POS_CRITICAL ) { + final java.awt.Point pA0 = component.getLocationOnScreen(); + final Point pA1 = new Point(pA0.x, pA0.y); + pA1.translate(-outterComp.getX(), -outterComp.getY()); + if( null != outterInsets ) { + pA1.translate(-outterInsets.left, -outterInsets.top); + } + System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], pA "+pA0+" -> "+pA1+ + ", p0 "+p0+" -> "+p1+", bounds "+bounds); + } else if( DEBUG ) { + System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], p0 "+p0+" -> "+p1+", bounds "+bounds); + } + // HiDPI: uniform pixel scale + OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, p1.getX(), p1.getY(), getWidth(), getHeight(), getPixelScaleX(), JAWTUtil.getOSXCALayerQuirks()); + } } ); } @Override @@ -204,12 +204,12 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { @Override protected void detachSurfaceLayerImpl(final long layerHandle, final Runnable detachNotify) { - OSXUtil.RunOnMainThread(false, new Runnable() { - @Override - public void run() { - detachNotify.run(); - OSXUtil.RemoveCASublayer(rootSurfaceLayer, layerHandle); - } } ); + OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() { + @Override + public void run() { + detachNotify.run(); + OSXUtil.RemoveCASublayer(rootSurfaceLayer, layerHandle); + } }); } @Override @@ -326,30 +326,30 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { } if(null == errMsg) { jawtSurfaceLayersHandle = GetJAWTSurfaceLayersHandle0(dsi.getBuffer()); - OSXUtil.RunOnMainThread(false, new Runnable() { - @Override - public void run() { - String errMsg = null; - if(0 == rootSurfaceLayer && 0 != jawtSurfaceLayersHandle) { - rootSurfaceLayer = OSXUtil.CreateCALayer(bounds.getWidth(), bounds.getHeight(), getPixelScaleX()); // HiDPI: uniform pixel scale - if(0 == rootSurfaceLayer) { - errMsg = "Could not create root CALayer"; - } else { - try { - SetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); - } catch(Exception e) { - errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)+", cause: "+e.getMessage(); + OSXUtil.RunOnMainThread(false, false, new Runnable() { + @Override + public void run() { + String errMsg = null; + if(0 == rootSurfaceLayer && 0 != jawtSurfaceLayersHandle) { + rootSurfaceLayer = OSXUtil.CreateCALayer(bounds.getWidth(), bounds.getHeight(), getPixelScaleX()); // HiDPI: uniform pixel scale + if(0 == rootSurfaceLayer) { + errMsg = "Could not create root CALayer"; + } else { + try { + SetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); + } catch(Exception e) { + errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)+", cause: "+e.getMessage(); + } } - } - if(null != errMsg) { - if(0 != rootSurfaceLayer) { - OSXUtil.DestroyCALayer(rootSurfaceLayer); - rootSurfaceLayer = 0; + if(null != errMsg) { + if(0 != rootSurfaceLayer) { + OSXUtil.DestroyCALayer(rootSurfaceLayer); + rootSurfaceLayer = 0; + } + throw new NativeWindowException(errMsg+": "+MacOSXJAWTWindow.this); } - throw new NativeWindowException(errMsg+": "+MacOSXJAWTWindow.this); } - } - } } ); + } } ); } if(null != errMsg) { if(0 != windowHandle) { diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index a91698f62..22ac9c355 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -251,9 +251,10 @@ public class OSXUtil implements ToolkitProperties { * </p> * * @param waitUntilDone + * @param kickNSApp if <code>true</code> issues {@link #KickNSApp()} * @param runnable */ - public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) { + public static void RunOnMainThread(final boolean waitUntilDone, final boolean kickNSApp, final Runnable runnable) { if( IsMainThread0() ) { runnable.run(); // don't leave the JVM } else { @@ -263,7 +264,7 @@ public class OSXUtil implements ToolkitProperties { final Object sync = new Object(); final RunnableTask rt = new RunnableTask( runnable, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); synchronized(sync) { - RunOnMainThread0(rt); + RunOnMainThread0(kickNSApp, rt); if( waitUntilDone ) { try { sync.wait(); @@ -288,14 +289,33 @@ public class OSXUtil implements ToolkitProperties { * @param delay delay to run the runnable in milliseconds */ public static void RunLater(boolean onMain, Runnable runnable, int delay) { - RunLater0(onMain, new RunnableTask( runnable, null, true, System.err ), delay); + RunLater0(onMain, false /* kickNSApp */, new RunnableTask( runnable, null, true, System.err ), delay); + } + + /** + * Wakes up NSApp thread by sending an empty NSEvent .. + * <p> + * This is deemed important <i>sometimes</i> where resources shall get freed ASAP, e.g. GL context etc. + * </p> + * <p> + * The following scenarios requiring this <i>wake-up</i> are currently known: + * <ul> + * <li>Destruction of an OpenGL context</li> + * <li>Destruction of Windows .. ?</li> + * <li>Stopping the NSApp</li> + * </ul> + * </p> + * FIXME: Complete list of scenarios and reason it. + */ + public static void KickNSApp() { + KickNSApp0(); } private static Runnable _nop = new Runnable() { @Override public void run() {}; }; - /** Issues a {@link #RunOnMainThread(boolean, Runnable)} w/ an <i>NOP</i> runnable, while waiting until done. */ + /** Issues a {@link #RunOnMainThread(boolean, boolean, Runnable)} w/ an <i>NOP</i> runnable, while waiting until done and issuing {@link #KickNSApp()}. */ public static void WaitUntilFinish() { - RunOnMainThread(true, _nop); + RunOnMainThread(true, true /* kickNSApp */, _nop); } /** @@ -305,9 +325,10 @@ public class OSXUtil implements ToolkitProperties { * </p> * * @param waitUntilDone + * @param kickNSApp if <code>true</code> issues {@link #KickNSApp()} * @param func */ - public static <R,A> R RunOnMainThread(boolean waitUntilDone, Function<R,A> func, A... args) { + public static <R,A> R RunOnMainThread(final boolean waitUntilDone, final boolean kickNSApp, final Function<R,A> func, final A... args) { if( IsMainThread0() ) { return func.eval(args); // don't leave the JVM } else { @@ -318,7 +339,7 @@ public class OSXUtil implements ToolkitProperties { final FunctionTask<R,A> rt = new FunctionTask<R,A>( func, waitUntilDone ? sync : null, true, waitUntilDone ? null : System.err ); synchronized(sync) { rt.setArgs(args); - RunOnMainThread0(rt); + RunOnMainThread0(kickNSApp, rt); if( waitUntilDone ) { try { sync.wait(); @@ -384,8 +405,9 @@ public class OSXUtil implements ToolkitProperties { private static native void SetCALayerPixelScale0(long rootCALayer, long subCALayer, float contentsScale); private static native void RemoveCASublayer0(long rootCALayer, long subCALayer); private static native void DestroyCALayer0(long caLayer); - private static native void RunOnMainThread0(Runnable runnable); - private static native void RunLater0(boolean onMain, Runnable runnable, int delay); + private static native void RunOnMainThread0(boolean kickNSApp, Runnable runnable); + private static native void RunLater0(boolean onMain, boolean kickNSApp, Runnable runnable, int delay); + private static native void KickNSApp0(); private static native boolean IsMainThread0(); private static native int GetScreenRefreshRate0(int scrn_idx); } diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index fa3bf026a..bf01f19d8 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -1006,29 +1006,61 @@ static void RunOnThread (JNIEnv *env, jobject runnable, BOOL onMain, jint delayI DBG_PRINT2( "RunOnThread.X\n"); } -/* +static void OSXUtil_KickNSApp() { + NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSMakePoint(0,0) + modifierFlags: 0 + timestamp: 0.0 + windowNumber: 0 + context: nil + subtype: 0 + data1: 0 + data2: 0]; + [NSApp postEvent: event atStart: true]; +} + +/** * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: RunOnMainThread0 * Signature: (ZLjava/lang/Runnable;)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0 - (JNIEnv *env, jclass unused, jobject runnable) + (JNIEnv *env, jclass unused, jboolean kickNSApp, jobject runnable) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; RunOnThread (env, runnable, YES, 0); + if( kickNSApp ) { + OSXUtil_KickNSApp(); + } [pool release]; } /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: RunLater0 - * Signature: (ZLjava/lang/Runnable;I)V + * Signature: (ZZLjava/lang/Runnable;I)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunLater0 - (JNIEnv *env, jclass unused, jboolean onMain, jobject runnable, jint delay) + (JNIEnv *env, jclass unused, jboolean onMain, jboolean kickNSApp, jobject runnable, jint delay) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; RunOnThread (env, runnable, onMain ? YES : NO, delay); + if( kickNSApp ) { + OSXUtil_KickNSApp(); + } + [pool release]; +} + +/** + * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: KickNSApp0 + * Signature: (V)V + */ +JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_KickNSApp0 + (JNIEnv *env, jclass unused) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + OSXUtil_KickNSApp(); [pool release]; } |