diff options
Diffstat (limited to 'src')
39 files changed, 1419 insertions, 734 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 508f1aafd..e1e797088 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -70,21 +70,49 @@ public class VectorUtil { return newVector; } - /** Scales a vector by param + /** Scales a vector by param creating a new float[] for the result! * @param vector input vector * @param scale constant to scale by - * @return scaled vector + * @return new scaled vector + * @deprecated Use {@link #scale(float[], float[], float)} */ public static float[] scale(float[] vector, float scale) { final float[] newVector = new float[3]; - newVector[0] = vector[0]*scale; - newVector[1] = vector[1]*scale; - newVector[2] = vector[2]*scale; + newVector[0] = vector[0] * scale; + newVector[1] = vector[1] * scale; + newVector[2] = vector[2] * scale; return newVector; } + /** Scales a vector by param using given result float[] + * @param result vector for the result + * @param vector input vector + * @param scale single scale constant for all vector components + */ + public static float[] scale(float[] result, float[] vector, float scale) + { + result[0] = vector[0] * scale; + result[1] = vector[1] * scale; + result[2] = vector[2] * scale; + return result; + } + + /** Scales a vector by param using given result float[] + * @param result vector for the result + * @param vector input vector + * @param scale 3 component scale constant for each vector component + * @return given result vector + */ + public static float[] scale(float[] result, float[] vector, float[] scale) + { + result[0] = vector[0] * scale[0]; + result[1] = vector[1] * scale[1]; + result[2] = vector[2] * scale[2]; + return result; + } + /** Adds to vectors * @param v1 vector 1 * @param v2 vector 2 diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java index b0a645cbb..22a5cfb32 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java @@ -358,7 +358,10 @@ public interface GLMediaPlayer extends TextureSequence { public void initStream(URI streamLoc, int vid, int aid, int textureCount) throws IllegalStateException, IllegalArgumentException; /** - * Returns the {@link StreamException} caught in the decoder thread, or <code>null</code>. + * Returns the {@link StreamException} caught in the decoder thread, or <code>null</code> if none occured. + * <p> + * Method clears the cached {@link StreamException}, hence an immediate subsequent call will return <code>null</code>. + * </p> * @see GLMediaEventListener#EVENT_CHANGE_ERR * @see StreamException */ diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 36c0144a9..0bc002f8e 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -858,7 +858,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing GLDrawableUtil.swapGLContextAndAllGLEventListener(GLCanvas.this, printGLAD); printDrawable = printGLAD.getDelegatedDrawable(); } - printAWTTiles.setIsGLOriented(printGLAD.isGLOriented()); + printAWTTiles.setGLOrientation(printGLAD.isGLOriented(), printGLAD.isGLOriented()); printAWTTiles.renderer.setTileSize(printDrawable.getWidth(), printDrawable.getHeight(), 0); printAWTTiles.renderer.attachAutoDrawable(printGLAD); if( DEBUG ) { diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 8670c3746..a71b47c64 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -649,7 +649,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing GLDrawableUtil.swapGLContextAndAllGLEventListener(GLJPanel.this, printGLAD); printDrawable = printGLAD.getDelegatedDrawable(); } - printAWTTiles.setIsGLOriented( !GLJPanel.this.skipGLOrientationVerticalFlip && printGLAD.isGLOriented() ); + printAWTTiles.setGLOrientation( !GLJPanel.this.skipGLOrientationVerticalFlip && printGLAD.isGLOriented(), printGLAD.isGLOriented() ); printAWTTiles.renderer.setTileSize(printDrawable.getWidth(), printDrawable.getHeight(), 0); printAWTTiles.renderer.attachAutoDrawable(printGLAD); if( DEBUG ) { diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java index ff07b04d0..1c1d2350a 100644 --- a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java +++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java @@ -74,7 +74,10 @@ public class AWTTilePainter { public final int customTileWidth, customTileHeight, customNumSamples; public final boolean verbose; + /** Default for OpenGL: True */ public boolean flipVertical; + /** Default for OpenGL: True */ + public boolean originBottomLeft; private AWTGLPixelBuffer tBuffer = null; private BufferedImage vFlipImage = null; private Graphics2D g2d = null; @@ -148,10 +151,18 @@ public class AWTTilePainter { } @Override - public String toString() { return renderer.toString(); } + public String toString() { + return "AWTTilePainter[flipVertical "+flipVertical+", startFromBottom "+originBottomLeft+", "+ + renderer.toString()+"]"; + } - public void setIsGLOriented(boolean v) { - flipVertical = v; + /** + * @param flipVertical if <code>true</code>, the image will be flipped vertically (Default for OpenGL). + * @param originBottomLeft if <code>true</code>, the image's origin is on the bottom left (Default for OpenGL). + */ + public void setGLOrientation(boolean flipVertical, boolean originBottomLeft) { + this.flipVertical = flipVertical; + this.originBottomLeft = originBottomLeft; } private static Rectangle2D getClipBounds2D(Graphics2D g) { @@ -307,7 +318,7 @@ public class AWTTilePainter { final int tHeight = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT); final int tY = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_Y_POS); final int tYOff = renderer.getParam(TileRenderer.TR_TILE_Y_OFFSET); - final int imgYOff = flipVertical ? 0 : renderer.getParam(TileRenderer.TR_TILE_HEIGHT) - tHeight; // imgYOff will be cut-off via sub-image + final int imgYOff = originBottomLeft ? 0 : renderer.getParam(TileRenderer.TR_TILE_HEIGHT) - tHeight; // imgYOff will be cut-off via sub-image final int pX = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS); // tileX == pX final int pY = cis.getHeight() - ( tY - tYOff + tHeight ) + scaledYOffset; @@ -380,7 +391,7 @@ public class AWTTilePainter { System.err.println("XXX tile-post.X "+renderer); System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight()); System.err.println("XXX tile-post.X out-img "+outImage.getWidth()+"x"+outImage.getHeight()); - System.err.println("XXX tile-post.X y-flip "+flipVertical+" -> "+pX+"/"+pY+", drawDone "+drawDone); + System.err.println("XXX tile-post.X y-flip "+flipVertical+", originBottomLeft "+originBottomLeft+" -> "+pX+"/"+pY+", drawDone "+drawDone); } } @Override diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java index ecb6b60e8..1229eb7b8 100644 --- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java +++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java @@ -3,14 +3,14 @@ * * 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 @@ -20,7 +20,7 @@ * 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. @@ -53,22 +53,22 @@ public class ALAudioSink implements AudioSink { private static final ALC alc; private static final AL al; private static final ALExt alExt; - private static final boolean staticAvailable; - + private static final boolean staticAvailable; + private String deviceSpecifier; private ALCdevice device; private boolean hasSOFTBufferSamples; - private AudioFormat preferredAudioFormat; + private AudioFormat preferredAudioFormat; private ALCcontext context; private final RecursiveLock lock = LockFactory.createRecursiveLock(); /** Playback speed, range [0.5 - 2.0], default 1.0. */ private float playSpeed; private float volume = 1.0f; - + static class ALAudioFrame extends AudioFrame { private final int alBuffer; - + ALAudioFrame(int alBuffer) { this.alBuffer = alBuffer; } @@ -76,20 +76,20 @@ public class ALAudioSink implements AudioSink { super(pts, duration, dataSize); this.alBuffer = alBuffer; } - + /** Get this frame's OpenAL buffer name */ public final int getALBuffer() { return alBuffer; } - - public String toString() { + + public String toString() { return "ALAudioFrame[pts " + pts + " ms, l " + duration + " ms, " + byteSize + " bytes, buffer "+alBuffer+"]"; } } - + // private ALAudioFrame[] alFrames = null; private int[] alBufferNames = null; private int frameGrowAmount = 0; private int frameLimit = 0; - + private Ringbuffer<ALAudioFrame> alFramesAvail = null; private Ringbuffer<ALAudioFrame> alFramesPlaying = null; private volatile int alBufferBytesQueued = 0; @@ -102,7 +102,7 @@ public class ALAudioSink implements AudioSink { private int alSampleType; private int alFormat; private boolean initialized; - + private volatile boolean playRequested = false; static { @@ -110,7 +110,7 @@ public class ALAudioSink implements AudioSink { AL _al = null; ALExt _alExt = null; try { - _alc = ALFactory.getALC(); + _alc = ALFactory.getALC(); _al = ALFactory.getAL(); _alExt = ALFactory.getALExt(); } catch(Throwable t) { @@ -124,41 +124,41 @@ public class ALAudioSink implements AudioSink { alExt = _alExt; staticAvailable = null != alc && null != al && null != alExt; } - + public ALAudioSink() { initialized = false; chosenFormat = null; - + if( !staticAvailable ) { return; } - + try { // Get handle to default device. device = alc.alcOpenDevice(null); if (device == null) { throw new RuntimeException("ALAudioSink: Error opening default OpenAL device"); } - + // Get the device specifier. deviceSpecifier = alc.alcGetString(device, ALC.ALC_DEVICE_SPECIFIER); if (deviceSpecifier == null) { throw new RuntimeException("ALAudioSink: Error getting specifier for default OpenAL device"); } - + // Create audio context. context = alc.alcCreateContext(device, null); if (context == null) { throw new RuntimeException("ALAudioSink: Error creating OpenAL context for "+deviceSpecifier); } - + lockContext(); try { // Check for an error. if ( alc.alcGetError(device) != ALC.ALC_NO_ERROR ) { throw new RuntimeException("ALAudioSink: Error making OpenAL context current"); } - + hasSOFTBufferSamples = al.alIsExtensionPresent(AL_SOFT_buffer_samples); preferredAudioFormat = queryPreferredAudioFormat(); if( DEBUG ) { @@ -168,7 +168,7 @@ public class ALAudioSink implements AudioSink { System.out.println("ALAudioSink: hasSOFTBufferSamples "+hasSOFTBufferSamples); System.out.println("ALAudioSink: preferredAudioFormat "+preferredAudioFormat); } - + // Create source { alSource = new int[1]; @@ -177,10 +177,10 @@ public class ALAudioSink implements AudioSink { if( err != AL.AL_NO_ERROR ) { alSource = null; throw new RuntimeException("ALAudioSink: Error generating Source: 0x"+Integer.toHexString(err)); - } + } } - - if( DEBUG ) { + + if( DEBUG ) { System.err.println("ALAudioSink: Using device: " + deviceSpecifier); } initialized = true; @@ -195,7 +195,7 @@ public class ALAudioSink implements AudioSink { destroy(); } } - + private final AudioFormat queryPreferredAudioFormat() { int sampleRate = DefaultFormat.sampleRate; final int[] value = new int[1]; @@ -205,7 +205,7 @@ public class ALAudioSink implements AudioSink { } return new AudioFormat(sampleRate, DefaultFormat.sampleSize, DefaultFormat.channelCount, DefaultFormat.signed, DefaultFormat.fixedP, DefaultFormat.planar, DefaultFormat.littleEndian); } - + private final void lockContext() { lock.lock(); alc.alcMakeContextCurrent(context); @@ -236,12 +236,12 @@ public class ALAudioSink implements AudioSink { lock.unlock(); } } - + @Override public final String toString() { final int alSrcName = null != alSource ? alSource[0] : 0; final int alBuffersLen = null != alBufferNames ? alBufferNames.length : 0; - final int ctxHash = context != null ? context.hashCode() : 0; + final int ctxHash = context != null ? context.hashCode() : 0; return "ALAudioSink[init "+initialized+", playRequested "+playRequested+", device "+deviceSpecifier+", ctx "+toHexString(ctxHash)+", alSource "+alSrcName+ ", chosen "+chosenFormat+ ", al[chan "+ALHelpers.alChannelLayoutName(alChannelLayout)+", type "+ALHelpers.alSampleTypeName(alSampleType)+ @@ -250,12 +250,12 @@ public class ALAudioSink implements AudioSink { "queued["+alFramesPlaying.size()+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes], "+ "queue[g "+frameGrowAmount+", l "+frameLimit+"]"; } - + public final String getPerfString() { final int alBuffersLen = null != alBufferNames ? alBufferNames.length : 0; return "Play [buffer "+alFramesPlaying.size()+"/"+alBuffersLen+", apts "+getPTS()+", "+getQueuedTime() + " ms, " + alBufferBytesQueued+" bytes]"; } - + @Override public final AudioFormat getPreferredFormat() { if( !staticAvailable ) { @@ -263,7 +263,7 @@ public class ALAudioSink implements AudioSink { } return preferredAudioFormat; } - + @Override public final int getMaxSupportedChannels() { if( !staticAvailable ) { @@ -271,14 +271,14 @@ public class ALAudioSink implements AudioSink { } return hasSOFTBufferSamples ? 8 : 2; } - + @Override public final boolean isSupported(AudioFormat format) { if( !staticAvailable ) { return false; } if( format.planar || !format.littleEndian ) { - // FIXME big-endian supported w/ SOFT where it's native format! + // FIXME big-endian supported w/ SOFT where it's native format! return false; } final int alChannelLayout = ALHelpers.getDefaultALChannelLayout(format.channelCount); @@ -286,7 +286,7 @@ public class ALAudioSink implements AudioSink { final int alSampleType = ALHelpers.getALSampleType(format.sampleSize, format.signed, format.fixedP); if( AL.AL_NONE != alSampleType ) { lockContext(); - try { + try { final int alFormat = ALHelpers.getALFormat(alChannelLayout, alSampleType, hasSOFTBufferSamples, al, alExt); return AL.AL_NONE != alFormat; } finally { @@ -296,7 +296,7 @@ public class ALAudioSink implements AudioSink { } return false; } - + @Override public final boolean init(AudioFormat requestedFormat, float frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { if( !staticAvailable ) { @@ -318,10 +318,10 @@ public class ALAudioSink implements AudioSink { // Allocate buffers destroyBuffers(); { - final float useFrameDuration = frameDuration > 1f ? frameDuration : AudioSink.DefaultFrameDuration; + final float useFrameDuration = frameDuration > 1f ? frameDuration : AudioSink.DefaultFrameDuration; final int initialFrameCount = requestedFormat.getFrameCount( initialQueueSize > 0 ? initialQueueSize : AudioSink.DefaultInitialQueueSize, useFrameDuration); - // frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { + // frameDuration, int initialQueueSize, int queueGrowAmount, int queueLimit) { alBufferNames = new int[initialFrameCount]; al.alGenBuffers(initialFrameCount, alBufferNames, 0); final int err = al.alGetError(); @@ -333,7 +333,7 @@ public class ALAudioSink implements AudioSink { for(int i=0; i<initialFrameCount; i++) { alFrames[i] = new ALAudioFrame(alBufferNames[i]); } - + alFramesAvail = new LFRingbuffer<ALAudioFrame>(alFrames); alFramesPlaying = new LFRingbuffer<ALAudioFrame>(ALAudioFrame[].class, initialFrameCount); this.frameGrowAmount = requestedFormat.getFrameCount( @@ -344,11 +344,11 @@ public class ALAudioSink implements AudioSink { } finally { unlockContext(); } - + chosenFormat = requestedFormat; return true; } - + private static int[] concat(int[] first, int[] second) { final int[] result = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, result, first.length, second.length); @@ -360,7 +360,7 @@ public class ALAudioSink implements AudioSink { System.arraycopy(second, 0, result, first.length, second.length); return result; } */ - + private boolean growBuffers() { if( !alFramesAvail.isEmpty() || !alFramesPlaying.isFull() ) { throw new InternalError("Buffers: Avail is !empty "+alFramesAvail+" or Playing is !full "+alFramesPlaying); @@ -371,7 +371,7 @@ public class ALAudioSink implements AudioSink { } return false; } - + final int[] newALBufferNames = new int[frameGrowAmount]; al.alGenBuffers(frameGrowAmount, newALBufferNames, 0); final int err = al.alGetError(); @@ -382,7 +382,7 @@ public class ALAudioSink implements AudioSink { return false; } alBufferNames = concat(alBufferNames, newALBufferNames); - + final ALAudioFrame[] newALBuffers = new ALAudioFrame[frameGrowAmount]; for(int i=0; i<frameGrowAmount; i++) { newALBuffers[i] = new ALAudioFrame(newALBufferNames[i]); @@ -399,7 +399,7 @@ public class ALAudioSink implements AudioSink { } return true; } - + private void destroyBuffers() { if( !staticAvailable ) { return; @@ -422,7 +422,7 @@ public class ALAudioSink implements AudioSink { alBufferNames = null; } } - + @Override public final void destroy() { initialized = false; @@ -445,7 +445,7 @@ public class ALAudioSink implements AudioSink { } alSource = null; } - + destroyBuffers(); } finally { destroyContext(); @@ -459,22 +459,20 @@ public class ALAudioSink implements AudioSink { t.printStackTrace(); } } - device = null; + device = null; } chosenFormat = null; } - + @Override public final boolean isInitialized() { return initialized; } - - private final int dequeueBuffer(boolean flush, boolean wait) { + + private final int dequeueBuffer(boolean wait) { int alErr = AL.AL_NO_ERROR; final int releaseBufferCount; - if( flush ) { - releaseBufferCount = alFramesPlaying.size(); - } else if( alBufferBytesQueued > 0 ) { + if( alBufferBytesQueued > 0 ) { final int releaseBufferLimes = Math.max(1, alFramesPlaying.size() / 4 ); final int[] val=new int[1]; int i=0; @@ -490,8 +488,8 @@ public class ALAudioSink implements AudioSink { final int avgBufferDura = chosenFormat.getBytesDuration( alBufferBytesQueued / alFramesPlaying.size() ); final int sleep = Math.max(2, Math.min(100, releaseBufferLimes * avgBufferDura)); if( DEBUG || true ) { - System.err.println(getThreadName()+": ALAudioSink: Dequeue.wait["+i+"]: avgBufferDura "+avgBufferDura+", releaseBufferLimes "+releaseBufferLimes+", sleep "+sleep+" ms, playImpl "+isPlayingImpl1()+", processed "+val[0]+", "+this); - } + System.err.println(getThreadName()+": ALAudioSink: Dequeue.wait["+i+"]: avgBufferDura "+avgBufferDura+", releaseBufferLimes "+releaseBufferLimes+", sleep "+sleep+" ms, playImpl "+(AL.AL_PLAYING == getSourceState())+", processed "+val[0]+", "+this); + } unlockContext(); try { Thread.sleep( sleep - 1 ); @@ -511,7 +509,7 @@ public class ALAudioSink implements AudioSink { al.alSourceUnqueueBuffers(alSource[0], releaseBufferCount, buffers, 0); alErr = al.alGetError(); if( AL.AL_NO_ERROR != alErr ) { - throw new RuntimeException("ALError "+toHexString(alErr)+" while dequeueing "+releaseBufferCount+" buffers. "+this); + throw new RuntimeException("ALError "+toHexString(alErr)+" while dequeueing "+releaseBufferCount+" buffers. "+this); } for ( int i=0; i<releaseBufferCount; i++ ) { final ALAudioFrame releasedBuffer = alFramesPlaying.get(); @@ -520,7 +518,7 @@ public class ALAudioSink implements AudioSink { } if( releasedBuffer.alBuffer != buffers[i] ) { alFramesAvail.dump(System.err, "Avail-deq02-post"); - alFramesPlaying.dump(System.err, "Playi-deq02-post"); + alFramesPlaying.dump(System.err, "Playi-deq02-post"); throw new InternalError("Buffer name mismatch: dequeued: "+buffers[i]+", released "+releasedBuffer+", "+this); } alBufferBytesQueued -= releasedBuffer.getByteSize(); @@ -528,17 +526,27 @@ public class ALAudioSink implements AudioSink { throw new InternalError("Internal Error: "+this); } } - if( flush && ( !alFramesAvail.isFull() || !alFramesPlaying.isEmpty() ) ) { - alFramesAvail.dump(System.err, "Avail-deq03-post"); - alFramesPlaying.dump(System.err, "Playi-deq03-post"); - throw new InternalError("Flush failure: "+this); - } } return releaseBufferCount; } - + private final void dequeueForceAll() { + while ( !alFramesPlaying.isEmpty() ) { + final ALAudioFrame releasedBuffer = alFramesPlaying.get(); + if( null == releasedBuffer ) { + throw new InternalError("Internal Error: "+this); + } + alBufferBytesQueued -= releasedBuffer.getByteSize(); + if( !alFramesAvail.put(releasedBuffer) ) { + throw new InternalError("Internal Error: "+this); + } + } + if( 0 != alBufferBytesQueued ) { + throw new InternalError("Internal Error: "+this); + } + } + private final int dequeueBuffer(boolean wait, int inPTS, int inDuration) { - final int dequeuedBufferCount = dequeueBuffer( false /* flush */, wait ); + final int dequeuedBufferCount = dequeueBuffer( wait ); final ALAudioFrame currentBuffer = alFramesPlaying.peek(); if( null != currentBuffer ) { playingPTS = currentBuffer.getPTS(); @@ -552,12 +560,12 @@ public class ALAudioSink implements AudioSink { } return dequeuedBufferCount; } - + @Override public final AudioFrame enqueueData(AudioDataFrame audioDataFrame) { return enqueueData(audioDataFrame.getPTS(), audioDataFrame.getData(), audioDataFrame.getByteSize()); } - + @Override public final AudioFrame enqueueData(int pts, ByteBuffer bytes, int byteCount) { if( !initialized || null == chosenFormat ) { @@ -565,7 +573,7 @@ public class ALAudioSink implements AudioSink { } final ALAudioFrame alFrame; int alErr = AL.AL_NO_ERROR; - + // OpenAL consumes buffers in the background // we first need to initialize the OpenAL buffers then // start continuous playback. @@ -575,7 +583,7 @@ public class ALAudioSink implements AudioSink { if(al.alGetError() != AL.AL_NO_ERROR) { throw new RuntimeException("ALError "+toHexString(alErr)+" while makeCurrent. "+this); } - + final int duration = chosenFormat.getBytesDuration(byteCount); final boolean dequeueDone; if( alFramesAvail.isEmpty() ) { @@ -592,7 +600,7 @@ public class ALAudioSink implements AudioSink { final boolean wait = isPlayingImpl0() && alFramesAvail.isEmpty(); // possible if grow failed or already exceeds it's limit! dequeueBuffer(wait, pts, duration); } - + alFrame = alFramesAvail.get(); if( null == alFrame ) { alFramesAvail.dump(System.err, "Avail"); @@ -612,7 +620,7 @@ public class ALAudioSink implements AudioSink { } else { al.alBufferData(alFrame.alBuffer, alFormat, bytes, byteCount, chosenFormat.sampleRate); } - + final int[] alBufferNames = new int[] { alFrame.alBuffer }; al.alSourceQueueBuffers(alSource[0], 1, alBufferNames, 0); alErr = al.alGetError(); @@ -621,7 +629,7 @@ public class ALAudioSink implements AudioSink { } alBufferBytesQueued += byteCount; enqueuedFrameCount++; - + playImpl(); // continue playing, fixes issue where we ran out of enqueued data! } finally { unlockContext(); @@ -640,28 +648,28 @@ public class ALAudioSink implements AudioSink { return isPlayingImpl0(); } finally { unlockContext(); - } + } } else { return false; } } private final boolean isPlayingImpl0() { if( playRequested ) { - return isPlayingImpl1(); + return AL.AL_PLAYING == getSourceState(); } else { return false; } } - private final boolean isPlayingImpl1() { + private final int getSourceState() { final int[] val = new int[1]; al.alGetSourcei(alSource[0], AL.AL_SOURCE_STATE, val, 0); final int alErr = al.alGetError(); if(al.alGetError() != AL.AL_NO_ERROR) { - throw new RuntimeException("ALError "+toHexString(alErr)+" while querying isPlaying. "+this); + throw new RuntimeException("ALError "+toHexString(alErr)+" while querying SOURCE_STATE. "+this); } - return val[0] == AL.AL_PLAYING; + return val[0]; } - + @Override public final void play() { if( !initialized || null == chosenFormat ) { @@ -672,22 +680,22 @@ public class ALAudioSink implements AudioSink { try { playImpl(); if( DEBUG ) { - System.err.println(getThreadName()+": ALAudioSink: PLAY playImpl "+isPlayingImpl1()+", "+this); - } + System.err.println(getThreadName()+": ALAudioSink: PLAY playImpl "+(AL.AL_PLAYING == getSourceState())+", "+this); + } } finally { unlockContext(); - } + } } private final void playImpl() { - if( playRequested && !isPlayingImpl1() ) { + if( playRequested && AL.AL_PLAYING != getSourceState() ) { al.alSourcePlay(alSource[0]); final int alErr = al.alGetError(); if(al.alGetError() != AL.AL_NO_ERROR) { throw new RuntimeException("ALError "+toHexString(alErr)+" while start playing. "+this); } - } + } } - + @Override public final void pause() { if( !initialized || null == chosenFormat ) { @@ -698,8 +706,8 @@ public class ALAudioSink implements AudioSink { try { pauseImpl(); if( DEBUG ) { - System.err.println(getThreadName()+": ALAudioSink: PAUSE playImpl "+isPlayingImpl1()+", "+this); - } + System.err.println(getThreadName()+": ALAudioSink: PAUSE playImpl "+(AL.AL_PLAYING == getSourceState())+", "+this); + } } finally { unlockContext(); } @@ -716,7 +724,7 @@ public class ALAudioSink implements AudioSink { } } private final void stopImpl() { - if( isPlayingImpl0() ) { + if( AL.AL_STOPPED != getSourceState() ) { playRequested = false; al.alSourceStop(alSource[0]); final int alErr = al.alGetError(); @@ -725,12 +733,12 @@ public class ALAudioSink implements AudioSink { } } } - + @Override public final float getPlaySpeed() { return playSpeed; } - + @Override - public final boolean setPlaySpeed(float rate) { + public final boolean setPlaySpeed(float rate) { if( !initialized || null == chosenFormat ) { return false; } @@ -739,22 +747,22 @@ public class ALAudioSink implements AudioSink { if( Math.abs(1.0f - rate) < 0.01f ) { rate = 1.0f; } - if( 0.5f <= rate && rate <= 2.0f ) { // OpenAL limits + if( 0.5f <= rate && rate <= 2.0f ) { // OpenAL limits playSpeed = rate; al.alSourcef(alSource[0], AL.AL_PITCH, playSpeed); return true; - } + } } finally { unlockContext(); } - return false; + return false; } - + @Override public final float getVolume() { - return volume; + return volume; } - + @Override public final boolean setVolume(float v) { if( !initialized || null == chosenFormat ) { @@ -767,17 +775,17 @@ public class ALAudioSink implements AudioSink { } else if( Math.abs(1.0f - v) < 0.01f ) { v = 1.0f; } - if( 0.0f <= v && v <= 1.0f ) { // OpenAL limits + if( 0.0f <= v && v <= 1.0f ) { // OpenAL limits volume = v; al.alSourcef(alSource[0], AL.AL_GAIN, v); return true; - } + } } finally { unlockContext(); } - return false; + return false; } - + @Override public final void flush() { if( !initialized || null == chosenFormat ) { @@ -787,28 +795,30 @@ public class ALAudioSink implements AudioSink { try { // pauseImpl(); stopImpl(); - dequeueBuffer( true /* flush */, false /* wait */ ); + al.alSourcei(alSource[0], AL.AL_BUFFER, 0); // explicit force zero buffer! + dequeueBuffer( false /* wait */ ); + dequeueForceAll(); if( alBufferNames.length != alFramesAvail.size() || alFramesPlaying.size() != 0 ) { throw new InternalError("XXX: "+this); } if( DEBUG ) { - System.err.println(getThreadName()+": ALAudioSink: FLUSH playImpl "+isPlayingImpl1()+", "+this); - } + System.err.println(getThreadName()+": ALAudioSink: FLUSH playImpl "+(AL.AL_PLAYING == getSourceState())+", "+this); + } } finally { unlockContext(); - } + } } - + @Override public final int getEnqueuedFrameCount() { return enqueuedFrameCount; } - + @Override public final int getFrameCount() { return null != alBufferNames ? alBufferNames.length : 0; } - + @Override public final int getQueuedFrameCount() { if( !initialized || null == chosenFormat ) { @@ -816,7 +826,7 @@ public class ALAudioSink implements AudioSink { } return alFramesPlaying.size(); } - + @Override public final int getFreeFrameCount() { if( !initialized || null == chosenFormat ) { @@ -824,7 +834,7 @@ public class ALAudioSink implements AudioSink { } return alFramesAvail.size(); } - + @Override public final int getQueuedByteCount() { if( !initialized || null == chosenFormat ) { @@ -832,7 +842,7 @@ public class ALAudioSink implements AudioSink { } return alBufferBytesQueued; } - + @Override public final int getQueuedTime() { if( !initialized || null == chosenFormat ) { @@ -840,10 +850,10 @@ public class ALAudioSink implements AudioSink { } return chosenFormat.getBytesDuration(alBufferBytesQueued); } - + @Override public final int getPTS() { return playingPTS; } - + private static final String toHexString(int v) { return "0x"+Integer.toHexString(v); } - private static final String getThreadName() { return Thread.currentThread().getName(); } + private static final String getThreadName() { return Thread.currentThread().getName(); } } diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java index 86e19c920..0de308cd1 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java +++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java @@ -138,6 +138,18 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { protected int displayedFrameCount = 0; protected volatile int video_pts_last = 0; + /** + * Help detect EOS, limit is {@link #MAX_FRAMELESS_MS_UNTIL_EOS}. + * To be used either by getNextTexture(..) or StreamWorker for audio-only. + */ + private int nullFrameCount = 0; + private int maxNullFrameCountUntilEOS = 0; + /** + * Help detect EOS, limit {@value} milliseconds without a valid frame. + */ + private static final int MAX_FRAMELESS_MS_UNTIL_EOS = 5000; + private static final int MAX_FRAMELESS_UNTIL_EOS_DEFAULT = MAX_FRAMELESS_MS_UNTIL_EOS / 30; // default value assuming 30fps + /** See {@link #getAudioSink()}. Set by implementation if used from within {@link #initStreamImpl(int, int)}! */ protected AudioSink audioSink = null; protected boolean audioSinkPlaySpeedSet = false; @@ -380,12 +392,20 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( null != streamWorker ) { streamWorker.doPause(); } + // Adjust target .. + if( msec >= duration ) { + msec = duration - (int)Math.floor(frame_duration); + } else if( msec < 0 ) { + msec = 0; + } pts1 = seekImpl(msec); resetAVPTSAndFlush(); if( null != audioSink && State.Playing == _state ) { audioSink.play(); // cont. w/ new data } - System.err.println("SEEK XXX: "+getPerfString()); + if(DEBUG) { + System.err.println("Seek("+msec+"): "+getPerfString()); + } if( null != streamWorker ) { streamWorker.doResume(); } @@ -507,6 +527,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { decodedFrameCount = 0; presentedFrameCount = 0; displayedFrameCount = 0; + nullFrameCount = 0; + maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT; this.streamLoc = streamLoc; // Pre-parse for camera-input scheme @@ -528,20 +550,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { this.vid = vid; this.aid = aid; if ( this.streamLoc != null ) { - if( TEXTURE_COUNT_MIN < textureCount ) { - streamWorker = new StreamWorker(); - } else { - new Thread() { - public void run() { - try { - initStreamImpl(vid, aid); - } catch (Throwable t) { - streamErr = new StreamException(t.getClass().getSimpleName()+" while initializing: "+GLMediaPlayerImpl.this.toString(), t); - changeState(GLMediaEventListener.EVENT_CHANGE_ERR, GLMediaPlayer.State.Uninitialized); - } // also initializes width, height, .. etc - } - }.start(); - } + new Thread() { + public void run() { + try { + // StreamWorker may be used, see API-doc of StreamWorker + initStreamImpl(vid, aid); + } catch (Throwable t) { + streamErr = new StreamException(t.getClass().getSimpleName()+" while initializing: "+GLMediaPlayerImpl.this.toString(), t); + changeState(GLMediaEventListener.EVENT_CHANGE_ERR, GLMediaPlayer.State.Uninitialized); + } // also initializes width, height, .. etc + } + }.start(); } } } @@ -746,6 +765,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { protected TextureFrame cachedFrame = null; protected long lastTimeMillis = 0; + private final boolean[] stGotVFrame = { false }; + @Override public final TextureFrame getNextTexture(GL gl) throws IllegalStateException { synchronized( stateLock ) { @@ -753,12 +774,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { throw new IllegalStateException("Instance not paused or playing: "+this); } if(State.Playing == state) { - TextureFrame nextFrame = null; boolean dropFrame = false; try { do { - final long currentTimeMillis; - final boolean playCached = null != cachedFrame; final boolean droppedFrame; if( dropFrame ) { presentedFrameCount--; @@ -767,24 +785,69 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } else { droppedFrame = false; } + final boolean playCached = null != cachedFrame; + final int video_pts; + final boolean hasVideoFrame; + TextureFrame nextFrame; if( playCached ) { nextFrame = cachedFrame; cachedFrame = null; presentedFrameCount--; - } else if( STREAM_ID_NONE != vid ) { - if( null != videoFramesDecoded ) { // single threaded ? TEXTURE_COUNT_MIN == textureCount + video_pts = nextFrame.getPTS(); + hasVideoFrame = true; + } else { + if( null != videoFramesDecoded ) { + // multi-threaded and video available nextFrame = videoFramesDecoded.get(); + if( null != nextFrame ) { + video_pts = nextFrame.getPTS(); + hasVideoFrame = true; + } else { + video_pts = TimeFrameI.INVALID_PTS; + hasVideoFrame = false; + } } else { - nextFrame = getNextSingleThreaded(gl, lastFrame); + // single-threaded or audio-only + video_pts = getNextSingleThreaded(gl, lastFrame, stGotVFrame); + nextFrame = lastFrame; + hasVideoFrame = stGotVFrame[0]; } } - currentTimeMillis = Platform.currentTimeMillis(); - if( null != nextFrame ) { - presentedFrameCount++; - final int video_pts = nextFrame.getPTS(); - if( video_pts == TimeFrameI.END_OF_STREAM_PTS ) { - pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); - } else if( video_pts != TimeFrameI.INVALID_PTS ) { + final long currentTimeMillis = Platform.currentTimeMillis(); + + if( TimeFrameI.END_OF_STREAM_PTS == video_pts || + ( duration > 0 && duration <= video_pts ) || maxNullFrameCountUntilEOS <= nullFrameCount ) + { + // EOS + if( DEBUG ) { + System.err.println( "AV-EOS (getNextTexture): EOS_PTS "+(TimeFrameI.END_OF_STREAM_PTS == video_pts)+", "+this); + } + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); + + } else if( TimeFrameI.INVALID_PTS == video_pts ) { // no audio or video frame + if( null == videoFramesDecoded || !videoFramesDecoded.isEmpty() ) { + nullFrameCount++; + } + if( DEBUG ) { + final int audio_pts = getAudioPTSImpl(); + final int audio_scr = (int) ( ( currentTimeMillis - audio_scr_t0 ) * playSpeed ); + final int d_apts; + if( audio_pts != TimeFrameI.INVALID_PTS ) { + d_apts = audio_pts - audio_scr; + } else { + d_apts = 0; + } + final int video_scr = video_scr_pts + (int) ( ( currentTimeMillis - video_scr_t0 ) * playSpeed ); + final int d_vpts = video_pts - video_scr; + System.err.println( "AV~: dT "+(currentTimeMillis-lastTimeMillis)+", nullFrames "+nullFrameCount+ + getPerfStringImpl( video_scr, video_pts, d_vpts, audio_scr, audio_pts, d_apts, 0 ) + ", droppedFrame "+droppedFrame); + } + } else { // valid pts: has audio or video frame + nullFrameCount=0; + + if( hasVideoFrame ) { // has video frame + presentedFrameCount++; + final int audio_pts = getAudioPTSImpl(); final int audio_scr = (int) ( ( currentTimeMillis - audio_scr_t0 ) * playSpeed ); final int d_apts; @@ -838,29 +901,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { ", avg dpy-fps "+avg_dpy_duration+" ms/f, maxD "+maxVideoDelay+" ms, "+_nextFrame+", playCached " + playCached + ", dropFrame "+dropFrame); } } - } else if( DEBUG ) { - System.err.println("Invalid PTS: "+nextFrame); - } - if( null != nextFrame && null != videoFramesFree ) { - // Had frame and not single threaded ? (TEXTURE_COUNT_MIN < textureCount) - final TextureFrame _lastFrame = lastFrame; - lastFrame = nextFrame; + } // has video frame + } // has audio or video frame + + if( null != videoFramesFree && null != nextFrame ) { + // Had frame and not single threaded ? (TEXTURE_COUNT_MIN < textureCount) + final TextureFrame _lastFrame = lastFrame; + lastFrame = nextFrame; + if( null != _lastFrame ) { videoFramesFree.putBlocking(_lastFrame); } - } else if( DEBUG ) { - final int video_pts = lastFrame.getPTS(); - final int audio_pts = getAudioPTSImpl(); - final int audio_scr = (int) ( ( currentTimeMillis - audio_scr_t0 ) * playSpeed ); - final int d_apts; - if( audio_pts != TimeFrameI.INVALID_PTS ) { - d_apts = audio_pts - audio_scr; - } else { - d_apts = 0; - } - final int video_scr = video_scr_pts + (int) ( ( currentTimeMillis - video_scr_t0 ) * playSpeed ); - final int d_vpts = video_pts - video_scr; - System.err.println( "AV~: dT "+(currentTimeMillis-lastTimeMillis)+", "+ - getPerfStringImpl( video_scr, video_pts, d_vpts, audio_scr, audio_pts, d_apts, 0 ) + ", droppedFrame "+droppedFrame); } lastTimeMillis = currentTimeMillis; } while( dropFrame ); @@ -897,24 +947,24 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { */ protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame); - protected final TextureFrame getNextSingleThreaded(final GL gl, final TextureFrame nextFrame) throws InterruptedException { + protected final int getNextSingleThreaded(final GL gl, final TextureFrame nextFrame, boolean[] gotVFrame) throws InterruptedException { + final int pts; if( STREAM_ID_NONE != vid ) { preNextTextureImpl(gl); - final int vPTS = getNextTextureImpl(gl, nextFrame); + pts = getNextTextureImpl(gl, nextFrame); postNextTextureImpl(gl); - if( TimeFrameI.INVALID_PTS != vPTS ) { + if( TimeFrameI.INVALID_PTS != pts ) { newFrameAvailable(nextFrame, Platform.currentTimeMillis()); - return nextFrame; + gotVFrame[0] = true; + } else { + gotVFrame[0] = false; } } else { // audio only - final int vPTS = getNextTextureImpl(null, null); - if( TimeFrameI.INVALID_PTS != vPTS && TimeFrameI.END_OF_STREAM_PTS == vPTS ) { - // state transition incl. notification - pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); - } + pts = getNextTextureImpl(null, null); + gotVFrame[0] = false; } - return null; + return pts; } @@ -962,6 +1012,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } private void resetAVPTS() { + nullFrameCount = 0; presentedFrameCount = 0; displayedFrameCount = 0; decodedFrameCount = 0; @@ -984,6 +1035,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } + /** + * After {@link GLMediaPlayerImpl#initStreamImpl(int, int) initStreamImpl(..)} is completed via + * {@link GLMediaPlayerImpl#updateAttributes(int, int, int, int, int, int, int, float, int, int, int, String, String) updateAttributes(..)}, + * the latter decides whether StreamWorker is being used. + */ class StreamWorker extends Thread { private volatile boolean isRunning = false; private volatile boolean isActive = false; @@ -998,14 +1054,23 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { /** * Starts this daemon thread, - * which initializes the stream first via {@link GLMediaPlayerImpl#initStreamImpl(int, int)} first. * <p> - * After stream initialization, this thread pauses! + * This thread pauses after it's started! * </p> **/ StreamWorker() { setDaemon(true); - start(); + synchronized(this) { + start(); + while( !isRunning ) { + this.notifyAll(); // wake-up startup-block + try { + this.wait(); // wait until started + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } private void makeCurrent(GLContext ctx) { @@ -1073,7 +1138,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { shallPause = false; if( Thread.currentThread() != this ) { while( !isActive ) { - this.notify(); // wake-up pause-block + this.notifyAll(); // wake-up pause-block try { this.wait(); // wait until resumed } catch (InterruptedException e) { @@ -1091,7 +1156,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { this.interrupt(); } while( isRunning ) { - this.notify(); // wake-up pause-block (opt) + this.notifyAll(); // wake-up pause-block (opt) try { this.wait(); // wait until stopped } catch (InterruptedException e) { @@ -1111,17 +1176,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { synchronized ( this ) { isRunning = true; - try { - isBlocked = true; - initStreamImpl(vid, aid); - isBlocked = false; - } catch (Throwable t) { - streamErr = new StreamException(t.getClass().getSimpleName()+" while initializing: "+GLMediaPlayerImpl.this.toString(), t); - isBlocked = false; - isRunning = false; - changeState(GLMediaEventListener.EVENT_CHANGE_ERR, GLMediaPlayer.State.Uninitialized); - return; // end of thread! - } // also initializes width, height, .. etc + this.notifyAll(); // wake-up ctor() } while( !shallStop ){ @@ -1133,7 +1188,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } while( shallPause && !shallStop ) { isActive = false; - this.notify(); // wake-up doPause() + this.notifyAll(); // wake-up doPause() try { this.wait(); // wait until resumed } catch (InterruptedException e) { @@ -1147,7 +1202,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { preNextTextureImpl(sharedGLCtx.getGL()); } isActive = true; - this.notify(); // wake-up doResume() + this.notifyAll(); // wake-up doResume() } } if( !sharedGLCtxCurrent && null != sharedGLCtx ) { @@ -1177,6 +1232,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } isBlocked = false; final int vPTS = getNextTextureImpl(gl, nextFrame); + boolean audioEOS = false; if( TimeFrameI.INVALID_PTS != vPTS ) { if( null != nextFrame ) { if( STREAM_WORKER_DELAY > 0 ) { @@ -1189,13 +1245,30 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { nextFrame = null; } else { // audio only - if( TimeFrameI.END_OF_STREAM_PTS == vPTS ) { - // state transition incl. notification - shallPause = true; - isActive = false; - pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); + if( TimeFrameI.END_OF_STREAM_PTS == vPTS || ( duration > 0 && duration < vPTS ) ) { + audioEOS = true; + } else { + nullFrameCount = 0; } } + } else if( null == nextFrame ) { + // audio only + audioEOS = maxNullFrameCountUntilEOS <= nullFrameCount; + if( null == audioSink || 0 == audioSink.getEnqueuedFrameCount() ) { + nullFrameCount++; + } + } + if( audioEOS ) { + // state transition incl. notification + synchronized ( this ) { + shallPause = true; + isActive = false; + this.notifyAll(); // wake-up potential do*() + } + if( DEBUG ) { + System.err.println( "AV-EOS (StreamWorker): EOS_PTS "+(TimeFrameI.END_OF_STREAM_PTS == vPTS)+", "+GLMediaPlayerImpl.this); + } + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); } } catch (InterruptedException e) { isBlocked = false; @@ -1215,8 +1288,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { t.printStackTrace(); } // state transition incl. notification - shallPause = true; - isActive = false; + synchronized ( this ) { + shallPause = true; + isActive = false; + this.notifyAll(); // wake-up potential do*() + } pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR); } } @@ -1229,12 +1305,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { destroySharedGL(); isRunning = false; isActive = false; - this.notify(); // wake-up doStop() + this.notifyAll(); // wake-up doStop() } } } static int StreamWorkerInstanceId = 0; - private StreamWorker streamWorker = null; + private volatile StreamWorker streamWorker = null; private volatile StreamException streamErr = null; protected final int addStateEventMask(int event_mask, State newState) { @@ -1280,7 +1356,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { int bps_video, int bps_audio, float fps, int videoFrames, int audioFrames, int duration, String vcodec, String acodec) { int event_mask = 0; - if( state == State.Uninitialized ) { + final boolean wasUninitialized = state == State.Uninitialized; + + if( wasUninitialized ) { event_mask |= GLMediaEventListener.EVENT_CHANGE_INIT; state = State.Initialized; } @@ -1306,7 +1384,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( this.fps != fps ) { event_mask |= GLMediaEventListener.EVENT_CHANGE_FPS; this.fps = fps; - this.frame_duration = 1000f / fps; + if( 0 != fps ) { + this.frame_duration = 1000f / fps; + this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_MS_UNTIL_EOS / (int)this.frame_duration; + } else { + this.frame_duration = 0; + this.maxNullFrameCountUntilEOS = MAX_FRAMELESS_UNTIL_EOS_DEFAULT; + } } if( this.bps_stream != bps_stream || this.bps_video != bps_video || this.bps_audio != bps_audio ) { event_mask |= GLMediaEventListener.EVENT_CHANGE_BPS; @@ -1331,6 +1415,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if(0==event_mask) { return; } + if( wasUninitialized ) { + if( null != streamWorker ) { + throw new InternalError("XXX: StreamWorker not null - "+this); + } + if( TEXTURE_COUNT_MIN < textureCount || STREAM_ID_NONE == vid ) { // Enable StreamWorker for 'audio only' as well (Bug 918). + streamWorker = new StreamWorker(); + } + if( DEBUG ) { + System.err.println("XXX Initialize @ updateAttributes: "+this); + } + } attributesUpdated(event_mask); } @@ -1426,9 +1521,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { final int decVideoFrames = null != videoFramesDecoded ? videoFramesDecoded.size() : 0; final int video_scr = video_scr_pts + (int) ( ( Platform.currentTimeMillis() - video_scr_t0 ) * playSpeed ); final String camPath = null != cameraPath ? ", camera: "+cameraPath : ""; - return "GLMediaPlayer["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s)], "+ - "speed "+playSpeed+", "+bps_stream+" bps, "+ - "Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", tagt "+toHexString(textureTarget)+", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+ + return "GLMediaPlayer["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s), z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+ + "speed "+playSpeed+", "+bps_stream+" bps, hasSW "+(null!=streamWorker)+ + ", Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", tagt "+toHexString(textureTarget)+", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+ "Video[id "+vid+", <"+vcodec+">, "+width+"x"+height+", glOrient "+isInGLOrientation+", "+fps+" fps, "+frame_duration+" fdur, "+bps_video+" bps], "+ "Audio[id "+aid+", <"+acodec+">, "+bps_audio+" bps, "+audioFrames+" frames], uri "+loc+camPath+"]"; } @@ -1462,7 +1557,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { freeVideoFrames = 0; decVideoFrames = 0; } - return state+", frames[(p "+presentedFrameCount+", d "+decodedFrameCount+") / "+videoFrames+", "+tt+" s], "+ + return state+", frames[(p "+presentedFrameCount+", d "+decodedFrameCount+") / "+videoFrames+", "+tt+" s, z "+nullFrameCount+" / "+maxNullFrameCountUntilEOS+"], "+ "speed " + playSpeed+", dAV "+( d_vpts - d_apts )+", vSCR "+video_scr+", vpts "+video_pts+", dSCR["+d_vpts+", avrg "+video_dpts_avg_diff+"], "+ "aSCR "+audio_scr+", apts "+audio_pts+" ( "+d_apts+" ), "+audioSinkInfo+ ", Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+"]"; diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c index 24fddd2c0..44acfe46a 100644 --- a/src/jogl/native/libav/ffmpeg_impl_template.c +++ b/src/jogl/native/libav/ffmpeg_impl_template.c @@ -846,14 +846,9 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0) pAV->frames_audio = pAV->pAStream->nb_frames; pAV->aSinkSupport = _isAudioFormatSupported(env, pAV->ffmpegMediaPlayer, pAV->aSampleFmt, pAV->aSampleRate, pAV->aChannels); if( pAV->verbose ) { - fprintf(stderr, "A channels %d [l %"PRId64"], sample_rate %d, frame_size %d, frame_number %d, [afps %f, rfps %f, cfps %f, sfps %f], nb_frames %"PRId64", [maxChan %d, prefRate %d, req_chan_layout %"PRId64", req_chan %d], sink-support %d \n", + fprintf(stderr, "A channels %d [l %"PRId64"], sample_rate %d, frame_size %d, frame_number %d, [afps %f, cfps %f, sfps %f], nb_frames %"PRId64", [maxChan %d, prefRate %d, req_chan_layout %"PRId64", req_chan %d], sink-support %d \n", pAV->aChannels, pAV->pACodecCtx->channel_layout, pAV->aSampleRate, pAV->aFrameSize, pAV->pACodecCtx->frame_number, my_av_q2f(pAV->pAStream->avg_frame_rate), - #if LIBAVCODEC_VERSION_MAJOR < 55 - my_av_q2f(pAV->pVStream->r_frame_rate), - #else - 0.0f, - #endif my_av_q2f_r(pAV->pAStream->codec->time_base), my_av_q2f_r(pAV->pAStream->time_base), pAV->pAStream->nb_frames, @@ -1149,6 +1144,11 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0) pkt_odata = packet.data; pkt_osize = packet.size; if( AVERROR_EOF == avRes || ( pAV->pFormatCtx->pb && pAV->pFormatCtx->pb->eof_reached ) ) { + if( pAV->verbose ) { + fprintf(stderr, "EOS: avRes[res %d, eos %d], pb-EOS %d\n", + avRes, AVERROR_EOF == avRes, + ( pAV->pFormatCtx->pb && pAV->pFormatCtx->pb->eof_reached ) ); + } resPTS = END_OF_STREAM_PTS; } else if( 0 <= avRes ) { if( pAV->verbose ) { @@ -1480,15 +1480,16 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0) (JNIEnv *env, jobject instance, jlong ptr, jint pos1) { const FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr)); - const int64_t pos0 = pAV->vPTS; - int64_t pts0; + int64_t pos0, pts0; int streamID; AVRational time_base; if( pAV->vid >= 0 ) { + pos0 = pAV->vPTS; streamID = pAV->vid; time_base = pAV->pVStream->time_base; pts0 = pAV->pVFrame->pkt_pts; } else if( pAV->aid >= 0 ) { + pos0 = pAV->aPTS; streamID = pAV->aid; time_base = pAV->pAStream->time_base; pts0 = pAV->pAFrames[pAV->aFrameCurrent]->pkt_pts; @@ -1498,16 +1499,16 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0) int64_t pts1 = (int64_t) (pos1 * (int64_t) time_base.den) / (1000 * (int64_t) time_base.num); if(pAV->verbose) { - fprintf(stderr, "SEEK: vid %d, aid %d, pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos1, pts0, pts1); + fprintf(stderr, "SEEK: vid %d, aid %d, pos0 %d, pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos0, pos1, pts0, pts1); } int flags = 0; if(pos1 < pos0) { flags |= AVSEEK_FLAG_BACKWARD; } - int res; + int res = -2; if(HAS_FUNC(sp_av_seek_frame)) { if(pAV->verbose) { - fprintf(stderr, "SEEK.0: pre : s %"PRId64" / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1); + fprintf(stderr, "SEEK.0: pre : s %d / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1); } sp_av_seek_frame(pAV->pFormatCtx, streamID, pts1, flags); } else if(HAS_FUNC(sp_avformat_seek_file)) { diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 869b56331..5c3bb7889 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -353,6 +353,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol { ACTION_NATIVE_CREATION_PENDING; } + /** Reparenting hint (bitfield value): Force destroy and hence {@link ReparentOperation#ACTION_NATIVE_CREATION re-creating} the window. */ + public static final int REPARENT_HINT_FORCE_RECREATION = 1 << 0; + /** Reparenting hint (bitfield value): Claim window becomes visible after reparenting, which is important for e.g. preserving the GL-states in case window is invisible while reparenting. */ + public static final int REPARENT_HINT_BECOMES_VISIBLE = 1 << 1; + /** * Change this window's parent window.<br> * <P> @@ -365,6 +370,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * * @return The issued reparent action type (strategy) as defined in Window.ReparentAction * @see #reparentWindow(NativeWindow, int, int, boolean) + * @deprecated Use {@link #reparentWindow(NativeWindow, int, int, int)} */ ReparentOperation reparentWindow(NativeWindow newParent); @@ -382,11 +388,28 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * @param forceDestroyCreate if true, uses re-creation strategy for reparenting, default is <code>false</code>. * * @return The issued reparent action type (strategy) as defined in Window.ReparentAction - * @see #reparentWindow(NativeWindow) + * @deprecated Use {@link #reparentWindow(NativeWindow, int, int, int)} */ ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate); /** + * Change this window's parent window.<br> + * <P> + * In case the old parent is not null and a Window, + * this window is removed from it's list of children.<br> + * In case the new parent is not null and a Window, + * this window is added to it's list of children.<br></P> + * + * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. + * @param x new top-level position, use -1 for default position. + * @param y new top-level position, use -1 for default position. + * @param hints May contain hints (bitfield values) like {@link #REPARENT_HINT_FORCE_RECREATION} or {@link #REPARENT_HINT_BECOMES_VISIBLE}. + * + * @return The issued reparent action type (strategy) as defined in Window.ReparentAction + */ + ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints); + + /** * Enable or disable fullscreen mode for this window. * <p> * Fullscreen mode is established on the {@link #getMainMonitor() main monitor}. diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index b6b8cf9e8..00c3f1eb7 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -673,7 +673,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto GLDrawableUtil.swapGLContextAndAllGLEventListener(glad, printGLAD); printDrawable = printGLAD.getDelegatedDrawable(); } - printAWTTiles.setIsGLOriented(printGLAD.isGLOriented()); + printAWTTiles.setGLOrientation(printGLAD.isGLOriented(), printGLAD.isGLOriented()); printAWTTiles.renderer.setTileSize(printDrawable.getWidth(), printDrawable.getHeight(), 0); printAWTTiles.renderer.attachAutoDrawable(printGLAD); if( DEBUG ) { @@ -867,7 +867,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } newtChild.setVisible(false); newtChild.setSize(w, h); - newtChild.reparentWindow(jawtWindow); + newtChild.reparentWindow(jawtWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); newtChild.addSurfaceUpdatedListener(jawtWindow); if( jawtWindow.isOffscreenLayerSurfaceEnabled() && 0 != ( JAWTUtil.JAWT_OSX_CALAYER_QUIRK_POSITION & JAWTUtil.getOSXCALayerQuirks() ) ) { @@ -917,7 +917,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto configureNewtChild(false); newtChild.setVisible(false); - newtChild.reparentWindow(null); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer + newtChild.reparentWindow(null, -1, -1, 0 /* hint */); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer if(DEBUG) { System.err.println("NewtCanvasAWT.detachNewtChild.X: win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+", comp "+this); diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java index 4a2878e3a..e6571d21a 100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -42,6 +42,7 @@ import javax.media.opengl.GLPipelineFactory; import jogamp.newt.Debug; +import com.jogamp.newt.Window; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.MouseListener; @@ -218,7 +219,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { @Override public void run() { if( glWindow.isNativeValid() && null != awtParent && 0 != awtParent.getWindowHandle() ) { - glWindow.reparentWindow(awtParent); + glWindow.reparentWindow(awtParent, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); } } }).start(); @@ -308,7 +309,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop()); } else if(e.getKeyChar()=='r' && null!=awtParent) { if(null == glWindow.getParent()) { - glWindow.reparentWindow(awtParent); + glWindow.reparentWindow(awtParent, -1, -1, 0 /* hints */); } else { final InsetsImmutable insets = glWindow.getInsets(); final int x, y; @@ -320,7 +321,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { x = insets.getLeftWidth(); y = insets.getTopHeight(); } - glWindow.reparentWindow(null, x, y, false /* forceDestroyCreate */); + glWindow.reparentWindow(null, x, y, 0 /* hints */); glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE ); } } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 52f19f783..208602aa1 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -397,6 +397,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override + public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) { + return window.reparentWindow(newParent, x, y, hints); + } + + @Override public final boolean removeChild(NativeWindow win) { return window.removeChild(win); } diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java index 5ed8d9e63..43e56c874 100644 --- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java +++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java @@ -247,7 +247,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol { } configureNewtChild(false); newtChild.setVisible(false); - newtChild.reparentWindow(null); + newtChild.reparentWindow(null, -1, -1, 0 /* hint */); newtChild.destroy(); newtChild = null; } @@ -361,7 +361,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol { } newtChild.setSize(w, h); - newtChild.reparentWindow(nativeWindow); + newtChild.reparentWindow(nativeWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); newtChild.setVisible(true); configureNewtChild(true); newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener @@ -372,7 +372,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol { } else { configureNewtChild(false); newtChild.setVisible(false); - newtChild.reparentWindow(null); + newtChild.reparentWindow(null, -1, -1, 0 /* hints */); } if(DEBUG) { System.err.println("NewtCanvasSWT.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()); diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 21343b263..ed7dd5600 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -1186,14 +1186,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class ReparentAction implements Runnable { final NativeWindow newParentWindow; final int topLevelX, topLevelY; - boolean forceDestroyCreate; + final int hints; ReparentOperation operation; - private ReparentAction(NativeWindow newParentWindow, int topLevelX, int topLevelY, boolean forceDestroyCreate) { + private ReparentAction(NativeWindow newParentWindow, int topLevelX, int topLevelY, int hints) { this.newParentWindow = newParentWindow; this.topLevelX = topLevelX; this.topLevelY = topLevelY; - this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE; + if( DEBUG_TEST_REPARENT_INCOMPATIBLE ) { + hints |= REPARENT_HINT_FORCE_RECREATION; + } + this.hints = hints; this.operation = ReparentOperation.ACTION_INVALID; // ensure it's set } @@ -1227,17 +1230,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer final int x, y; int width = oldWidth; int height = oldHeight; - boolean wasVisible; + + final boolean wasVisible; + final boolean becomesVisible; + final boolean forceDestroyCreate; final RecursiveLock _lock = windowLock; _lock.lock(); try { - if(isNativeValid()) { - // force recreation if offscreen, since it may become onscreen - forceDestroyCreate |= isOffscreenInstance(WindowImpl.this, newParentWindow); + { + boolean v = 0 != ( REPARENT_HINT_FORCE_RECREATION & hints ); + if(isNativeValid()) { + // force recreation if offscreen, since it may become onscreen + v |= isOffscreenInstance(WindowImpl.this, newParentWindow); + } + forceDestroyCreate = v; } wasVisible = isVisible(); + becomesVisible = wasVisible || 0 != ( REPARENT_HINT_BECOMES_VISIBLE & hints ); Window newParentWindowNEWT = null; if(newParentWindow instanceof Window) { @@ -1246,8 +1257,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer long newParentWindowHandle = 0 ; - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate); + if( DEBUG_IMPLEMENTATION) { + System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+ + ", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+ + ", visible "+wasVisible+", becomesVisible "+becomesVisible+ + ", forceDestroyCreate "+forceDestroyCreate+ + ", HINT_FORCE_RECREATION "+( 0 != ( REPARENT_HINT_FORCE_RECREATION & hints ) )+ + ", HINT_BECOMES_VISIBLE "+( 0 != ( REPARENT_HINT_BECOMES_VISIBLE & hints ) ) + + ", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+ + ", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow) ); } if(null!=newParentWindow) { @@ -1274,7 +1292,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // Destroy this window and use parent's Screen. // It may be created properly when the parent is made visible. - destroy( false ); + destroy( becomesVisible ); setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() ); operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING; } else if(newParentWindow != getParent()) { @@ -1298,7 +1316,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, screen) ) { // Destroy this window, may create a new compatible Screen/Display, while trying to preserve resources if becoming visible again. - destroy( wasVisible ); + destroy( becomesVisible ); if(null!=newParentWindowNEWT) { setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() ); } else { @@ -1336,7 +1354,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else if( !isNativeValid() || forceDestroyCreate ) { // Destroy this window and mark it for [pending] creation. // If isNativeValid() and becoming visible again - try to preserve resources, i.e. b/c on-/offscreen switch. - destroy( isNativeValid() && wasVisible ); + destroy( becomesVisible ); if( 0 < width && 0 < height ) { operation = ReparentOperation.ACTION_NATIVE_CREATION; } else { @@ -1437,7 +1455,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(DEBUG_IMPLEMENTATION) { System.err.println("Window.reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentWindowHandle)+" - Trying recreation"); } - destroy( wasVisible ); + destroy( becomesVisible ); operation = ReparentOperation.ACTION_NATIVE_CREATION ; } } else { @@ -1500,12 +1518,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final ReparentOperation reparentWindow(NativeWindow newParent) { - return reparentWindow(newParent, -1, -1, false); + return reparentWindow(newParent, -1, -1, 0); } @Override public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) { - final ReparentAction reparentAction = new ReparentAction(newParent, x, y, forceDestroyCreate); + return reparentWindow(newParent, x, y, forceDestroyCreate ? REPARENT_HINT_FORCE_RECREATION : 0); + } + + @Override + public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) { + final ReparentAction reparentAction = new ReparentAction(newParent, x, y, hints); runOnEDTIfAvail(true, reparentAction); return reparentAction.getOp(); } @@ -2161,11 +2184,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreenMonitors = monitors; fullscreenUseMainMonitor = useMainMonitor; if( fullScreenAction.init(fullscreen) ) { - if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) { + if( fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow) ) { // enable fullscreen on offscreen instance if(null != parentWindow) { nfs_parent = parentWindow; - reparentWindow(null, -1, -1, true /* forceDestroyCreate */); + reparentWindow(null, -1, -1, REPARENT_HINT_FORCE_RECREATION | REPARENT_HINT_BECOMES_VISIBLE); } else { throw new InternalError("Offscreen instance w/o parent unhandled"); } @@ -2175,7 +2198,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(!fullScreenAction.fsOn() && null != nfs_parent) { // disable fullscreen on offscreen instance - reparentWindow(nfs_parent, -1, -1, true /* forceDestroyCreate */); + reparentWindow(nfs_parent, -1, -1, REPARENT_HINT_FORCE_RECREATION | REPARENT_HINT_BECOMES_VISIBLE); nfs_parent = null; } } diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java index fb7faf90b..1e0d6067f 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java +++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher0.java @@ -58,7 +58,7 @@ public class MovieCubeActivityLauncher0 extends LauncherUtil.BaseActivityLaunche // props.setProperty("jogl.debug.GLProfile", "true"); // props.setProperty("jogl.debug.GLDrawable", "true"); // props.setProperty("jogl.debug.GLContext", "true"); - // props.setProperty("jogl.debug.GLMediaPlayer", "true"); + props.setProperty("jogl.debug.GLMediaPlayer", "true"); props.setProperty("jogl.debug.GLSLCode", "true"); // props.setProperty("jogl.debug.CapabilitiesChooser", "true"); // props.setProperty("jogl.debug.GLSLState", "true"); diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher1a.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher1a.java index 79b8b210d..c4eea084a 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher1a.java +++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivityLauncher1a.java @@ -57,7 +57,7 @@ public class MovieCubeActivityLauncher1a extends LauncherUtil.BaseActivityLaunch // props.setProperty("jogl.debug.GLProfile", "true"); // props.setProperty("jogl.debug.GLDrawable", "true"); // props.setProperty("jogl.debug.GLContext", "true"); - // props.setProperty("jogl.debug.GLMediaPlayer", "true"); + props.setProperty("jogl.debug.GLMediaPlayer", "true"); props.setProperty("jogl.debug.GLSLCode", "true"); // props.setProperty("jogl.debug.CapabilitiesChooser", "true"); // props.setProperty("jogl.debug.GLSLState", "true"); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java index 4e2e91320..9f367ef0b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.jogl.acore; import java.awt.Frame; @@ -36,11 +36,14 @@ import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; +import com.jogamp.common.os.Platform; +import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.Animator; @@ -49,7 +52,7 @@ import com.jogamp.opengl.util.Animator; public class TestShutdownCompleteAWT extends UITestCase { static long duration = 300; // ms - + protected void runTestGL() throws InterruptedException, InvocationTargetException { final Frame frame = new Frame("Gears AWT Test"); Assert.assertNotNull(frame); @@ -67,8 +70,8 @@ public class TestShutdownCompleteAWT extends UITestCase { frame.setSize(256, 256); frame.setVisible(true); }}); - - animator.setUpdateFPSFrames(60, System.err); + + animator.setUpdateFPSFrames(60, System.err); animator.start(); Assert.assertEquals(true, animator.isAnimating()); Assert.assertEquals(true, glCanvas.isVisible()); @@ -93,37 +96,70 @@ public class TestShutdownCompleteAWT extends UITestCase { }}); } - protected void oneLife() throws InterruptedException, InvocationTargetException { - long t0 = System.nanoTime(); + @AfterClass + public static void afterAll() { + if(waitForKey) { + UITestCase.waitForKey("Exit"); + } + } + + protected void oneLife(boolean glInfo) throws InterruptedException, InvocationTargetException { + final long t0 = Platform.currentTimeMicros(); GLProfile.initSingleton(); - long t1 = System.nanoTime(); - runTestGL(); - long t2 = System.nanoTime(); - GLProfile.shutdown(); - long t3 = System.nanoTime(); - System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); - System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); - System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(): "+ (t3-t2)/1e6 +"ms"); + final long t1 = Platform.currentTimeMicros(); + if(!initOnly) { + runTestGL(); + } + final long t2 = Platform.currentTimeMicros(); + if(glInfo) { + System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString()); + } + final long t3 = Platform.currentTimeMicros(); + GLProfile.shutdown(); + final long t4 = Platform.currentTimeMicros(); + System.err.println("Total: "+ (t4-t0)/1e3 +"ms"); + System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e3 +"ms"); + System.err.println(" Demo Code: "+ (t2-t1)/1e3 +"ms"); + System.err.println(" GLInfo: "+ (t3-t2)/1e3 +"ms"); + System.err.println(" GLProfile.shutdown(): "+ (t4-t3)/1e3 +"ms"); } - + @Test public void test01OneLife() throws InterruptedException, InvocationTargetException { - oneLife(); + oneLife(false); + } + + @Test + public void test02AnotherLifeWithGLInfo() throws InterruptedException, InvocationTargetException { + oneLife(true); } @Test - public void test01AnotherLife() throws InterruptedException, InvocationTargetException { - oneLife(); + public void test03AnotherLife() throws InterruptedException, InvocationTargetException { + oneLife(true); } - + @Test - public void test01TwoLifes() throws InterruptedException, InvocationTargetException { - oneLife(); - oneLife(); + public void test03TwoLifes() throws InterruptedException, InvocationTargetException { + oneLife(false); + oneLife(false); } - + + static boolean initOnly = false; + static boolean waitForKey = false; + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-wait")) { + waitForKey = true; + } else if(args[i].equals("-initOnly")) { + initOnly = true; + } + } + + if(waitForKey) { + UITestCase.waitForKey("Start"); + } String tstname = TestShutdownCompleteAWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java index 881d6c8de..e7d1cb8e9 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,26 +20,26 @@ * 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.test.junit.jogl.acore; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; +import com.jogamp.common.os.Platform; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; @@ -50,12 +50,12 @@ import com.jogamp.opengl.util.Animator; public class TestShutdownCompleteNEWT extends UITestCase { static long duration = 300; // ms - + protected void runTestGL(boolean onscreen) throws InterruptedException { GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2()); caps.setOnscreen(onscreen); caps.setPBuffer(!onscreen); - + GLWindow glWindow = GLWindow.create(caps); Assert.assertNotNull(glWindow); glWindow.setTitle("Gears NEWT Test"); @@ -81,59 +81,63 @@ public class TestShutdownCompleteNEWT extends UITestCase { glWindow.destroy(); } + @AfterClass + public static void afterAll() { + if(waitForKey) { + UITestCase.waitForKey("Exit"); + } + } + protected void oneLife(boolean glInfo) throws InterruptedException { if(waitForEach) { - waitForEnter(); + UITestCase.waitForKey("Start One Life"); } - long t0 = System.nanoTime(); + final long t0 = Platform.currentTimeMicros(); GLProfile.initSingleton(); - long t1 = System.nanoTime(); + final long t1 = Platform.currentTimeMicros(); if(!initOnly) { runTestGL(true); } - long t2 = System.nanoTime(); + final long t2 = Platform.currentTimeMicros(); if(glInfo) { System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString()); } - long t3 = System.nanoTime(); - GLProfile.shutdown(); - long t4 = System.nanoTime(); - System.err.println("Total: "+ (t3-t0)/1e6 +"ms"); - System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms"); - System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms"); - System.err.println(" GLProfile.shutdown(): "+ (t4-t3)/1e6 +"ms"); + final long t3 = Platform.currentTimeMicros(); + GLProfile.shutdown(); + final long t4 = Platform.currentTimeMicros(); + System.err.println("Total: "+ (t4-t0)/1e3 +"ms"); + System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e3 +"ms"); + System.err.println(" Demo Code: "+ (t2-t1)/1e3 +"ms"); + System.err.println(" GLInfo: "+ (t3-t2)/1e3 +"ms"); + System.err.println(" GLProfile.shutdown(): "+ (t4-t3)/1e3 +"ms"); } - + @Test public void test01OneLife() throws InterruptedException { + oneLife(false); + } + + @Test + public void test02AnotherLifeWithGLInfo() throws InterruptedException { oneLife(true); } @Test - public void test01AnotherLife() throws InterruptedException { - oneLife(false); + public void test03AnotherLife() throws InterruptedException { + oneLife(true); } - + @Test - public void test01TwoLifes() throws InterruptedException { + public void test03TwoLifes() throws InterruptedException { oneLife(false); oneLife(false); } - + static boolean initOnly = false; static boolean waitForEach = false; - - static void waitForEnter() { - BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - System.err.println("Press enter to continue"); - try { - System.err.println(stdin.readLine()); - } catch (IOException e) { } - } - + static boolean waitForKey = false; + public static void main(String args[]) throws IOException { - boolean waitForKey = false; - for(int i=0; i<args.length; i++) { if(args[i].equals("-wait")) { waitForKey = true; @@ -144,11 +148,11 @@ public class TestShutdownCompleteNEWT extends UITestCase { initOnly = true; } } - + if(waitForKey) { - waitForEnter(); + UITestCase.waitForKey("Start"); } - + String tstname = TestShutdownCompleteNEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java index 811e91886..5891bce0d 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquareES1.java @@ -23,10 +23,11 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende private boolean debug = false ; private boolean trace = false ; private int swapInterval = 0; - private float aspect = 1.0f; + private final float aspect = 1.0f; private boolean doRotate = true; private TileRendererBase tileRendererInUse = null; private boolean doRotateBeforePrinting; + private boolean flipVerticalInGLOrientation = false; long startTime = 0; long curTime = 0; @@ -38,17 +39,17 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende public RedSquareES1() { this.swapInterval = 1; } - + @Override public void addTileRendererNotify(TileRendererBase tr) { tileRendererInUse = tr; doRotateBeforePrinting = doRotate; - setDoRotation(false); + setDoRotation(false); } @Override public void removeTileRendererNotify(TileRendererBase tr) { tileRendererInUse = null; - setDoRotation(doRotateBeforePrinting); + setDoRotation(doRotateBeforePrinting); } @Override public void startTileRendering(TileRendererBase tr) { @@ -58,7 +59,7 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende public void endTileRendering(TileRendererBase tr) { System.err.println("RedSquareES1.endTileRendering: "+tr); } - + public void setDoRotation(boolean rotate) { this.doRotate = rotate; } public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) { this.forceFFPEmu = forceFFPEmu; @@ -66,7 +67,8 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende this.debugFFPEmu = debugFFPEmu; this.traceFFPEmu = traceFFPEmu; } - + public void setFlipVerticalInGLOrientation(boolean v) { flipVerticalInGLOrientation=v; } + // FIXME: we must add storage of the pointers in the GL state to // the GLImpl classes. The need for this can be seen by making // these variables method local instead of instance members. The @@ -93,12 +95,12 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende trace = false; } GL2ES1 gl = FixedFuncUtil.wrapFixedFuncEmul(_gl, ShaderSelectionMode.AUTO, null, forceFFPEmu, verboseFFPEmu); - + if(debug) { try { // Debug .. gl = (GL2ES1) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, gl, null) ); - } catch (Exception e) {e.printStackTrace();} + } catch (Exception e) {e.printStackTrace();} } if(trace) { try { @@ -139,34 +141,37 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende @Override public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { final GL2ES1 gl = glad.getGL().getGL2ES1(); - if(-1 != swapInterval) { + if(-1 != swapInterval) { gl.setSwapInterval(swapInterval); } reshapeImpl(gl, x, y, width, height, width, height); } - + @Override public void reshapeTile(TileRendererBase tr, - int tileX, int tileY, int tileWidth, int tileHeight, + int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { final GL2ES1 gl = tr.getAttachedDrawable().getGL().getGL2ES1(); gl.setSwapInterval(0); reshapeImpl(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight); } - + void reshapeImpl(GL2ES1 gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { System.err.println(Thread.currentThread()+" RedSquareES1.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse); - + // Set location in front of camera gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); gl.glLoadIdentity(); - + if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { + gl.glScalef(1f, -1f, 1f); + } + // compute projection parameters 'normal' perspective final float fovy=45f; final float aspect2 = ( (float) imageWidth / (float) imageHeight ) / aspect; final float zNear=1f; final float zFar=100f; - + // compute projection parameters 'normal' frustum final float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear; final float bottom=-1.0f*top; @@ -174,18 +179,22 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende final float right=aspect2*top; final float w = right - left; final float h = top - bottom; - + // compute projection parameters 'tiled' final float l = left + tileX * w / imageWidth; final float r = l + tileWidth * w / imageWidth; final float b = bottom + tileY * h / imageHeight; final float t = b + tileHeight * h / imageHeight; - + gl.glFrustumf(l, r, b, t, zNear, zFar); // gl.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f); + + gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + gl.glLoadIdentity(); + System.err.println(Thread.currentThread()+" RedSquareES1.reshape FIN"); } - + @Override public void display(GLAutoDrawable drawable) { curTime = System.currentTimeMillis(); @@ -201,11 +210,9 @@ public class RedSquareES1 implements GLEventListener, TileRendererBase.TileRende gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -10); - if(doRotate) { - float ang = ((float) (curTime - startTime) * 360.0f) / 4000.0f; - gl.glRotatef(ang, 0, 0, 1); - gl.glRotatef(ang, 0, 1, 0); - } + float ang = doRotate ? ((curTime - startTime) * 360.0f) / 4000.0f : 1f; + gl.glRotatef(ang, 0, 0, 1); + gl.glRotatef(ang, 0, 1, 0); // Draw a square gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java index ff5de7cb0..d85d38618 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java @@ -356,8 +356,6 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL } st.useProgram(gl, true); - pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); // compute projection parameters 'normal' float left, right, bottom, top; @@ -386,17 +384,19 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL final float _w = r - l; final float _h = t - b; if(verbose) { - System.err.println(">> angle "+sid()+" "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); + System.err.println(">> GearsES2 "+sid()+", angle "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h+", v-flip "+flipVerticalInGLOrientation); } + pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { + pmvMatrix.glScalef(1f, -1f, 1f); + } pmvMatrix.glFrustumf(l, r, b, t, 5.0f, 200.0f); pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); pmvMatrix.glLoadIdentity(); pmvMatrix.glTranslatef(0.0f, 0.0f, -40.0f); - if(flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { - pmvMatrix.glRotatef(180f, 1.0f, 0.0f, 0.0f); - } st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); @@ -490,15 +490,18 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL return; } - gl.glEnable(GL.GL_CULL_FACE); + // Only possible if we do not flip the projection matrix + final boolean enableCullFace = ! ( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ); + if( enableCullFace ) { + gl.glEnable(GL.GL_CULL_FACE); + } st.useProgram(gl, true); pmvMatrix.glPushMatrix(); pmvMatrix.glTranslatef(panX, panY, panZ); - final float flipVF = ( flipVerticalInGLOrientation && drawable.isGLOriented() ) ? -1f : 1f; - pmvMatrix.glRotatef(flipVF*view_rotx, 1.0f, 0.0f, 0.0f); - pmvMatrix.glRotatef(flipVF*view_roty, 0.0f, 1.0f, 0.0f); - pmvMatrix.glRotatef(flipVF*view_rotz, 0.0f, 0.0f, 1.0f); + pmvMatrix.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); + pmvMatrix.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); + pmvMatrix.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); gear1.draw(gl, -3.0f, -2.0f, 1f * angle - 0f); gear2.draw(gl, 3.1f, -2.0f, -2f * angle - 9.0f); @@ -506,7 +509,9 @@ public class GearsES2 implements GLEventListener, TileRendererBase.TileRendererL pmvMatrix.glPopMatrix(); st.useProgram(gl, false); - gl.glDisable(GL.GL_CULL_FACE); + if( enableCullFace ) { + gl.glDisable(GL.GL_CULL_FACE); + } } @Override diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java index 8f27e19c4..c1ccf7c39 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java @@ -153,7 +153,7 @@ public class MovieCube implements GLEventListener { return; } System.err.println("MC "+e); - int pts0 = mPlayer.getVideoPTS(); + final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS(); int pts1 = 0; switch(e.getKeyCode()) { case KeyEvent.VK_RIGHT: pts1 = pts0 + 1000; break; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java index 1a9914bb7..ddf5c709c 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java @@ -150,7 +150,8 @@ public class MovieSimple implements GLEventListener { if(y>winHeight/2) { final float dp = (float)(x-prevMouseX)/(float)winWidth; - mPlayer.seek(mPlayer.getVideoPTS() + (int) (mPlayer.getDuration() * dp)); + final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS(); + mPlayer.seek(pts0 + (int) (mPlayer.getDuration() * dp)); } else { mPlayer.play(); rotate = 1; @@ -174,7 +175,7 @@ public class MovieSimple implements GLEventListener { return; } System.err.println("MC "+e); - int pts0 = mPlayer.getVideoPTS(); + final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS(); int pts1 = 0; switch(e.getKeyCode()) { case KeyEvent.VK_RIGHT: pts1 = pts0 + 1000; break; @@ -372,9 +373,7 @@ public class MovieSimple implements GLEventListener { if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) { throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer); } - if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) { - throw new IllegalStateException("mPlayer has no VID/stream selected: "+mPlayer); - } + final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID(); resetGLState = false; zoom0 = orthoProjection ? 0f : -2.5f; @@ -397,10 +396,20 @@ public class MovieSimple implements GLEventListener { } System.out.println("p1 "+mPlayer+", shared "+mPlayerShared); final TextureFrame frame = mPlayer.getLastTexture(); - if( null == frame ) { - throw new InternalError("XXX: "+mPlayer); + if( null != frame ) { + if( !hasVideo ) { + throw new InternalError("XXX: "+mPlayer); + } + tex = frame.getTexture(); + if( null == tex ) { + throw new InternalError("XXX: "+mPlayer); + } + } else { + tex = null; + if( hasVideo ) { + throw new InternalError("XXX: "+mPlayer); + } } - tex = mPlayer.getLastTexture().getTexture(); if(!mPlayerShared) { mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } ); } @@ -413,74 +422,76 @@ public class MovieSimple implements GLEventListener { throw new GLException(glex); } - initShader(gl); + if( hasVideo ) { + initShader(gl); - // Push the 1st uniform down the path - st.useProgram(gl, true); + // Push the 1st uniform down the path + st.useProgram(gl, true); - int[] viewPort = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight()}; - pmvMatrix = new PMVMatrix(); - reshapePMV(viewPort[2], viewPort[3]); - pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); - if(!st.uniform(gl, pmvMatrixUniform)) { - throw new GLException("Error setting PMVMatrix in shader: "+st); - } - if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) { - throw new GLException("Error setting mgl_ActiveTexture in shader: "+st); - } + int[] viewPort = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight()}; + pmvMatrix = new PMVMatrix(); + reshapePMV(viewPort[2], viewPort[3]); + pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); + if(!st.uniform(gl, pmvMatrixUniform)) { + throw new GLException("Error setting PMVMatrix in shader: "+st); + } + if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) { + throw new GLException("Error setting mgl_ActiveTexture in shader: "+st); + } - float dWidth = drawable.getWidth(); - float dHeight = drawable.getHeight(); - float mWidth = mPlayer.getWidth(); - float mHeight = mPlayer.getHeight(); - float mAspect = mWidth/mHeight; - System.err.println("XXX0: mov aspect: "+mAspect); - float xs, ys; - if(orthoProjection) { - if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { - xs = mWidth/2f; ys = xs / mAspect; + float dWidth = drawable.getWidth(); + float dHeight = drawable.getHeight(); + float mWidth = mPlayer.getWidth(); + float mHeight = mPlayer.getHeight(); + float mAspect = mWidth/mHeight; + System.err.println("XXX0: mov aspect: "+mAspect); + float xs, ys; + if(orthoProjection) { + if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { + xs = mWidth/2f; ys = xs / mAspect; + } else { + xs = dWidth/2f; ys = xs / mAspect; // w>h + } } else { - xs = dWidth/2f; ys = xs / mAspect; // w>h + if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { + xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ; + } else { + xs = mAspect; ys = 1f; // b>h + } } - } else { - if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { - xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ; - } else { - xs = mAspect; ys = 1f; // b>h + verts = new float[] { -1f*xs, -1f*ys, 0f, // LB + 1f*xs, 1f*ys, 0f // RT + }; + { + System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]); + System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]); + float[] winLB = new float[3]; + float[] winRT = new float[3]; + pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0); + pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0); + System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]); + System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]); } - } - verts = new float[] { -1f*xs, -1f*ys, 0f, // LB - 1f*xs, 1f*ys, 0f // RT - }; - { - System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]); - System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]); - float[] winLB = new float[3]; - float[] winRT = new float[3]; - pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0); - pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0); - System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]); - System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]); - } - interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW); - { - interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER); - interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER); - interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER); - } - updateInterleavedVBO(gl, tex); + interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW); + { + interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER); + interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER); + interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER); + } + updateInterleavedVBO(gl, tex); - st.ownAttribute(interleavedVBO, true); - gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f); + st.ownAttribute(interleavedVBO, true); + gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f); - gl.glEnable(GL2ES2.GL_DEPTH_TEST); + gl.glEnable(GL2ES2.GL_DEPTH_TEST); - st.useProgram(gl, false); + st.useProgram(gl, false); - // Let's show the completed shader state .. - System.out.println("iVBO: "+interleavedVBO); - System.out.println(st); + // Let's show the completed shader state .. + System.out.println("iVBO: "+interleavedVBO); + System.out.println(st); + } if(!mPlayerShared) { mPlayer.play(); @@ -697,6 +708,7 @@ public class MovieSimple implements GLEventListener { int textureCount = 3; // default - threaded boolean ortho = true; boolean zoom = false; + boolean _loopEOS = false; boolean forceES2 = false; boolean forceES3 = false; @@ -742,6 +754,8 @@ public class MovieSimple implements GLEventListener { ortho=false; } else if(args[i].equals("-zoom")) { zoom=true; + } else if(args[i].equals("-loop")) { + _loopEOS=true; } else if(args[i].equals("-url")) { i++; url_s = args[i]; @@ -757,6 +771,7 @@ public class MovieSimple implements GLEventListener { } origSize = _origSize; } + final boolean loopEOS = _loopEOS; final URI streamLoc; if( null != url_s ) { streamLoc = new URI(url_s); @@ -827,6 +842,7 @@ public class MovieSimple implements GLEventListener { System.err.println("MovieSimple AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when); System.err.println("MovieSimple State: "+mp); if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) { + System.err.println("MovieSimple State: CHANGE_SIZE"); if( origSize ) { window.setSize(mp.getWidth(), mp.getHeight()); } @@ -834,11 +850,14 @@ public class MovieSimple implements GLEventListener { ms.resetGLState(); } if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) { - if( GLMediaPlayer.STREAM_ID_NONE != ms.mPlayer.getVID() ) { - window.addGLEventListener(ms); - anim.setUpdateFPSFrames(60, System.err); - anim.resetFPSCounter(); - } else { + System.err.println("MovieSimple State: INIT"); + // Use GLEventListener in all cases [A+V, V, A] + window.addGLEventListener(ms); + anim.setUpdateFPSFrames(60, System.err); + anim.resetFPSCounter(); + /** + * Kick off player w/o GLEventListener, i.e. for audio only. + * try { ms.mPlayer.initGL(null); } catch (Exception e) { @@ -848,12 +867,38 @@ public class MovieSimple implements GLEventListener { } ms.mPlayer.play(); System.out.println("play.1 "+ms.mPlayer); + */ + } + boolean destroy = false; + Throwable err = null; + + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) { + err = ms.mPlayer.getStreamException(); + if( null != err ) { + System.err.println("MovieSimple State: EOS + Exception"); + destroy = true; + } else { + System.err.println("MovieSimple State: EOS"); + if( loopEOS ) { + ms.mPlayer.seek(0); + ms.mPlayer.play(); + } else { + destroy = true; + } + } + } + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) { + err = ms.mPlayer.getStreamException(); + if( null != err ) { + System.err.println("MovieSimple State: ERR + Exception"); + } else { + System.err.println("MovieSimple State: ERR"); } + destroy = true; } - if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) { - final StreamException se = ms.mPlayer.getStreamException(); - if( null != se ) { - se.printStackTrace(); + if( destroy ) { + if( null != err ) { + err.printStackTrace(); } destroyWindow(); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java index 3a9cf8f98..46e39bebf 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2GLJPanelAWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.jogl.demos.es2.awt; import java.awt.AWTException; @@ -63,12 +63,14 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { static Dimension wsize, rwsize=null; static boolean forceES2 = false; static boolean forceGL3 = false; + static boolean forceGLFFP = false; static boolean shallUsePBuffer = false; static boolean shallUseBitmap = false; static boolean useMSAA = false; static int swapInterval = 0; static boolean useAnimator = true; static boolean manualTest = false; + static boolean skipGLOrientationVerticalFlip = false; @BeforeClass public static void initClass() { @@ -93,9 +95,9 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { } catch( Throwable throwable ) { throwable.printStackTrace(); Assume.assumeNoException( throwable ); - } + } } - + protected void runTestGL(GLCapabilities caps) throws AWTException, InterruptedException, InvocationTargetException { @@ -104,13 +106,18 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { final GLJPanel glJPanel = new GLJPanel(caps); Assert.assertNotNull(glJPanel); + glJPanel.setSkipGLOrientationVerticalFlip(skipGLOrientationVerticalFlip); glJPanel.setMinimumSize(wsize); glJPanel.setPreferredSize(wsize); glJPanel.setSize(wsize); - if( caps.isBitmap() ) { - glJPanel.addGLEventListener(new Gears(swapInterval)); + if( caps.isBitmap() || caps.getGLProfile().isGL2() ) { + final Gears gears = new Gears(swapInterval); + gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); + glJPanel.addGLEventListener(gears); } else { - glJPanel.addGLEventListener(new GearsES2(swapInterval)); + final GearsES2 gears = new GearsES2(swapInterval); + gears.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); + glJPanel.addGLEventListener(gears); } final SnapshotGLEventListener snap = new SnapshotGLEventListener(); glJPanel.addGLEventListener(snap); @@ -135,17 +142,17 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter)).addTo(glJPanel); new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter)).addTo(frame); - + snap.setMakeSnapshot(); - + if( null != rwsize ) { - Thread.sleep(500); // 500ms delay + Thread.sleep(500); // 500ms delay setFrameSize(frame, true, rwsize); System.err.println("window resize pos/siz: "+glJPanel.getX()+"/"+glJPanel.getY()+" "+glJPanel.getWidth()+"x"+glJPanel.getHeight()); } - + snap.setMakeSnapshot(); - + final long t0 = System.currentTimeMillis(); long t1 = t0; boolean triggerSnap = false; @@ -187,6 +194,8 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { glp = GLProfile.get(GLProfile.GL3); } else if(forceES2) { glp = GLProfile.get(GLProfile.GLES2); + } else if(forceGLFFP) { + glp = GLProfile.getMaxFixedFunc(true); } else { glp = GLProfile.getGL2ES2(); } @@ -216,7 +225,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { caps.setSampleBuffers(true); runTestGL(caps); } - + @Test public void test03_PbufferNorm() throws AWTException, InterruptedException, InvocationTargetException @@ -228,7 +237,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { caps.setPBuffer(true); runTestGL(caps); } - + @Test public void test04_PbufferMsaa() throws AWTException, InterruptedException, InvocationTargetException @@ -242,7 +251,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { caps.setPBuffer(true); runTestGL(caps); } - + @Test public void test05_BitmapNorm() throws AWTException, InterruptedException, InvocationTargetException @@ -254,7 +263,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { caps.setBitmap(true); runTestGL(caps); } - + @Test public void test06_BitmapMsaa() throws AWTException, InterruptedException, InvocationTargetException @@ -268,7 +277,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { caps.setBitmap(true); runTestGL(caps); } - + @Test public void test20_GLES2() throws AWTException, InterruptedException, InvocationTargetException @@ -276,7 +285,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { if( manualTest ) { return; } - + if( !GLProfile.isAvailable(GLProfile.GLES2) ) { System.err.println("GLES2 n/a"); return; @@ -285,7 +294,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { final GLCapabilities caps = new GLCapabilities( glp ); runTestGL(caps); } - + @Test public void test30_GL3() throws AWTException, InterruptedException, InvocationTargetException @@ -293,7 +302,7 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { if( manualTest ) { return; } - + if( !GLProfile.isAvailable(GLProfile.GL3) ) { System.err.println("GL3 n/a"); return; @@ -302,12 +311,12 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { final GLCapabilities caps = new GLCapabilities( glp ); runTestGL(caps); } - + static long duration = 500; // ms public static void main(String args[]) { int w=640, h=480, rw=-1, rh=-1; - + for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { i++; @@ -316,6 +325,8 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { forceES2 = true; } else if(args[i].equals("-gl3")) { forceGL3 = true; + } else if(args[i].equals("-glFFP")) { + forceGLFFP = true; } else if(args[i].equals("-width")) { i++; w = MiscUtils.atoi(args[i], w); @@ -328,6 +339,8 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { } else if(args[i].equals("-rheight")) { i++; rh = MiscUtils.atoi(args[i], rh); + } else if(args[i].equals("-userVFlip")) { + skipGLOrientationVerticalFlip = true; } else if(args[i].equals("-vsync")) { i++; swapInterval = MiscUtils.atoi(args[i], swapInterval); @@ -347,18 +360,20 @@ public class TestGearsES2GLJPanelAWT extends UITestCase { if( 0 < rw && 0 < rh ) { rwsize = new Dimension(rw, rh); } - + System.err.println("size "+wsize); System.err.println("resize "+rwsize); + System.err.println("userVFlip "+skipGLOrientationVerticalFlip); System.err.println("swapInterval "+swapInterval); System.err.println("forceES2 "+forceES2); System.err.println("forceGL3 "+forceGL3); + System.err.println("forceGLFFP "+forceGLFFP); System.err.println("useMSAA "+useMSAA); System.err.println("useAnimator "+useAnimator); System.err.println("shallUsePBuffer "+shallUsePBuffer); System.err.println("shallUseBitmap "+shallUseBitmap); System.err.println("manualTest "+manualTest); - + org.junit.runner.JUnitCore.main(TestGearsES2GLJPanelAWT.class.getName()); } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java index 031d6a1c1..0d71c7ad0 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java @@ -27,17 +27,19 @@ import com.jogamp.opengl.util.TileRendererBase; * This version is equal to Brian Paul's version 1.2 1999/10/21 */ public class Gears implements GLEventListener, TileRendererBase.TileRendererListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; + private float view_rotx = 20.0f, view_roty = 30.0f; + private final float view_rotz = 0.0f; private int gear1=0, gear2=0, gear3=0; private float angle = 0.0f; private boolean doRotate = true; - private int swapInterval; - private MouseListener gearsMouse = new GearsMouseAdapter(); - private KeyListener gearsKeys = new GearsKeyAdapter(); + private final int swapInterval; + private final MouseListener gearsMouse = new GearsMouseAdapter(); + private final KeyListener gearsKeys = new GearsKeyAdapter(); private TileRendererBase tileRendererInUse = null; private boolean doRotateBeforePrinting; private boolean verbose = true; - + private boolean flipVerticalInGLOrientation = false; + // private boolean mouseRButtonDown = false; private int prevMouseX, prevMouseY; @@ -48,17 +50,17 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList public Gears() { this.swapInterval = 1; } - + @Override public void addTileRendererNotify(TileRendererBase tr) { tileRendererInUse = tr; doRotateBeforePrinting = doRotate; - setDoRotation(false); + setDoRotation(false); } @Override public void removeTileRendererNotify(TileRendererBase tr) { tileRendererInUse = null; - setDoRotation(doRotateBeforePrinting); + setDoRotation(doRotateBeforePrinting); } @Override public void startTileRendering(TileRendererBase tr) { @@ -68,10 +70,11 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList public void endTileRendering(TileRendererBase tr) { System.err.println("Gears.endTileRendering: "+tr); } - + public void setDoRotation(boolean rotate) { doRotate = rotate; } public void setVerbose(boolean v) { verbose = v; } - + public void setFlipVerticalInGLOrientation(boolean v) { flipVerticalInGLOrientation=v; } + public void setGears(int g1, int g2, int g3) { gear1 = g1; gear2 = g2; @@ -98,24 +101,24 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList GL2 gl = drawable.getGL().getGL2(); init(gl); - + final Object upstreamWidget = drawable.getUpstreamWidget(); - if (upstreamWidget instanceof Window) { + if (upstreamWidget instanceof Window) { final Window window = (Window) upstreamWidget; window.addMouseListener(gearsMouse); window.addKeyListener(gearsKeys); } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) { final java.awt.Component comp = (java.awt.Component) upstreamWidget; new AWTMouseAdapter(gearsMouse).addTo(comp); - new AWTKeyAdapter(gearsKeys).addTo(comp); + new AWTKeyAdapter(gearsKeys).addTo(comp); } } - + public void init(GL2 gl) { - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 0.7f }; - float green[] = { 0.0f, 0.8f, 0.2f, 0.7f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 0.7f }; + final float lightPos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; + final float red[] = { 0.8f, 0.1f, 0.0f, 0.7f }; + final float green[] = { 0.0f, 0.8f, 0.2f, 0.7f }; + final float blue[] = { 0.2f, 0.2f, 1.0f, 0.7f }; System.err.println(Thread.currentThread()+" Gears.init: tileRendererInUse "+tileRendererInUse); if(verbose) { @@ -124,13 +127,16 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList System.err.println("INIT GL IS: " + gl.getClass().getName()); System.err.println(JoglVersion.getGLStrings(gl, null, false).toString()); } - - gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, pos, 0); - gl.glEnable(GL2.GL_CULL_FACE); + + gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPos, 0); + if( ! ( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) ) { + // Only possible if we do not flip the projection matrix + gl.glEnable(GL2.GL_CULL_FACE); + } gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_LIGHT0); gl.glEnable(GL2.GL_DEPTH_TEST); - + /* make the gears */ if(0>=gear1) { gear1 = gl.glGenLists(1); @@ -142,7 +148,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } else { System.err.println("gear1 list reused: "+gear1); } - + if(0>=gear2) { gear2 = gl.glGenLists(1); gl.glNewList(gear2, GL2.GL_COMPILE); @@ -153,7 +159,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } else { System.err.println("gear2 list reused: "+gear2); } - + if(0>=gear3) { gear3 = gl.glGenLists(1); gl.glNewList(gear3, GL2.GL_COMPILE); @@ -164,14 +170,14 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } else { System.err.println("gear3 list reused: "+gear3); } - + gl.glEnable(GL2.GL_NORMALIZE); } - + @Override public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { final GL2 gl = glad.getGL().getGL2(); - if(-1 != swapInterval) { + if(-1 != swapInterval) { gl.setSwapInterval(swapInterval); } reshape(gl, x, y, width, height, width, height); @@ -179,7 +185,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList @Override public void reshapeTile(TileRendererBase tr, - int tileX, int tileY, int tileWidth, int tileHeight, + int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { final GL2 gl = tr.getAttachedDrawable().getGL().getGL2(); gl.setSwapInterval(0); @@ -193,13 +199,9 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList if( msaa ) { gl.glEnable(GL.GL_MULTISAMPLE); } - - gl.glMatrixMode(GL2.GL_PROJECTION); - gl.glLoadIdentity(); - // compute projection parameters 'normal' - float left, right, bottom, top; + float left, right, bottom, top; if( imageHeight > imageWidth ) { float a = (float)imageHeight / (float)imageWidth; left = -1.0f; @@ -215,24 +217,31 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } final float w = right - left; final float h = top - bottom; - + // compute projection parameters 'tiled' final float l = left + tileX * w / imageWidth; final float r = l + tileWidth * w / imageWidth; + final float b = bottom + tileY * h / imageHeight; final float t = b + tileHeight * h / imageHeight; final float _w = r - l; final float _h = t - b; if(verbose) { - System.err.println(">> angle "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h); + System.err.println(">> Gears angle "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h+", v-flip "+flipVerticalInGLOrientation); + } + + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glLoadIdentity(); + if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { + gl.glScalef(1f, -1f, 1f); } gl.glFrustum(l, r, b, t, 5.0f, 60.0f); - gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -40.0f); - + if( msaa ) { gl.glDisable(GL.GL_MULTISAMPLE); } @@ -243,7 +252,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList System.err.println(Thread.currentThread()+" Gears.dispose: tileRendererInUse "+tileRendererInUse); try { final Object upstreamWidget = drawable.getUpstreamWidget(); - if (upstreamWidget instanceof Window) { + if (upstreamWidget instanceof Window) { final Window window = (Window) upstreamWidget; window.removeMouseListener(gearsMouse); window.removeKeyListener(gearsKeys); @@ -261,7 +270,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList if( msaa ) { gl.glEnable(GL.GL_MULTISAMPLE); } - + if( null == tileRendererInUse ) { gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } else { @@ -270,7 +279,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList // Special handling for the case where the GLJPanel is translucent // and wants to be composited with other Java 2D content - if (GLProfile.isAWTAvailable() && + if (GLProfile.isAWTAvailable() && (drawable instanceof javax.media.opengl.awt.GLJPanel) && !((javax.media.opengl.awt.GLJPanel) drawable).isOpaque() && ((javax.media.opengl.awt.GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { @@ -310,31 +319,31 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - + // Place the first gear and call its display list gl.glPushMatrix(); gl.glTranslatef(-3.0f, -2.0f, 0.0f); gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); gl.glCallList(gear1); gl.glPopMatrix(); - + // Place the second gear and call its display list gl.glPushMatrix(); gl.glTranslatef(3.1f, -2.0f, 0.0f); gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); gl.glCallList(gear2); gl.glPopMatrix(); - + // Place the third gear and call its display list gl.glPushMatrix(); gl.glTranslatef(-3.1f, 4.2f, 0.0f); gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); gl.glCallList(gear3); gl.glPopMatrix(); - + // Remember that every push needs a pop; this one is paired with // rotating the entire gear assembly - gl.glPopMatrix(); + gl.glPopMatrix(); } public static void gear(GL2 gl, @@ -352,9 +361,9 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList r0 = inner_radius; r1 = outer_radius - tooth_depth / 2.0f; r2 = outer_radius + tooth_depth / 2.0f; - + da = 2.0f * (float) Math.PI / teeth / 4.0f; - + gl.glShadeModel(GL2.GL_FLAT); gl.glNormal3f(0.0f, 0.0f, 1.0f); @@ -385,7 +394,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); } gl.glEnd(); - + /* draw back face */ gl.glBegin(GL2.GL_QUAD_STRIP); for (i = 0; i <= teeth; i++) @@ -397,7 +406,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); } gl.glEnd(); - + /* draw back sides of teeth */ gl.glBegin(GL2.GL_QUADS); for (i = 0; i < teeth; i++) @@ -409,7 +418,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); } gl.glEnd(); - + /* draw outward faces of teeth */ gl.glBegin(GL2.GL_QUAD_STRIP); for (i = 0; i < teeth; i++) @@ -438,9 +447,9 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); gl.glEnd(); - + gl.glShadeModel(GL2.GL_SMOOTH); - + /* draw inside radius cylinder */ gl.glBegin(GL2.GL_QUAD_STRIP); for (i = 0; i <= teeth; i++) @@ -453,7 +462,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList gl.glEnd(); } - class GearsKeyAdapter extends KeyAdapter { + class GearsKeyAdapter extends KeyAdapter { public void keyPressed(KeyEvent e) { int kc = e.getKeyCode(); if(KeyEvent.VK_LEFT == kc) { @@ -467,7 +476,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } } } - + class GearsMouseAdapter extends MouseAdapter { public void mousePressed(MouseEvent e) { prevMouseX = e.getX(); @@ -476,13 +485,13 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList // mouseRButtonDown = true; } } - + public void mouseReleased(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { // mouseRButtonDown = false; } } - + public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); @@ -501,7 +510,7 @@ public class Gears implements GLEventListener, TileRendererBase.TileRendererList } float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)width); float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)height); - + prevMouseX = x; prevMouseY = y; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java index e0d0e00dc..3dd3a83c8 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT.java @@ -100,11 +100,12 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { public static void releaseClass() { } - protected void runTestGL(GLCapabilities caps, boolean layered) throws InterruptedException, InvocationTargetException { + protected void runTestGL(GLCapabilities caps, boolean layered, boolean skipGLOrientationVerticalFlip) throws InterruptedException, InvocationTargetException { final int layerStepX = width/6, layerStepY = height/6; final Dimension glc_sz = new Dimension(layered ? width - 2*layerStepX : width/2, layered ? height - 2*layerStepY : height); final GLJPanel glJPanel1 = new GLJPanel(caps); Assert.assertNotNull(glJPanel1); + glJPanel1.setSkipGLOrientationVerticalFlip(skipGLOrientationVerticalFlip); glJPanel1.setMinimumSize(glc_sz); glJPanel1.setPreferredSize(glc_sz); if( layered ) { @@ -112,10 +113,15 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { } else { glJPanel1.setBounds(0, 0, glc_sz.width, glc_sz.height); } - glJPanel1.addGLEventListener(new Gears()); + { + final Gears demo = new Gears(); + demo.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); + glJPanel1.addGLEventListener(demo); + } final GLJPanel glJPanel2 = new GLJPanel(caps); Assert.assertNotNull(glJPanel2); + glJPanel2.setSkipGLOrientationVerticalFlip(skipGLOrientationVerticalFlip); glJPanel2.setMinimumSize(glc_sz); glJPanel2.setPreferredSize(glc_sz); if( layered ) { @@ -123,8 +129,11 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { } else { glJPanel2.setBounds(0, 0, glc_sz.width, glc_sz.height); } - glJPanel2.addGLEventListener(new RedSquareES1()); - // glJPanel2.addGLEventListener(new Gears()); + { + final RedSquareES1 demo = new RedSquareES1(); + demo.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); + glJPanel2.addGLEventListener(demo); + } final JComponent demoPanel; if( layered ) { @@ -293,43 +302,83 @@ public class TestTiledPrintingGearsSwingAWT extends TiledPrintingAWTBase { } @Test - public void test01_aa0() throws InterruptedException, InvocationTargetException { + public void test01_flip1_aa0() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + runTestGL(caps, false, false); + } + + @Test + public void test01_flip1_aa0_layered() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + caps.setAlphaBits(8); + runTestGL(caps, true, false); + } + + @Test + public void test01_flip1_aa0_bitmap() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS == Platform.getOSType() ) { + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + runTestGL(caps, false, false); + } // issues w/ AMD catalyst driver and pixmap surface .. + } + + @Test + public void test01_flip1_aa0_bitmap_layered() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS == Platform.getOSType() ) { + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + caps.setAlphaBits(8); + runTestGL(caps, true, false); + } // issues w/ AMD catalyst driver and pixmap surface .. + } + + @Test + public void test02_flip1_aa8() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + caps.setSampleBuffers(true); + caps.setNumSamples(8); + runTestGL(caps, false, false); + } + + @Test + public void test11_flip0_aa0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); - runTestGL(caps, false); + runTestGL(caps, false, true); } @Test - public void test01_aa0_layered() throws InterruptedException, InvocationTargetException { + public void test11_flip0_aa0_layered() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); caps.setAlphaBits(8); - runTestGL(caps, true); + runTestGL(caps, true, true); } @Test - public void test01_aa0_bitmap() throws InterruptedException, InvocationTargetException { + public void test11_flip0_aa0_bitmap() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS == Platform.getOSType() ) { GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); - runTestGL(caps, false); + runTestGL(caps, false, true); } // issues w/ AMD catalyst driver and pixmap surface .. } @Test - public void test01_aa0_bitmap_layered() throws InterruptedException, InvocationTargetException { + public void test11_flip0_aa0_bitmap_layered() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS == Platform.getOSType() ) { GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); caps.setAlphaBits(8); - runTestGL(caps, true); + runTestGL(caps, true, true); } // issues w/ AMD catalyst driver and pixmap surface .. } @Test - public void test02_aa8() throws InterruptedException, InvocationTargetException { + public void test12_flip0_aa8() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); caps.setSampleBuffers(true); caps.setNumSamples(8); - runTestGL(caps, false); + runTestGL(caps, false, true); } static long duration = 500; // ms diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT2.java index 2d4973d6b..29bf8a6c3 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledPrintingGearsSwingAWT2.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.jogl.tile; import java.awt.BorderLayout; @@ -77,7 +77,7 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { static boolean waitForKey = false; static GLProfile glp; static int width, height; - + @BeforeClass public static void initClass() { if(GLProfile.isAvailable(GLProfile.GL2)) { @@ -95,16 +95,21 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { @AfterClass public static void releaseClass() { } - - protected void runTestGL(GLCapabilities caps, final boolean addLayout, boolean layered, boolean useAnim) throws InterruptedException, InvocationTargetException { + + protected void runTestGL(GLCapabilities caps, final boolean addLayout, boolean layered, boolean skipGLOrientationVerticalFlip, boolean useAnim) throws InterruptedException, InvocationTargetException { final Dimension glc_sz = new Dimension(width, height); final GLJPanel glJPanel1 = new GLJPanel(caps); - Assert.assertNotNull(glJPanel1); + Assert.assertNotNull(glJPanel1); + glJPanel1.setSkipGLOrientationVerticalFlip(skipGLOrientationVerticalFlip); glJPanel1.setMinimumSize(glc_sz); glJPanel1.setPreferredSize(glc_sz); glJPanel1.setBounds(0, 0, glc_sz.width, glc_sz.height); - glJPanel1.addGLEventListener(new Gears()); - + { + final Gears demo = new Gears(); + demo.setFlipVerticalInGLOrientation(skipGLOrientationVerticalFlip); + glJPanel1.addGLEventListener(demo); + } + final JComponent tPanel, demoPanel; if( layered ) { glJPanel1.setOpaque(true); @@ -133,13 +138,13 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { demoPanel = new JPanel(); demoPanel.add(glJPanel1); } else { - demoPanel = glJPanel1; + demoPanel = glJPanel1; } } - + final JFrame frame = new JFrame("Swing Print"); Assert.assertNotNull(frame); - + final ActionListener print72DPIAction = new ActionListener() { public void actionPerformed(ActionEvent e) { doPrintManual(frame, 72, 0, -1, -1); @@ -158,7 +163,7 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { print150DPIButton.addActionListener(print150DPIAction); final Button print300DPIButton = new Button("300dpi"); print300DPIButton.addActionListener(print300DPIAction); - + final JPanel printPanel = new JPanel(); printPanel.add(print72DPIButton); printPanel.add(print150DPIButton); @@ -169,7 +174,7 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { eastPanel.add(new Label("East")); final JPanel westPanel = new JPanel(); westPanel.add(new Label("West")); - + final Animator animator = useAnim ? new Animator() : null; if( null != animator ) { animator.add(glJPanel1); @@ -181,7 +186,7 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { SwingUtilities.invokeAndWait(new Runnable() { public void run() { - final Container fcont = frame.getContentPane(); + final Container fcont = frame.getContentPane(); if( addLayout ) { fcont.setLayout(new BorderLayout()); fcont.add(printPanel, BorderLayout.NORTH); @@ -201,12 +206,12 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { } frame.setVisible(true); } } ) ; - + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glJPanel1, true)); - + if( null != animator ) { - animator.setUpdateFPSFrames(60, System.err); + animator.setUpdateFPSFrames(60, System.err); animator.start(); Assert.assertEquals(true, animator.isAnimating()); } @@ -226,11 +231,11 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { } t1 = System.currentTimeMillis(); } - + Assert.assertNotNull(frame); Assert.assertNotNull(glJPanel1); - if( null != animator ) { + if( null != animator ) { animator.stop(); Assert.assertEquals(false, animator.isAnimating()); } @@ -248,69 +253,133 @@ public class TestTiledPrintingGearsSwingAWT2 extends TiledPrintingAWTBase { } @Test - public void test01_norm_layout0_layered0() throws InterruptedException, InvocationTargetException { + public void test001_flip1_norm_layout0_layered0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); - runTestGL(caps, false /* addLayout */, false /* layered */, false /* useAnim */); + runTestGL(caps, false /* addLayout */, false /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test02_norm_layout1_layered0() throws InterruptedException, InvocationTargetException { + public void test002_flip1_norm_layout1_layered0() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); - runTestGL(caps, true /* addLayout */, false /* layered */, false /* useAnim */); + runTestGL(caps, true /* addLayout */, false /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test03_norm_layout0_layered1() throws InterruptedException, InvocationTargetException { + public void test003_flip1_norm_layout0_layered1() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); - runTestGL(caps, false /* addLayout */, true /* layered */, false /* useAnim */); + runTestGL(caps, false /* addLayout */, true /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test04_norm_layout1_layered1() throws InterruptedException, InvocationTargetException { + public void test004_flip1_norm_layout1_layered1() throws InterruptedException, InvocationTargetException { GLCapabilities caps = new GLCapabilities(glp); - runTestGL(caps, true /* addLayout */, true /* layered */, false /* useAnim */); + runTestGL(caps, true /* addLayout */, true /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test11_bitm_layout0_layered0() throws InterruptedException, InvocationTargetException { + public void test011_flip1_bitm_layout0_layered0() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS != Platform.getOSType() ) { return; } GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); - runTestGL(caps, false /* addLayout */, false /* layered */, false /* useAnim */); + runTestGL(caps, false /* addLayout */, false /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test12_bitm_layout1_layered0() throws InterruptedException, InvocationTargetException { + public void test012_flip1_bitm_layout1_layered0() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS != Platform.getOSType() ) { return; } GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); - runTestGL(caps, true /* addLayout */, false /* layered */, false /* useAnim */); + runTestGL(caps, true /* addLayout */, false /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test13_bitm_layout0_layered1() throws InterruptedException, InvocationTargetException { + public void test013_flip1_bitm_layout0_layered1() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS != Platform.getOSType() ) { return; } GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); - runTestGL(caps, false /* addLayout */, true /* layered */, false /* useAnim */); + runTestGL(caps, false /* addLayout */, true /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + @Test - public void test14_bitm_layout1_layered1() throws InterruptedException, InvocationTargetException { + public void test014_flip1_bitm_layout1_layered1() throws InterruptedException, InvocationTargetException { if( Platform.OSType.WINDOWS != Platform.getOSType() ) { return; } GLCapabilities caps = new GLCapabilities(glp); caps.setBitmap(true); - runTestGL(caps, true /* addLayout */, true /* layered */, false /* useAnim */); + runTestGL(caps, true /* addLayout */, true /* layered */, false /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test101_flip1_norm_layout0_layered0() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + runTestGL(caps, false /* addLayout */, false /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test102_flip1_norm_layout1_layered0() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + runTestGL(caps, true /* addLayout */, false /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test103_flip1_norm_layout0_layered1() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + runTestGL(caps, false /* addLayout */, true /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); } - + + @Test + public void test104_flip1_norm_layout1_layered1() throws InterruptedException, InvocationTargetException { + GLCapabilities caps = new GLCapabilities(glp); + runTestGL(caps, true /* addLayout */, true /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test111_flip1_bitm_layout0_layered0() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS != Platform.getOSType() ) { + return; + } + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + runTestGL(caps, false /* addLayout */, false /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test112_flip1_bitm_layout1_layered0() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS != Platform.getOSType() ) { + return; + } + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + runTestGL(caps, true /* addLayout */, false /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test113_flip1_bitm_layout0_layered1() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS != Platform.getOSType() ) { + return; + } + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + runTestGL(caps, false /* addLayout */, true /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + + @Test + public void test114_flip1_bitm_layout1_layered1() throws InterruptedException, InvocationTargetException { + if( Platform.OSType.WINDOWS != Platform.getOSType() ) { + return; + } + GLCapabilities caps = new GLCapabilities(glp); + caps.setBitmap(true); + runTestGL(caps, true /* addLayout */, true /* layered */, true /* skipGLOrientationVerticalFlip */, false /* useAnim */); + } + static long duration = 500; // ms public static void main(String args[]) { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java index 4bf1f95c3..f7fbc7332 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -3,14 +3,14 @@ * * 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 @@ -20,7 +20,7 @@ * 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. @@ -42,24 +42,24 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { final NewtCanvasAWT newtCanvasAWT; final GLWindow glWindow; final QuitAdapter quitAdapter; - + public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow, QuitAdapter quitAdapter) { this.frame = frame; this.newtCanvasAWT = newtCanvasAWT; this.glWindow = glWindow; this.quitAdapter = quitAdapter; } - + public void keyReleased(KeyEvent e) { if( !e.isPrintableKey() || e.isAutoRepeat() ) { return; - } + } if( e.getKeySymbol() == KeyEvent.VK_I ) { System.err.println(glWindow); } else if( e.getKeySymbol() == KeyEvent.VK_L ) { javax.media.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null); javax.media.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null); - System.err.println("NewtCanvasAWT position: "+p0+", "+p1); + System.err.println("NewtCanvasAWT position: "+p0+", "+p1); } else if( e.getKeySymbol() == KeyEvent.VK_D ) { glWindow.setUndecorated(!glWindow.isUndecorated()); } else if( e.getKeySymbol() == KeyEvent.VK_S ) { @@ -68,7 +68,7 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { glWindow.setPosition(100, 100); } else { System.err.println("XXX glWin to 0/0"); - glWindow.setPosition(0, 0); + glWindow.setPosition(0, 0); } } else if( e.getKeySymbol() == KeyEvent.VK_F ) { if( null != quitAdapter ) { @@ -92,8 +92,8 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { if(glWindow.getAnimator().isPaused()) { glWindow.getAnimator().resume(); } else { - glWindow.getAnimator().pause(); - } + glWindow.getAnimator().pause(); + } } }.run(); } else if( e.getKeySymbol() == KeyEvent.VK_R ) { @@ -105,7 +105,7 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { final Thread t = glWindow.setExclusiveContextThread(null); if(glWindow.getParent()==null) { System.err.println("XXX glWin to HOME"); - glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); + glWindow.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, 0 /* hints */); } else { if( null != frame ) { final InsetsImmutable nInsets = glWindow.getInsets(); @@ -121,10 +121,10 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { final int topLevelX = frame.getX()+frame.getWidth()+dx; final int topLevelY = frame.getY()+dy; System.err.println("XXX glWin to TOP.1 "+topLevelX+"/"+topLevelY+" - insets " + nInsets + ", " + aInsets); - glWindow.reparentWindow(null, topLevelX, topLevelY, false); + glWindow.reparentWindow(null, topLevelX, topLevelY, 0 /* hint */); } else { System.err.println("XXX glWin to TOP.0"); - glWindow.reparentWindow(null); + glWindow.reparentWindow(null, -1, -1, 0 /* hints */); } } glWindow.requestFocus(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java index 1f19241d8..7beceb291 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.newt.parenting; @@ -62,7 +62,7 @@ public class TestParenting01NEWT extends UITestCase { } @Test - public void testWindowParenting01CreateVisibleDestroy() throws InterruptedException { + public void test01CreateVisibleDestroy() throws InterruptedException { Assert.assertEquals(0,Display.getActiveDisplayNumber()); Display display = null; Screen screen = null; @@ -82,7 +82,7 @@ public class TestParenting01NEWT extends UITestCase { Assert.assertEquals(false,screen.isNativeValid()); Assert.assertEquals(0,Display.getActiveDisplayNumber()); - glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy"); + glWindow1.setTitle("test01CreateVisibleDestroy"); glWindow1.setSize(640, 480); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -151,13 +151,13 @@ public class TestParenting01NEWT extends UITestCase { glWindow1.resetFPSCounter(); glWindow2.resetFPSCounter(); Animator animator1 = new Animator(glWindow1); - animator1.setUpdateFPSFrames(1, null); + animator1.setUpdateFPSFrames(1, null); animator1.start(); Assert.assertEquals(true, animator1.isAnimating()); Assert.assertEquals(false, animator1.isPaused()); Assert.assertNotNull(animator1.getThread()); Animator animator2 = new Animator(glWindow2); - animator2.setUpdateFPSFrames(1, null); + animator2.setUpdateFPSFrames(1, null); animator2.start(); Assert.assertEquals(true, animator2.isAnimating()); Assert.assertEquals(false, animator2.isPaused()); @@ -286,25 +286,27 @@ public class TestParenting01NEWT extends UITestCase { } @Test - public void testWindowParenting02ReparentTop2WinReparentRecreate() throws InterruptedException { - testWindowParenting02ReparentTop2WinImpl(true); + public void test02aReparentTop2WinReparentRecreate() throws InterruptedException { + test02ReparentTop2WinImpl(true); } @Test - public void testWindowParenting02ReparentTop2WinReparentNative() throws InterruptedException { - testWindowParenting02ReparentTop2WinImpl(false); + public void test02bReparentTop2WinReparentNative() throws InterruptedException { + test02ReparentTop2WinImpl(false); } /** * @param reparentRecreate true, if the followup reparent should utilize destroy/create, instead of native reparenting */ - protected void testWindowParenting02ReparentTop2WinImpl(boolean reparentRecreate) throws InterruptedException { + protected void test02ReparentTop2WinImpl(final boolean reparentRecreate) throws InterruptedException { + final int reparentHints = reparentRecreate ? Window.REPARENT_HINT_FORCE_RECREATION : 0; + Assert.assertEquals(0,Display.getActiveDisplayNumber()); Display display1 = null; Screen screen1 = null; GLWindow glWindow1 = GLWindow.create(glCaps); - glWindow1.setTitle("testWindowParenting02ReparentTop2Win"); + glWindow1.setTitle("test02ReparentTop2Win"); glWindow1.setSize(640, 480); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -379,7 +381,7 @@ public class TestParenting01NEWT extends UITestCase { // glWindow2 -- child --> glWindow1: compatible Assert.assertEquals(true, glWindow2.isVisible()); System.err.println("Frames(1) "+glWindow2.getTotalFPSFrames()); - reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentHints); System.err.println("Frames(2) "+glWindow2.getTotalFPSFrames()); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); @@ -405,7 +407,7 @@ public class TestParenting01NEWT extends UITestCase { // glWindow2 --> top Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentHints); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); @@ -484,16 +486,18 @@ public class TestParenting01NEWT extends UITestCase { } @Test - public void testWindowParenting03ReparentWin2TopReparentRecreate() throws InterruptedException { - testWindowParenting03ReparentWin2TopImpl(true); + public void test03aReparentWin2TopReparentRecreate() throws InterruptedException { + test03ReparentWin2TopImpl(true); } @Test - public void testWindowParenting03ReparentWin2TopReparentNative() throws InterruptedException { - testWindowParenting03ReparentWin2TopImpl(false); + public void test03bReparentWin2TopReparentNative() throws InterruptedException { + test03ReparentWin2TopImpl(false); } - protected void testWindowParenting03ReparentWin2TopImpl(boolean reparentRecreate) throws InterruptedException { + protected void test03ReparentWin2TopImpl(final boolean reparentRecreate) throws InterruptedException { + final int reparentHints = reparentRecreate ? Window.REPARENT_HINT_FORCE_RECREATION : 0; + Assert.assertEquals(0,Display.getActiveDisplayNumber()); Display display1 = null; Screen screen1 = null; @@ -503,7 +507,7 @@ public class TestParenting01NEWT extends UITestCase { GLWindow glWindow1 = GLWindow.create(glCaps); screen1 = glWindow1.getScreen(); display1 = screen1.getDisplay(); - glWindow1.setTitle("testWindowParenting03ReparentWin2Top"); + glWindow1.setTitle("test03ReparentWin2Top"); glWindow1.setSize(640, 480); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -567,14 +571,14 @@ public class TestParenting01NEWT extends UITestCase { switch(state) { case 0: Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentHints); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B2: "+glWindow2.getTotalFPSFrames()); Assert.assertTrue(0 < glWindow2.getTotalFPSFrames()); - + Assert.assertNull(glWindow2.getParent()); Assert.assertSame(screen1,glWindow2.getScreen()); Assert.assertSame(display1,glWindow2.getScreen().getDisplay()); @@ -582,14 +586,14 @@ public class TestParenting01NEWT extends UITestCase { break; case 1: Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentHints); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); Thread.sleep(20*16); // Wait for a few frames since counter could be reset - 20 frames at 60Hz System.err.println("Frames for reparentWindow(parent, "+reparentRecreate+"): "+reparentAction+", B3 "+glWindow2.getTotalFPSFrames()); Assert.assertTrue(0 < glWindow2.getTotalFPSFrames()); - + Assert.assertSame(glWindow1,glWindow2.getParent()); Assert.assertSame(screen1,glWindow2.getScreen()); Assert.assertSame(display1,glWindow2.getScreen().getDisplay()); @@ -657,7 +661,7 @@ public class TestParenting01NEWT extends UITestCase { public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { Assert.assertNotNull(demo); - Assert.assertNotNull(glWindow); + Assert.assertNotNull(glWindow); if(debug) { MiscUtils.setFieldIfExists(demo, "glDebug", true); MiscUtils.setFieldIfExists(demo, "glTrace", true); @@ -689,8 +693,8 @@ public class TestParenting01NEWT extends UITestCase { try { TestParenting01NEWT.initClass(); TestParenting01NEWT m = new TestParenting01NEWT(); - m.testWindowParenting02ReparentTop2WinReparentRecreate(); - m.testWindowParenting01CreateVisibleDestroy(); + m.test02aReparentTop2WinReparentRecreate(); + m.test01CreateVisibleDestroy(); } catch (Throwable t ) { t.printStackTrace(); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java index 6de24d1ea..420a39cb2 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,7 +20,7 @@ * 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. @@ -68,7 +68,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { + public void test01WindowParenting01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { final GLWindow glWindow1 = GLWindow.create(glCaps); Assert.assertNotNull(glWindow1); Assert.assertEquals(false, glWindow1.isVisible()); @@ -112,11 +112,11 @@ public class TestParenting01aAWT extends UITestCase { Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); final Animator animator1 = new Animator(glWindow1); - animator1.setUpdateFPSFrames(1, null); + animator1.setUpdateFPSFrames(1, null); animator1.start(); Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow1, true)); Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow1, true)); - + while(animator1.isAnimating() && animator1.getTotalFPSDuration()<durationPerTest) { Thread.sleep(100); } @@ -126,17 +126,17 @@ public class TestParenting01aAWT extends UITestCase { SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame1.setVisible(false); - } } ); + } } ); Assert.assertEquals(true, glWindow1.isNativeValid()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame1.setVisible(true); - } } ); + } } ); Assert.assertEquals(true, glWindow1.isNativeValid()); final boolean wasOnscreen = glWindow1.getChosenCapabilities().isOnscreen(); - + SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame1.remove(newtCanvasAWT); @@ -159,7 +159,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting02CreateVisibleDestroy2Defered() throws InterruptedException, InvocationTargetException { + public void test02WindowParenting02CreateVisibleDestroy2Defered() throws InterruptedException, InvocationTargetException { final GLWindow glWindow1 = GLWindow.create(glCaps); Assert.assertNotNull(glWindow1); Assert.assertEquals(false, glWindow1.isVisible()); @@ -211,7 +211,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting02CreateVisibleDestroy3Odd() throws InterruptedException, InvocationTargetException { + public void test03WindowParenting02CreateVisibleDestroy3Odd() throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -256,7 +256,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting03ReparentNewtWin2Top() throws InterruptedException, InvocationTargetException { + public void test04WindowParenting03ReparentNewtWin2Top() throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -283,7 +283,7 @@ public class TestParenting01aAWT extends UITestCase { Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); Animator animator1 = new Animator(glWindow1); - animator1.setUpdateFPSFrames(1, null); + animator1.setUpdateFPSFrames(1, null); animator1.start(); int state = 0; @@ -291,12 +291,12 @@ public class TestParenting01aAWT extends UITestCase { Thread.sleep(durationPerTest); switch(state) { case 0: - glWindow1.reparentWindow(null); + System.err.println("Reparent CHILD -> TOP: "+glWindow1.reparentWindow(null, -1, -1, 0 /* hints */)); Assert.assertEquals(true, glWindow1.isNativeValid()); Assert.assertNull(glWindow1.getParent()); break; case 1: - glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow()); + System.err.println("Reparent TOP -> CHILD: "+glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, 0 /* hints */)); Assert.assertEquals(true, glWindow1.isNativeValid()); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); break; @@ -315,7 +315,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting04ReparentNewtWin2TopLayouted() throws InterruptedException, InvocationTargetException { + public void test05WindowParenting04ReparentNewtWin2TopLayouted() throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); GLEventListener demo1 = new RedSquareES2(); setDemoFields(demo1, glWindow1, false); @@ -329,7 +329,7 @@ public class TestParenting01aAWT extends UITestCase { frame.add(new Button("South"), BorderLayout.SOUTH); frame.add(new Button("East"), BorderLayout.EAST); frame.add(new Button("West"), BorderLayout.WEST); - + SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame.setSize(width, height); @@ -344,11 +344,11 @@ public class TestParenting01aAWT extends UITestCase { frame.validate(); } }); - + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); Animator animator1 = new Animator(glWindow1); - animator1.setUpdateFPSFrames(1, null); + animator1.setUpdateFPSFrames(1, null); animator1.start(); int state = 0; @@ -356,12 +356,12 @@ public class TestParenting01aAWT extends UITestCase { Thread.sleep(durationPerTest); switch(state) { case 0: - glWindow1.reparentWindow(null); + System.err.println("Reparent CHILD -> TOP: "+glWindow1.reparentWindow(null, -1, -1, 0 /* hints */)); Assert.assertEquals(true, glWindow1.isNativeValid()); Assert.assertNull(glWindow1.getParent()); break; case 1: - glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow()); + System.err.println("Reparent TOP -> CHILD: "+glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, 0 /* hints */)); Assert.assertEquals(true, glWindow1.isNativeValid()); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); break; @@ -380,7 +380,7 @@ public class TestParenting01aAWT extends UITestCase { } @Test - public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { + public void test06WindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); glWindow1.setUndecorated(true); GLEventListener demo1 = new RedSquareES2(); @@ -427,7 +427,7 @@ public class TestParenting01aAWT extends UITestCase { Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); Animator animator1 = new Animator(glWindow1); - animator1.setUpdateFPSFrames(1, null); + animator1.setUpdateFPSFrames(1, null); animator1.start(); int state = 0; @@ -442,7 +442,7 @@ public class TestParenting01aAWT extends UITestCase { frame1.validate(); frame2.validate(); } - }); + }); break; case 1: SwingUtilities.invokeAndWait(new Runnable() { @@ -452,7 +452,7 @@ public class TestParenting01aAWT extends UITestCase { frame2.validate(); frame1.validate(); } - }); + }); break; } state++; @@ -471,7 +471,7 @@ public class TestParenting01aAWT extends UITestCase { public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { Assert.assertNotNull(demo); - Assert.assertNotNull(glWindow); + Assert.assertNotNull(glWindow); if(debug) { MiscUtils.setFieldIfExists(demo, "glDebug", true); MiscUtils.setFieldIfExists(demo, "glTrace", true); @@ -498,17 +498,7 @@ public class TestParenting01aAWT extends UITestCase { } } String tstname = TestParenting01aAWT.class.getName(); - org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { - tstname, - "filtertrace=true", - "haltOnError=false", - "haltOnFailure=false", - "showoutput=true", - "outputtoformatters=true", - "logfailedtests=true", - "logtestlistenerevents=true", - "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", - "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + org.junit.runner.JUnitCore.main(tstname); } } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java index 45612eb1a..598e5f10f 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.newt.parenting; import org.junit.Assert; @@ -68,16 +68,16 @@ public class TestParenting01bAWT extends UITestCase { } @Test - public void testWindowParenting05ReparentAWTWinHopFrame2FrameFPS25Animator() throws InterruptedException, InvocationTargetException { - testWindowParenting05ReparentAWTWinHopFrame2FrameImpl(25); + public void test01AWTWinHopFrame2FrameFPS25Animator() throws InterruptedException, InvocationTargetException { + testAWTWinHopFrame2FrameImpl(25); } @Test - public void testWindowParenting05ReparentAWTWinHopFrame2FrameStdAnimator() throws InterruptedException, InvocationTargetException { - testWindowParenting05ReparentAWTWinHopFrame2FrameImpl(0); + public void test02AWTWinHopFrame2FrameStdAnimator() throws InterruptedException, InvocationTargetException { + testAWTWinHopFrame2FrameImpl(0); } - public void testWindowParenting05ReparentAWTWinHopFrame2FrameImpl(int fps) throws InterruptedException, InvocationTargetException { + public void testAWTWinHopFrame2FrameImpl(int fps) throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); glWindow1.setUndecorated(true); GLEventListener demo1 = new RedSquareES2(); @@ -85,7 +85,7 @@ public class TestParenting01bAWT extends UITestCase { glWindow1.addGLEventListener(demo1); final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); - + final Frame frame1 = new Frame("AWT Parent Frame"); frame1.setLayout(new BorderLayout()); frame1.add(new Button("North"), BorderLayout.NORTH); @@ -96,7 +96,7 @@ public class TestParenting01bAWT extends UITestCase { public void run() { frame1.setSize(width, height); frame1.setLocation(0, 0); - frame1.setVisible(true); + frame1.setVisible(true); } }); @@ -110,7 +110,7 @@ public class TestParenting01bAWT extends UITestCase { public void run() { frame2.setSize(width, height); frame2.setLocation(640, 480); - frame2.setVisible(true); + frame2.setVisible(true); } }); @@ -142,7 +142,7 @@ public class TestParenting01bAWT extends UITestCase { frame1.validate(); frame2.validate(); } - }); + }); break; case 1: SwingUtilities.invokeAndWait(new Runnable() { @@ -152,7 +152,7 @@ public class TestParenting01bAWT extends UITestCase { frame2.validate(); frame1.validate(); } - }); + }); break; } } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java index dd5d6eb13..1d7401728 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java @@ -66,7 +66,7 @@ public class TestParenting01cAWT extends UITestCase { } @Test - public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { + public void test01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { int i; GLWindow glWindow1 = GLWindow.create(glCaps); @@ -154,7 +154,7 @@ public class TestParenting01cAWT extends UITestCase { } @Test - public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { + public void test02AWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { GLWindow glWindow1 = GLWindow.create(glCaps); glWindow1.setUndecorated(true); GLEventListener demo1 = new RedSquareES2(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java index 375f676f4..4d5c3b25d 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java @@ -121,7 +121,7 @@ public class TestParenting01cSwingAWT extends UITestCase { } @Test - public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { + public void test01CreateVisibleDestroy1() throws InterruptedException, InvocationTargetException { /** * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow */ @@ -236,7 +236,7 @@ public class TestParenting01cSwingAWT extends UITestCase { } @Test - public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { + public void test02AWTWinHopFrame2Frame() throws InterruptedException, InvocationTargetException { /** * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow */ diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java new file mode 100644 index 000000000..00b32ac35 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01dAWT.java @@ -0,0 +1,248 @@ +/** + * Copyright 2013 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.test.junit.newt.parenting; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +import java.awt.Button; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Frame; + +import javax.media.opengl.*; +import javax.swing.SwingUtilities; + +import com.jogamp.newt.Window; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.awt.NewtCanvasAWT; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; + +/** + * Test GL preservation case for reparenting. + * <p> + * Also simulates adding and attaching an already created GLWindow + * to a NewtCanvasAWT in recreation mode, where the GL state shall be preserved. + * </p> + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestParenting01dAWT extends UITestCase { + static int width, height; + static long durationPerTest = 800; + static GLCapabilities glCaps; + + @BeforeClass + public static void initClass() throws InterruptedException { + width = 640; + height = 480; + glCaps = new GLCapabilities(null); + // Thread.sleep(10000); + } + + static class MyGLEventListenerCounter extends GLEventListenerCounter { + @Override + public void init(GLAutoDrawable drawable) { + super.init(drawable); + System.err.println("MyGLEventListenerCounter.init: "+this); + // Thread.dumpStack(); + } + + @Override + public void dispose(GLAutoDrawable drawable) { + super.dispose(drawable); + System.err.println("MyGLEventListenerCounter.dispose: "+this); + // Thread.dumpStack(); + } + } + + @Test + public void test01GLWindowReparentRecreateNoPreserve() throws InterruptedException, InvocationTargetException { + testGLWindowInvisibleReparentRecreateImpl(false /* triggerPreserveGLState */); + } + + @Test + public void test02GLWindowReparentRecreateGLPreserve() throws InterruptedException, InvocationTargetException { + testGLWindowInvisibleReparentRecreateImpl(true /* triggerPreserveGLState */); + } + + private void testGLWindowInvisibleReparentRecreateImpl(boolean triggerPreserveGLState) throws InterruptedException, InvocationTargetException { + final GLWindow glWindow1 = GLWindow.create(glCaps); + Assert.assertNotNull(glWindow1); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeValid()); + Assert.assertNull(glWindow1.getParent()); + glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy"); + final MyGLEventListenerCounter glelCounter = new MyGLEventListenerCounter(); + glWindow1.addGLEventListener(glelCounter); + GLEventListener demo1 = new RedSquareES2(); + glWindow1.addGLEventListener(demo1); + Assert.assertEquals("Init Counter Invalid "+glelCounter, 0, glelCounter.initCount); + + final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + Assert.assertNotNull(newtCanvasAWT); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeValid()); + Assert.assertNull(glWindow1.getParent()); + Assert.assertEquals("Init Counter Invalid "+glelCounter, 0, glelCounter.initCount); + + final Frame frame1 = new Frame("AWT Parent Frame"); + frame1.setLayout(new BorderLayout()); + frame1.add(new Button("North"), BorderLayout.NORTH); + frame1.add(new Button("South"), BorderLayout.SOUTH); + frame1.add(new Button("East"), BorderLayout.EAST); + frame1.add(new Button("West"), BorderLayout.WEST); + + final Container container1 = new Container(); + container1.setLayout(new BorderLayout()); + container1.add(new Button("north"), BorderLayout.NORTH); + container1.add(new Button("south"), BorderLayout.SOUTH); + container1.add(new Button("east"), BorderLayout.EAST); + container1.add(new Button("west"), BorderLayout.WEST); + container1.add(newtCanvasAWT, BorderLayout.CENTER); + + frame1.add(container1, BorderLayout.CENTER); + + // visible test + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.setSize(width, height); + frame1.setVisible(true); + } + }); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParent()); + + Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow1, true)); + Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow1, true)); + glWindow1.display(); + Assert.assertEquals("Init Counter Invalid "+glelCounter, 1, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid "+glelCounter, 0, glelCounter.disposeCount); + + final int reparentingHints = Window.REPARENT_HINT_FORCE_RECREATION | + ( triggerPreserveGLState ? Window.REPARENT_HINT_BECOMES_VISIBLE : 0 ); + + // + // Even though the hint REPARENT_HINT_BECOMES_VISIBLE is not set (triggerPrerveGLState == false), + // since GLWindow is visible already the GL state shall be preserved! + // + System.err.println(getSimpleTestName(".")+": Start Reparent #1"); + final Window.ReparentOperation rop1 = glWindow1.reparentWindow(null, -1, -1, reparentingHints); + System.err.println(getSimpleTestName(".")+": Result Reparent #1: "+rop1); + Assert.assertEquals(Window.ReparentOperation.ACTION_NATIVE_CREATION, rop1); + glWindow1.display(); + Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 0, glelCounter.disposeCount); + + // + // The following step is equivalent with adding and attaching an already created GLWindow + // to a NewtCanvasAWT in recreation mode if REPARENT_HINT_BECOMES_VISIBLE hint is set (triggerPrerveGLState == true). + // GL state shall be preserved! + // + glWindow1.setVisible(false); + System.err.println(getSimpleTestName(".")+": Start Reparent #2"); + final Window.ReparentOperation rop2 = glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), -1, -1, reparentingHints); + System.err.println(getSimpleTestName(".")+": Result Reparent #2: "+rop2); + Assert.assertEquals(Window.ReparentOperation.ACTION_NATIVE_CREATION, rop2); + glWindow1.setVisible(true); + glWindow1.display(); + if( triggerPreserveGLState ) { + Assert.assertEquals("Init Counter Invalid (Preserve Failed 2) "+glelCounter, 1, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 2) "+glelCounter, 0, glelCounter.disposeCount); + } else { + Assert.assertEquals("Init Counter Invalid (Preserve Failed 2) "+glelCounter, 2, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 2) "+glelCounter, 1, glelCounter.disposeCount); + } + + final long t0 = System.currentTimeMillis(); + long t1 = t0; + while( t1 - t0 < durationPerTest ) { + Thread.sleep(100); + t1 = System.currentTimeMillis(); + } + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.setVisible(false); + } } ); + Assert.assertEquals(true, glWindow1.isNativeValid()); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.setVisible(true); + } } ); + Assert.assertEquals(true, glWindow1.isNativeValid()); + + final boolean wasOnscreen = glWindow1.getChosenCapabilities().isOnscreen(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.remove(newtCanvasAWT); + } } ); + // Assert.assertNull(glWindow1.getParent()); + if( wasOnscreen ) { + Assert.assertEquals(true, glWindow1.isNativeValid()); + } // else OK to be destroyed - due to offscreen/onscreen transition + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame1.dispose(); + } } ); + if( wasOnscreen ) { + Assert.assertEquals(true, glWindow1.isNativeValid()); + } // else OK to be destroyed - due to offscreen/onscreen transition + + glWindow1.destroy(); + Assert.assertEquals(false, glWindow1.isNativeValid()); + if( triggerPreserveGLState ) { + Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 1, glelCounter.disposeCount); + } else { + Assert.assertEquals("Init Counter Invalid (Preserve Failed 1) "+glelCounter, 2, glelCounter.initCount); + Assert.assertEquals("Dispose Counter Invalid (Preserve Failed 1) "+glelCounter, 2, glelCounter.disposeCount); + } + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = MiscUtils.atol(args[++i], durationPerTest); + } + } + String tstname = TestParenting01dAWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java index d79bdcaf6..b304a2ce7 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.newt.parenting; import org.junit.Assert; @@ -65,22 +65,22 @@ public class TestParenting02AWT extends UITestCase { } @Test - public void testWindowParenting01NewtChildOnAWTParentLayouted() throws InterruptedException, InvocationTargetException { + public void test01NewtChildOnAWTParentLayouted() throws InterruptedException, InvocationTargetException { runNewtChildOnAWTParent(true, false); } @Test - public void testWindowParenting02NewtChildOnAWTParentLayoutedDef() throws InterruptedException, InvocationTargetException { + public void test02NewtChildOnAWTParentLayoutedDef() throws InterruptedException, InvocationTargetException { runNewtChildOnAWTParent(true, true); } @Test - public void testWindowParenting03NewtChildOnAWTParentDirect() throws InterruptedException, InvocationTargetException { + public void test03NewtChildOnAWTParentDirect() throws InterruptedException, InvocationTargetException { runNewtChildOnAWTParent(false, false); } @Test - public void testWindowParenting04NewtChildOnAWTParentDirectDef() throws InterruptedException, InvocationTargetException { + public void test04NewtChildOnAWTParentDirectDef() throws InterruptedException, InvocationTargetException { runNewtChildOnAWTParent(false, true); } @@ -152,7 +152,7 @@ public class TestParenting02AWT extends UITestCase { } while(!glWindow.isNativeValid()) ; final boolean wasOnscreen = glWindow.getChosenCapabilities().isOnscreen(); - + Assert.assertEquals(true, glWindow.isNativeValid()); Assert.assertNotNull(glWindow.getParent()); if(verbose) { @@ -203,7 +203,7 @@ public class TestParenting02AWT extends UITestCase { Thread.sleep(step); duration -= step; - while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { + while( null != ( event = eventFifo.get() ) ) { Window source = (Window) event.getSource(); if(event instanceof KeyEvent) { KeyEvent keyEvent = (KeyEvent) event; @@ -215,7 +215,7 @@ public class TestParenting02AWT extends UITestCase { source.setFullscreen(!source.isFullscreen()); break; } - } + } } } if(verbose) { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java index 6294483f0..9f56ecdbf 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.newt.parenting; @@ -92,7 +92,7 @@ public class TestParenting02NEWT extends UITestCase { } @Test - public void testWindowParenting01NewtOnNewtParentChildDraw() throws InterruptedException { + public void test01NewtOnNewtParentChildDraw() throws InterruptedException { GLCapabilities caps = new GLCapabilities(null); Assert.assertNotNull(caps); Display display = NewtFactory.createDisplay(null); // local display @@ -112,7 +112,7 @@ public class TestParenting02NEWT extends UITestCase { glWindow1.setSize(width, height); Assert.assertEquals(width,glWindow1.getWidth()); Assert.assertEquals(height,glWindow1.getHeight()); - glWindow1.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - PARENT"); + glWindow1.setTitle("test01NewtOnNewtParentChildDraw - PARENT"); glWindow1.setPosition(x,y); //glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); //glWindow1.addWindowListener(new TraceWindowAdapter()); @@ -133,7 +133,7 @@ public class TestParenting02NEWT extends UITestCase { glWindow2.setSize(width/2, height/2); //Assert.assertEquals(width/2,glWindow2.getWidth()); //Assert.assertEquals(height/2,glWindow2.getHeight()); - glWindow2.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - CHILD"); + glWindow2.setTitle("test01NewtOnNewtParentChildDraw - CHILD"); glWindow2.setPosition(glWindow1.getWidth()/2, glWindow1.getHeight()/2); //glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); //glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); @@ -166,7 +166,7 @@ public class TestParenting02NEWT extends UITestCase { glWindow2.setPosition(glWindow1.getWidth()/2,glWindow1.getHeight()/2-y); Thread.sleep(step); - while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { + while( null != ( event = eventFifo.get() ) ) { Window source = (Window) event.getSource(); if(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY == event.getEventType()) { shouldQuit = true; @@ -180,7 +180,7 @@ public class TestParenting02NEWT extends UITestCase { source.setFullscreen(!source.isFullscreen()); break; } - } + } } } destroyWindow(null, null, window2, glWindow2); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java index 30ee0f129..b7497196c 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java @@ -3,14 +3,14 @@ * * 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 @@ -20,12 +20,12 @@ * 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.test.junit.newt.parenting; import java.lang.reflect.*; @@ -69,16 +69,16 @@ public class TestParenting03AWT extends UITestCase { } @Test - public void testWindowParenting1AWTOneNewtChilds01() throws InterruptedException, InvocationTargetException { - testWindowParenting1AWT(false); + public void test01AWTOneNewtChilds01() throws InterruptedException, InvocationTargetException { + testImpl(false); } @Test - public void testWindowParenting1AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException { - testWindowParenting1AWT(true); + public void test02AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException { + testImpl(true); } - - public void testWindowParenting1AWT(boolean use2nd) throws InterruptedException, InvocationTargetException { + + public void testImpl(boolean use2nd) throws InterruptedException, InvocationTargetException { final Frame frame1 = new Frame("AWT Parent Frame"); GLWindow glWindow1 = GLWindow.create(glCaps); glWindow1.setUpdateFPSFrames(1, null); @@ -100,7 +100,7 @@ public class TestParenting03AWT extends UITestCase { glWindow2.setUpdateFPSFrames(1, null); newtCanvasAWT2 = new NewtCanvasAWT(glWindow2); newtCanvasAWT2.setPreferredSize(glSize); - + GLEventListener demo2 = new GearsES2(1); setDemoFields(demo2, glWindow2, false); glWindow2.addGLEventListener(demo2); @@ -141,12 +141,12 @@ public class TestParenting03AWT extends UITestCase { System.err.println("******* Frame setVisible"); frame1.setLocation(0, 0); frame1.setSize(fSize); - frame1.validate(); + frame1.validate(); frame1.setVisible(true); }}); Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent()); - + Assert.assertEquals(true, animator1.isAnimating()); Assert.assertEquals(false, animator1.isPaused()); Assert.assertNotNull(animator1.getThread()); @@ -157,7 +157,7 @@ public class TestParenting03AWT extends UITestCase { Assert.assertNotNull(animator2.getThread()); Thread.sleep(waitAdd2nd); - + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame1.add(cont2, BorderLayout.WEST); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04AWT.java index 827ac525a..126aaaffa 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04AWT.java @@ -70,13 +70,13 @@ public class TestParenting04AWT extends UITestCase { } @Test - public void winHopFrame2FrameDirectHop() throws InterruptedException, InvocationTargetException { + public void test01WinHopFrame2FrameDirectHop() throws InterruptedException, InvocationTargetException { // Will produce some artifacts .. resizing etc winHopFrame2Frame(false); } @Test - public void winHopFrame2FrameDetachFirst() throws InterruptedException, InvocationTargetException { + public void test02WinHopFrame2FrameDetachFirst() throws InterruptedException, InvocationTargetException { // Note: detaching first setNEWTChild(null) is much cleaner visually winHopFrame2Frame(true); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04SWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04SWT.java index 78b3bc464..586db8a2b 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04SWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting04SWT.java @@ -136,13 +136,13 @@ public class TestParenting04SWT extends UITestCase { } @Test - public void winHopFrame2FrameDirectHop() throws InterruptedException, InvocationTargetException { + public void test01WinHopFrame2FrameDirectHop() throws InterruptedException, InvocationTargetException { // Will produce some artifacts .. resizing etc winHopFrame2Frame(false); } @Test - public void winHopFrame2FrameDetachFirst() throws InterruptedException, InvocationTargetException { + public void test02WinHopFrame2FrameDetachFirst() throws InterruptedException, InvocationTargetException { // Note: detaching first setNEWTChild(null) is much cleaner visually winHopFrame2Frame(true); } diff --git a/src/test/com/jogamp/opengl/test/junit/util/GLEventListenerCounter.java b/src/test/com/jogamp/opengl/test/junit/util/GLEventListenerCounter.java index b121a4c2a..b0f6e2c7e 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/GLEventListenerCounter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/GLEventListenerCounter.java @@ -3,14 +3,14 @@ * * 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 @@ -20,7 +20,7 @@ * 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. @@ -35,14 +35,14 @@ public class GLEventListenerCounter implements GLEventListener { public int displayCount = 0; public int reshapeCount = 0; public int disposeCount = 0; - + public void reset() { initCount = 0; displayCount = 0; reshapeCount = 0; - disposeCount = 0; + disposeCount = 0; } - + @Override public void init(GLAutoDrawable drawable) { initCount++; @@ -50,7 +50,7 @@ public class GLEventListenerCounter implements GLEventListener { @Override public void dispose(GLAutoDrawable drawable) { - disposeCount++; + disposeCount++; } @Override @@ -61,5 +61,9 @@ public class GLEventListenerCounter implements GLEventListener { @Override public void reshape(GLAutoDrawable d, int x, int y, int width, int height) { reshapeCount++; - } + } + + public String toString() { + return "GLEventListenerCounter[init "+initCount+", dispose "+disposeCount+", reshape "+reshapeCount+", display "+displayCount+"]"; + } }
\ No newline at end of file |