aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-02-15 17:15:49 +0100
committerSven Gothel <[email protected]>2013-02-15 17:15:49 +0100
commit2aeff053c55dadafb94bfbba661250e0c96f1fe5 (patch)
treef65c8fd9a2ccd3b44bb90a59b99fe59fa58fcb88 /src/nativewindow
parentf6e6fab2a7ddfb5c9b614cb072c27ff697629161 (diff)
Fix Bug 691 (part-2): Extra '[subLayer release]' is wrong, since 'CGL.releaseNSOpenGLLayer' triggers release - but very late w/ AWT usage.
OSXUtil_RemoveCASublayer0's added '[subLayer release]' in commit f6e6fab2a7ddfb5c9b614cb072c27ff697629161 is wrong, since 'CGL.releaseNSOpenGLLayer' actually does trigger it's release. This was not seen w/ AWT tests, since it happens very later. A NewtCanvasAWT test disclosed this error -> removed that extra release call. The culprit for the late release w/ AWT usage was CGL.createNSOpenGLLayer's call in the current thread. Moving it to the Main-Thread fixed the problem. All CALayer lifecycle calls are issued on the Main-Thread now. NSOpenGLLayer's CVDisplayLink OpenGL fitting via 'CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext' is now performed at it's context creation in 'NSOpenGLLayer::openGLContextForPixelFormat'. The 'extra' release of the NSOpenGLLayer's NSOpenGLContext as introduced in commit f6e6fab2a7ddfb5c9b614cb072c27ff697629161 is still valid.
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java16
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m119
2 files changed, 109 insertions, 26 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 2e133c22f..b765a68c3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -136,8 +136,11 @@ public class OSXUtil implements ToolkitProperties {
return GetNSWindow0(nsView);
}
- public static long CreateCALayer(int x, int y, int width, int height) {
- return CreateCALayer0(x, y, width, height);
+ public static long CreateCALayer(final int x, final int y, final int width, final int height) {
+ return OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
+ public Long eval(Object... args) {
+ return Long.valueOf( CreateCALayer0(x, y, width, height) );
+ } } ).longValue();
}
public static void AddCASublayer(final long rootCALayer, final long subCALayer) {
if(0==rootCALayer || 0==subCALayer) {
@@ -145,7 +148,7 @@ public class OSXUtil implements ToolkitProperties {
}
RunOnMainThread(true, new Runnable() {
public void run() {
- AddCASublayer0(rootCALayer, subCALayer);
+ AddCASublayer0(rootCALayer, subCALayer);
}
});
}
@@ -205,6 +208,13 @@ public class OSXUtil implements ToolkitProperties {
}
}
+ private static Runnable _nop = new Runnable() { public void run() {}; };
+
+ /** Issues a {@link #RunOnMainThread(boolean, Runnable)} w/ an <i>NOP</i> runnable, while waiting until done. */
+ public static void WaitUntilFinish() {
+ RunOnMainThread(true, _nop);
+ }
+
/**
* Run on OSX UI main thread.
* <p>
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 3fa320042..83f3c821f 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -32,6 +32,7 @@
#include <stdarg.h>
#include <unistd.h>
#include <AppKit/AppKit.h>
+#import <QuartzCore/QuartzCore.h>
#include "NativewindowCommon.h"
#include "jogamp_nativewindow_macosx_OSXUtil.h"
@@ -323,6 +324,64 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0
return res;
}
+/**
+ * Track lifecycle via DBG_PRINT messages, if VERBOSE is enabled!
+ */
+@interface MyCALayer: CALayer
+{
+}
+- (id)init;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+- (void)dealloc;
+#endif
+
+@end
+
+@implementation MyCALayer
+
+- (id)init
+{
+ DBG_PRINT("MyCALayer.0\n");
+ MyCALayer * o = [super init];
+ DBG_PRINT("MyNSOpenGLContext.init.X: new %p\n", o);
+ DBG_PRINT("MyCALayer.0\n");
+ return o;
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyCALayer::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyCALayer::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyCALayer::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::release: %@",[NSThread callStackSymbols]);
+ [super release];
+ // DBG_PRINT("MyCALayer::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyCALayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyCALayer::dealloc: %@",[NSThread callStackSymbols]);
+ [super dealloc];
+ // DBG_PRINT("MyCALayer.dealloc.X: %p\n", self);
+}
+
+#endif
+
+
+@end
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: CreateCALayer0
@@ -333,7 +392,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- CALayer* layer = [[CALayer alloc] init];
+ MyCALayer* layer = [[MyCALayer alloc] init];
DBG_PRINT("CALayer::CreateCALayer.0: root %p %d/%d %dx%d (refcnt %d)\n", layer, (int)x, (int)y, (int)width, (int)height, (int)[layer retainCount]);
// avoid zero size
if(0 == width) { width = 32; }
@@ -349,12 +408,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[layer removeAllAnimations];
+ // [layer addAnimation:nil forKey:kCATransition];
[layer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[layer setNeedsDisplayOnBoundsChange: YES];
DBG_PRINT("CALayer::CreateCALayer.1: root %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
- DBG_PRINT("CALayer::CreateCALayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
-
[pool release];
+ DBG_PRINT("CALayer::CreateCALayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
return (jlong) ((intptr_t) layer);
}
@@ -367,8 +426,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer);
CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
CGRect lRectRoot = [rootLayer frame];
@@ -385,6 +444,9 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
rootLayer, (int)[rootLayer retainCount],
subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]);
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
// simple 1:1 layout !
[subLayer setFrame:lRectRoot];
[rootLayer addSublayer:subLayer];
@@ -392,14 +454,19 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
// no animations for add/remove/swap sublayers etc
// doesn't work: [layer removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
[rootLayer removeAllAnimations];
+ // [rootLayer addAnimation:nil forKey:kCATransition];
[rootLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[rootLayer setNeedsDisplayOnBoundsChange: YES];
[subLayer removeAllAnimations];
+ // [sublayer addAnimation:nil forKey:kCATransition];
[subLayer setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[subLayer setNeedsDisplayOnBoundsChange: YES];
+
+ [CATransaction commit];
+
+ [pool release];
DBG_PRINT("CALayer::AddCASublayer0.X: root %p (refcnt %d) .sub %p (refcnt %d)\n",
rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
- JNF_COCOA_EXIT(env);
}
/*
@@ -410,19 +477,26 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* rootLayer = (MyCALayer*) ((intptr_t) rootCALayer);
CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
(void)rootLayer; // no warnings
DBG_PRINT("CALayer::RemoveCASublayer0.0: root %p (refcnt %d) .sub %p (refcnt %d)\n",
rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
[subLayer removeFromSuperlayer];
- [subLayer release];
+ // [subLayer release] is called explicitly, e.g. via CGL.releaseNSOpenGLLayer(..) (MyNSOpenGLLayer::releaseLayer)
+
+ [CATransaction commit];
+
+ [pool release];
DBG_PRINT("CALayer::RemoveCASublayer0.X: root %p (refcnt %d) .sub %p (refcnt %d)\n",
rootLayer, (int)[rootLayer retainCount], subLayer, (int)[subLayer retainCount]);
- JNF_COCOA_EXIT(env);
}
/*
@@ -433,14 +507,13 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0
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);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyCALayer* layer = (MyCALayer*) ((intptr_t) caLayer);
DBG_PRINT("CALayer::DestroyCALayer0.0: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
- [layer release]; // Var.A
- // [layer dealloc]; // Var.B -> SIGSEGV
+ [layer release]; // Trigger release of root CALayer
+ [pool release];
DBG_PRINT("CALayer::DestroyCALayer0.X: root %p\n", layer);
- JNF_COCOA_EXIT(env);
}
/*
@@ -451,18 +524,18 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
- JNF_COCOA_ENTER(env);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
if (NULL == dsi) {
NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
return JNI_FALSE;
}
- CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: pre %p -> root %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]);
- surfaceLayers.layer = layer; // already incr. retain count
+ surfaceLayers.layer = [layer retain]; // Pairs w/ Unset
+ [pool release];
DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
- JNF_COCOA_EXIT(env);
return JNI_TRUE;
}
@@ -474,23 +547,23 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
- JNF_COCOA_ENTER(env);
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
if (NULL == dsi) {
NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
return JNI_FALSE;
}
- CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
if(layer != surfaceLayers.layer) {
NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
return JNI_FALSE;
}
DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.0: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
+ [layer release]; // Pairs w/ Set
surfaceLayers.layer = NULL;
- [layer release]; // Var.A
+ [pool release];
DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.X: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
- JNF_COCOA_EXIT(env);
return JNI_TRUE;
}