Jogamp
Bug 1267 - OSX El Capitan: Animated NEWT GLWindow flickers at resize
authorSven Gothel <sgothel@jausoft.com>
Sun, 15 Nov 2015 03:34:51 +0000 (04:34 +0100)
committerSven Gothel <sgothel@jausoft.com>
Sun, 15 Nov 2015 03:34:51 +0000 (04:34 +0100)
OSX El Capitan 10.11.1 using JRE 1.8.0_66:

Animated NEWT GLWindow flickers at resize.

While at live resize the animation thread renders
into the live resized NSView which causes flickering on OSX 10.11.

Resolution is to pause animation during live resize
and resume at its end.

src/newt/classes/jogamp/newt/WindowImpl.java
src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
src/newt/native/NewtMacWindow.h
src/newt/native/NewtMacWindow.m

index 88f9e07..0d395b9 100644 (file)
@@ -3275,6 +3275,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
             sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
             if(animatorPaused) {
                 lifecycleHook.resumeRenderingAction();
+                animatorPaused = false;
             }
             if( hadFocus ) {
                 requestFocus(true);
index a433ef3..46c86d2 100644 (file)
@@ -211,6 +211,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
             surfaceHandle = 0;
             sscSurfaceHandle = 0;
             isOffscreenInstance = false;
+            resizeAnimatorPaused = false;
             if (0 != handle) {
                 OSXUtil.RunOnMainThread(false, true /* kickNSApp */, new Runnable() {
                    @Override
@@ -593,10 +594,21 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
                                               final int newX, final int newY,
                                               final int newWidth, final int newHeight,
                                               final int left, final int right, final int top, final int bottom,
-                                              final boolean force) {
+                                              final boolean force,
+                                              final boolean withinLiveResize) {
+        final LifecycleHook lh = getLifecycleHook();
+        if( withinLiveResize && !resizeAnimatorPaused && null!=lh ) {
+            resizeAnimatorPaused = lh.pauseRenderingAction();
+        }
         sizeChanged(defer, newWidth, newHeight, force);
         screenPositionChanged(defer, newX, newY);
         insetsChanged(defer, left, right, top, bottom);
+        if( !withinLiveResize && resizeAnimatorPaused ) {
+            resizeAnimatorPaused = false;
+            if( null!=lh ) {
+                lh.resumeRenderingAction();
+            }
+        }
     }
 
     @Override
@@ -847,5 +859,5 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
     private volatile long surfaceHandle = 0;
     private long sscSurfaceHandle = 0;
     private boolean isOffscreenInstance = false;
-
+    private boolean resizeAnimatorPaused = false;
 }
index bd08878..14474bc 100644 (file)
@@ -142,6 +142,7 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
 #endif
 {
     BOOL realized;
+    jboolean withinLiveResize;
 @public
     BOOL hasPresentationSwitch;
     NSUInteger defaultPresentationOptions;
@@ -192,7 +193,12 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
 - (void) windowDidBecomeKey: (NSNotification *) notification;
 - (void) windowDidResignKey: (NSNotification *) notification;
 
+- (void) windowWillStartLiveResize: (NSNotification *) notification;
+- (void) windowDidEndLiveResize: (NSNotification *) notification;
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize;
 - (void) windowDidResize: (NSNotification*) notification;
+- (void) sendResizeEvent;
+
 - (void) windowDidMove: (NSNotification*) notification;
 - (BOOL) windowClosingImpl: (BOOL) force;
 - (BOOL) windowShouldClose: (id) sender;
index 86c4490..6024a90 100644 (file)
@@ -832,7 +832,7 @@ NS_ENDHANDLER
     updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V");
     visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
     insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
-    sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZ)V");
+    sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
     screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
     focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
     windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
@@ -893,6 +893,7 @@ NS_ENDHANDLER
     cachedInsets[3] = 0; // b
 
     realized = YES;
+    withinLiveResize = JNI_FALSE;
     DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", 
         res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
     return res;
@@ -974,7 +975,7 @@ NS_ENDHANDLER
     NSRect frameRect = [self frame];
     NSRect contentRect = [self contentRectForFrameRect: frameRect];
 
-    DBG_PRINT( "updateSize: [ w %d, h %d ]\n", (jint) contentRect.size.width, (jint) contentRect.size.height);
+    DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) contentRect.size.width, (jint) contentRect.size.height, (jint)withinLiveResize);
 
     NSPoint p0 = { 0, 0 };
     p0 = [self getLocationOnScreen: p0];
@@ -986,7 +987,8 @@ NS_ENDHANDLER
                                (jint) p0.x, (jint) p0.y,
                                (jint) contentRect.size.width, (jint) contentRect.size.height,
                                cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
-                               JNI_FALSE // force
+                               JNI_FALSE, // force
+                               withinLiveResize
                               );
     }
 }
@@ -1227,8 +1229,30 @@ NS_ENDHANDLER
     [self focusChanged: NO];
 }
 
+- (void) windowWillStartLiveResize: (NSNotification *) notification
+{
+    DBG_PRINT( "*************** windowWillStartLiveResize\n");
+    withinLiveResize = JNI_TRUE;
+}
+- (void) windowDidEndLiveResize: (NSNotification *) notification
+{
+    DBG_PRINT( "*************** windowDidEndLiveResize\n");
+    withinLiveResize = JNI_FALSE;
+    [self sendResizeEvent];
+}
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize
+{
+    DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height);
+    return frameSize;
+}
 - (void)windowDidResize: (NSNotification*) notification
 {
+    DBG_PRINT( "*************** windowDidResize\n");
+    [self sendResizeEvent];
+}
+
+- (void) sendResizeEvent
+{
     jobject javaWindowObject = NULL;
     int shallBeDetached = 0;
     JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
http://JogAmp.org git info: FAQ, tutorial and man pages.