Jogamp
NewtVersionActivity: Remove 'gears' test; Version Info: Drop NativeWindow/Newt Versio...
[jogl.git] / src / newt / classes / com / jogamp / newt / opengl / GLWindow.java
index 5531bf1..1cc2298 100644 (file)
 
 package com.jogamp.newt.opengl;
 
+import java.io.PrintStream;
+import java.util.List;
+
 import com.jogamp.common.GlueGenVersion;
 import com.jogamp.common.util.VersionUtil;
 import com.jogamp.nativewindow.NativeWindowVersion;
 import com.jogamp.newt.*;
 import com.jogamp.newt.event.*;
-import com.jogamp.newt.impl.WindowImpl;
+import jogamp.newt.WindowImpl;
+
 import javax.media.nativewindow.*;
 import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Insets;
 import javax.media.opengl.*;
-import com.jogamp.opengl.impl.GLDrawableHelper;
+
+import jogamp.opengl.FPSCounterImpl;
+import jogamp.opengl.GLDrawableHelper;
 import com.jogamp.opengl.JoglVersion;
-import javax.media.nativewindow.util.Insets;
 
 /**
  * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
@@ -60,49 +66,54 @@ import javax.media.nativewindow.util.Insets;
  * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.<br>
  * <p>
  */
-public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
+public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter {
     private WindowImpl window;
 
     /**
      * Constructor. Do not call this directly -- use {@link #create()} instead.
      */
     protected GLWindow(Window window) {
-        resetCounter();
+        resetFPSCounter();
         this.window = (WindowImpl) window;
         ((WindowImpl)this.window).setHandleDestroyNotify(false);
         window.addWindowListener(new WindowAdapter() {
+                @Override
                 public void windowRepaint(WindowUpdateEvent e) {
-                    if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
+                    if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
                         display();
                     }
                 }
 
+                @Override
                 public void windowResized(WindowEvent e) {
                     sendReshape = true;
-                    if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
+                    if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
                         display();
                     }
                 }
 
+                @Override
                 public void windowDestroyNotify(WindowEvent e) {
-                    // Is an animator thread perform rendering?
-                    if (GLWindow.this.helper.isExternalAnimatorRunning()) {
-                        // Pause animations before initiating safe destroy.
-                        GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
-                        boolean isPaused = ctrl.pause();
-                        destroy();
-                        if(isPaused) {
-                            ctrl.resume();
+                    if( DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) {
+                        // Is an animator thread perform rendering?
+                        if (GLWindow.this.helper.isExternalAnimatorRunning()) {
+                            // Pause animations before initiating safe destroy.
+                            GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
+                            boolean isPaused = ctrl.pause();
+                            destroy();
+                            if(isPaused) {
+                                ctrl.resume();
+                            }
+                        } else if (GLWindow.this.window.isWindowLockedByOtherThread()) {
+                            // Window is locked by another thread
+                            // Flag that destroy should be performed on the next
+                            // attempt to display.
+                            sendDestroy = true;
+                        } else {
+                            // Without an external thread animating or locking the
+                            // surface, we are safe.
+                            destroy ();
                         }
-                    } else if (GLWindow.this.window.isSurfaceLockedByOtherThread()) {
-                        // Surface is locked by another thread
-                        // Flag that destroy should be performed on the next
-                        // attempt to display.
-                        sendDestroy = true;
-                    } else {
-                        // Without an external thread animating or locking the
-                        // surface, we are safe.
-                        destroy ();
                     }
                 }
             });
@@ -152,6 +163,17 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
     }
 
     //----------------------------------------------------------------------
+    // WindowClosingProtocol implementation
+    //
+    public int getDefaultCloseOperation() {
+        return window.getDefaultCloseOperation();
+    }
+
+    public int setDefaultCloseOperation(int op) {
+        return window.setDefaultCloseOperation(op);
+    }
+
+    //----------------------------------------------------------------------
     // Window Access
     //
 
@@ -231,6 +253,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         return window.isVisible();
     }
 
+    @Override
     public final String toString() {
         return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + 
                ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
@@ -283,8 +306,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
     // Hide methods here ..
     protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
 
-        class DisposeAction implements Runnable {
-            public void run() {
+        private class DisposeAction implements Runnable {
+            public final void run() {
                 // Lock: Covered by DestroyAction ..
                 helper.dispose(GLWindow.this);
             }
@@ -297,7 +320,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
 
         public synchronized void destroyActionInLock() {
             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
-                String msg = new String("GLWindow.destroy() "+Thread.currentThread()+", start");
+                String msg = "GLWindow.destroy() "+Thread.currentThread()+", start";
                 System.err.println(msg);
                 //Exception e1 = new Exception(msg);
                 //e1.printStackTrace();
@@ -318,38 +341,28 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
             }
             context = null;
             drawable = null;
-
+            
+            GLAnimatorControl ctrl = GLWindow.this.getAnimator();
+            if ( null!=ctrl ) {
+                ctrl.remove(GLWindow.this);
+            }            
+            // helper=null; // pending events ..
+            
             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
                 System.err.println("GLWindow.destroy() "+Thread.currentThread()+", fin");
             }
         }
 
-        public synchronized void invalidate(boolean unrecoverable) {
-            if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
-                String msg = new String("GLWindow.invalidate("+unrecoverable+") "+Thread.currentThread()+", start");
-                System.err.println(msg);
-                //Exception e1 = new Exception(msg);
-                //e1.printStackTrace();
-            }
-            if(unrecoverable) {
-                GLAnimatorControl ctrl = GLWindow.this.getAnimator();
-                if ( null!=ctrl ) {
-                    ctrl.remove(GLWindow.this);
-                }
-                helper=null;
-            }
-        }
-
         public synchronized void resetCounter() {
             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
                 System.err.println("GLWindow.resetCounter() "+Thread.currentThread());
             }
-            GLWindow.this.resetCounter();
+            GLWindow.this.resetFPSCounter();
         }
 
         public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) {
             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
-                String msg = new String("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start");
+                String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start";
                 System.err.println(msg);
                 // Exception e1 = new Exception(msg);
                 // e1.printStackTrace();
@@ -373,29 +386,31 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
                     drawable = factory.createGLDrawable(nw);
                 }
                 drawable.setRealized(true);
-                context = drawable.createContext(null);
+                context = drawable.createContext(sharedContext);
+                context.setContextCreationFlags(additionalCtxCreationFlags);                
             }
             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
-                String msg = new String("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin");
+                String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin";
                 System.err.println(msg);
                 //Exception e1 = new Exception(msg);
                 //e1.printStackTrace();
             }
         }
         
+        private GLAnimatorControl savedAnimator = null;
+        
         public synchronized boolean pauseRenderingAction() {
             boolean animatorPaused = false;
-            GLAnimatorControl ctrl = GLWindow.this.getAnimator();
-            if ( null!=ctrl ) {
-                animatorPaused = ctrl.pause();
+            savedAnimator = GLWindow.this.getAnimator();
+            if ( null != savedAnimator ) {
+                animatorPaused = savedAnimator.pause();
             }
             return animatorPaused;
         }
 
         public synchronized void resumeRenderingAction() {
-            GLAnimatorControl ctrl = GLWindow.this.getAnimator();
-            if ( null!=ctrl && ctrl.isPaused() ) {
-                ctrl.resume();
+            if ( null != savedAnimator && savedAnimator.isPaused() ) {
+                savedAnimator.resume();
             }
         }
     }
@@ -404,6 +419,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
     // OpenGL-related methods and state
     //
 
+    private GLContext sharedContext = null;
+    private int additionalCtxCreationFlags = 0;
     private GLDrawableFactory factory;
     private GLDrawable drawable;
     private GLContext context;
@@ -411,16 +428,29 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
     // To make reshape events be sent immediately before a display event
     private boolean sendReshape=false;
     private boolean sendDestroy=false;
-    private boolean perfLog = false;
-    private long startTime, curTime, lastCheck;
-    private int  totalFrames, lastFrames;
+    private FPSCounterImpl fpsCounter = new FPSCounterImpl();    
 
     public GLDrawableFactory getFactory() {
         return factory;
     }
 
+    /**
+     * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br>
+     * At native creation, {@link #setVisible(boolean) setVisible(true)},
+     * a {@link javax.media.opengl.GLDrawable drawable} and {@link javax.media.opengl.GLContext context} is created besides the native Window itself,<br>
+     * hence you shall set the shared context before.
+     *
+     * @param sharedContext The OpenGL context shared by this GLWindow's one
+     */
+    public void setSharedContext(GLContext sharedContext) {
+        this.sharedContext = sharedContext;
+    }
+
     public void setContext(GLContext newCtx) {
         context = newCtx;
+        if(null != context) {
+            context.setContextCreationFlags(additionalCtxCreationFlags);
+        }        
     }
 
     public GLContext getContext() {
@@ -473,12 +503,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         return null;
     }
 
-    public boolean getPerfLogEnabled() { return perfLog; }
-
-    public void enablePerfLog(boolean v) {
-        perfLog = v;
-    }
-
     public void invoke(boolean wait, GLRunnable glRunnable) {
         if(null!=helper) {
             helper.invoke(this, wait, glRunnable);
@@ -517,7 +541,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
             }
         }
     }
-
+    
     /** This implementation uses a static value */
     public void setAutoSwapBufferMode(boolean onOrOff) {
         if(null!=helper) {
@@ -532,30 +556,32 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         }
         return false;
     }
-
+    
     public void swapBuffers() {
         if(drawable!=null && context != null) {
-            // Lock: Locked Surface/Window by MakeCurrent/Release
-            if (context != GLContext.getCurrent()) {
-                // Assume we should try to make the context current before swapping the buffers
-                helper.invokeGL(drawable, context, swapBuffersAction, initAction);
-            } else {
-                drawable.swapBuffers();
-            }
+            drawable.swapBuffers();
         }
     }
 
-    class InitAction implements Runnable {
-        public void run() {
+    public void setContextCreationFlags(int flags) {
+        additionalCtxCreationFlags = flags;
+    }
+      
+    public int getContextCreationFlags() {
+        return additionalCtxCreationFlags;                
+    }
+        
+    private class InitAction implements Runnable {
+        public final void run() {
             // Lock: Locked Surface/Window by MakeCurrent/Release
             helper.init(GLWindow.this);
-            resetCounter();
+            resetFPSCounter();
         }
     }
     private InitAction initAction = new InitAction();
 
-    class DisplayAction implements Runnable {
-        public void run() {
+    private class DisplayAction implements Runnable {
+        public final void run() {
             // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release
             if (sendReshape) {
                 helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight());
@@ -564,69 +590,53 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
 
             helper.display(GLWindow.this);
 
-            curTime = System.currentTimeMillis();
-            totalFrames++;
-
-            if(perfLog) {
-                long dt0, dt1;
-                lastFrames++;
-                dt0 = curTime-lastCheck;
-                if ( dt0 > 5000 ) {
-                    dt1 = curTime-startTime;
-                    System.err.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+
-                                       "total: "+ dt1/1000+"s, "+(totalFrames*1000)/dt1 + " fps, "+dt1/totalFrames+" ms/f");
-                    lastCheck=curTime;
-                    lastFrames=0;
-                }
-            }
+            fpsCounter.tickFPS();
         }
     }
     private DisplayAction displayAction = new DisplayAction();
 
-    /** 
-     * @return Time of the first display call in milliseconds.
-     *         This value is reset if becoming visible again or reparenting.
-     */
-    public final long getStartTime()   { 
-        return startTime; 
+    public final void setUpdateFPSFrames(int frames, PrintStream out) {
+        fpsCounter.setUpdateFPSFrames(frames, out);
+    }
+    
+    public final void resetFPSCounter() {
+        fpsCounter.resetFPSCounter();
     }
 
-    /** 
-     * @return Time of the last display call in milliseconds.
-     *         This value is reset if becoming visible again or reparenting.
-     */
-    public final long getCurrentTime() {
-        return curTime;
+    public final int getUpdateFPSFrames() {
+        return fpsCounter.getUpdateFPSFrames();
+    }
+    
+    public final long getFPSStartTime()   {
+        return fpsCounter.getFPSStartTime();
     }
 
-    /** 
-     * @return Duration <code>getCurrentTime() - getStartTime()</code>.
-     *
-     * @see #getStartTime()
-     * @see #getCurrentTime()
-     */
-    public final long getDuration() { 
-        return getCurrentTime()-getStartTime(); 
+    public final long getLastFPSUpdateTime() {
+        return fpsCounter.getLastFPSUpdateTime();
     }
 
-    /** 
-     * @return Number of frames displayed since the first display call, ie <code>getStartTime()</code>.
-     *         This value is reset if becoming visible again or reparenting.
-     */
-    public final int getTotalFrames() { 
-        return totalFrames; 
+    public final long getLastFPSPeriod() {
+        return fpsCounter.getLastFPSPeriod();
+    }
+    
+    public final float getLastFPS() {
+        return fpsCounter.getLastFPS();
+    }
+    
+    public final int getTotalFPSFrames() {
+        return fpsCounter.getTotalFPSFrames();
     }
 
-    /** Reset all counter (startTime, currentTime, frame number) */
-    public synchronized void resetCounter() {
-        startTime = System.currentTimeMillis(); // overwrite startTime to real init one
-        curTime   = startTime;
-        lastCheck  = startTime;
-        totalFrames = 0; lastFrames = 0;
+    public final long getTotalFPSDuration() {
+        return fpsCounter.getTotalFPSDuration();
     }
+    
+    public final float getTotalFPS() {
+        return fpsCounter.getTotalFPS();
+    }        
 
-    class SwapBuffersAction implements Runnable {
-        public void run() {
+    private class SwapBuffersAction implements Runnable {
+        public final void run() {
             drawable.swapBuffers();
         }
     }
@@ -830,10 +840,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         return window.surfaceSwap();
     }
 
-    public final void invalidate() {
-        window.invalidate();
-    }
-    
     public final long getWindowHandle() {
         return window.getWindowHandle();
 
@@ -866,10 +872,17 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
     public static void main(String args[]) {
         System.err.println(VersionUtil.getPlatformInfo());
         System.err.println(GlueGenVersion.getInstance());
-        System.err.println(NativeWindowVersion.getInstance());
+        // System.err.println(NativeWindowVersion.getInstance());
         System.err.println(JoglVersion.getInstance());
         System.err.println(NewtVersion.getInstance());
-        GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault() );
+
+        final GLProfile glp = GLProfile.getDefault();
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
+        final List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
+        for(int i=0; i<availCaps.size(); i++) {
+            System.err.println(availCaps.get(i));
+        }
+        final GLCapabilitiesImmutable caps = new GLCapabilities( glp );
 
         GLWindow glWindow = GLWindow.create(caps);
         glWindow.setSize(128, 128);
@@ -877,7 +890,9 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         glWindow.addGLEventListener(new GLEventListener() {
             public void init(GLAutoDrawable drawable) {
                 GL gl = drawable.getGL();
-                System.err.println(JoglVersion.getInstance().getGLInfo(gl, null));
+                System.err.println(JoglVersion.getGLInfo(gl, null));
+                System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
+                System.err.println("Chosen   : "+drawable.getChosenGLCapabilities());
             }
 
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
@@ -891,7 +906,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer {
         });
 
         glWindow.setVisible(true);
-        glWindow.invalidate();
+        glWindow.destroy();
     }
 
 }
http://JogAmp.org git info: FAQ, tutorial and man pages.