diff options
author | Sven Gothel <[email protected]> | 2011-11-10 17:14:51 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-11-10 17:14:51 +0100 |
commit | 0120a81c36ffc7455d196960048fe935f82fc9a6 (patch) | |
tree | c7933d3df1a645b277de9fd73eafa31a0c737d8f /src/nativewindow | |
parent | af083029321b3ff57c37f9426ecf5eb526b5e7ae (diff) |
OS X Layered View: Part6 (native) Using a root CALayer where we attach/detach our GL one
- it seems to be more stable, having one root CALayer attached to the JAWT_SurfaceView forever
- tackles crach at GL layer destruction
- proper release of all GL layer resources
- now final [gl-layer dealloc] happens at very destruction of JAWT object,
even though it was removed from root-layer earlier (and all other references)
- see comment in MacOSXWindowSystemInterface-pbuffer.m :: createNSOpenGLLayer(..)
- at least no more crash .. and resource release ASAP, but the GL-layer itself (see above)
Diffstat (limited to 'src/nativewindow')
3 files changed, 184 insertions, 74 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 71b297791..364b2054d 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -58,7 +58,6 @@ import jogamp.nativewindow.jawt.JAWTUtil; import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.nativewindow.jawt.JAWT_DrawingSurface; import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; -import jogamp.nativewindow.jawt.JAWT_Rectangle; import jogamp.nativewindow.macosx.OSXUtil; public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { @@ -78,17 +77,47 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { OSXUtil.DestroyNSWindow(drawable); drawable = 0; } - if(0 != surfaceLayerHandle && null!=dsi) { - OSXUtil.AttachJAWTSurfaceLayer(dsi, 0); - } - surfaceLayerHandle = 0; } } public final boolean isOffscreenLayerSurface() { return isOffscreenLayerSurface; + } + public void attachSurfaceLayer(final long layerHandle) { + if( !isOffscreenLayerSurface() ) { + throw new NativeWindowException("Not using CALAYER"); + } + int lockRes = lockSurface(); + if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + throw new NativeWindowException("Could not lock layeredSurfaceHost: "+this); + } + try { + if(DEBUG) { + System.err.println("MacOSXJAWTWindow.attachSurfaceLayer(): 0x"+Long.toHexString(layerHandle)); + } + OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle); + } finally { + unlockSurface(); + } } - + public void detachSurfaceLayer(final long layerHandle) { + if( !isOffscreenLayerSurface() ) { + throw new NativeWindowException("Not using CALAYER"); + } + int lockRes = lockSurface(); + if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + throw new NativeWindowException("Could not lock layeredSurfaceHost: "+this); + } + try { + if(DEBUG) { + System.err.println("MacOSXJAWTWindow.detachSurfaceLayer(): 0x"+Long.toHexString(layerHandle)); + } + OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle); + } finally { + unlockSurface(); + } + } + public long getSurfaceHandle() { return isOffscreenLayerSurface ? surfaceHandle : super.getSurfaceHandle() ; } @@ -117,45 +146,6 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { return sscSet ? sscHeight: super.getHeight(); } - /* - public long getSurfaceLayer() { - if( !isLayeredSurface() ) { - throw new java.lang.UnsupportedOperationException("Not using CALAYER"); - } - if( !dsLocked ) { - throw new NativeWindowException("Not locked"); - } - // return macosxsl.getLayer(); - return getSurfaceLayers().getLayer(); - } */ - - public void attachSurfaceLayer(final long layerHandle) { - if( !isOffscreenLayerSurface() ) { - throw new NativeWindowException("Not using CALAYER"); - } - int lockRes = lockSurface(); - if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { - throw new NativeWindowException("Could not lock layeredSurfaceHost: "+this); - } - try { - if(DEBUG) { - System.err.println("MacOSXJAWTWindow.attachSurfaceLayer(): 0x"+Long.toHexString(layerHandle)); - } - if(!OSXUtil.AttachJAWTSurfaceLayer(dsi, layerHandle)) { - throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this); - } - surfaceLayerHandle = layerHandle; - } finally { - unlockSurface(); - } - /* - if( null == macosxsl) { - throw new NativeWindowException("Not locked and/or SurfaceLayers null"); - } - macosxsl.setLayer(layerHandle); */ - // getSurfaceLayers().setLayer(layerHandle); - } - protected int lockSurfaceImpl() throws NativeWindowException { int ret = NativeWindow.LOCK_SURFACE_NOT_READY; if(null == ds) { @@ -234,15 +224,24 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { Capabilities caps = (Capabilities) config.getChosenCapabilities().cloneMutable(); caps.setOnscreen(false); config.setChosenCapabilities(caps); + } + if(0 == rootSurfaceLayerHandle) { + rootSurfaceLayerHandle = OSXUtil.CreateCALayer(); + if(0 == rootSurfaceLayerHandle) { + OSXUtil.DestroyNSWindow(drawable); + drawable = 0; + unlockSurfaceImpl(); + throw new NativeWindowException("Could not create root CALayer: "+this); + } + if(!OSXUtil.AttachJAWTSurfaceLayer(dsi, rootSurfaceLayerHandle)) { + OSXUtil.DestroyCALayer(rootSurfaceLayerHandle); + rootSurfaceLayerHandle = 0; + OSXUtil.DestroyNSWindow(drawable); + drawable = 0; + unlockSurfaceImpl(); + throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this); + } } - /** - macosxsl = (JAWT_SurfaceLayers) dsi.platformInfo(); - if (null == macosxsl) { - unlockSurfaceImpl(); - return NativeWindow.LOCK_SURFACE_NOT_READY; - } else { - ret = NativeWindow.LOCK_SUCCESS; - } */ ret = NativeWindow.LOCK_SUCCESS; } @@ -261,31 +260,14 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { } ds = null; dsi = null; - // macosxsl = null; } - /** - protected JAWT_SurfaceLayers getSurfaceLayers() { - if( !dsLocked || null == dsi ) { - throw new NativeWindowException("Locked: "+dsLocked+", dsi valid: "+(null!=dsi)); - } - final JAWT_SurfaceLayers macosxsl = (JAWT_SurfaceLayers) dsi.platformInfo(); - if (null == macosxsl) { - throw new NativeWindowException("SurfaceLayer null"); - } - return macosxsl; - } */ - private void dumpInfo() { System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName()); // System.err.println(this); System.err.println("JAWT version: 0x"+Integer.toHexString(JAWT.getJAWT().getVersionCached())+ ", CA_LAYER: "+ (0!=(JAWT.getJAWT().getVersionCached() & JAWT.JAWT_MACOSX_USE_CALAYER))+ - ", isLayeredSurface "+isOffscreenLayerSurface()); - if(null != dsi) { - JAWT_Rectangle r = dsi.getBounds(); - System.err.println("dsi bounds: "+r.getX()+"/"+r.getY()+" "+r.getWidth()+"x"+r.getHeight()); - } + ", isLayeredSurface "+isOffscreenLayerSurface()+", bounds "+bounds); // Thread.dumpStack(); } @@ -307,10 +289,10 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { private JAWT_DrawingSurfaceInfo dsi; private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; - // private JAWT_SurfaceLayers macosxsl; private final boolean isOffscreenLayerSurface; - private long surfaceLayerHandle = 0; + private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer + private long surfaceHandle = 0; private int sscWidth, sscHeight; private boolean sscSet = false; diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index a07001def..1739288a7 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -51,7 +51,31 @@ public class OSXUtil { DestroyNSWindow0(nsWindow); } + public static long CreateCALayer() { + return CreateCALayer0(); + } + public static void AddCASublayer(long rootCALayer, long subCALayer) { + if(0==rootCALayer || 0==subCALayer) { + throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer)); + } + AddCASublayer0(rootCALayer, subCALayer); + } + public static void RemoveCASublayer(long rootCALayer, long subCALayer) { + if(0==rootCALayer || 0==subCALayer) { + throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer)); + } + RemoveCASublayer0(rootCALayer, subCALayer); + } + public static void DestroyCALayer(long caLayer) { + if(0==caLayer) { + throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer)); + } + DestroyCALayer0(caLayer); + } public static boolean AttachJAWTSurfaceLayer(JAWT_DrawingSurfaceInfo dsi, long caLayer) { + if(0==caLayer) { + throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer)); + } return AttachJAWTSurfaceLayer0(dsi.getBuffer(), caLayer); } @@ -73,6 +97,10 @@ public class OSXUtil { private static native void DestroyNSView0(long nsView); private static native long CreateNSWindow0(int x, int y, int width, int height); private static native void DestroyNSWindow0(long nsWindow); + private static native long CreateCALayer0(); + private static native void AddCASublayer0(long rootCALayer, long subCALayer); + private static native void RemoveCASublayer0(long rootCALayer, long subCALayer); + private static native void DestroyCALayer0(long caLayer); private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer); private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable); private static native boolean IsMainThread0(); diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index 16a4ed148..7b7897701 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -39,6 +39,15 @@ #include <jawt_md.h> #import <JavaNativeFoundation.h> +#define VERBOSE 1 +// +#ifdef VERBOSE + // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__) + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) +#else + #define DBG_PRINT(...) +#endif + static const char * const ClazzNameRunnable = "java/lang/Runnable"; static jmethodID runnableRunID = NULL; @@ -224,6 +233,97 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0 /* * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: CreateCALayer0 + * Signature: (V)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0 + (JNIEnv *env, jclass unused) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + // CALayer* layer = [[CALayer alloc] init]; + CALayer* layer = [CALayer layer]; + + // initial dummy size ! + CGRect lRect = [layer frame]; + lRect.origin.x = 0; + lRect.origin.y = 0; + lRect.size.width = 32; + lRect.size.height = 32; + [layer setFrame: lRect]; + DBG_PRINT("CALayer::CreateCALayer0: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height); + + [pool release]; + + return (jlong) ((intptr_t) layer); +} + +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: AddCASublayer0 + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0 + (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer) +{ + JNF_COCOA_ENTER(env); + CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer); + CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer); + + CGRect lRectRoot = [rootLayer frame]; + // simple 1:1 layout ! + [subLayer setFrame:lRectRoot]; + DBG_PRINT("CALayer::AddCASublayer0.0: %p . %p %lf/%lf %lfx%lf (%lf/%lf %lfx%lf) (refcnt %d)\n", + rootLayer, subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]); + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + [rootLayer addSublayer:subLayer]; + }]; + DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]); + JNF_COCOA_EXIT(env); +} + +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: RemoveCASublayer0 + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0 + (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer) +{ + JNF_COCOA_ENTER(env); + CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer); + CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer); + + DBG_PRINT("CALayer::RemoveCASublayer0.0: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]); + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + [subLayer removeFromSuperlayer]; + // [[rootLayer sublayers] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; + }]; + DBG_PRINT("CALayer::RemoveCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]); + JNF_COCOA_EXIT(env); +} + +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil + * Method: DestroyCALayer0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0 + (JNIEnv *env, jclass unused, jlong caLayer) +{ + JNF_COCOA_ENTER(env); + CALayer* layer = (CALayer*) ((intptr_t) caLayer); + + DBG_PRINT("CALayer::DestroyCALayer0.0: %p (refcnt %d)\n", layer, (int)[layer retainCount]); + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + [layer release]; // performs release! + }]; + DBG_PRINT("CALayer::DestroyCALayer0.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]); + JNF_COCOA_EXIT(env); +} + +/* + * Class: Java_jogamp_nativewindow_macosx_OSXUtil * Method: attachJAWTSurfaceLayer * Signature: (JJ)Z */ @@ -239,8 +339,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AttachJAWTSur CALayer* layer = (CALayer*) (intptr_t) caLayer; [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo; + DBG_PRINT("CALayer::attachJAWTSurfaceLayer: %p -> %p\n", surfaceLayers.layer, layer); surfaceLayers.layer = [layer autorelease]; - // surfaceLayers.layer = layer; // FIXME: JAU }]; JNF_COCOA_EXIT(env); return JNI_TRUE; |