From 8e0f3ad54b5aa8ef4d71e0b85f84a34be4987b5e Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Sat, 17 Dec 2011 21:53:48 +0100
Subject: New Interface 'OffscreenLayerOption', impl. by JAWTWindow (impl) and
 NewtCanvasAWT/GLCanvas (delegation) ; Fix GLCanvas OffscreenLayerSurface
 usage.

JAWTWindow.destroy():
- No more getGraphicsConfiguration().getScreen().getDevice().close() call,
  since the configuration (hence the device) is passed @ creation and owned by the caller.

New Interface 'OffscreenLayerOption', impl. by JAWTWindow (impl) and NewtCanvasAWT/GLCanvas (delegation)
- Abstract offscreenLayer option to be delegated by using classes
- Allow offscreen testing of GLCanvas as well (like NewtCanvasAWT)

Fix GLCanvas OffscreenLayerSurface usage
- common 'createDrawableAndContext()' for context and drawable instance creation

- addNotify() calls createDrawableAndContext() after super.addNotify() to be able
  to lock the surface (JAWTWindow) and hence to determine offscreen usage.

- reshape(...) issues recreation 'dispose(true)' in case of using an offscreen layer

- dispose() explicitly destroys the JAWTWindow

NewtCanvasAWT:
- explicitly close the device of the JAWTWindow (as GLCanvas does)

Tests:
  com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT
  com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT
---
 .../classes/javax/media/opengl/awt/GLCanvas.java   | 98 +++++++++++++++-------
 1 file changed, 67 insertions(+), 31 deletions(-)

(limited to 'src/jogl/classes/javax/media/opengl/awt')

diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index ab4276dee..e909416d9 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -59,8 +59,8 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.media.nativewindow.OffscreenLayerOption;
 import javax.media.nativewindow.WindowClosingProtocol;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -92,6 +92,8 @@ import com.jogamp.opengl.JoglVersion;
 
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
+
+import jogamp.nativewindow.jawt.JAWTWindow;
 import jogamp.opengl.Debug;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableHelper;
@@ -136,7 +138,7 @@ import jogamp.opengl.ThreadingImpl;
  */
 
 @SuppressWarnings("serial")
-public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol, OffscreenLayerOption {
 
   private static final boolean DEBUG;
 
@@ -156,6 +158,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   private GLContext shareWith;
   private int additionalCtxCreationFlags = 0;  
   private GraphicsDevice device;
+  private boolean shallUseOffscreenLayer = false;
 
   private AWTWindowClosingProtocol awtWindowClosingProtocol =
           new AWTWindowClosingProtocol(this, new Runnable() {
@@ -250,6 +253,22 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     this.device = device;
   }
 
+  public void setShallUseOffscreenLayer(boolean v) {
+      shallUseOffscreenLayer = v;
+  }
+
+  public final boolean getShallUseOffscreenLayer() {
+      return shallUseOffscreenLayer;        
+  }
+
+  public final boolean isOffscreenLayerSurfaceEnabled() {
+      if(null != drawable) {
+          return ((JAWTWindow)drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+      }
+      return false;
+  }
+
+  
   /**
    * Overridden to choose a GraphicsConfiguration on a parent container's
    * GraphicsDevice because both devices
@@ -406,15 +425,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
   private void dispose(boolean regenerate) {
     drawableSync.lock();
     try {
+        final GLAnimatorControl animator =  getAnimator();
         if(DEBUG) {
-            Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
-                    (null!=context) + ", hasDrawable " + (null!=drawable));
+            Exception ex1 = new Exception("Info: dispose("+regenerate+") - START, hasContext " +
+                    (null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
             ex1.printStackTrace();
         }
 
         if(null!=context) {
             boolean animatorPaused = false;
-            GLAnimatorControl animator =  getAnimator();
             if(null!=animator) {
                 // can't remove us from animator for recreational addNotify()
                 animatorPaused = animator.pause();
@@ -452,7 +471,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         }
 
         if(DEBUG) {
-            System.err.println("dispose("+regenerate+") - stop");
+            System.err.println("dispose("+regenerate+") - END, "+animator);
         }
     } finally {
         drawableSync.unlock();
@@ -532,15 +551,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
             throw new GLException("Error: NULL AWTGraphicsConfiguration");
         }
 
-        if (!Beans.isDesignTime()) {
-            // no lock required, since this resource ain't available yet
-            drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
-                           .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
-            context = (GLContextImpl) drawable.createContext(shareWith);
-            context.setSynchronized(true);
-            context.setContextCreationFlags(additionalCtxCreationFlags);            
-        }
-
         // before native peer is valid: X11
         disableBackgroundErase();
 
@@ -550,6 +560,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
         // after native peer is valid: Windows
         disableBackgroundErase();
 
+        if (!Beans.isDesignTime()) {
+            createDrawableAndContext();
+        }
+
         // init drawable by paint/display makes the init sequence more equal
         // for all launch flavors (applet/javaws/..)
         // validateGLDrawable();
@@ -562,6 +576,21 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     }
   }
 
+  private void createDrawableAndContext() {
+    // no lock required, since this resource ain't available yet
+    final JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+    jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+    jawtWindow.lockSurface();
+    try {
+        drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+        context = (GLContextImpl) drawable.createContext(shareWith);
+        context.setSynchronized(true);
+        context.setContextCreationFlags(additionalCtxCreationFlags);
+    } finally {
+        jawtWindow.unlockSurface();
+    }
+  }
+  
   private boolean validateGLDrawable() {
     boolean realized = false;
     if (!Beans.isDesignTime()) {
@@ -636,7 +665,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     @Override
   public void reshape(int x, int y, int width, int height) {
     super.reshape(x, y, width, height);
-    sendReshape = true;
+    if(null != drawable && drawable.isRealized() && !drawable.getChosenGLCapabilities().isOnscreen()) {
+        dispose(true);
+    } else {
+        sendReshape = true;
+    }
   }
 
   /** <B>Overrides:</B>
@@ -811,21 +844,24 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
       }
 
       if(null!=drawable) {
+          final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
           drawable.setRealized(false);
           drawable=null;
+          if(null!=jawtWindow) {
+            jawtWindow.destroy();
+          }          
       }
-
+      
       if(disposeRegenerate) {
-          // recreate GLDrawable to reflect it's new graphics configuration
-          drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
-                        .createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig));
+          // Similar process as in addNotify()!
+          
+          // Recreate GLDrawable/GLContext to reflect it's new graphics configuration
+          createDrawableAndContext();
+          
           if(DEBUG) {
             System.err.println("GLCanvas.dispose(true): new drawable: "+drawable);
           }
-          drawable.setRealized(true);
-          context = (GLContextImpl) drawable.createContext(shareWith);
-          context.setSynchronized(true);
-          sendReshape=true; // ensure a reshape is being send ..
+          validateGLDrawable(); // immediate attempt to recreate the drawable
       }
     }
   }
@@ -843,20 +879,20 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
 
   class DisposeAbstractGraphicsDeviceAction implements Runnable {
     public void run() {
-      AbstractGraphicsConfiguration aconfig = (null!=awtConfig) ? awtConfig.getNativeGraphicsConfiguration() : null;
-      AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
-      AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null;
-      if(null!=adevice) {
-          String adeviceMsg=null;
+      if(null != awtConfig) {
+          final AbstractGraphicsDevice adevice = awtConfig.getScreen().getDevice();
+          final String adeviceMsg;
           if(DEBUG) {
             adeviceMsg = adevice.toString();
+          } else {
+            adeviceMsg = null;  
           }
-          boolean closed = adevice.close();
+          boolean closed = awtConfig.getScreen().getDevice().close();
           if(DEBUG) {
             System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
           }
+          awtConfig=null;
       }
-      awtConfig=null;
     }
   }
   private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
-- 
cgit v1.2.3