diff options
author | Sven Gothel <[email protected]> | 2019-12-04 04:35:06 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2019-12-04 04:35:06 +0100 |
commit | 22ee0cfa7dc3f3a7ac5e30322537196dcab8b310 (patch) | |
tree | c9686804dd1664810823b8dc20b5d9e76b561656 /src/demos/com/jogamp | |
parent | 97c5fbc891f3315f913e519aaf15cdc5d987b31d (diff) |
Bug 1405: Provide stand alone demo launcher reducing complexity
The launcher script also allows inflating classes and native libs to test impact on Raspberry Pi 3 Model B+.
Diffstat (limited to 'src/demos/com/jogamp')
-rw-r--r-- | src/demos/com/jogamp/opengl/demos/Launcher0.java | 484 | ||||
-rw-r--r-- | src/demos/com/jogamp/opengl/demos/MiscUtils.java | 259 |
2 files changed, 743 insertions, 0 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/Launcher0.java b/src/demos/com/jogamp/opengl/demos/Launcher0.java new file mode 100644 index 000000000..c5e736733 --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/Launcher0.java @@ -0,0 +1,484 @@ +/** + * Copyright 2019 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.demos; + +import java.io.IOException; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.TraceMouseAdapter; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.newt.opengl.util.NEWTDemoListener; +import com.jogamp.newt.util.EDTUtil; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.AnimatorBase; +import com.jogamp.nativewindow.ScalableSurface; +import com.jogamp.nativewindow.util.Dimension; +import com.jogamp.nativewindow.util.Point; +import com.jogamp.nativewindow.util.PointImmutable; +import com.jogamp.nativewindow.util.DimensionImmutable; +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GLAnimatorControl; +import com.jogamp.opengl.GLAutoDrawable; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLEventListener; +import com.jogamp.opengl.GLPipelineFactory; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.demos.es2.GearsES2; + +import jogamp.newt.DefaultEDTUtil; + +/** + * <p> + * The demo code uses {@link NEWTDemoListener} functionality. + * </p> + * <p> + * Manual invocation via main allows setting each tests's duration in milliseconds, e.g.{@code -duration 10000} and many more, see {@link #main(String[])} + * </p> + */ +public class Launcher0 { + static int screenIdx = 0; + static PointImmutable wpos; + static DimensionImmutable wsize = new Dimension(640, 480), rwsize=null; + static float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + + static long duration = 500; // ms + static boolean opaque = true; + static int forceAlpha = -1; + static boolean undecorated = false; + static boolean alwaysOnTop = false; + static boolean alwaysOnBottom = false; + static boolean resizable = true; + static boolean sticky = false; + static boolean max_vert= false; + static boolean max_horz= false; + static boolean fullscreen = false; + static int swapInterval = 1; + static boolean waitForKey = false; + static boolean mouseVisible = true; + static boolean mouseConfined = false; + static boolean setPointerIcon = false; + static boolean showFPS = false; + static boolean forceES2 = false; + static boolean forceES3 = false; + static boolean forceGL3 = false; + static boolean forceGL2 = false; + static boolean forceDebug = false; + static boolean forceTrace = false; + static boolean traceMouse = false; + static boolean exclusiveContext = false; + static boolean useAnimator = true; + static boolean useMappedBuffers = false; + static enum SysExit { none, testExit, testError, testEDTError, displayExit, displayError, displayEDTError }; + static SysExit sysExit = SysExit.none; + + public void runTest() throws InterruptedException { + final GLProfile glp; + if(forceGL3) { + glp = GLProfile.get(GLProfile.GL3); + } else if(forceES3) { + glp = GLProfile.get(GLProfile.GLES3); + } else if(forceES2) { + glp = GLProfile.get(GLProfile.GLES2); + } else if(forceGL2) { + glp = GLProfile.get(GLProfile.GL2); + } else { + glp = GLProfile.getGL2ES2(); + } + final GLCapabilities caps = new GLCapabilities( glp ); + caps.setBackgroundOpaque(opaque); + if(-1 < forceAlpha) { + caps.setAlphaBits(forceAlpha); + } + + System.err.println("requested: vsync "+swapInterval+", "+caps); + final Display dpy = NewtFactory.createDisplay(null); + final Screen screen = NewtFactory.createScreen(dpy, screenIdx); + final GLWindow glWindow = GLWindow.create(screen, caps); + + glWindow.setSurfaceScale(reqSurfacePixelScale); + final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]); + glWindow.setSize(wsize.getWidth(), wsize.getHeight()); + if(null != wpos) { + glWindow.setPosition(wpos.getX(), wpos.getY()); + } + glWindow.setUndecorated(undecorated); + glWindow.setAlwaysOnTop(alwaysOnTop); + glWindow.setAlwaysOnBottom(alwaysOnBottom); + glWindow.setResizable(resizable); + glWindow.setSticky(sticky); + glWindow.setMaximized(max_horz, max_vert); + glWindow.setFullscreen(fullscreen); + glWindow.setPointerVisible(mouseVisible); + glWindow.confinePointer(mouseConfined); + + final GLEventListener demo; + { + final GearsES2 gearsES2 = new GearsES2(swapInterval); + gearsES2.setUseMappedBuffers(useMappedBuffers); + gearsES2.setValidateBuffers(true); + demo = gearsES2; + } + if( forceDebug || forceTrace ) { + glWindow.addGLEventListener(new GLEventListener() { + @Override + public void init(final GLAutoDrawable drawable) { + GL _gl = drawable.getGL(); + if(forceDebug) { + try { + _gl = _gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, _gl, null) ); + } catch (final Exception e) {e.printStackTrace();} + } + + if(forceTrace) { + try { + // Trace .. + _gl = _gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, _gl, new Object[] { System.err } ) ); + } catch (final Exception e) {e.printStackTrace();} + } + } + @Override + public void dispose(final GLAutoDrawable drawable) {} + @Override + public void display(final GLAutoDrawable drawable) {} + @Override + public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {} + }); + } + + if( null != demo ) { + glWindow.addGLEventListener(demo); + } + + if(waitForKey) { + glWindow.addGLEventListener(new GLEventListener() { + public void init(final GLAutoDrawable drawable) { } + public void dispose(final GLAutoDrawable drawable) { } + public void display(final GLAutoDrawable drawable) { + final GLAnimatorControl actrl = drawable.getAnimator(); + if(waitForKey && actrl.getTotalFPSFrames() == 60*3) { + MiscUtils.waitForKey("3s mark"); + actrl.resetFPSCounter(); + waitForKey = false; + } + } + public void reshape(final GLAutoDrawable drawable, final int x, final int y, + final int width, final int height) { } + }); + } + + final Animator animator = useAnimator ? new Animator() : null; + if( useAnimator ) { + animator.setModeBits(false, AnimatorBase.MODE_EXPECT_AWT_RENDERING_THREAD); + animator.setExclusiveContext(exclusiveContext); + } + + glWindow.addWindowListener(new WindowAdapter() { + public void windowResized(final WindowEvent e) { + System.err.println("window resized: "+glWindow.getBounds()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); + NEWTDemoListener.setTitle(glWindow); + } + public void windowMoved(final WindowEvent e) { + System.err.println("window moved: "+glWindow.getBounds()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); + NEWTDemoListener.setTitle(glWindow); + } + }); + + final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow); + newtDemoListener.quitAdapterEnable(true); + glWindow.addKeyListener(newtDemoListener); + if( traceMouse ) { + glWindow.addMouseListener(new TraceMouseAdapter()); + } + glWindow.addMouseListener(newtDemoListener); + glWindow.addWindowListener(newtDemoListener); + + if( useAnimator ) { + animator.add(glWindow); + animator.start(); + } + + if( SysExit.displayError == sysExit || SysExit.displayExit == sysExit || SysExit.displayEDTError == sysExit ) { + glWindow.addGLEventListener(new GLEventListener() { + @Override + public void init(final GLAutoDrawable drawable) {} + @Override + public void dispose(final GLAutoDrawable drawable) { } + @Override + public void display(final GLAutoDrawable drawable) { + final GLAnimatorControl anim = drawable.getAnimator(); + if( null != anim && anim.isAnimating() ) { + final long ms = anim.getTotalFPSDuration(); + if( ms >= duration/2 || ms >= 3000 ) { // max 3s wait until provoking error + if( SysExit.displayError == sysExit ) { + throw new Error("test error send from GLEventListener.display - "+Thread.currentThread()); + } else if ( SysExit.displayExit == sysExit ) { + System.err.println("exit(0) send from GLEventListener"); + System.exit(0); + } else if ( SysExit.displayEDTError == sysExit ) { + final Object upstream = drawable.getUpstreamWidget(); + System.err.println("EDT invokeAndWaitError: upstream type "+upstream.getClass().getName()); + if( upstream instanceof Window ) { + final EDTUtil edt = ((Window)upstream).getScreen().getDisplay().getEDTUtil(); + System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName()); + if( edt instanceof DefaultEDTUtil ) { + newtDemoListener.doQuit(); + ((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() { + public void run() { + throw new RuntimeException("XXX Should never ever be seen! - "+Thread.currentThread()); + } + }); + } + } + } + } + } else { + System.exit(0); + } + } + @Override + public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { } + }); + } + + glWindow.setVisible(true); + if( useAnimator ) { + animator.setUpdateFPSFrames(60, showFPS ? System.err : null); + } + + System.err.println("Window Current State : "+glWindow.getStateMaskString()); + System.err.println("Window Supported States: "+glWindow.getSupportedStateMaskString()); + System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); + System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); + System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); + + final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + NEWTDemoListener.setTitle(glWindow); + + if( null != rwsize ) { + Thread.sleep(500); // 500ms delay + glWindow.setSize(rwsize.getWidth(), rwsize.getHeight()); + System.err.println("window resize pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); + } + + final long t0 = System.currentTimeMillis(); + long t1 = t0; + while(!newtDemoListener.shouldQuit() && t1-t0<duration) { + Thread.sleep(100); + t1 = System.currentTimeMillis(); + if( SysExit.testError == sysExit || SysExit.testExit == sysExit || SysExit.testEDTError == sysExit) { + final long ms = t1-t0; + if( ms >= duration/2 || ms >= 3000 ) { // max 3s wait until provoking error + if( SysExit.testError == sysExit ) { + throw new Error("test error send from test thread"); + } else if ( SysExit.testExit == sysExit ) { + System.err.println("exit(0) send from test thread"); + System.exit(0); + } else if ( SysExit.testEDTError == sysExit ) { + final EDTUtil edt = glWindow.getScreen().getDisplay().getEDTUtil(); + System.err.println("EDT invokeAndWaitError: edt type "+edt.getClass().getName()); + if( edt instanceof DefaultEDTUtil ) { + newtDemoListener.doQuit(); + ((DefaultEDTUtil)edt).invokeAndWaitError(new Runnable() { + public void run() { + throw new RuntimeException("XXX Should never ever be seen!"); + } + }); + } + } + } + } + } + + if( useAnimator ) { + animator.stop(); + } + glWindow.destroy(); + } + + public static void main(final String args[]) throws IOException { + int x=0, y=0, w=640, h=480, rw=-1, rh=-1; + boolean usePos = false; + + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + duration = MiscUtils.atol(args[i], duration); + } else if(args[i].equals("-translucent")) { + opaque = false; + } else if(args[i].equals("-forceAlpha")) { + i++; + forceAlpha = MiscUtils.atoi(args[i], 0); + } else if(args[i].equals("-undecorated")) { + undecorated = true; + } else if(args[i].equals("-atop")) { + alwaysOnTop = true; + } else if(args[i].equals("-abottom")) { + alwaysOnBottom = true; + } else if(args[i].equals("-noresize")) { + resizable = false; + } else if(args[i].equals("-sticky")) { + sticky = true; + } else if(args[i].equals("-maxv")) { + max_vert = true; + } else if(args[i].equals("-maxh")) { + max_horz = true; + } else if(args[i].equals("-fullscreen")) { + fullscreen = true; + } else if(args[i].equals("-vsync")) { + i++; + swapInterval = MiscUtils.atoi(args[i], swapInterval); + } else if(args[i].equals("-exclctx")) { + exclusiveContext = true; + } else if(args[i].equals("-noanim")) { + useAnimator = false; + } else if(args[i].equals("-es2")) { + forceES2 = true; + } else if(args[i].equals("-es3")) { + forceES3 = true; + } else if(args[i].equals("-gl3")) { + forceGL3 = true; + } else if(args[i].equals("-gl2")) { + forceGL2 = true; + } else if(args[i].equals("-debug")) { + forceDebug = true; + } else if(args[i].equals("-trace")) { + forceTrace = true; + } else if(args[i].equals("-mappedBuffers")) { + useMappedBuffers = true; + } else if(args[i].equals("-wait")) { + waitForKey = true; + } else if(args[i].equals("-mouseInvisible")) { + mouseVisible = false; + } else if(args[i].equals("-mouseConfine")) { + mouseConfined = true; + } else if(args[i].equals("-pointerIcon")) { + setPointerIcon = true; + } else if(args[i].equals("-showFPS")) { + showFPS = true; + } else if(args[i].equals("-width")) { + i++; + w = MiscUtils.atoi(args[i], w); + } else if(args[i].equals("-height")) { + i++; + h = MiscUtils.atoi(args[i], h); + } else if(args[i].equals("-x")) { + i++; + x = MiscUtils.atoi(args[i], x); + usePos = true; + } else if(args[i].equals("-y")) { + i++; + y = MiscUtils.atoi(args[i], y); + usePos = true; + } else if(args[i].equals("-pixelScale")) { + i++; + final float pS = MiscUtils.atof(args[i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[0] = pS; + reqSurfacePixelScale[1] = pS; + } else if(args[i].equals("-rwidth")) { + i++; + rw = MiscUtils.atoi(args[i], rw); + } else if(args[i].equals("-rheight")) { + i++; + rh = MiscUtils.atoi(args[i], rh); + } else if(args[i].equals("-screen")) { + i++; + screenIdx = MiscUtils.atoi(args[i], 0); + } else if(args[i].equals("-sysExit")) { + i++; + sysExit = SysExit.valueOf(args[i]); + } else if(args[i].equals("-traceMouse")) { + traceMouse = true; + } + } + wsize = new Dimension(w, h); + if( 0 < rw && 0 < rh ) { + rwsize = new Dimension(rw, rh); + } + + if(usePos) { + wpos = new Point(x, y); + } + System.err.println("position "+wpos); + System.err.println("size "+wsize); + System.err.println("resize "+rwsize); + System.err.println("screen "+screenIdx); + System.err.println("translucent "+(!opaque)); + System.err.println("forceAlpha "+forceAlpha); + System.err.println("undecorated "+undecorated); + System.err.println("atop "+alwaysOnTop); + System.err.println("abottom "+alwaysOnBottom); + System.err.println("resizable "+resizable); + System.err.println("sticky "+sticky); + System.err.println("max_vert "+max_vert); + System.err.println("max_horz "+max_horz); + System.err.println("fullscreen "+fullscreen); + System.err.println("mouseVisible "+mouseVisible); + System.err.println("mouseConfined "+mouseConfined); + System.err.println("pointerIcon "+setPointerIcon); + System.err.println("forceES2 "+forceES2); + System.err.println("forceES3 "+forceES3); + System.err.println("forceGL3 "+forceGL3); + System.err.println("forceGL2 "+forceGL2); + System.err.println("forceDebug "+forceDebug); + System.err.println("forceTrace "+forceTrace); + System.err.println("swapInterval "+swapInterval); + System.err.println("exclusiveContext "+exclusiveContext); + System.err.println("useAnimator "+useAnimator); + System.err.println("sysExitWithin "+sysExit); + System.err.println("mappedBuffers "+useMappedBuffers); + System.err.println("traceMouse "+traceMouse); + + if(waitForKey) { + MiscUtils.waitForKey("Start"); + } + + final Launcher0 l = new Launcher0(); + try { + System.err.println("Start-Demo"); + l.runTest(); + System.err.println("End-Demo"); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + if(waitForKey) { + MiscUtils.waitForKey("End-Pre-Shutdown"); + } + System.err.println("End-Pre-Shutdown"); + GLProfile.shutdown(); + System.err.println("End-Post-Shutdown"); + } +} diff --git a/src/demos/com/jogamp/opengl/demos/MiscUtils.java b/src/demos/com/jogamp/opengl/demos/MiscUtils.java new file mode 100644 index 000000000..304e4f18a --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/MiscUtils.java @@ -0,0 +1,259 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + + +package com.jogamp.opengl.demos; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.reflect.*; +import java.nio.FloatBuffer; +import java.util.Iterator; +import java.util.List; + +import com.jogamp.opengl.GLContext; + +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.InterruptSource; + +public class MiscUtils { + public static boolean atob(final String str, final boolean def) { + try { + return Boolean.parseBoolean(str); + } catch (final Exception ex) { + ex.printStackTrace(); + } + return def; + } + + public static int atoi(final String str, final int def) { + try { + return Integer.parseInt(str); + } catch (final Exception ex) { + ex.printStackTrace(); + } + return def; + } + + public static long atol(final String str, final long def) { + try { + return Long.parseLong(str); + } catch (final Exception ex) { + ex.printStackTrace(); + } + return def; + } + + public static float atof(final String str, final float def) { + try { + return Float.parseFloat(str); + } catch (final Exception ex) { + ex.printStackTrace(); + } + return def; + } + + public static String toHexString(final byte hex) { + return "0x" + Integer.toHexString( hex & 0x000000FF ); + } + + public static String toHexString(final short hex) { + return "0x" + Integer.toHexString( hex & 0x0000FFFF ); + } + + public static String toHexString(final int hex) { + return "0x" + Integer.toHexString( hex ); + } + + public static String toHexString(final long hex) { + return "0x" + Long.toHexString( hex ); + } + + public static void assertFloatBufferEquals(final String errmsg, final FloatBuffer expected, final FloatBuffer actual, final float delta) { + if(null == expected && null == actual) { + return; + } + final String msg = null != errmsg ? errmsg + " " : ""; + if(null == expected) { + throw new AssertionError(msg+"; Expected is null, but actual not: "+actual); + } + if(null == actual) { + throw new AssertionError(msg+"; Actual is null, but expected not: "+expected); + } + if(expected.remaining() != actual.remaining()) { + throw new AssertionError(msg+"; Expected has "+expected.remaining()+" remaining, but actual has "+actual.remaining()); + } + final int a0 = expected.position(); + final int b0 = actual.position(); + for(int i=0; i<expected.remaining(); i++) { + final float ai = expected.get(a0 + i); + final float bi = actual.get(b0 + i); + final float daibi = Math.abs(ai - bi); + if( daibi > delta ) { + throw new AssertionError(msg+"; Expected @ ["+a0+"+"+i+"] has "+ai+", but actual @ ["+b0+"+"+i+"] has "+bi+", it's delta "+daibi+" > "+delta); + } + } + } + + public static void assertFloatBufferNotEqual(final String errmsg, final FloatBuffer expected, final FloatBuffer actual, final float delta) { + if(null == expected || null == actual) { + return; + } + if(expected.remaining() != actual.remaining()) { + return; + } + final String msg = null != errmsg ? errmsg + " " : ""; + final int a0 = expected.position(); + final int b0 = actual.position(); + for(int i=0; i<expected.remaining(); i++) { + final float ai = expected.get(a0 + i); + final float bi = actual.get(b0 + i); + final float daibi = Math.abs(ai - bi); + if( daibi > delta ) { + return; + } + } + throw new AssertionError(msg+"; Expected and actual are equal."); + } + + public static boolean setFieldIfExists(final Object instance, final String fieldName, final Object value) { + try { + final Field f = instance.getClass().getField(fieldName); + if(value instanceof Boolean || f.getType().isInstance(value)) { + f.set(instance, value); + return true; + } else { + System.out.println(instance.getClass()+" '"+fieldName+"' field not assignable with "+value.getClass()+", it's a: "+f.getType()); + } + } catch (final IllegalAccessException ex) { + throw new RuntimeException(ex); + } catch (final NoSuchFieldException nsfe) { + // OK - throw new RuntimeException(instance.getClass()+" has no '"+fieldName+"' field", nsfe); + } + return false; + } + + public static void waitForKey(final String preMessage) { + final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println(preMessage+"> Press enter to continue"); + try { + System.err.println(stdin.readLine()); + } catch (final IOException e) { e.printStackTrace(); } + } + + + public static class StreamDump extends InterruptSource.Thread { + final InputStream is; + final StringBuilder outString; + final OutputStream outStream; + final String prefix; + final Object sync; + volatile boolean eos = false; + + public StreamDump(final OutputStream out, final String prefix, final InputStream is, final Object sync) { + this.is = is; + this.outString = null; + this.outStream = out; + this.prefix = prefix; + this.sync = sync; + } + public StreamDump(final StringBuilder sb, final String prefix, final InputStream is, final Object sync) { + this.is = is; + this.outString = sb; + this.outStream = null; + this.prefix = prefix; + this.sync = sync; + } + public StreamDump(final StringBuilder sb, final InputStream is, final Object sync) { + this.is = is; + this.outString = sb; + this.outStream = null; + this.prefix = null; + this.sync = sync; + } + + public final boolean eos() { return eos; } + + @Override + public void run() { + synchronized ( sync ) { + try { + final BufferedReader in = new BufferedReader( new InputStreamReader(is) ); + String line = null; + while ((line = in.readLine()) != null) { + if( null != outString ) { + outString.append(line).append(Platform.getNewline()); + } else if( null != outStream ) { + if( null != prefix ) { + outStream.write(prefix.getBytes()); + } + outStream.write(line.getBytes()); + outStream.write(Platform.getNewline().getBytes()); + outStream.flush(); + } + } + } catch (final IOException ioe) { + System.err.println("Caught "+ioe.getClass().getName()+": "+ioe.getMessage()); + ioe.printStackTrace(); + } finally { + eos = true; + sync.notifyAll(); + } + } + } + } + + public static void dumpSharedGLContext(final String prefix, final GLContext self) { + int i = 0, j = 0; + final GLContext master = self.getSharedMaster(); + final int masterHash = null != master ? master.hashCode() : 0; + System.err.println(prefix+": hash 0x"+Integer.toHexString(self.hashCode())+", \t(isShared "+self.isShared()+", created "+self.isCreated()+", master 0x"+Integer.toHexString(masterHash)+")"); + { + final List<GLContext> set = self.getCreatedShares(); + for (final Iterator<GLContext> iter = set.iterator(); iter.hasNext(); ) { + final GLContext c = iter.next(); + System.err.println(" Created Ctx #"+(i++)+": hash 0x"+Integer.toHexString(c.hashCode())+", \t(created "+c.isCreated()+")"); + } + } + { + final List<GLContext> set = self.getDestroyedShares(); + for (final Iterator<GLContext> iter = set.iterator(); iter.hasNext(); ) { + final GLContext c = iter.next(); + System.err.println(" Destroyed Ctx #"+(j++)+": hash 0x"+Integer.toHexString(c.hashCode())+", \t(created "+c.isCreated()+")"); + } + } + System.err.println("\t Total created "+i+" + destroyed "+j+" = "+(i+j)); + System.err.println(); + } +} + + + |