diff options
author | Sven Gothel <[email protected]> | 2013-03-19 00:33:00 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-03-19 00:33:00 +0100 |
commit | 81cbcdc8469143587b2044661dd613c798ae02ba (patch) | |
tree | 813982c77435a9ca75225019b8ea0ebe3d22b08c /src/newt/native/NewtMacWindow.m | |
parent | f354fb204d8973453c538dda78a2c82c87be61dc (diff) |
OSX/NEWT: Following CALayer streaming design, i.e. issue NSWindow/NSView Ops on main-thread w/o blocking; NEWT/WindowImpl: Volatile multithreaded mutable values
Similar to commits:
28c6472335b924080d638b33a28f8f4eedb459b1
f354fb204d8973453c538dda78a2c82c87be61dc
main-thread operations cannot block main-thread.
Luckily we are able to create the NSWindow and NSView instance uninitialized (deferred) on the current thread,
while issuing their initialization on the main-thread w/o blocking.
Further more a size glitch is fixed, which didn't take the title bar into account.
+++
NEWT/WindowImpl: Volatile multithreaded mutable values
Since position, size and other attributes might get changes off-thread, these fields needs to be volatile.
Diffstat (limited to 'src/newt/native/NewtMacWindow.m')
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 145 |
1 files changed, 81 insertions, 64 deletions
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 282c13fd3..d7b357349 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -113,7 +113,7 @@ static jmethodID windowRepaintID = NULL; jvmHandle = NULL; jvmVersion = 0; destroyNotifySent = NO; - softLocked = NO; + softLockCount = 0; pthread_mutexattr_t softLockSyncAttr; pthread_mutexattr_init(&softLockSyncAttr); @@ -134,19 +134,21 @@ static jmethodID windowRepaintID = NULL; return res; } +#ifdef DBG_LIFECYCLE - (void) release { DBG_PRINT("NewtView::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON - // NSLog(@"%@",[NSThread callStackSymbols]); -#endif [super release]; } +#endif - (void) dealloc { DBG_PRINT("NewtView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag); - if(softLocked) { +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); +#endif + if( 0 < softLockCount ) { NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n"); } if(0 != ptrTrackingTag) { @@ -155,9 +157,6 @@ static jmethodID windowRepaintID = NULL; ptrTrackingTag = 0; } pthread_mutex_destroy(&softLockSync); -#ifdef VERBOSE_ON - //NSLog(@"%@",[NSThread callStackSymbols]); -#endif DBG_PRINT("NewtView::dealloc.X: %p\n", self); [super dealloc]; } @@ -206,6 +205,7 @@ static jmethodID windowRepaintID = NULL; if(0 != ptrTrackingTag) { // [self removeCursorRect: ptrRect cursor: myCursor]; [self removeTrackingRect: ptrTrackingTag]; + ptrTrackingTag = 0; } ptrRect = [self bounds]; // [self addCursorRect: ptrRect cursor: myCursor]; @@ -230,18 +230,27 @@ static jmethodID windowRepaintID = NULL; - (BOOL) softLock { // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self()); - // NSLog(@"NewtView::softLock: %@",[NSThread callStackSymbols]); - pthread_mutex_lock(&softLockSync); - softLocked = YES; + int err; + if( 0 != ( err = pthread_mutex_lock(&softLockSync) ) ) { + NSLog(@"NewtView::softLock failed: errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + softLockCount++; // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self()); - return softLocked; + return 0 < softLockCount; } -- (void) softUnlock +- (BOOL) softUnlock { // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self()); - softLocked = NO; - pthread_mutex_unlock(&softLockSync); + softLockCount--; + int err; + if( 0 != ( err = pthread_mutex_unlock(&softLockSync) ) ) { + softLockCount++; + NSLog(@"NewtView::softUnlock failed: Not locked by current thread - errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + return YES; } - (BOOL) needsDisplay @@ -398,25 +407,26 @@ static jmethodID windowRepaintID = NULL; mouseInside = NO; cursorIsHidden = NO; realized = YES; - DBG_PRINT("NewtWindow::create: %p (refcnt %d)\n", res, (int)[res retainCount]); + DBG_PRINT("NewtWindow::create: %p, realized %d (refcnt %d)\n", res, realized, (int)[res retainCount]); return res; } +#ifdef DBG_LIFECYCLE - (void) release { DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON // NSLog(@"%@",[NSThread callStackSymbols]); -#endif [super release]; } +#endif - (void) dealloc { DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON - // NSLog(@"%@",[NSThread callStackSymbols]); +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); #endif + NewtView* mView = (NewtView *)[self contentView]; if( NULL != mView ) { [mView release]; @@ -425,9 +435,9 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT("NewtWindow::dealloc.X: %p\n", self); } -- (void) setUnrealized +- (void) setRealized: (BOOL)v { - realized = NO; + realized = v; } - (BOOL) isRealized @@ -435,18 +445,8 @@ static jmethodID windowRepaintID = NULL; return realized; } -- (void) updateInsets: (JNIEnv*) env +- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin { - NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; - } - NewtView* view = (NewtView *) nsview; - jobject javaWindowObject = [view getJavaWindowObject]; - if (env==NULL || javaWindowObject == NULL) { - return; - } - NSRect frameRect = [self frame]; NSRect contentRect = [self contentRectForFrameRect: frameRect]; @@ -460,7 +460,9 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); - (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); + if( NULL != env && NULL != javaWin ) { + (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); + } } - (void) attachToParent: (NSWindow*) parent @@ -502,11 +504,21 @@ static jmethodID windowRepaintID = NULL; { int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: given %d/%d %dx%d, insets bottom %d -> totalHeight %d\n", + (int)p.x, (int)p.y, (int)nsz.width, (int)nsz.height, cachedInsets[3], totalHeight); + NSScreen* screen = [self screen]; NSRect screenFrame = [screen frame]; - return NSMakePoint(screenFrame.origin.x + p.x, - screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight); + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen %d/%d %dx%d\n", + (int)screenFrame.origin.x, (int)screenFrame.origin.y, (int)screenFrame.size.width, (int)screenFrame.size.height); + + NSPoint r = NSMakePoint(screenFrame.origin.x + p.x, + screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight); + + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: result %d/%d\n", (int)r.x, (int)r.y); + + return r; } /** @@ -524,6 +536,12 @@ static jmethodID windowRepaintID = NULL; winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view } +- (NSSize) newtClientSize2TLSize: (NSSize) nsz +{ + NSSize topSZ = { nsz.width, nsz.height + cachedInsets[2] + cachedInsets[3] }; // height + insets.top + insets.bottom + return topSZ; +} + /** * y-flips input / output * p rel client window position w/ top-left origin @@ -646,7 +664,7 @@ static jint mods2JavaMods(NSUInteger mods) - (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -706,7 +724,7 @@ static jint mods2JavaMods(NSUInteger mods) - (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -783,7 +801,7 @@ static jint mods2JavaMods(NSUInteger mods) { DBG_PRINT( "focusChanged: gained %d\n", gained); NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -981,43 +999,42 @@ static jint mods2JavaMods(NSUInteger mods) - (void)windowDidResize: (NSNotification*) notification { - NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; - } - NewtView* view = (NewtView *) nsview; - jobject javaWindowObject = [view getJavaWindowObject]; - if (javaWindowObject == NULL) { - DBG_PRINT("windowDidResize: null javaWindowObject\n"); - return; - } + JNIEnv* env = NULL; + jobject javaWindowObject = NULL; int shallBeDetached = 0; - JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); - if(NULL==env) { - DBG_PRINT("windowDidResize: null JNIEnv\n"); - return; + JavaVM *jvmHandle = NULL; + + NSView* nsview = [self contentView]; + if( [nsview isKindOfClass:[NewtView class]] ) { + NewtView* view = (NewtView *) nsview; + javaWindowObject = [view getJavaWindowObject]; + if (javaWindowObject != NULL) { + jvmHandle = [view getJVMHandle]; + env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + } } // update insets on every window resize for lack of better hook place - [self updateInsets: env]; + [self updateInsets: env jwin:javaWindowObject]; - NSRect frameRect = [self frame]; - NSRect contentRect = [self contentRectForFrameRect: frameRect]; + if( NULL != env && NULL != javaWindowObject ) { + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; - (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE, - (jint) contentRect.size.width, - (jint) contentRect.size.height, JNI_FALSE); + (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE, + (jint) contentRect.size.width, + (jint) contentRect.size.height, JNI_FALSE); - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); + if (shallBeDetached) { + (*jvmHandle)->DetachCurrentThread(jvmHandle); + } } } - (void)windowDidMove: (NSNotification*) notification { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -1061,7 +1078,7 @@ static jint mods2JavaMods(NSUInteger mods) [self cursorHide: NO]; NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return NO; } NewtView* view = (NewtView *) nsview; |