diff options
author | Sven Gothel <[email protected]> | 2011-09-08 03:53:33 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-09-08 03:53:33 +0200 |
commit | a9289ce0fde4d4d344e4ab895790642383226cb4 (patch) | |
tree | 51f482164527586fdcf56eb6777740ed5a07864a /src/newt | |
parent | 3812f3400e5156622ae1c11178bacc675941693b (diff) |
NEWT/ScreenMode: X11 fixes ; Ensure Screen's size is set if screenMode changed ; Enhanced tests; Catch NV/XRANDR/GL bug
X11 fixes
- X11Screen properly uses it's display's connection
decorated in lock/unlock (for ScreenMode etc)
Ensure Screen's size is set if screenMode changed
- ScreenImpl's ScreenModeListener updates it's screen size
so 'external' changes will be detected.
Enhanced tests
- Verify more data rel. ScreenMode
Catch NV/XRANDR/GL bug
- Read TestScreenMode01NEWT/TestScreenMode01bNEWT comments
Diffstat (limited to 'src/newt')
-rw-r--r-- | src/newt/classes/jogamp/newt/DisplayImpl.java | 19 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/ScreenImpl.java | 18 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/x11/X11Screen.java | 342 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 9 |
4 files changed, 214 insertions, 174 deletions
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index ddb409338..92add6a4e 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -38,6 +38,7 @@ import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.event.NEWTEvent; import com.jogamp.newt.event.NEWTEventConsumer; + import jogamp.newt.event.NEWTEventTask; import com.jogamp.newt.util.EDTUtil; import com.jogamp.newt.util.MainThread; @@ -445,6 +446,24 @@ public abstract class DisplayImpl extends Display { } } + public interface DisplayRunnable { + Object run(long dpy); + } + public final Object runWithLockedDisplayHandle(DisplayRunnable action) { + final AbstractGraphicsDevice aDevice = getGraphicsDevice(); + if(null == aDevice) { + throw new RuntimeException("null device - not initialized: "+this); + } + Object res; + aDevice.lock(); + try { + res = action.run(aDevice.getHandle()); + } finally { + aDevice.unlock(); + } + return res; + } + protected EDTUtil edtUtil = null; protected int id; protected String name; diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index c83a82a7c..749bba114 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -169,16 +169,12 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")"); } t0 = System.currentTimeMillis(); - display.createNative(); // 1st display: trigger creation w/o incr ref count (hold native dispatching) - try { - createNativeImpl(); - if(null == aScreen) { - throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen"); - } - initScreenModeStatus(); - } finally { - display.addReference(); // 1st display: allow native dispatching + display.addReference(); + createNativeImpl(); + if(null == aScreen) { + throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen"); } + initScreenModeStatus(); if(DEBUG) { System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")"); } @@ -322,7 +318,6 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { // if mode has changed somehow, update it .. if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) { - setScreenSize(smU.getRotatedWidth(), smU.getRotatedHeight()); sms.fireScreenModeChanged(smU, true); } } finally { @@ -391,6 +386,9 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { } public void screenModeChanged(ScreenMode sm, boolean success) { + if(success) { + setScreenSize(sm.getRotatedWidth(), sm.getRotatedHeight()); + } for(int i=0; i<referencedScreenModeListener.size(); i++) { ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java index 8dd5bba83..a67352138 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java +++ b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java @@ -32,12 +32,14 @@ */ package jogamp.newt.driver.x11; +import jogamp.newt.DisplayImpl; import jogamp.newt.ScreenImpl; +import jogamp.newt.DisplayImpl.DisplayRunnable; + import com.jogamp.newt.ScreenMode; import com.jogamp.newt.util.ScreenModeUtil; import java.util.List; -import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.x11.*; public class X11Screen extends ScreenImpl { @@ -50,13 +52,19 @@ public class X11Screen extends ScreenImpl { } protected void createNativeImpl() { - long handle = GetScreen0(getDisplayEDTHandle(), screen_idx); - if (handle == 0) { + // validate screen index + Long handle = (Long) display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + long handle = GetScreen0(dpy, screen_idx); + if(0 != handle) { + setScreenSize(getWidth0(dpy, screen_idx), getHeight0(dpy, screen_idx)); + } + return new Long(handle); + } } ); + if (handle.longValue() == 0) { throw new RuntimeException("Error creating screen: " + screen_idx); - } + } aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx); - setScreenSize(getWidth0(getDisplayEDTHandle(), screen_idx), - getHeight0(getDisplayEDTHandle(), screen_idx)); } protected void closeNativeImpl() { @@ -71,184 +79,202 @@ public class X11Screen extends ScreenImpl { private int nmode_number; protected int[] getScreenModeFirstImpl() { - // initialize iterators and static data - nrotations = getAvailableScreenModeRotations0(getDisplayEDTHandle(), screen_idx); - if(null==nrotations || 0==nrotations.length) { - return null; - } - nrotation_index = 0; - - nres_number = getNumScreenModeResolutions0(getDisplayEDTHandle(), screen_idx); - if(0==nres_number) { - return null; - } - nres_index = 0; - - nrates = getScreenModeRates0(getDisplayEDTHandle(), screen_idx, nres_index); - if(null==nrates || 0==nrates.length) { - return null; - } - nrate_index = 0; - - nmode_number = 0; - - return getScreenModeNextImpl(); - } - - protected int[] getScreenModeNextImpl() { - // assemble: w x h x bpp x f x r - - /** - System.err.println("******** mode: "+nmode_number); - System.err.println("rot "+nrotation_index); - System.err.println("rate "+nrate_index); - System.err.println("res "+nres_index); */ - - int[] res = getScreenModeResolution0(getDisplayEDTHandle(), screen_idx, nres_index); - if(null==res || 0==res.length) { - return null; - } - if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number); - } - int bpp = 32; // FIXME - int rate = nrates[nrate_index]; - if(0>=rate) { - throw new InternalError("invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length); - } - int rotation = nrotations[nrotation_index]; - - int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ]; - int i = 0; - props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode - props[i++] = 0; // set later for verification of iterator - props[i++] = res[0]; // width - props[i++] = res[1]; // height - props[i++] = bpp; // bpp - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate - props[i++] = rotation; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element - - nmode_number++; - - // iteration: r -> f -> bpp -> [w x h] - nrotation_index++; - if(nrotation_index == nrotations.length) { - nrotation_index=0; - nrate_index++; - if(null == nrates || nrate_index == nrates.length){ - nres_index++; - if(nres_index == nres_number) { - // done - nrates=null; - nrotations=null; + return (int[]) runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + // initialize iterators and static data + nrotations = getAvailableScreenModeRotations0(dpy, screen_idx); + if(null==nrotations || 0==nrotations.length) { return null; } - - nrates = getScreenModeRates0(getDisplayEDTHandle(), screen_idx, nres_index); + nrotation_index = 0; + + nres_number = getNumScreenModeResolutions0(dpy, screen_idx); + if(0==nres_number) { + return null; + } + nres_index = 0; + + nrates = getScreenModeRates0(dpy, screen_idx, nres_index); if(null==nrates || 0==nrates.length) { return null; } nrate_index = 0; - } - } + + nmode_number = 0; + + return getScreenModeNextImpl(); + } } ); + } - return props; + protected int[] getScreenModeNextImpl() { + // assemble: w x h x bpp x f x r + return (int[]) runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + /** + System.err.println("******** mode: "+nmode_number); + System.err.println("rot "+nrotation_index); + System.err.println("rate "+nrate_index); + System.err.println("res "+nres_index); */ + + int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index); + if(null==res || 0==res.length) { + return null; + } + if(0>=res[0] || 0>=res[1]) { + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number); + } + int bpp = 32; // FIXME + int rate = nrates[nrate_index]; + if(0>=rate) { + throw new InternalError("invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length); + } + int rotation = nrotations[nrotation_index]; + + int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode + props[i++] = 0; // set later for verification of iterator + props[i++] = res[0]; // width + props[i++] = res[1]; // height + props[i++] = bpp; // bpp + props[i++] = res[2]; // widthmm + props[i++] = res[3]; // heightmm + props[i++] = rate; // rate + props[i++] = rotation; + props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element + + nmode_number++; + + // iteration: r -> f -> bpp -> [w x h] + nrotation_index++; + if(nrotation_index == nrotations.length) { + nrotation_index=0; + nrate_index++; + if(null == nrates || nrate_index == nrates.length){ + nres_index++; + if(nres_index == nres_number) { + // done + nrates=null; + nrotations=null; + return null; + } + + nrates = getScreenModeRates0(dpy, screen_idx, nres_index); + if(null==nrates || 0==nrates.length) { + return null; + } + nrate_index = 0; + } + } + + return props; + } } ); } protected ScreenMode getCurrentScreenModeImpl() { - int resNumber = getNumScreenModeResolutions0(getDisplayEDTHandle(), screen_idx); - if(0==resNumber) { - return null; - } - int resIdx = getCurrentScreenResolutionIndex0(getDisplayEDTHandle(), screen_idx); - if(0>resIdx) { - return null; - } - if(resIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber); - } - int[] res = getScreenModeResolution0(getDisplayEDTHandle(), screen_idx, resIdx); - if(null==res || 0==res.length) { - return null; - } - if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber); - } - int rate = getCurrentScreenRate0(getDisplayEDTHandle(), screen_idx); - if(0>rate) { - return null; - } - int rot = getCurrentScreenRotation0(getDisplayEDTHandle(), screen_idx); - if(0>rot) { - return null; - } - - int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; - int i = 0; - props[i++] = 0; // set later for verification of iterator - props[i++] = res[0]; // width - props[i++] = res[1]; // height - props[i++] = 32; // FIXME: bpp - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate - props[i++] = rot; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count - return ScreenModeUtil.streamIn(props, 0); + return (ScreenMode) runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); + if(0==resNumber) { + return null; + } + int resIdx = getCurrentScreenResolutionIndex0(dpy, screen_idx); + if(0>resIdx) { + return null; + } + if(resIdx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber); + } + int[] res = getScreenModeResolution0(dpy, screen_idx, resIdx); + if(null==res || 0==res.length) { + return null; + } + if(0>=res[0] || 0>=res[1]) { + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber); + } + int rate = getCurrentScreenRate0(dpy, screen_idx); + if(0>rate) { + return null; + } + int rot = getCurrentScreenRotation0(dpy, screen_idx); + if(0>rot) { + return null; + } + int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; + int i = 0; + props[i++] = 0; // set later for verification of iterator + props[i++] = res[0]; // width + props[i++] = res[1]; // height + props[i++] = 32; // FIXME: bpp + props[i++] = res[2]; // widthmm + props[i++] = res[3]; // heightmm + props[i++] = rate; // rate + props[i++] = rot; + props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count + return ScreenModeUtil.streamIn(props, 0); + } } ); } - protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) { - List<ScreenMode> screenModes = this.getScreenModesOrig(); - int screenModeIdx = screenModes.indexOf(screenMode); + protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { + final List<ScreenMode> screenModes = this.getScreenModesOrig(); + final int screenModeIdx = screenModes.indexOf(screenMode); if(0>screenModeIdx) { throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); } - int resNumber = getNumScreenModeResolutions0(getDisplayEDTHandle(), screen_idx); - int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - if(0>resIdx || resIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode); - } - - final AbstractGraphicsDevice aDevice = display.getGraphicsDevice(); - if(null == aDevice) { - throw new RuntimeException("null device - not initialized: "+display); - } - aDevice.lock(); - boolean done = false; - long t0 = System.currentTimeMillis(); - try { - long dpy = aDevice.getHandle(); - 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) { - try { Thread.sleep(10); } catch (InterruptedException e) { } + final long t0 = System.currentTimeMillis(); + Boolean done = (Boolean) runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + boolean done = false; + int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); + int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); + if(0>resIdx || resIdx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode); + } + + final int f = screenMode.getMonitorMode().getRefreshRate(); + final 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) { + try { Thread.sleep(10); } catch (InterruptedException e) { } + } } } - } - } finally { - aDevice.unlock(); - } - - if(!done) { + return Boolean.valueOf(done); + } + }); + + if(!done.booleanValue()) { System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+ (System.currentTimeMillis()-t0)+"ms"); } - return done; + return done.booleanValue(); } //---------------------------------------------------------------------- // Internals only - // - private final long getDisplayEDTHandle() { - return ((X11Display) display).getEDTHandle(); + // + private final Object runWithLockedDisplayHandle(DisplayRunnable action) { + return display.runWithLockedDisplayHandle(action); + // return runWithTempDisplayHandle(action); } + /** just here for testing some X11 RANDR bugs .. etc .. + private final Object runWithTempDisplayHandle(DisplayRunnable action) { + long dpy = X11Util.openDisplay(null); + if(0 == dpy) { + throw new RuntimeException("null device"); + } + Object res; + try { + res = action.run(dpy); + } finally { + X11Util.closeDisplay(dpy); + } + return res; + } */ + private static native long GetScreen0(long dpy, int scrn_idx); private static native int getWidth0(long display, int scrn_idx); diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 8d47f544a..092f3f7d3 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -910,14 +910,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0 NewtCommon_FatalError(env, "invalid display connection.."); } - scrn = ScreenOfDisplay(dpy,screen_index); + scrn = ScreenOfDisplay(dpy, screen_index); if(scrn==NULL) { - scrn=DefaultScreenOfDisplay(dpy); + fprintf(stderr, "couldn't get screen idx %d\n", screen_index); } - if(scrn==NULL) { - fprintf(stderr, "couldn't get screen ..\n"); - } - DBG_PRINT("X11: X11Screen_GetScreen0 scrn %p DONE\n", scrn); + DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn); return (jlong) (intptr_t) scrn; } |