From 006acbb9463af33a8b45aa0b3a298604eba72d82 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 21 Jun 2008 02:33:51 +0000 Subject: 2nd big refactoring. Goals are orthogonal components for: - OS Windowing system - NEWT, X11, Windows, MacOsX - GL Windowing GLUE - EGL, GLX, WGL, CGL - GL profiles - core and util packages - generate all Java components from any platform All above goals are achieved. TODO: - Native compilation fix and test - Check/Fix Win32, MacOSX and the mobile devices - .. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1665 232f8b59-042b-4e1e-8c03-345bb8c30851 --- .../opengl/impl/macosx/awt/MacOSXJAWTWindow.java | 103 +++++- .../opengl/impl/macosx/cgl/MacOSXCGLContext.java | 377 +++++++++++++++++++++ .../opengl/impl/macosx/cgl/MacOSXCGLDrawable.java | 117 +++++++ .../impl/macosx/cgl/MacOSXCGLDrawableFactory.java | 173 ++++++++++ .../impl/macosx/cgl/MacOSXExternalCGLContext.java | 123 +++++++ .../impl/macosx/cgl/MacOSXOffscreenCGLContext.java | 64 ++++ .../macosx/cgl/MacOSXOffscreenCGLDrawable.java | 54 +++ .../impl/macosx/cgl/MacOSXOnscreenCGLContext.java | 131 +++++++ .../impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java | 105 ++++++ .../impl/macosx/cgl/MacOSXPbufferCGLContext.java | 340 +++++++++++++++++++ .../impl/macosx/cgl/MacOSXPbufferCGLDrawable.java | 243 +++++++++++++ .../cgl/awt/MacOSXAWTCGLDrawableFactory.java | 64 ++++ .../macosx/cgl/awt/MacOSXJava2DCGLContext.java | 160 +++++++++ 13 files changed, 2044 insertions(+), 10 deletions(-) create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java create mode 100644 src/classes/com/sun/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java (limited to 'src/classes/com/sun/opengl/impl/macosx') diff --git a/src/classes/com/sun/opengl/impl/macosx/awt/MacOSXJAWTWindow.java b/src/classes/com/sun/opengl/impl/macosx/awt/MacOSXJAWTWindow.java index 5f676a138..44a34b98d 100644 --- a/src/classes/com/sun/opengl/impl/macosx/awt/MacOSXJAWTWindow.java +++ b/src/classes/com/sun/opengl/impl/macosx/awt/MacOSXJAWTWindow.java @@ -41,28 +41,111 @@ package com.sun.opengl.impl.macosx.awt; import com.sun.opengl.impl.macosx.*; import com.sun.opengl.impl.awt.*; +import com.sun.opengl.impl.*; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import javax.media.opengl.*; -import com.sun.opengl.impl.*; +import java.security.*; public class MacOSXJAWTWindow extends JAWTWindow { - // Variables for lockSurface/unlockSurface - //private JAWT_DrawingSurface ds; - //private JAWT_DrawingSurfaceInfo dsi; - //private JAWT_MacOSXDrawingSurfaceInfo x11dsi; - public MacOSXJAWTWindow(Object comp) { super(comp); } - public int lockSurface() throws NativeWindowException { - super.lockSurface(); - return 0; + protected void initNative() throws NativeWindowException { } - public void unlockSurface() { + public int lockSurface() throws NativeWindowException { + int ret = super.lockSurface(); + if(NativeWindow.LOCK_SUCCESS != ret) { + return ret; + } + ds = JAWT.getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + int res = ds.Lock(); + if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) { + throw new GLException("Unable to lock surface"); + } + // See whether the surface changed and if so destroy the old + // OpenGL context so it will be recreated (NOTE: removeNotify + // should handle this case, but it may be possible that race + // conditions can cause this code to be triggered -- should test + // more) + if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { + ret = NativeWindow.LOCK_SURFACE_CHANGED; + } + if (firstLock) { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + dsi = ds.GetDrawingSurfaceInfo(); + return null; + } + }); + } else { + dsi = ds.GetDrawingSurfaceInfo(); + } + if (dsi == null) { + // Widget not yet realized + ds.Unlock(); + JAWT.getJAWT().FreeDrawingSurface(ds); + ds = null; + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + firstLock = false; + macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(); + if (macosxdsi == null) { + // Widget not yet realized + ds.FreeDrawingSurfaceInfo(dsi); + ds.Unlock(); + JAWT.getJAWT().FreeDrawingSurface(ds); + ds = null; + dsi = null; + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + drawable = macosxdsi.cocoaViewRef(); + // FIXME: Are the followup abstractions available ? would it be usefull ? + display = 0; + visualID = 0; + screen= 0; + screenIndex = 0; + + if (drawable == 0) { + // Widget not yet realized + ds.FreeDrawingSurfaceInfo(dsi); + ds.Unlock(); + JAWT.getJAWT().FreeDrawingSurface(ds); + ds = null; + dsi = null; + macosxdsi = null; + return NativeWindow.LOCK_SURFACE_NOT_READY; + } + return ret; + } + + public void unlockSurface() throws GLException { + if(!isSurfaceLocked()) return; + ds.FreeDrawingSurfaceInfo(dsi); + ds.Unlock(); + JAWT.getJAWT().FreeDrawingSurface(ds); + ds = null; + dsi = null; + macosxdsi = null; super.unlockSurface(); } + + // Variables for lockSurface/unlockSurface + private JAWT_DrawingSurface ds; + private JAWT_DrawingSurfaceInfo dsi; + private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; + + // Workaround for instance of 4796548 + private boolean firstLock = true; + } diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java new file mode 100644 index 000000000..ad71774b5 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2003 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.cgl; + +import java.nio.*; +import java.util.*; +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public abstract class MacOSXCGLContext extends GLContextImpl +{ + protected MacOSXCGLDrawable drawable; + protected long nsContext; // NSOpenGLContext + private CGLExt cglExt; + // Table that holds the addresses of the native C-language entry points for + // CGL extension functions. + private CGLExtProcAddressTable cglExtProcAddressTable; + + public MacOSXCGLContext(MacOSXCGLDrawable drawable, + GLContext shareWith) + { + super(shareWith); + this.drawable = drawable; + } + + public Object getPlatformGLExtensions() { + return getCGLExt(); + } + + public CGLExt getCGLExt() { + if (cglExt == null) { + cglExt = new CGLExtImpl(this); + } + return cglExt; + } + + public GLDrawable getGLDrawable() { + return drawable; + } + + protected String mapToRealGLFunctionName(String glFunctionName) + { + return glFunctionName; + } + + protected String mapToRealGLExtensionName(String glExtensionName) + { + return glExtensionName; + } + + protected abstract boolean create(); + + /** + * Creates and initializes an appropriate OpenGl nsContext. Should only be + * called by {@link makeCurrentImpl()}. + */ + protected boolean create(boolean pbuffer, boolean floatingPoint) { + MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getNSContext(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + int[] viewNotReady = new int[1]; + GLCapabilities capabilities = drawable.getCapabilities(); + int[] iattribs = new int[128]; + int[] ivalues = new int[128]; + int idx = 0; + if (pbuffer) { + iattribs[idx] = CGL.NSOpenGLPFAPixelBuffer; ivalues[idx] = 1; idx++; + } + if (floatingPoint) { + iattribs[idx] = CGL.kCGLPFAColorFloat; ivalues[idx] = 1; idx++; + } + iattribs[idx] = CGL.NSOpenGLPFADoubleBuffer; ivalues[idx] = (capabilities.getDoubleBuffered() ? 1 : 0); idx++; + iattribs[idx] = CGL.NSOpenGLPFAStereo; ivalues[idx] = (capabilities.getStereo() ? 1 : 0); idx++; + iattribs[idx] = CGL.NSOpenGLPFAColorSize; ivalues[idx] = (capabilities.getRedBits() + + capabilities.getGreenBits() + + capabilities.getBlueBits()); idx++; + iattribs[idx] = CGL.NSOpenGLPFAAlphaSize; ivalues[idx] = capabilities.getAlphaBits(); idx++; + iattribs[idx] = CGL.NSOpenGLPFADepthSize; ivalues[idx] = capabilities.getDepthBits(); idx++; + iattribs[idx] = CGL.NSOpenGLPFAAccumSize; ivalues[idx] = (capabilities.getAccumRedBits() + + capabilities.getAccumGreenBits() + + capabilities.getAccumBlueBits() + + capabilities.getAccumAlphaBits()); idx++; + iattribs[idx] = CGL.NSOpenGLPFAStencilSize; ivalues[idx] = capabilities.getStencilBits(); idx++; + if (capabilities.getSampleBuffers()) { + iattribs[idx] = CGL.NSOpenGLPFASampleBuffers; ivalues[idx] = 1; idx++; + iattribs[idx] = CGL.NSOpenGLPFASamples; ivalues[idx] = capabilities.getNumSamples(); idx++; + } + + long pixelFormat = CGL.createPixelFormat(iattribs, 0, idx, ivalues, 0); + if (pixelFormat == 0) { + throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); + } + try { + // Try to allocate a context with this + nsContext = CGL.createContext(share, + drawable.getNativeWindow().getWindowHandle(), + pixelFormat, + viewNotReady, 0); + if (nsContext == 0) { + if (viewNotReady[0] == 1) { + if (DEBUG) { + System.err.println("!!! View not ready for " + getClass().getName()); + } + // View not ready at the window system level -- this is OK + return false; + } + throw new GLException("Error creating NSOpenGLContext with requested pixel format"); + } + + // On this platform the pixel format is associated with the + // context and not the drawable. However it's a reasonable + // approximation to just store the chosen pixel format up in the + // drawable since the public API doesn't provide for a different + // GLCapabilities per context. + if (drawable.getChosenGLCapabilities() == null) { + // Figure out what attributes we really got + GLCapabilities caps = new GLCapabilities(); + CGL.queryPixelFormat(pixelFormat, iattribs, 0, idx, ivalues, 0); + for (int i = 0; i < idx; i++) { + int attr = iattribs[i]; + switch (attr) { + case CGL.kCGLPFAColorFloat: + caps.setPbufferFloatingPointBuffers(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFADoubleBuffer: + caps.setDoubleBuffered(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFAStereo: + caps.setStereo(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFAColorSize: + { + int bitSize = ivalues[i]; + if (bitSize == 32) + bitSize = 24; + bitSize /= 3; + caps.setRedBits(bitSize); + caps.setGreenBits(bitSize); + caps.setBlueBits(bitSize); + } + break; + + case CGL.NSOpenGLPFAAlphaSize: + caps.setAlphaBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFADepthSize: + caps.setDepthBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFAAccumSize: + { + int bitSize = ivalues[i] / 4; + caps.setAccumRedBits(bitSize); + caps.setAccumGreenBits(bitSize); + caps.setAccumBlueBits(bitSize); + caps.setAccumAlphaBits(bitSize); + } + break; + + case CGL.NSOpenGLPFAStencilSize: + caps.setStencilBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFASampleBuffers: + caps.setSampleBuffers(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFASamples: + caps.setNumSamples(ivalues[i]); + break; + + default: + break; + } + } + + drawable.setChosenGLCapabilities(caps); + } + + + } finally { + CGL.deletePixelFormat(pixelFormat); + } + GLContextShareSet.contextCreated(this); + return true; + } + + protected int makeCurrentImpl() throws GLException { + if (drawable.getNativeWindow().getWindowHandle() == 0) { + if (DEBUG) { + System.err.println("drawable not properly initialized"); + } + return CONTEXT_NOT_CURRENT; + } + boolean created = false; + if (nsContext == 0) { + if (!create()) { + return CONTEXT_NOT_CURRENT; + } + if (DEBUG) { + System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName()); + } + created = true; + } + + if (!CGL.makeCurrentContext(nsContext)) { + throw new GLException("Error making nsContext current"); + } + + if (created) { + resetGLFunctionAvailability(); + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } + + protected void releaseImpl() throws GLException { + if (!CGL.clearCurrentContext(nsContext)) { + throw new GLException("Error freeing OpenGL nsContext"); + } + } + + protected void destroyImpl() throws GLException { + if (nsContext != 0) { + if (!CGL.deleteContext(nsContext)) { + throw new GLException("Unable to delete OpenGL context"); + } + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL context " + nsContext); + } + nsContext = 0; + GLContextShareSet.contextDestroyed(this); + } + } + + public boolean isCreated() { + return (nsContext != 0); + } + + public void copy(GLContext source, int mask) throws GLException { + long dst = getNSContext(); + long src = ((MacOSXCGLContext) source).getNSContext(); + if (src == 0) { + throw new GLException("Source OpenGL context has not been created"); + } + if (dst == 0) { + throw new GLException("Destination OpenGL context has not been created"); + } + CGL.copyContext(dst, src, mask); + } + + protected void resetGLFunctionAvailability() + { + super.resetGLFunctionAvailability(); + if (DEBUG) { + System.err.println("!!! Initializing CGL extension address table"); + } + if (cglExtProcAddressTable == null) { + // FIXME: cache ProcAddressTables by capability bits so we can + // share them among contexts with the same capabilities + cglExtProcAddressTable = new CGLExtProcAddressTable(); + } + resetProcAddressTable(getCGLExtProcAddressTable()); + } + + public final CGLExtProcAddressTable getCGLExtProcAddressTable() { + return cglExtProcAddressTable; + } + + public String getPlatformExtensionsString() + { + return ""; + } + + public void setSwapInterval(int interval) { + if (nsContext == 0) { + throw new GLException("OpenGL context not current"); + } + CGL.setSwapInterval(nsContext, interval); + } + + public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { + // FIXME: apparently the Apple extension doesn't require a custom memory allocator + throw new GLException("Not yet implemented"); + } + + public boolean isFunctionAvailable(String glFunctionName) + { + return super.isFunctionAvailable(glFunctionName); + } + + public boolean isExtensionAvailable(String glExtensionName) { + if (glExtensionName.equals("GL_ARB_pbuffer") || + glExtensionName.equals("GL_ARB_pixel_format")) { + return true; + } + return super.isExtensionAvailable(glExtensionName); + } + + public int getOffscreenContextPixelDataType() { + 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"); + } + + public void bindPbufferToTexture() { + throw new GLException("Should not call this"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Should not call this"); + } + + // Support for "mode switching" as described in MacOSXCGLDrawable + public abstract void setOpenGLMode(int mode); + public abstract int getOpenGLMode(); + + //---------------------------------------------------------------------- + // Internals only below this point + // + + public long getNSContext() { + return nsContext; + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java new file mode 100644 index 000000000..ccafc6738 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 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.cgl; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public abstract class MacOSXCGLDrawable extends GLDrawableImpl { + protected static final boolean DEBUG = Debug.debug("MacOSXCGLDrawable"); + + protected GLCapabilitiesChooser chooser; + + // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs + // to represent the contexts for e.g. the Java2D back buffer. When + // the Java2D/JOGL bridge is active, this means that if we want to + // be able to share textures and display lists with the Java2D + // contexts, we need to use the CGL APIs rather than the NSOpenGL + // APIs on the JOGL side. For example, if we create a pbuffer using + // the NSOpenGL APIs and want to share textures and display lists + // between it and the Java2D back buffer, there is no way to do so, + // because the Java2D context is actually a CGLContextObj and the + // NSOpenGLContext's initWithFormat:shareContext: only accepts an + // NSOpenGLContext as its second argument. Of course there is no way + // to wrap an NSOpenGLContext around an arbitrary CGLContextObj. + // + // The situation we care most about is allowing a GLPbuffer to share + // textures, etc. with a GLJPanel when the Java2D/JOGL bridge is + // active; several of the demos rely on this functionality. We aim + // to get there by allowing a GLPBuffer to switch its implementation + // between using an NSOpenGLPixelBuffer and a CGLPBufferObj. In + // order to track whether this has been done we need to have the + // notion of a "mode" of both the MacOSXCGLDrawable and the + // MacOSXGLContext. Initially the mode is "unspecified", meaning it + // leans toward the default (NSOpenGL). If sharing is requested + // between either a GLJPanel and a GLPbuffer or a GLCanvas and a + // GLPbuffer, the GLPbuffer will be switched into the appropriate + // mode: CGL mode for a GLJPanel and NSOpenGL mode for a GLCanvas. + // To avoid thrashing we support exactly one such switch during the + // lifetime of a given GLPbuffer. This is not a fully general + // solution (for example, you can't share textures among a + // GLPbuffer, a GLJPanel and a GLCanvas simultaneously) but should + // be enough to get things off the ground. + public static final int NSOPENGL_MODE = 1; + public static final int CGL_MODE = 2; + + public MacOSXCGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized, + GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + super(factory, comp, realized); + setChosenGLCapabilities(capabilities); + this.chooser = chooser; + } + + public void destroy() { + } + + public GLCapabilities getChosenGLCapabilities() { + int numFormats = 1; + GLCapabilities availableCaps[] = new GLCapabilities[numFormats]; + availableCaps[0] = super.getChosenGLCapabilities(); + int pixelFormat = chooser.chooseCapabilities(getCapabilities(), availableCaps, 0); + if ((pixelFormat < 0) || (pixelFormat >= numFormats)) { + throw new GLException("Invalid result " + pixelFormat + + " from GLCapabilitiesChooser (should be between 0 and " + + (numFormats - 1) + ")"); + } + if (DEBUG) { + System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); + System.err.println(availableCaps[pixelFormat]); + } + return availableCaps[pixelFormat]; + } + + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + + // Support for "mode switching" as per above + public abstract void setOpenGLMode(int mode); + public abstract int getOpenGLMode(); +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java new file mode 100644 index 000000000..ae108121c --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2003 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.cgl; + +import java.lang.reflect.InvocationTargetException; +import java.nio.*; +import java.util.*; +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { + static { + NativeLibLoader.loadCore(); + } + + public MacOSXCGLDrawableFactory() { + super(); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice device) { + return null; + } + + public GLDrawable createGLDrawable(NativeWindow target, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + if (capabilities == null) { + capabilities = new GLCapabilities(); + } + if (chooser == null) { + chooser = new DefaultGLCapabilitiesChooser(); + } + return new MacOSXOnscreenCGLDrawable(this, target, capabilities, chooser); + } + + public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, + GLCapabilitiesChooser chooser) { + return new MacOSXOffscreenCGLDrawable(this, capabilities); + } + + public boolean canCreateGLPbuffer() { + return true; + } + + public GLPbuffer createGLPbuffer(final GLCapabilities capabilities, + final GLCapabilitiesChooser chooser, + final int initialWidth, + final int initialHeight, + final GLContext shareWith) { + final List returnList = new ArrayList(); + final GLDrawableFactory factory = this; + Runnable r = new Runnable() { + public void run() { + MacOSXPbufferCGLDrawable pbufferDrawable = new MacOSXPbufferCGLDrawable(factory, capabilities, + initialWidth, + initialHeight); + GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith); + returnList.add(pbuffer); + } + }; + maybeDoSingleThreadedWorkaround(r); + return (GLPbuffer) returnList.get(0); + } + + public GLContext createExternalGLContext() { + return new MacOSXExternalCGLContext(); + } + + public boolean canCreateExternalGLDrawable() { + return false; + } + + public GLDrawable createExternalGLDrawable() { + // FIXME + throw new GLException("Not yet implemented"); + } + + public void loadGLULibrary() { + // Nothing to do; already loaded by native code; not much point in + // making it lazier on this platform + } + + public long dynamicLookupFunction(String glFuncName) { + return CGL.getProcAddress(glFuncName); + } + + private void maybeDoSingleThreadedWorkaround(Runnable action) { + if (Threading.isSingleThreaded() && + !Threading.isOpenGLThread()) { + Threading.invokeOnOpenGLThread(action); + } else { + action.run(); + } + } + + public boolean canCreateContextOnJava2DSurface() { + return false; + } + + public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) + throws GLException { + throw new GLException("not supported in non AWT enviroment"); + } + + //------------------------------------------------------ + // Gamma-related functionality + // + + private static final int GAMMA_RAMP_LENGTH = 256; + + /** Returns the length of the computed gamma ramp for this OS and + hardware. Returns 0 if gamma changes are not supported. */ + protected int getGammaRampLength() { + return GAMMA_RAMP_LENGTH; + } + + protected boolean setGammaRamp(float[] ramp) { + return CGL.setGammaRamp(ramp.length, + ramp, 0, + ramp, 0, + ramp, 0); + } + + protected Buffer getGammaRamp() { + return null; + } + + protected void resetGammaRamp(Buffer originalGammaRamp) { + CGL.resetGammaRamp(); + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java new file mode 100644 index 000000000..b19e221f0 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2005 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.cgl; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXExternalCGLContext extends MacOSXCGLContext { + private boolean firstMakeCurrent = true; + private boolean created = true; + private GLContext lastContext; + + public MacOSXExternalCGLContext() { + super(null, null); + + // FIXME: we don't have a "current context" primitive implemented + // yet on OS X. In the current implementation this would need to + // return an NSOpenGLContext*, but "external" toolkits are not + // guaranteed to be using the Cocoa OpenGL API. Additionally, if + // we switched this implementation to use the low-level CGL APIs, + // we would lose the ability to share textures and display lists + // between contexts since you need an NSOpenGLContext, not a + // CGLContextObj, in order to share textures and display lists + // between two NSOpenGLContexts. + // + // The ramifications here are that it is not currently possible to + // share textures and display lists between an OpenGL context + // created by JOGL and one created by a third-party library on OS + // X. + + // context = CGL.CGLGetCurrentContext(); + + GLContextShareSet.contextCreated(this); + resetGLFunctionAvailability(); + } + + protected boolean create() { + return true; + } + + public int makeCurrent() throws GLException { + // Save last context if necessary to allow external GLContexts to + // talk to other GLContexts created by this library + GLContext cur = getCurrent(); + if (cur != null && cur != this) { + lastContext = cur; + setCurrent(null); + } + return super.makeCurrent(); + } + + public void release() throws GLException { + super.release(); + setCurrent(lastContext); + lastContext = null; + } + + protected int makeCurrentImpl() throws GLException { + if (firstMakeCurrent) { + firstMakeCurrent = false; + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } + + protected void releaseImpl() throws GLException { + } + + protected void destroyImpl() throws GLException { + created = false; + GLContextShareSet.contextDestroyed(this); + } + + public boolean isCreated() { + return created; + } + + public void setOpenGLMode(int mode) { + if (mode != MacOSXCGLDrawable.NSOPENGL_MODE) + throw new GLException("OpenGL mode switching not supported for external GLContexts"); + } + + public int getOpenGLMode() { + return MacOSXCGLDrawable.NSOPENGL_MODE; + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java new file mode 100644 index 000000000..b60c48237 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2003 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.cgl; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXOffscreenCGLContext extends MacOSXPbufferCGLContext +{ + public MacOSXOffscreenCGLContext(MacOSXPbufferCGLDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + public int getOffscreenContextPixelDataType() { + GL gl = getGL(); + return gl.isGL2()?GL2.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1; + } + + public int getOffscreenContextReadBuffer() { + return GL.GL_FRONT; + } + + public boolean offscreenImageNeedsVerticalFlip() { + return true; + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java new file mode 100644 index 000000000..bf3e402cc --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003 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.cgl; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable { + + public MacOSXOffscreenCGLDrawable(GLDrawableFactory factory, GLCapabilities capabilities) { + super(factory, capabilities, 0, 0); + } + + public GLContext createContext(GLContext shareWith) { + return new MacOSXOffscreenCGLContext(this, shareWith); + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java new file mode 100644 index 000000000..1165e759d --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2003 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.cgl; + +import java.util.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { + protected MacOSXOnscreenCGLDrawable drawable; + + public MacOSXOnscreenCGLContext(MacOSXOnscreenCGLDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + this.drawable = drawable; + } + + protected int makeCurrentImpl() throws GLException { + int lockRes = drawable.lockSurface(); + boolean exceptionOccurred = false; + try { + if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { + return CONTEXT_NOT_CURRENT; + } + if (lockRes == NativeWindow.LOCK_SURFACE_CHANGED) { + destroyImpl(); + } + int ret = super.makeCurrentImpl(); + if ((ret == CONTEXT_CURRENT) || + (ret == CONTEXT_CURRENT_NEW)) { + // Assume the canvas might have been resized or moved and tell the OpenGL + // context to update itself. This used to be done only upon receiving a + // reshape event but that doesn't appear to be sufficient. An experiment + // was also done to add a HierarchyBoundsListener to the GLCanvas and + // do this updating only upon reshape of this component or reshape or movement + // of an ancestor, but this also wasn't sufficient and left garbage on the + // screen in some situations. + CGL.updateContext(nsContext); + } else { + if (!isOptimizable()) { + // This can happen if the window currently is zero-sized, for example. + // Make sure we don't leave the surface locked in this case. + drawable.unlockSurface(); + } + } + return ret; + } catch (RuntimeException e) { + exceptionOccurred = true; + throw e; + } finally { + if (exceptionOccurred || + (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY)) { + drawable.unlockSurface(); + } + } + } + + protected void releaseImpl() throws GLException { + try { + super.releaseImpl(); + } finally { + if (!isOptimizable()) { + drawable.unlockSurface(); + } + } + } + + public void swapBuffers() throws GLException { + if (!CGL.flushBuffer(nsContext)) { + throw new GLException("Error swapping buffers"); + } + } + + protected void update() throws GLException { + if (nsContext == 0) { + throw new GLException("Context not created"); + } + CGL.updateContext(nsContext); + } + + protected boolean create() { + return create(false, false); + } + + public void setOpenGLMode(int mode) { + if (mode != MacOSXCGLDrawable.NSOPENGL_MODE) + throw new GLException("OpenGL mode switching not supported for on-screen GLContexts"); + } + + public int getOpenGLMode() { + return MacOSXCGLDrawable.NSOPENGL_MODE; + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java new file mode 100644 index 000000000..cb2799f5c --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003 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.cgl; + +import java.lang.ref.WeakReference; +import java.security.*; +import java.util.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable { + private List/*>*/ createdContexts = + new ArrayList(); + + protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeWindow component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser) { + super(factory, component, false, capabilities, chooser); + } + + public GLContext createContext(GLContext shareWith) { + MacOSXOnscreenCGLContext context = + new MacOSXOnscreenCGLContext(this, shareWith); + // NOTE: we need to keep track of the created contexts in order to + // implement swapBuffers() because of how Mac OS X implements its + // OpenGL window interface + synchronized (this) { + List newContexts = new ArrayList(); + newContexts.addAll(createdContexts); + newContexts.add(new WeakReference(context)); + createdContexts = newContexts; + } + return context; + } + + public void setSize(int width, int height) { + component.setSize(width, height); + } + + public int getWidth() { + return component.getWidth(); + } + + public int getHeight() { + return component.getHeight(); + } + + public void swapBuffers() throws GLException { + for (Iterator iter = createdContexts.iterator(); iter.hasNext(); ) { + WeakReference ref = (WeakReference) iter.next(); + MacOSXOnscreenCGLContext ctx = (MacOSXOnscreenCGLContext) ref.get(); + // FIXME: clear out unreachable contexts + if (ctx != null) { + ctx.swapBuffers(); + } + } + } + + public void setOpenGLMode(int mode) { + if (mode != NSOPENGL_MODE) + throw new GLException("OpenGL mode switching not supported for on-screen GLDrawables"); + } + + public int getOpenGLMode() { + return NSOPENGL_MODE; + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java new file mode 100644 index 000000000..7b29dbfb6 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java @@ -0,0 +1,340 @@ +package com.sun.opengl.impl.macosx.cgl; + +import java.security.*; +import java.util.*; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXPbufferCGLContext extends MacOSXCGLContext { + protected MacOSXPbufferCGLDrawable drawable; + + // State for render-to-texture and render-to-texture-rectangle support + private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV + private int texture; // actual texture object + + private static boolean isTigerOrLater; + + static { + String osVersion = + (String) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty("os.version"); + } + }); + StringTokenizer tok = new StringTokenizer(osVersion, ". "); + int major = Integer.parseInt(tok.nextToken()); + int minor = Integer.parseInt(tok.nextToken()); + isTigerOrLater = ((major > 10) || (minor > 3)); + } + + public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + this.drawable = drawable; + initOpenGLImpl(); + } + + public void bindPbufferToTexture() { + GL gl = getGL(); + gl.glBindTexture(textureTarget, texture); + // FIXME: not clear whether this is really necessary, but since + // the API docs seem to imply it is and since it doesn't seem to + // impact performance, leaving it in + CGL.setContextTextureImageToPBuffer(nsContext, drawable.getPbuffer(), GL.GL_FRONT); + } + + public void releasePbufferFromTexture() { + } + + protected int makeCurrentImpl() throws GLException { + if (drawable.getPbuffer() == 0) { + if (DEBUG) { + System.err.println("Pbuffer not instantiated yet for " + this); + } + // pbuffer not instantiated yet + return CONTEXT_NOT_CURRENT; + } + + if (getOpenGLMode() != drawable.getOpenGLMode()) { + setOpenGLMode(drawable.getOpenGLMode()); + } + + boolean created = false; + if (nsContext == 0) { + if (!create()) { + return CONTEXT_NOT_CURRENT; + } + if (DEBUG) { + System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName()); + } + created = true; + } + + if (!impl.makeCurrent(nsContext)) { + throw new GLException("Error making nsContext current"); + } + + if (created) { + resetGLFunctionAvailability(); + + // Initialize render-to-texture support if requested + GL gl = getGL(); + boolean rect = gl.isGL2() && drawable.getCapabilities().getPbufferRenderToTextureRectangle(); + if (rect) { + if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) { + System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " + + "supported; skipping requested render_to_texture_rectangle support for pbuffer"); + rect = false; + } + } + textureTarget = (rect ? GL2.GL_TEXTURE_RECTANGLE_EXT : GL.GL_TEXTURE_2D); + int[] tmp = new int[1]; + gl.glGenTextures(1, tmp, 0); + texture = tmp[0]; + gl.glBindTexture(textureTarget, texture); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); + gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0); + + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } + + protected void releaseImpl() throws GLException { + if (!impl.release(nsContext)) { + throw new GLException("Error releasing OpenGL nsContext"); + } + } + + protected void destroyImpl() throws GLException { + if (nsContext != 0) { + if (!impl.destroy(nsContext)) { + throw new GLException("Unable to delete OpenGL context"); + } + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL context " + nsContext); + } + nsContext = 0; + GLContextShareSet.contextDestroyed(this); + } + } + + public void setSwapInterval(int interval) { + if (nsContext == 0) { + throw new GLException("OpenGL context not current"); + } + impl.setSwapInterval(nsContext, interval); + } + + public int getFloatingPointMode() { + return GLPbuffer.APPLE_FLOAT; + } + + protected boolean create() { + GLCapabilities capabilities = drawable.getCapabilities(); + if (capabilities.getPbufferFloatingPointBuffers() && + !isTigerOrLater) { + throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); + } + // Change our OpenGL mode to match that of any share context before we create ourselves + MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); + if (other != null) { + setOpenGLMode(other.getOpenGLMode()); + } + // Will throw exception upon error + nsContext = impl.create(); + return true; + } + + //--------------------------------------------------------------------------- + // OpenGL "mode switching" functionality + // + private boolean haveSetOpenGLMode = false; + // FIXME: should consider switching the default mode based on + // whether the Java2D/JOGL bridge is active -- need to ask ourselves + // whether it's more likely that we will share with a GLCanvas or a + // GLJPanel when the bridge is turned on + private int openGLMode = MacOSXCGLDrawable.NSOPENGL_MODE; + // Implementation object (either NSOpenGL-based or CGL-based) + protected Impl impl; + + public void setOpenGLMode(int mode) { + if (mode == openGLMode) { + return; + } + if (haveSetOpenGLMode) { + throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); + } + destroyImpl(); + drawable.setOpenGLMode(mode); + openGLMode = mode; + haveSetOpenGLMode = true; + if (DEBUG) { + System.err.println("Switching PBuffer context mode to " + + ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE")); + } + initOpenGLImpl(); + } + + public int getOpenGLMode() { + return openGLMode; + } + + private void initOpenGLImpl() { + switch (openGLMode) { + case MacOSXCGLDrawable.NSOPENGL_MODE: + impl = new NSOpenGLImpl(); + break; + case MacOSXCGLDrawable.CGL_MODE: + impl = new CGLImpl(); + break; + default: + throw new InternalError("Illegal implementation mode " + openGLMode); + } + } + + // Abstract interface for implementation of this context (either + // NSOpenGL-based or CGL-based) + interface Impl { + public long create(); + public boolean destroy(long ctx); + public boolean makeCurrent(long ctx); + public boolean release(long ctx); + public void setSwapInterval(long ctx, int interval); + } + + // NSOpenGLContext-based implementation + class NSOpenGLImpl implements Impl { + public long create() { + GLCapabilities capabilities = drawable.getCapabilities(); + if (capabilities.getPbufferFloatingPointBuffers() && + !isTigerOrLater) { + throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); + } + if (!MacOSXPbufferCGLContext.this.create(true, capabilities.getPbufferFloatingPointBuffers())) { + throw new GLException("Error creating context for pbuffer"); + } + // Must now associate the pbuffer with our newly-created context + CGL.setContextPBuffer(nsContext, drawable.getPbuffer()); + return nsContext; + } + + public boolean destroy(long ctx) { + return CGL.deleteContext(ctx); + } + + public boolean makeCurrent(long ctx) { + return CGL.makeCurrentContext(ctx); + } + + public boolean release(long ctx) { + return CGL.clearCurrentContext(ctx); + } + + public void setSwapInterval(long ctx, int interval) { + CGL.setSwapInterval(ctx, interval); + } + } + + class CGLImpl implements Impl { + public long create() { + // Find and configure share context + MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(MacOSXPbufferCGLContext.this); + long share = 0; + if (other != null) { + // Reconfigure pbuffer-based GLContexts + if (other instanceof MacOSXPbufferCGLContext) { + MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other; + ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE); + } else { + if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) { + throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs"); + } + } + share = other.getNSContext(); + // Note we don't check for a 0 return value, since switching + // the context's mode causes it to be destroyed and not + // re-initialized until the next makeCurrent + } + + // Set up pixel format attributes + int[] attrs = new int[256]; + int i = 0; + attrs[i++] = CGL.kCGLPFAPBuffer; + GLCapabilities capabilities = drawable.getCapabilities(); + if (capabilities.getPbufferFloatingPointBuffers()) + attrs[i++] = CGL.kCGLPFAColorFloat; + if (capabilities.getDoubleBuffered()) + attrs[i++] = CGL.kCGLPFADoubleBuffer; + if (capabilities.getStereo()) + attrs[i++] = CGL.kCGLPFAStereo; + attrs[i++] = CGL.kCGLPFAColorSize; + attrs[i++] = (capabilities.getRedBits() + + capabilities.getGreenBits() + + capabilities.getBlueBits()); + attrs[i++] = CGL.kCGLPFAAlphaSize; + attrs[i++] = capabilities.getAlphaBits(); + attrs[i++] = CGL.kCGLPFADepthSize; + attrs[i++] = capabilities.getDepthBits(); + // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m + attrs[i++] = CGL.kCGLPFAStencilSize; + attrs[i++] = capabilities.getStencilBits(); + attrs[i++] = CGL.kCGLPFAAccumSize; + attrs[i++] = (capabilities.getAccumRedBits() + + capabilities.getAccumGreenBits() + + capabilities.getAccumBlueBits() + + capabilities.getAccumAlphaBits()); + if (capabilities.getSampleBuffers()) { + attrs[i++] = CGL.kCGLPFASampleBuffers; + attrs[i++] = 1; + attrs[i++] = CGL.kCGLPFASamples; + attrs[i++] = capabilities.getNumSamples(); + } + + // Use attribute array to select pixel format + long[] fmt = new long[1]; + long[] numScreens = new long[1]; + int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, 0, numScreens, 0); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while choosing pixel format"); + } + + // Create new context + long[] ctx = new long[1]; + if (DEBUG) { + System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share)); + } + res = CGL.CGLCreateContext(fmt[0], share, ctx, 0); + CGL.CGLDestroyPixelFormat(fmt[0]); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while creating context"); + } + // Attach newly-created context to the pbuffer + res = CGL.CGLSetPBuffer(ctx[0], drawable.getPbuffer(), 0, 0, 0); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while attaching context to pbuffer"); + } + return ctx[0]; + } + + public boolean destroy(long ctx) { + return (CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError); + } + + public boolean makeCurrent(long ctx) { + return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError; + } + + public boolean release(long ctx) { + return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError); + } + + public void setSwapInterval(long ctx, int interval) { + // For now not supported (not really relevant for off-screen contexts anyway) + } + } +} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java new file mode 100644 index 000000000..6efe175fe --- /dev/null +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2003 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.cgl; + +import javax.media.opengl.*; +import com.sun.opengl.impl.*; + +public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { + private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable"); + + // State for render-to-texture and render-to-texture-rectangle support + private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV + private int texture; // actual texture object + + public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, GLCapabilities capabilities, int initialWidth, int initialHeight) { + super(factory, new NullWindow(), true, capabilities, null); + NullWindow nw = (NullWindow) getNativeWindow(); + nw.setSize(initialWidth, initialHeight); + initOpenGLImpl(); + createPbuffer(); + } + + public GLContext createContext(GLContext shareWith) { + return new MacOSXPbufferCGLContext(this, shareWith); + } + + public void destroy() { + getFactory().lockToolkit(); + try { + NullWindow nw = (NullWindow) getNativeWindow(); + + if (nw.getWindowHandle() != 0) { + impl.destroy(nw.getWindowHandle()); + nw.setWindowHandle(0); + + if (DEBUG) { + System.err.println("Destroyed pbuffer: " + nw); + } + } + } finally { + getFactory().unlockToolkit(); + } + } + + public void setSize(int width, int height) { + super.setSize(width, height); + destroy(); + createPbuffer(); + } + + public long getPbuffer() { + return getNativeWindow().getWindowHandle(); + } + + public void swapBuffers() throws GLException { + // FIXME: do we need to do anything if the pbuffer is double-buffered? + } + + protected void createPbuffer() { + NullWindow nw = (NullWindow) getNativeWindow(); + getFactory().lockToolkit(); + try { + int renderTarget; + GLCapabilities capabilities = getCapabilities(); + if (GLProfile.isGL2() && capabilities.getPbufferRenderToTextureRectangle()) { + renderTarget = GL2.GL_TEXTURE_RECTANGLE_EXT; + } else { + int w = getNextPowerOf2(getWidth()); + int h = getNextPowerOf2(getHeight()); + nw.setSize(w, h); + renderTarget = GL.GL_TEXTURE_2D; + } + + int internalFormat = GL.GL_RGBA; + if (capabilities.getPbufferFloatingPointBuffers()) { + // FIXME: want to check availability of GL_APPLE_float_pixels + // extension, but need valid OpenGL context in order to do so -- + // in worst case would need to create dummy window / GLCanvas + // (undesirable) -- could maybe also do this with pbuffers + /* + if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) { + throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available"); + } + */ + if(GLProfile.isGL2()) { + switch (capabilities.getRedBits()) { + case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break; + case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break; + default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)"); + } + } else { + internalFormat = GL.GL_RGBA; + } + } + + long pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight()); + if (pBuffer == 0) { + throw new GLException("pbuffer creation error: CGL.createPBuffer() failed"); + } + nw.setWindowHandle(pBuffer); + } finally { + getFactory().unlockToolkit(); + } + + if (DEBUG) { + System.err.println("Created pbuffer " + nw + " for " + this); + } + } + + private 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<