From fbdf8c337805b02385bf43b65aad93c20a2e3ad2 Mon Sep 17 00:00:00 2001
From: Gerard Ziemski <gerard.ziemski@sun.com>
Date: Sun, 12 Oct 2003 06:31:59 +0000
Subject: Implemented PBuffers (available in >= Panther). Reimplemented window
 resizing using update listener

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@67 232f8b59-042b-4e1e-8c03-345bb8c30851
---
 .../games/jogl/impl/macosx/MacOSXGLContext.java    |  57 ++++++++++-
 .../jogl/impl/macosx/MacOSXOffscreenGLContext.java |  31 +++---
 .../jogl/impl/macosx/MacOSXOnscreenGLContext.java  |  84 ++++-----------
 .../jogl/impl/macosx/MacOSXPbufferGLContext.java   | 113 +++++++++++++++++++++
 4 files changed, 200 insertions(+), 85 deletions(-)
 create mode 100644 src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java

(limited to 'src/net/java/games/jogl/impl/macosx')

diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
index 53e5986ec..e6169a4b9 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
@@ -49,6 +49,8 @@ public abstract class MacOSXGLContext extends GLContext
 {	
   private static JAWT jawt;
   protected long nsContext; // NSOpenGLContext
+  protected long nsView; // NSView
+  protected long updater; // ContextUpdater
   // Table that holds the addresses of the native C-language entry points for
   // OpenGL functions.
   private GLProcAddressTable glProcAddressTable;
@@ -61,6 +63,11 @@ public abstract class MacOSXGLContext extends GLContext
     super(component, capabilities, chooser, shareWith);
   }
 	
+  protected GL createGL()
+  {
+    return new MacOSXGLImpl(this);
+  }
+  
   protected String mapToRealGLFunctionName(String glFunctionName)
   {
     return glFunctionName;
@@ -88,11 +95,51 @@ public abstract class MacOSXGLContext extends GLContext
    * Creates and initializes an appropriate OpenGl nsContext. Should only be
    * called by {@link makeCurrent(Runnable)}.
    */
-  protected abstract void create();
+  protected void create() {
+    MacOSXGLContext other = (MacOSXGLContext) GLContextShareSet.getShareContext(this);
+    long share = 0;
+    if (other != null) {
+      share = other.getNSContext();
+      if (share == 0) {
+        throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+      }
+    }
+    nsContext = CGL.createContext(share, nsView);
+    if (nsContext == 0) {
+      throw new GLException("Error creating nsContext");
+    }
+	updater = CGL.updateContextRegister(nsContext, nsView);
+    GLContextShareSet.contextCreated(this);
+  }    
 	
-  protected abstract boolean makeCurrent(Runnable initAction) throws GLException;
+  protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+      boolean created = false;
+      if (nsContext == 0) {
+        create();
+        if (DEBUG) {
+          System.err.println("!!! Created GL nsContext for " + getClass().getName());
+        }
+        created = true;
+      }
+            
+      if (!CGL.makeCurrentContext(nsContext, nsView)) {
+        throw new GLException("Error making nsContext current");
+      }
+            
+      if (created) {
+        resetGLFunctionAvailability();
+        if (initAction != null) {
+          initAction.run();
+        }
+      }
+      return true;
+  }
 	
-  protected abstract void free() throws GLException;
+  protected synchronized void free() throws GLException {
+      if (!CGL.clearCurrentContext(nsContext, nsView)) {
+        throw new GLException("Error freeing OpenGL nsContext");
+      }
+  }
 	
   protected abstract void swapBuffers() throws GLException;
 	
@@ -136,6 +183,10 @@ public abstract class MacOSXGLContext extends GLContext
     return nsContext;
   }
 
+  protected long getNSView() {
+    return nsView;
+  }
+
   protected JAWT getJAWT()
   {
     if (jawt == null)
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
index e9f3bed24..431710a7c 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
@@ -48,12 +48,11 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
   // Width and height of the underlying bitmap
   private int  width;
   private int  height;
-	
+  
   public MacOSXOffscreenGLContext(GLCapabilities capabilities,
                                   GLCapabilitiesChooser chooser,
                                   GLContext shareWith) {
     super(null, capabilities, chooser, shareWith);
-    System.err.println("MacOSXOffscreenGLContext not implemented yet");
   }
 	
   protected GL createGL() {
@@ -65,15 +64,10 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
   }
 	
   public int getOffscreenContextBufferedImageType() {
-    if (capabilities.getAlphaBits() > 0) {
       return BufferedImage.TYPE_INT_ARGB;
-    } else {
-      return BufferedImage.TYPE_INT_RGB;
-    }
   }
 	
   public int getOffscreenContextReadBuffer() {
-    // On Windows these nsContexts are always single-buffered
     return GL.GL_FRONT;
   }
 	
@@ -100,22 +94,23 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
   }
 	
   protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
-    return false;
+    if (pendingOffscreenResize) {
+      if (pendingOffscreenWidth != width || pendingOffscreenHeight != height) {
+        if (nsContext != 0) {
+          destroy();
+        }
+        width  = pendingOffscreenWidth;
+        height = pendingOffscreenHeight;
+        pendingOffscreenResize = false;
+      }
+    }
+    return super.makeCurrent(initAction);
   }
 	
   protected synchronized void swapBuffers() throws GLException {
-    throw new GLException("Not yet implemented");
-  }
-	
-  protected synchronized void free() throws GLException {
-    throw new GLException("Not yet implemented");
-  }
-
-  protected void create() {
-    throw new GLException("Not yet implemented");
   }
 	
   private void destroy() {
-    throw new GLException("Not yet implemented");
+	free();
   }
 }
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
index 8f75fd561..ec46de0d8 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
@@ -50,33 +50,17 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
   private JAWT_DrawingSurface ds;
   private JAWT_DrawingSurfaceInfo dsi;
   private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
-  private long nsView; // NSView
-  private Runnable myDeferredReshapeAction;
     
+  // Variables for pbuffer support
+  List pbuffersToInstantiate = new ArrayList();
+
   public MacOSXOnscreenGLContext(Component component,
                                  GLCapabilities capabilities,
                                  GLCapabilitiesChooser chooser,
                                  GLContext shareWith) {
     super(component, capabilities, chooser, shareWith);
   }
-    
-  public synchronized void invokeGL(final Runnable runnable, boolean isReshape, Runnable initAction) throws GLException {
-    if (isReshape) {
-      myDeferredReshapeAction = new Runnable() {
-          public void run() {
-            CGL.updateContext(nsView, nsContext);
-            runnable.run();
-          }
-        };
-    } else {
-      if (myDeferredReshapeAction != null) {
-        super.invokeGL(myDeferredReshapeAction, true, initAction);
-        myDeferredReshapeAction = null;
-      }
-      super.invokeGL(runnable, isReshape, initAction);
-    }
-  }
-    
+
   protected GL createGL() {
     return new MacOSXGLImpl(this);
   }
@@ -98,12 +82,13 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
   }
     
   public boolean canCreatePbufferContext() {
-    // For now say no
-    return false;
+    return true;
   }
     
   public synchronized GLContext createPbufferContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
-    throw new GLException("Not supported");
+    MacOSXPbufferGLContext ctx = new MacOSXPbufferGLContext(capabilities, initialWidth, initialHeight);
+    pbuffersToInstantiate.add(ctx);
+    return ctx;
   }
     
   public void bindPbufferToTexture() {
@@ -122,72 +107,42 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
     // yet on this platform. This method can be deleted once
     // the update for that release ships.
   }
-
-  protected void create() {
-    MacOSXGLContext other = (MacOSXGLContext) GLContextShareSet.getShareContext(this);
-    long share = 0;
-    if (other != null) {
-      share = other.getNSContext();
-      if (share == 0) {
-        throw new GLException("GLContextShareSet returned an invalid OpenGL context");
-      }
-    }
-    nsContext = CGL.createContext(nsView, share);
-    if (nsContext == 0) {
-      throw new GLException("Error creating nsContext");
-    }
-    GLContextShareSet.contextCreated(this);
-  }    
     
   protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
     try {
       if (!lockSurface()) {
         return false;
       }
-            
-      boolean created = false;
-      if (nsContext == 0) {
-        create();
-        if (DEBUG) {
-          System.err.println("!!! Created GL nsContext for " + getClass().getName());
-        }
-        created = true;
-      }
-            
-      if (!CGL.makeCurrentContext(nsView, nsContext)) {
-        throw new GLException("Error making nsContext current");
-      }
-            
-      if (created) {
-        resetGLFunctionAvailability();
-        if (initAction != null) {
-          initAction.run();
+      boolean ret = super.makeCurrent(initAction);
+      if (ret) {
+        // Instantiate any pending pbuffers
+        while (!pbuffersToInstantiate.isEmpty()) {
+          MacOSXPbufferGLContext ctx =
+            (MacOSXPbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+          ctx.createPbuffer(nsView, nsContext);
         }
       }
-      return true;
+      return ret;
     } catch (RuntimeException e) {
       try {
         unlockSurface();
       } catch (Exception e2) {
         // do nothing if unlockSurface throws
       }
-            
       throw(e); 
     }
   }
     
   protected synchronized void free() throws GLException {
     try {
-      if (!CGL.clearCurrentContext(nsView, nsContext)) {
-        throw new GLException("Error freeing OpenGL nsContext");
-      }
+      super.free();
     } finally {
       unlockSurface();
     }
   }
     
   protected synchronized void swapBuffers() throws GLException {
-    if (!CGL.flushBuffer(nsView, nsContext)) {
+    if (!CGL.flushBuffer(nsContext, nsView)) {
       throw new GLException("Error swapping buffers");
     }
   }
@@ -212,7 +167,8 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
     // OpenGL nsContext so it will be recreated
     if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
       if (nsContext != 0) {
-        if (!CGL.deleteContext(nsView, nsContext)) {
+		CGL.updateContextUnregister(nsContext, nsView, updater);
+        if (!CGL.deleteContext(nsContext, nsView)) {
           throw new GLException("Unable to delete old GL nsContext after surface changed");
         }
       }
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java
new file mode 100644
index 000000000..70068ce63
--- /dev/null
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java
@@ -0,0 +1,113 @@
+package net.java.games.jogl.impl.macosx;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class MacOSXPbufferGLContext extends MacOSXGLContext {
+  private static final boolean DEBUG = false;
+
+  private int  initWidth;
+  private int  initHeight;
+
+  private long pBuffer;
+  private int pBufferTextureName;
+  
+  private int  width;
+  private int  height;
+
+  // FIXME: kept around because we create the OpenGL context lazily to
+  // better integrate with the MacOSXGLContext framework
+  private long nsContextOfParent;
+
+  public MacOSXPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+    super(null, capabilities, null, null);
+    this.initWidth  = initialWidth;
+    this.initHeight = initialHeight;
+    if (initWidth <= 0 || initHeight <= 0) {
+      throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+			    initWidth + ", " + initHeight + "))");
+    }
+  }
+
+  public boolean canCreatePbufferContext() {
+    return false;
+  }
+
+  public GLContext createPbufferContext(GLCapabilities capabilities,
+                                        int initialWidth,
+                                        int initialHeight) {
+    throw new GLException("Not supported");
+  }
+
+  public void bindPbufferToTexture() {
+	pBufferTextureName = CGL.bindPBuffer(nsContextOfParent, pBuffer);
+  }
+
+  public void releasePbufferFromTexture() {
+	CGL.unbindPBuffer(nsContextOfParent, pBuffer, pBufferTextureName);
+  }
+
+  public void createPbuffer(long parentView, long parentContext) {
+    GL gl = getGL();
+    // Must initally grab OpenGL function pointers while parent's
+    // context is current because otherwise we don't have the cgl
+    // extensions available to us
+    resetGLFunctionAvailability();
+		
+	this.pBuffer = CGL.createPBuffer(nsContext, initWidth, initHeight);
+    if (this.pBuffer == 0) {
+      throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
+    }
+	
+	nsContextOfParent = parentContext;
+	
+	width = getNextPowerOf2(initWidth);
+	height = getNextPowerOf2(initHeight);
+	
+    if (DEBUG) {
+      System.err.println("Created pbuffer " + width + " x " + height);
+    }
+  }
+
+  public void handleModeSwitch(long parentView, long parentContext) {
+    throw new GLException("Not yet implemented");
+  }
+
+  protected boolean isOffscreen() {
+    // FIXME: currently the only caller of this won't cause proper
+    // resizing of the pbuffer anyway.
+    return false;
+  }
+
+  public int getOffscreenContextBufferedImageType() {
+    throw new GLException("Should not call this");
+  }
+
+  public int getOffscreenContextReadBuffer() {
+    throw new GLException("Should not call this");
+  }
+
+  public boolean offscreenImageNeedsVerticalFlip() {
+    throw new GLException("Should not call this");
+  }
+
+  protected void swapBuffers() throws GLException {
+    // FIXME: do we need to do anything if the pbuffer is double-buffered?
+  }
+
+  int getNextPowerOf2(int number)
+  {
+	if (((number-1) & number) == 0)
+	{
+		//ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+		return number;
+	}	
+	int power = 0;
+	while (number > 0)
+	{
+      number = number>>1;
+      power++;
+	}	
+	return (1<<power);
+  }
+}
-- 
cgit v1.2.3