summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-11-03 07:37:31 +0100
committerSven Gothel <[email protected]>2010-11-03 07:37:31 +0100
commita0e9d6c8382b7275db6fae664be44db6b59671d5 (patch)
tree135b6c0924e992f19666bdf564bc64b74a4dd8f9 /src
parent701cc44d7b2c9f0b7fd977ca29951c2fb779ce2f (diff)
NEWT Window Lifecycle / ScreenMode:
Lifecycle.reparentActionPre()/reparentActionPost() -> pauseRenderingAction()/resumeRenderingAction() for a more generic use, ie reparenting and screen mode change. ScreenMode change: No more visibility/fullscreen changes, no more locking, just pause/resume animation. X11 ScreenMode set: move from thread/wait to simple polling over time (timeout)
Diffstat (limited to 'src')
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java71
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java64
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java5
-rw-r--r--src/newt/native/X11Window.c84
4 files changed, 117 insertions, 107 deletions
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
index 7d80712e6..dfa768147 100644
--- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -163,11 +163,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
*/
void destroyActionInLock(boolean unrecoverable);
- /** Only informal, when starting reparenting */
- void reparentActionPre();
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.<br>
+ * No lock is hold when invoked.<br>
+ *
+ * @see #resumeRenderingAction()
+ */
+ void pauseRenderingAction();
- /** Only informal, when finishing reparenting */
- void reparentActionPost(int reparentActionType);
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.
+ * No lock is hold when invoked.<br>
+ *
+ * @see #pauseRenderingAction()
+ */
+ void resumeRenderingAction();
}
private LifecycleHook lifecycleHook = null;
@@ -475,13 +485,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
class VisibleAction implements Runnable {
boolean visible;
- long timeOut;
boolean nativeWindowCreated;
boolean madeVisible;
- public VisibleAction (boolean visible, long timeOut) {
+ public VisibleAction (boolean visible) {
this.visible = visible;
- this.timeOut = timeOut;
this.nativeWindowCreated = false;
this.madeVisible = false;
}
@@ -510,13 +518,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
if(0==windowHandle && visible) {
if( 0<width*height ) {
nativeWindowCreated = createNative();
- WindowImpl.this.waitForVisible(visible, true, timeOut);
+ WindowImpl.this.waitForVisible(visible, true);
madeVisible = visible;
}
} else if(WindowImpl.this.visible != visible) {
if(0 != windowHandle) {
setVisibleImpl(visible, x, y, width, height);
- WindowImpl.this.waitForVisible(visible, true, timeOut);
+ WindowImpl.this.waitForVisible(visible, true);
madeVisible = visible;
}
}
@@ -545,17 +553,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
}
public void setVisible(boolean visible) {
- setVisible(visible, TIMEOUT_NATIVEWINDOW);
-
- }
-
- protected final void setVisible(boolean visible, long timeOut) {
if(isValid()) {
if( 0==windowHandle && visible && 0>=width*height ) {
// fast-path: not realized yet, make visible, but zero size
return;
}
- VisibleAction visibleAction = new VisibleAction(visible, timeOut);
+ VisibleAction visibleAction = new VisibleAction(visible);
runOnEDTIfAvail(true, visibleAction);
if( visibleAction.getChanged() ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
@@ -1034,20 +1037,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
int reparentActionStrategy = ReparentAction.ACTION_INVALID;
if(isValid()) {
if(null!=lifecycleHook) {
- lifecycleHook.reparentActionPre();
+ // pause animation
+ lifecycleHook.pauseRenderingAction();
}
try {
ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
runOnEDTIfAvail(true, reparentAction);
reparentActionStrategy = reparentAction.getStrategy();
- if( isVisible() ) {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
- }
} finally {
if(null!=lifecycleHook) {
- lifecycleHook.reparentActionPost(reparentActionStrategy);
+ // resume animation
+ lifecycleHook.resumeRenderingAction();
}
}
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
return reparentActionStrategy;
}
@@ -1379,7 +1382,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
display.dispatchMessagesNative(); // status up2date
boolean wasVisible = isVisible();
setVisibleImpl(false, x, y, width, height);
- WindowImpl.this.waitForVisible(false, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
+ WindowImpl.this.waitForVisible(false, true);
display.dispatchMessagesNative(); // status up2date
// write back mirrored values, to be able to detect satisfaction
@@ -1429,29 +1432,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
return this.fullscreen;
}
- boolean screenModeChangeVisible;
- boolean screenModeChangeFullscreen;
-
public void screenModeChangeNotify(ScreenMode sm) {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
System.err.println("Window.screenModeChangeNotify: "+sm);
}
- screenModeChangeFullscreen = isFullscreen();
- if(screenModeChangeFullscreen) {
- setFullscreen(false);
- }
- screenModeChangeVisible = isVisible();
- if(screenModeChangeVisible) {
- setVisible(false);
+
+ if(null!=lifecycleHook) {
+ // pause animation
+ lifecycleHook.pauseRenderingAction();
}
- windowLock.lock();
}
public void screenModeChanged(ScreenMode sm, boolean success) {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
System.err.println("Window.screenModeChanged: "+sm+", success: "+success);
}
- windowLock.unlock();
if(success) {
DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution();
@@ -1460,11 +1455,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenMod
setSize(screenSize.getWidth(), screenSize.getHeight());
}
}
- if(screenModeChangeFullscreen) {
- setFullscreen(true);
- }
- if(screenModeChangeVisible) {
- setVisible(true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
+
+ if(null!=lifecycleHook) {
+ // resume animation
+ lifecycleHook.resumeRenderingAction();
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
index 3f49b5e79..5e89a9972 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
@@ -211,51 +211,34 @@ public class X11Screen extends ScreenImpl {
if(0>resIdx || resIdx>=resNumber) {
throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
}
- String tname = Thread.currentThread()+"-X11Screen.setCurrentScreenModeImpl()";
- SetScreenModeAction setScreenModeAction = new SetScreenModeAction(screenMode, resIdx);
- Thread randrTask = new Thread(setScreenModeAction, tname);
- randrTask.start();
- int to = SCREEN_MODE_CHANGE_TIMEOUT / 100 ;
- while(to>0 && randrTask.isAlive()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException ex) { }
- to--;
- }
- if(0==to && DEBUG) {
- System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
- randrTask+", alive "+randrTask.isAlive());
- }
- return setScreenModeAction.getResult();
- }
-
- class SetScreenModeAction implements Runnable {
- boolean res;
- ScreenMode screenMode;
- int resIdx;
- public SetScreenModeAction(ScreenMode screenMode, int resIdx) {
- this.screenMode = screenMode;
- this.resIdx = resIdx;
- this.res = false;
+ long dpy = X11Util.createDisplay(display.getName());
+ if( 0 == dpy ) {
+ throw new RuntimeException("Error creating display: "+display.getName());
}
- public boolean getResult() {
- return res;
+ boolean done = false;
+ long t0 = System.currentTimeMillis();
+ try {
+ int f = screenMode.getMonitorMode().getRefreshRate();
+ int r = screenMode.getRotation();
+ if( setCurrentScreenModeStart0(dpy, screen_idx, resIdx, f, r) ) {
+ while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) {
+ done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r);
+ if(!done) {
+ Thread.yield();
+ }
+ }
+ }
+ } finally {
+ X11Util.closeDisplay(dpy);
}
- public void run() {
- long dpy = X11Util.createDisplay(display.getName());
- if( 0 == dpy ) {
- throw new RuntimeException("Error creating display: "+display.getName());
- }
- try {
- res = setCurrentScreenMode0(dpy, screen_idx, resIdx,
- screenMode.getMonitorMode().getRefreshRate(), screenMode.getRotation());
- } finally {
- X11Util.closeDisplay(dpy);
- }
+ if(!done) {
+ System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
+ (System.currentTimeMillis()-t0)+"ms");
}
+ return done;
}
//----------------------------------------------------------------------
@@ -282,5 +265,6 @@ public class X11Screen extends ScreenImpl {
private static native int getCurrentScreenRotation0(long display, int screen_index);
/** needs own Display connection for XRANDR event handling */
- private static native boolean setCurrentScreenMode0(long display, int screen_index, int mode_index, int freq, int rot);
+ private static native boolean setCurrentScreenModeStart0(long display, int screen_index, int mode_index, int freq, int rot);
+ private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot);
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 7836bec68..36302c55a 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -367,7 +367,7 @@ public class GLWindow implements GLAutoDrawable, Window {
boolean animatorPaused = false;
- public synchronized void reparentActionPre() {
+ public synchronized void pauseRenderingAction() {
GLAnimatorControl ctrl = GLWindow.this.getAnimator();
if ( null!=ctrl && ctrl.isAnimating() && ctrl.getThread() != Thread.currentThread() ) {
animatorPaused = true;
@@ -375,7 +375,7 @@ public class GLWindow implements GLAutoDrawable, Window {
}
}
- public synchronized void reparentActionPost(int reparentActionType) {
+ public synchronized void resumeRenderingAction() {
resetCounter();
GLAnimatorControl ctrl = GLWindow.this.getAnimator();
if ( null!=ctrl && animatorPaused ) {
@@ -384,6 +384,7 @@ public class GLWindow implements GLAutoDrawable, Window {
}
}
}
+
//----------------------------------------------------------------------
// OpenGL-related methods and state
//
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 7b09ffeb0..becfa7596 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -43,6 +43,7 @@
#include <stdint.h>
#endif
#include <unistd.h>
+#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@@ -175,16 +176,15 @@ static XErrorHandler origErrorHandler = NULL ;
static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
{
- fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X\n", dpy, e->error_code);
+ fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
- if (e->error_code == BadAtom)
- {
+ if (e->error_code == BadAtom) {
fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid);
- } else if (e->error_code == BadWindow)
- {
+ } else if (e->error_code == BadWindow) {
fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
} else {
- NewtCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X", dpy, e->error_code);
+ NewtCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X, errno %s",
+ dpy, e->error_code, strerror(errno));
}
return 0;
@@ -197,8 +197,10 @@ static void displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
}
} else {
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
+ if(NULL!=origErrorHandler) {
+ XSetErrorHandler(origErrorHandler);
+ origErrorHandler = NULL;
+ }
}
}
@@ -850,7 +852,6 @@ JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getAvailable
int major, minor;
if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getAvailableScreenModeRotations0: RANDR not available\n");
fprintf(stderr, "RANDR not available\n");
return (*env)->NewIntArray(env, 0);
}
@@ -897,7 +898,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModeR
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
return 0;
}
@@ -919,7 +920,7 @@ JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenMod
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
return (*env)->NewIntArray(env, 0);
}
@@ -962,7 +963,7 @@ JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenMod
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
return (*env)->NewIntArray(env, 0);
}
@@ -1006,7 +1007,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenR
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
return -1;
}
@@ -1032,7 +1033,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenR
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
return -1;
}
@@ -1061,7 +1062,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenR
Window root = RootWindow(dpy, (int)scrn_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
return -1;
}
@@ -1080,24 +1081,20 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenR
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: setScreenMode0
+ * Method: setCurrentScreenModeStart0
* Signature: (JIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenMode0
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenModeStart0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
- int randr_event_base, randr_error_base;
Display *dpy = (Display *) (intptr_t) display;
Window root = RootWindow(dpy, (int)screen_idx);
if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT(stderr, "Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenMode0: RANDR not available\n");
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
return JNI_FALSE;
}
- XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
- DBG_PRINT("RANDR: event_base: %d\n", randr_event_base);
-
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
XRRScreenConfiguration *conf;
@@ -1134,12 +1131,48 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScr
XSync(dpy, False);
XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
XSync(dpy, False);
-
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_x11_X11Screen
+ * Method: setCurrentScreenModePollEnd0
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenModePollEnd0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ int randr_event_base, randr_error_base;
XEvent evt;
XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
+
int done = 0;
+ int rot;
do {
- // XWindowEvent(dpy, root, randr_event_base + RRScreenChangeNotify, &evt);
+ if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
+ return;
+ }
XNextEvent(dpy, &evt);
switch (evt.type - randr_event_base) {
@@ -1160,11 +1193,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScr
XRRUpdateConfiguration(&evt);
} while(!done);
- //free
- XRRFreeScreenConfigInfo(conf);
XSync(dpy, False);
- return JNI_TRUE;
}
/**