From a0c04406276133db40cd39799a0f845369385400 Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Mon, 10 Jul 2006 20:18:26 +0000
Subject: Added code to support new entry points in
 sun.java2d.opengl.CGLSurfaceData added by gziemski to enable the Java2D/JOGL
 bridge on Mac OS X. Currently untested.

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@838 232f8b59-042b-4e1e-8c03-345bb8c30851
---
 .../com/sun/opengl/impl/GLDrawableFactoryImpl.java |  12 ++
 src/classes/com/sun/opengl/impl/Java2D.java        |  88 +++++++++++++++
 .../com/sun/opengl/impl/Java2DGLContext.java       |  51 +++++++++
 .../impl/macosx/MacOSXGLDrawableFactory.java       |  11 ++
 .../opengl/impl/macosx/MacOSXJava2DGLContext.java  | 122 +++++++++++++++++++++
 .../impl/windows/WindowsGLDrawableFactory.java     |  10 ++
 .../sun/opengl/impl/x11/X11GLDrawableFactory.java  |  10 ++
 src/classes/javax/media/opengl/GLJPanel.java       |  13 ++-
 8 files changed, 315 insertions(+), 2 deletions(-)
 create mode 100644 src/classes/com/sun/opengl/impl/Java2DGLContext.java
 create mode 100644 src/classes/com/sun/opengl/impl/macosx/MacOSXJava2DGLContext.java

diff --git a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java
index 3f9580cc7..2991263b6 100644
--- a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java
@@ -40,6 +40,7 @@
 package com.sun.opengl.impl;
 
 import java.awt.Component;
+import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsDevice;
 import java.nio.*;
@@ -80,6 +81,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory implements
   // RTLD_LOCAL and we need to call dlsym(RTLD_DEFAULT)
   public abstract void loadGLULibrary();
 
+  //---------------------------------------------------------------------------
+  // Support for Java2D/JOGL bridge on Mac OS X; the external
+  // GLDrawable mechanism in the public API is sufficienit to
+  // implement this functionality on all other platforms
+  //
+
+  public abstract boolean canCreateContextOnJava2DSurface();
+
+  public abstract GLContext createContextOnJava2DSurface(Graphics g)
+    throws GLException;
+
   //----------------------------------------------------------------------
   // Gamma adjustment support
   // Thanks to the LWJGL team for illustrating how to make these
diff --git a/src/classes/com/sun/opengl/impl/Java2D.java b/src/classes/com/sun/opengl/impl/Java2D.java
index 457c819bd..137545512 100755
--- a/src/classes/com/sun/opengl/impl/Java2D.java
+++ b/src/classes/com/sun/opengl/impl/Java2D.java
@@ -88,6 +88,15 @@ public class Java2D {
   private static boolean initializedJ2DFBOShareContext;
   private static GLContext j2dFBOShareContext;
 
+  // Accessors for new methods in sun.java2d.opengl.CGLSurfaceData
+  // class on OS X for enabling bridge
+  //  public static long    createOGLContextOnSurface(Graphics g);
+  //  public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx);
+  //  public static void    destroyOGLContext(long ctx);
+  private static Method createOGLContextOnSurfaceMethod;
+  private static Method makeOGLContextCurrentOnSurfaceMethod;
+  private static Method destroyOGLContextMethod;
+
   static {
     AccessController.doPrivileged(new PrivilegedAction() {
         public Object run() {
@@ -177,6 +186,40 @@ public class Java2D {
                   System.err.println("GL_ARB_texture_rectangle FBO support disabled");
                 }
               }
+
+              // Try to set up APIs for enabling the bridge on OS X,
+              // where it isn't possible to create generalized
+              // external GLDrawables
+              Class cglSurfaceData = null;
+              try {
+                cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
+              } catch (Exception e) {
+                if (DEBUG && VERBOSE) {
+                  e.printStackTrace();
+                  System.err.println("Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
+                }
+              }
+              if (cglSurfaceData != null) {
+                // We need to find these methods in order to make the bridge work on OS X
+                createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
+                                                                                   new Class[] {
+                                                                                     Graphics.class
+                                                                                   });
+                createOGLContextOnSurfaceMethod.setAccessible(true);
+
+                makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
+                                                                                        new Class[] {
+                                                                                          Graphics.class,
+                                                                                          Long.TYPE
+                                                                                        });
+                makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
+
+                destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
+                                                                           new Class[] {
+                                                                             Long.TYPE
+                                                                           });
+                destroyOGLContextMethod.setAccessible(true);
+              }
             } catch (Exception e) {
               if (DEBUG && VERBOSE) {
                 e.printStackTrace();
@@ -396,6 +439,51 @@ public class Java2D {
     return j2dFBOShareContext;
   }
 
+  //----------------------------------------------------------------------
+  // Mac OS X-specific methods
+  //
+
+  /** (Mac OS X-specific) Creates a new OpenGL context on the surface associated with the
+      given Graphics object. */
+  public static long createOGLContextOnSurface(Graphics g) {
+    checkActive();
+
+    try {
+      return ((Long) createOGLContextOnSurfaceMethod.invoke(null, new Object[] { g })).longValue();
+    } catch (InvocationTargetException e) {
+      throw new GLException(e.getTargetException());
+    } catch (Exception e) {
+      throw (InternalError) new InternalError().initCause(e);
+    }
+  }
+
+  /** (Mac OS X-specific) Makes the given OpenGL context current on
+      the surface associated with the given Graphics object. */
+  public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
+    checkActive();
+
+    try {
+      return ((Boolean) makeOGLContextCurrentOnSurfaceMethod.invoke(null, new Object[] { g, new Long(ctx) })).booleanValue();
+    } catch (InvocationTargetException e) {
+      throw new GLException(e.getTargetException());
+    } catch (Exception e) {
+      throw (InternalError) new InternalError().initCause(e);
+    }
+  }
+
+  /** (Mac OS X-specific) Destroys the given OpenGL context. */
+  public static void destroyOGLContext(long ctx) {
+    checkActive();
+
+    try {
+      destroyOGLContextMethod.invoke(null, new Object[] { new Long(ctx) });
+    } catch (InvocationTargetException e) {
+      throw new GLException(e.getTargetException());
+    } catch (Exception e) {
+      throw (InternalError) new InternalError().initCause(e);
+    }
+  }
+
   //----------------------------------------------------------------------
   // Internals only below this point
   //
diff --git a/src/classes/com/sun/opengl/impl/Java2DGLContext.java b/src/classes/com/sun/opengl/impl/Java2DGLContext.java
new file mode 100644
index 000000000..86bcb6482
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/Java2DGLContext.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution 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.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ * 
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.sun.opengl.impl;
+
+import java.awt.Graphics;
+
+/** Provides a construct by which the shared GLJPanel code can
+ * interact with a few methods in the Mac OS X-specific Java2D/JOGL
+ * bridge implementation.
+ */
+
+public interface Java2DGLContext {
+  public void setGraphics(Graphics g);
+}
\ No newline at end of file
diff --git a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java
index facf9e648..855512213 100644
--- a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java
+++ b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java
@@ -41,6 +41,7 @@ package com.sun.opengl.impl.macosx;
 
 import java.awt.Component;
 import java.awt.EventQueue;
+import java.awt.Graphics;
 import java.lang.reflect.InvocationTargetException;
 import java.nio.*;
 import java.util.*;
@@ -142,6 +143,16 @@ public class MacOSXGLDrawableFactory extends GLDrawableFactoryImpl {
   public void unlockAWTForJava2D() {
   }
 
+  public boolean canCreateContextOnJava2DSurface() {
+    return true;
+  }
+
+  public GLContext createContextOnJava2DSurface(Graphics g)
+    throws GLException {
+    return new MacOSXJava2DGLContext();
+  }
+  
+
   //------------------------------------------------------
   // Gamma-related functionality
   //
diff --git a/src/classes/com/sun/opengl/impl/macosx/MacOSXJava2DGLContext.java b/src/classes/com/sun/opengl/impl/macosx/MacOSXJava2DGLContext.java
new file mode 100644
index 000000000..bea74cc8f
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/macosx/MacOSXJava2DGLContext.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution 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.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ * 
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.sun.opengl.impl.macosx;
+
+import java.awt.Graphics;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+/** MacOSXGLContext implementation supporting the Java2D/JOGL bridge
+ * on Mac OS X. The external GLDrawable mechanism does not work on Mac
+ * OS X due to how drawables and contexts are operated upon on this
+ * platform, so it is necessary to supply an alternative means to
+ * create, make current, and destroy contexts on the Java2D "drawable"
+ * on the Mac platform.
+ */
+
+public class MacOSXJava2DGLContext extends MacOSXGLContext implements Java2DGLContext {
+  private Graphics graphics;
+
+  // FIXME: ignoring context sharing for the time being; will need to
+  // rethink this in particular if using FBOs to implement the
+  // Java2D/OpenGL pipeline on Mac OS X
+
+  public MacOSXJava2DGLContext() {
+    super(null, null);
+  }
+
+  public void setGraphics(Graphics g) {
+    this.graphics = g;
+  }
+
+  protected int makeCurrentImpl() throws GLException {
+    boolean created = false;
+    if (nsContext == 0) {
+      if (!create()) {
+        return CONTEXT_NOT_CURRENT;
+      }
+      if (DEBUG) {
+        System.err.println("!!! Created GL nsContext for " + getClass().getName());
+      }
+      created = true;
+    }
+            
+    if (!Java2D.makeOGLContextCurrentOnSurface(graphics, nsContext)) {
+      throw new GLException("Error making context current");
+    }
+            
+    if (created) {
+      resetGLFunctionAvailability();
+      return CONTEXT_CURRENT_NEW;
+    }
+    return CONTEXT_CURRENT;
+  }
+
+  protected boolean create() {
+    long ctx = Java2D.createOGLContextOnSurface(graphics);
+    if (ctx == 0) {
+      return false;
+    }
+    // FIXME: think about GLContext sharing
+    nsContext = ctx;
+    return true;
+  }
+
+  protected void releaseImpl() throws GLException {
+    // FIXME: would need another primitive in the Java2D class in
+    // order to implement this; hopefully should not matter for
+    // correctness
+  }
+
+  protected void destroyImpl() throws GLException {
+    if (nsContext != 0) {
+      Java2D.destroyOGLContext(nsContext);
+      if (DEBUG) {
+        System.err.println("!!! Destroyed OpenGL context " + nsContext);
+      }
+      nsContext = 0;
+      // FIXME
+      // GLContextShareSet.contextDestroyed(this);
+    }
+  }
+  
+
+  
+}
\ No newline at end of file
diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
index 94fd0eb1e..dada5d0c3 100644
--- a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
+++ b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java
@@ -40,6 +40,7 @@
 package com.sun.opengl.impl.windows;
 
 import java.awt.Component;
+import java.awt.Graphics;
 import java.awt.Rectangle;
 import java.nio.*;
 import java.util.*;
@@ -222,6 +223,15 @@ public class WindowsGLDrawableFactory extends GLDrawableFactoryImpl {
   public void unlockAWTForJava2D() {
   }
 
+  public boolean canCreateContextOnJava2DSurface() {
+    return false;
+  }
+
+  public GLContext createContextOnJava2DSurface(Graphics g)
+    throws GLException {
+    throw new GLException("Unimplemented on this platform");
+  }
+
   //------------------------------------------------------
   // Gamma-related functionality
   //
diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
index 01141c121..a5a174236 100644
--- a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
+++ b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
@@ -40,6 +40,7 @@
 package com.sun.opengl.impl.x11;
 
 import java.awt.Component;
+import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
@@ -526,6 +527,15 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
     }
   }
 
+  public boolean canCreateContextOnJava2DSurface() {
+    return false;
+  }
+
+  public GLContext createContextOnJava2DSurface(Graphics g)
+    throws GLException {
+    throw new GLException("Unimplemented on this platform");
+  }
+
   //---------------------------------------------------------------------------
   // Xinerama-related functionality
   //
diff --git a/src/classes/javax/media/opengl/GLJPanel.java b/src/classes/javax/media/opengl/GLJPanel.java
index 192c5f1b1..6ab2a9ec7 100644
--- a/src/classes/javax/media/opengl/GLJPanel.java
+++ b/src/classes/javax/media/opengl/GLJPanel.java
@@ -551,8 +551,13 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
                   j2dSurface = curSurface;
                 }
                 if (joglContext == null) {
-                  joglDrawable = GLDrawableFactory.getFactory().createExternalGLDrawable();
-                  joglContext = joglDrawable.createContext(shareWith);
+                  if (GLDrawableFactory.getFactory().canCreateExternalGLDrawable()) {
+                    joglDrawable = GLDrawableFactory.getFactory().createExternalGLDrawable();
+                    joglContext = joglDrawable.createContext(shareWith);
+                  } else if (GLDrawableFactoryImpl.getFactoryImpl().canCreateContextOnJava2DSurface()) {
+                    // Mac OS X code path
+                    joglContext = GLDrawableFactoryImpl.getFactoryImpl().createContextOnJava2DSurface(g);
+                  }
                   if (DEBUG) {
                     joglContext.setGL(new DebugGL(joglContext.getGL()));
                   }
@@ -563,6 +568,10 @@ public class GLJPanel extends JPanel implements GLAutoDrawable {
                     createNewDepthBuffer = true;
                   }
                 }
+                if (joglContext instanceof Java2DGLContext) {
+                  // Mac OS X code path
+                  ((Java2DGLContext) joglContext).setGraphics(g);
+                }
 
                 if (DEBUG && VERBOSE && Java2D.isFBOEnabled()) {
                   System.err.print("-- Surface type: ");
-- 
cgit v1.2.3