diff options
author | Sven Gothel <[email protected]> | 2014-02-23 14:51:06 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-23 14:51:06 +0100 |
commit | 3352601e0860584509adf2b76f993d03893ded4b (patch) | |
tree | 974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/jogl/classes/jogamp/opengl/macosx | |
parent | f51933f0ebe9ae030c26c066e59a728ce08b8559 (diff) | |
parent | c67de337a8aaf52e36104c3f13e273aa19d21f1f (diff) |
Merge branch 'master' into stash_glyphcache
Conflicts:
make/scripts/tests.sh
src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
src/jogl/classes/com/jogamp/graph/curve/Region.java
src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
src/jogl/classes/com/jogamp/graph/font/Font.java
src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java
src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/macosx')
16 files changed, 1401 insertions, 1237 deletions
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 3cd4b340c..259c70641 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -41,6 +41,7 @@ package jogamp.opengl.macosx.cgl; import java.nio.ByteBuffer; +import java.nio.IntBuffer; import java.util.Map; import javax.media.nativewindow.AbstractGraphicsConfiguration; @@ -48,110 +49,180 @@ import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.OffscreenLayerSurface; +import javax.media.nativewindow.ProxySurface; +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES2; +import javax.media.opengl.GL3ES3; +import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import javax.media.opengl.GLUniformData; +import jogamp.nativewindow.macosx.OSXUtil; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.GLFBODrawableImpl; import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; +import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.os.Platform; import com.jogamp.common.util.VersionNumber; +import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; +import com.jogamp.opengl.GLRendererQuirks; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; -public abstract class MacOSXCGLContext extends GLContextImpl -{ +public class MacOSXCGLContext extends GLContextImpl +{ // Abstract interface for implementation of this context (either // NSOpenGL-based or CGL-based) protected interface GLBackendImpl { boolean isNSContext(); long create(long share, int ctp, int major, int minor); boolean destroy(long ctx); + void associateDrawable(boolean bound); boolean copyImpl(long src, int mask); boolean makeCurrent(long ctx); boolean release(long ctx); + boolean detachPBuffer(); boolean setSwapInterval(int interval); boolean swapBuffers(); } - + /* package */ static final boolean isTigerOrLater; /* package */ static final boolean isLionOrLater; + /* package */ static final boolean isMavericksOrLater; static { final VersionNumber osvn = Platform.getOSVersionNumber(); - isTigerOrLater = osvn.getMajor() > 10 || ( osvn.getMajor() == 10 && osvn.getMinor() >= 4 ); - isLionOrLater = osvn.getMajor() > 10 || ( osvn.getMajor() == 10 && osvn.getMinor() >= 7 ); + isTigerOrLater = osvn.compareTo(Platform.OSXVersion.Tiger) >= 0; + isLionOrLater = osvn.compareTo(Platform.OSXVersion.Lion) >= 0; + isMavericksOrLater = osvn.compareTo(Platform.OSXVersion.Mavericks) >= 0; } static boolean isGLProfileSupported(int ctp, int major, int minor) { boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ; - + // We exclude 3.0, since we would map it's core to GL2. Hence we force mapping 2.1 to GL2 - if(3==major && 1<=minor && minor<=2) { - // [3.1..3.2] -> GL3* + if( 3 < major || 3 == major && 1 <= minor ) { + if(ctBwdCompat || !ctCore) { + // No compatibility profile on OS X + // Only core is supported + return false; + } if(!isLionOrLater) { - // no GL3* on pre lion + // no GL Profile >= GL3 core on pre lion return false; } - if(ctBwdCompat) { - // no compatibility profile on OS X + if(3 < major && !isMavericksOrLater) { + // no GL Profile >= GL4 core on pre mavericks return false; } - return ctCore; - } else if(major<3) { + // [3.1..3.x] -> GL3 + // [4.0..4.x] -> GL4 + return true; + } else if( major < 3 ) { // < 3.0 -> GL2 return true; } return false; // 3.0 && > 3.2 } - static int GLProfile2CGLOGLProfileValue(int ctp, int major, int minor) { + static int GLProfile2CGLOGLProfileValue(AbstractGraphicsDevice device, int ctp, int major, int minor) { if(!MacOSXCGLContext.isGLProfileSupported(ctp, major, minor)) { throw new GLException("OpenGL profile not supported: "+getGLVersion(major, minor, ctp, "@GLProfile2CGLOGLProfileVersion")); } - boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ; - if( major == 3 && minor >= 1 && ctCore ) { - return CGL.kCGLOGLPVersion_3_2_Core; + final boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ; + + if( major == 4 && ctCore ) { + if( GLRendererQuirks.existStickyDeviceQuirk(device, GLRendererQuirks.GL4NeedsGL3Request) ) { + // Thread safe GLRendererQuirks sticky access, since we are only interested of the result _after_ GL version mapping, + // i.e. after single threaded initialization! + return CGL.kCGLOGLPVersion_GL3_Core; + } else { + return CGL.kCGLOGLPVersion_GL4_Core; + } + } else if( major == 3 && minor >= 1 && ctCore ) { + return CGL.kCGLOGLPVersion_GL3_Core; } else { return CGL.kCGLOGLPVersion_Legacy; - } - } + } + } + + private static final String shaderBasename = "texture01_xxx"; + + private static ShaderProgram createCALayerShader(GL3ES3 gl) { + // Create & Link the shader program + final ShaderProgram sp = new ShaderProgram(); + final ShaderCode vp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MacOSXCGLContext.class, + "../../shader", "../../shader/bin", shaderBasename, true); + final ShaderCode fp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MacOSXCGLContext.class, + "../../shader", "../../shader/bin", shaderBasename, true); + vp.defaultShaderCustomization(gl, true, true); + fp.defaultShaderCustomization(gl, true, true); + sp.add(vp); + sp.add(fp); + if(!sp.link(gl, System.err)) { + throw new GLException("Couldn't link program: "+sp); + } + sp.useProgram(gl, true); + + // setup mgl_PMVMatrix + final PMVMatrix pmvMatrix = new PMVMatrix(); + pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + final GLUniformData pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()); // P, Mv + pmvMatrixUniform.setLocation(gl, sp.program()); + gl.glUniform(pmvMatrixUniform); + + sp.useProgram(gl, false); + return sp; + } + private boolean haveSetOpenGLMode = false; private GLBackendType openGLMode = GLBackendType.NSOPENGL; - + // Implementation object (either NSOpenGL-based or CGL-based) protected GLBackendImpl impl; - + private CGLExt _cglExt; // Table that holds the addresses of the native C-language entry points for // CGL extension functions. private CGLExtProcAddressTable cglExtProcAddressTable; - + + private long updateHandle = 0; + private int lastWidth, lastHeight; + protected MacOSXCGLContext(GLDrawableImpl drawable, GLContext shareWith) { super(drawable, shareWith); initOpenGLImpl(getOpenGLMode()); } - + @Override - protected void resetStates() { + protected void resetStates(boolean isInit) { // no inner state _cglExt = null; cglExtProcAddressTable = null; - super.resetStates(); + super.resetStates(isInit); } + @Override public Object getPlatformGLExtensions() { return getCGLExt(); } - protected boolean isNSContext() { - return (null != impl) ? impl.isNSContext() : this.openGLMode == GLBackendType.NSOPENGL; + protected boolean isNSContext() { + return (null != impl) ? impl.isNSContext() : this.openGLMode == GLBackendType.NSOPENGL; } public CGLExt getCGLExt() { @@ -161,6 +232,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl return _cglExt; } + @Override public final ProcAddressTable getPlatformExtProcAddressTable() { return getCGLExtProcAddressTable(); } @@ -169,10 +241,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl return cglExtProcAddressTable; } + @Override protected Map<String, String> getFunctionNameMap() { return null; } + @Override protected Map<String, String> getExtensionNameMap() { return null; } + @Override protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { if(!isGLProfileSupported(ctp, major, minor)) { if(DEBUG) { @@ -200,69 +275,130 @@ public abstract class MacOSXCGLContext extends GLContextImpl return ctx; } + @Override protected void destroyContextARBImpl(long _context) { impl.release(_context); impl.destroy(_context); } + @Override public final boolean isGLReadDrawableAvailable() { return false; } - protected long createImplPreset(GLContextImpl shareWith) throws GLException { - long share = 0; - if (shareWith != null) { - // Change our OpenGL mode to match that of any share context before we create ourselves - setOpenGLMode(((MacOSXCGLContext)shareWith).getOpenGLMode()); - share = shareWith.getHandle(); - if (share == 0) { - throw new GLException("GLContextShareSet returned a NULL OpenGL context"); - } - } - - MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); - GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - if (capabilitiesChosen.getPbufferFloatingPointBuffers() && !isTigerOrLater) { - throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); - } - GLProfile glp = capabilitiesChosen.getGLProfile(); - if(glp.isGLES1() || glp.isGLES2() || glp.isGL4() || glp.isGL3() && !isLionOrLater) { + @Override + protected boolean createImpl(final long shareWithHandle) throws GLException { + final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); + final GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final GLProfile glp = capabilitiesChosen.getGLProfile(); + if( glp.isGLES() || + ( glp.isGL3() && !isLionOrLater ) || ( glp.isGL4() && !isMavericksOrLater ) ) { throw new GLException("OpenGL profile not supported on MacOSX "+Platform.getOSVersionNumber()+": "+glp); } - - if (DEBUG) { - System.err.println("Share context is " + toHexString(share) + " for " + this); + if( 0 != shareWithHandle && GLBackendType.NSOPENGL != getOpenGLMode() ) { + throw new GLException("Context sharing only supported in mode "+GLBackendType.NSOPENGL+": "+this); } - return share; - } - - protected boolean createImpl(GLContextImpl shareWith) throws GLException { - long share = createImplPreset(shareWith); - contextHandle = createContextARB(share, true); + contextHandle = createContextARB(shareWithHandle, true); return 0 != contextHandle; } - + + @Override protected void makeCurrentImpl() throws GLException { + /** FIXME: won't work w/ special drawables (like FBO) - check for CGL mode regressions! + * if (getOpenGLMode() != ((MacOSXCGLDrawable)drawable).getOpenGLMode()) { setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode()); - } + } */ if (!impl.makeCurrent(contextHandle)) { throw new GLException("Error making Context current: "+this); - } + } + drawableUpdatedNotify(); } - + + @Override protected void releaseImpl() throws GLException { if (!impl.release(contextHandle)) { throw new GLException("Error releasing OpenGL Context: "+this); } } + @Override protected void destroyImpl() throws GLException { + releaseUpdateHandle(); if(!impl.destroy(contextHandle)) { throw new GLException("Error destroying OpenGL Context: "+this); } } + private final long getUpdateHandle() { + if( 0 == updateHandle ) { + lastWidth = -1; + lastHeight = -1; + if( isCreated() && drawable.getChosenGLCapabilities().isOnscreen() && isNSContext() ) { + final boolean incompleteView; + final NativeSurface surface = drawable.getNativeSurface(); + if( surface instanceof ProxySurface ) { + incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE ); + } else { + incompleteView = false; + } + if(!incompleteView) { + updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle()); + if(0 == updateHandle) { + throw new InternalError("XXX2"); + } + } + } + } + return updateHandle; + } + + private final void releaseUpdateHandle() { + if ( 0 != updateHandle ) { + CGL.updateContextUnregister(updateHandle); + updateHandle = 0; + } + } + + @Override + protected void drawableUpdatedNotify() throws GLException { + if( drawable.getChosenGLCapabilities().isOnscreen() ) { + final long _updateHandle = getUpdateHandle(); + final int w = drawable.getWidth(); + final int h = drawable.getHeight(); + final boolean updateContext = ( 0!=_updateHandle && CGL.updateContextNeedsUpdate(_updateHandle) ) || + w != lastWidth || h != lastHeight; + if(updateContext) { + lastWidth = w; + lastHeight = h; + if (contextHandle == 0) { + throw new GLException("Context not created"); + } + CGL.updateContext(contextHandle); + } + } + } + + @Override + protected void associateDrawable(boolean bound) { + // context stuff depends on drawable stuff + if(bound) { + super.associateDrawable(true); // 1) init drawable stuff + impl.associateDrawable(true); // 2) init context stuff + getUpdateHandle(); + } else { + releaseUpdateHandle(); + impl.associateDrawable(false); // 1) free context stuff + super.associateDrawable(false); // 2) free drawable stuff + } + } + + /* pp */ void detachPBuffer() { + impl.detachPBuffer(); + } + + + @Override protected void copyImpl(GLContext source, int mask) throws GLException { if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) { throw new GLException("Source/Destination OpenGL Context tyoe mismatch: source "+source+", dest: "+this); @@ -275,7 +411,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl protected void swapBuffers() { // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers() if(!impl.swapBuffers()) { - throw new GLException("Error swapping buffers: "+this); + throw new GLException("Error swapping buffers: "+this); } } @@ -284,11 +420,19 @@ public abstract class MacOSXCGLContext extends GLContextImpl return impl.setSwapInterval(interval); } - public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { + @Override + public final ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority) { + // FIXME: apparently the Apple extension doesn't require a custom memory allocator + throw new GLException("Not yet implemented"); + } + + @Override + public final void glFreeMemoryNV(ByteBuffer pointer) { // FIXME: apparently the Apple extension doesn't require a custom memory allocator throw new GLException("Not yet implemented"); } + @Override protected final void updateGLXProcAddressTable() { final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration(); final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); @@ -316,39 +460,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } } - + + @Override protected final StringBuilder getPlatformExtensionsStringImpl() { return new StringBuilder(); } - - 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 void setOpenGLMode(GLBackendType mode) { if (mode == openGLMode) { @@ -364,10 +481,10 @@ public abstract class MacOSXCGLContext extends GLContextImpl } initOpenGLImpl(mode); openGLMode = mode; - haveSetOpenGLMode = true; + haveSetOpenGLMode = true; } public final GLBackendType getOpenGLMode() { return openGLMode; } - + protected void initOpenGLImpl(GLBackendType backend) { switch (backend) { case NSOPENGL: @@ -379,8 +496,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl default: throw new InternalError("Illegal implementation mode " + backend); } - } - + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()); @@ -391,291 +509,736 @@ public abstract class MacOSXCGLContext extends GLContextImpl sb.append("] "); return sb.toString(); } - + // NSOpenGLContext-based implementation class NSOpenGLImpl implements GLBackendImpl { - long nsOpenGLLayer = 0; - long nsOpenGLLayerPFmt = 0; - float screenVSyncTimeout; // microSec - int vsyncTimeout; // microSec - for nsOpenGLLayer mode - - public boolean isNSContext() { return true; } - - public long create(long share, int ctp, int major, int minor) { - long ctx = 0; - final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.drawable; - final NativeSurface surface = drawable.getNativeSurface(); - final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration(); - final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true); - final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor); - if (pixelFormat == 0) { + private OffscreenLayerSurface backingLayerHost = null; + /** lifecycle: [create - destroy] */ + private long pixelFormat = 0; + /** microSec - defaults to 1/60s */ + private int screenVSyncTimeout = 16666; + /** microSec - for nsOpenGLLayer mode - defaults to 1/60s + 1ms */ + private volatile int vsyncTimeout = 16666 + 1000; + private int lastWidth=0, lastHeight=0; // allowing to detect size change + private boolean needsSetContextPBuffer = false; + private ShaderProgram gl3ShaderProgram = null; + + @Override + public boolean isNSContext() { return true; } + + + /** Only returns a valid NSView. If !NSView, return null and mark either pbuffer and FBO. */ + private long getNSViewHandle(boolean[] isPBuffer, boolean[] isFBO) { + final long nsViewHandle; + if(drawable instanceof GLFBODrawableImpl) { + nsViewHandle = 0; + isPBuffer[0] = false; + isFBO[0] = true; + if(DEBUG) { + System.err.println("NS viewHandle.1: GLFBODrawableImpl drawable: isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable); + } + } else { + final long drawableHandle = drawable.getHandle(); + final boolean isNSView = OSXUtil.isNSView(drawableHandle); + final boolean isNSWindow = OSXUtil.isNSWindow(drawableHandle); + isPBuffer[0] = CGL.isNSOpenGLPixelBuffer(drawableHandle); + isFBO[0] = false; + + if( isNSView ) { + nsViewHandle = drawableHandle; + } else if( isNSWindow ) { + nsViewHandle = OSXUtil.GetNSView(drawableHandle); + } else if( isPBuffer[0] ) { + nsViewHandle = 0; + } else { + throw new RuntimeException("Drawable's handle neither NSView, NSWindow nor PBuffer: drawableHandle "+toHexString(drawableHandle)+", isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO[0]+", isPBuffer "+isPBuffer[0]+", "+drawable.getClass().getName()+",\n\t"+drawable); + } + if(DEBUG) { + System.err.println("NS viewHandle.2: drawableHandle "+toHexString(drawableHandle)+" -> nsViewHandle "+toHexString(nsViewHandle)+": isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO[0]+", isPBuffer "+isPBuffer[0]+", "+drawable.getClass().getName()+",\n\t"+drawable); + } + } + needsSetContextPBuffer = isPBuffer[0]; + return nsViewHandle; + } + + @Override + public long create(long share, int ctp, int major, int minor) { + long ctx = 0; + final NativeSurface surface = drawable.getNativeSurface(); + final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration(); + final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final long nsViewHandle; + final boolean isPBuffer; + final boolean isFBO; + { + boolean[] _isPBuffer = { false }; + boolean[] _isFBO = { false }; + nsViewHandle = getNSViewHandle(_isPBuffer, _isFBO); + isPBuffer = _isPBuffer[0]; + isFBO = _isFBO[0]; + } + final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true); + + boolean incompleteView = null != backingLayerHost; + if( !incompleteView && surface instanceof ProxySurface ) { + incompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE ); + } + { + final GLCapabilitiesImmutable targetCaps; + if( isFBO ) { + // Use minimum GLCapabilities for the target surface w/ same profile + targetCaps = new GLCapabilities( chosenCaps.getGLProfile() ); + } else { + targetCaps = chosenCaps; + } + pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(config.getScreen().getDevice(), targetCaps, ctp, major, minor); + } + if (pixelFormat == 0) { + if(DEBUG) { + System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps); + } + return 0; + } + final GLCapabilitiesImmutable fixedCaps; + if( isFBO ) { + // pixelformat of target doesn't affect caps w/ FBO + fixedCaps = chosenCaps; + } else { + final GLCapabilities _fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat); + if( !_fixedCaps.isPBuffer() && isPBuffer ) { + throw new InternalError("handle is PBuffer, fixedCaps not: "+drawable); + } + // determine on-/offscreen caps, since pformat is ambiguous + _fixedCaps.setPBuffer( isPBuffer ); // exclusive + _fixedCaps.setBitmap( false ); // n/a in our OSX impl. + _fixedCaps.setOnscreen( !isFBO && !isPBuffer ); + fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(_fixedCaps, chosenCaps.isBackgroundOpaque()); + } + final int sRefreshRate = OSXUtil.GetScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex()); + if( 0 < sRefreshRate ) { + screenVSyncTimeout = 1000000 / sRefreshRate; + } if(DEBUG) { - System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps); + System.err.println("NS create OSX>=lion "+isLionOrLater+", OSX>=mavericks "+isMavericksOrLater); + System.err.println("NS create incompleteView: "+incompleteView); + System.err.println("NS create backingLayerHost: "+backingLayerHost); + System.err.println("NS create share: "+share); + System.err.println("NS create drawable type: "+drawable.getClass().getName()); + System.err.println("NS create drawable handle: isPBuffer "+isPBuffer+", isFBO "+isFBO); + System.err.println("NS create pixelFormat: "+toHexString(pixelFormat)); + System.err.println("NS create chosenCaps: "+chosenCaps); + System.err.println("NS create fixedCaps: "+fixedCaps); + System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle())); + System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle)); + System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros"); + // Thread.dumpStack(); } - return 0; - } - config.setChosenPixelFormat(pixelFormat); - int sRefreshRate = CGL.getScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex()); - screenVSyncTimeout = 1000000f / (float)sRefreshRate; - if(DEBUG) { - System.err.println("NS create OSX>=lion "+isLionOrLater); - System.err.println("NS create backendType: "+drawable.getOpenGLMode()); - System.err.println("NS create backingLayerHost: "+backingLayerHost); - System.err.println("NS create share: "+share); - System.err.println("NS create chosenCaps: "+chosenCaps); - System.err.println("NS create pixelFormat: "+toHexString(pixelFormat)); - System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle())); - System.err.println("NS create drawable NSView-handle: "+toHexString(drawable.getNSViewHandle())); - System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros"); - // Thread.dumpStack(); - } - try { - int[] viewNotReady = new int[1]; + config.setChosenCapabilities(fixedCaps); + + final IntBuffer viewNotReady = Buffers.newDirectIntBuffer(1); // Try to allocate a context with this - ctx = CGL.createContext(share, - drawable.getNSViewHandle(), null!=backingLayerHost, - pixelFormat, - chosenCaps.isBackgroundOpaque(), - viewNotReady, 0); + ctx = CGL.createContext(share, nsViewHandle, incompleteView, + pixelFormat, chosenCaps.isBackgroundOpaque(), viewNotReady); if (0 == ctx) { - if(DEBUG) { - System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0])); - } - return 0; + if(DEBUG) { + System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady.get(0))); + } + return 0; } - - if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) { + + if (chosenCaps.isOnscreen() && !chosenCaps.isBackgroundOpaque()) { // Set the context opacity CGL.setContextOpacity(ctx, 0); } + return ctx; + } - if(DEBUG) { - GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat); - System.err.println("NS create pixelformat2GLCaps: "+caps0); + @Override + public boolean destroy(long ctx) { + if(0!=pixelFormat) { + CGL.deletePixelFormat(pixelFormat); + pixelFormat = 0; } - GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat); - fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque()); - config.setChosenCapabilities(fixedCaps); - if(DEBUG) { - System.err.println("NS create fixedCaps: "+fixedCaps); + return CGL.deleteContext(ctx, true); + } + + /** + * NSOpenGLLayer creation and it's attachment is performed on the main-thread w/o [infinite] blocking. + * <p> + * Since NSOpenGLLayer creation requires this context for it's shared context creation, + * this method attempts to acquire the surface and context lock with {@link #screenVSyncTimeout}/2 maximum wait time. + * If the surface and context lock could not be acquired, this runnable is being re-queued for later execution. + * </p> + * <p> + * Hence this method blocks the main-thread only for a short period of time. + * </p> + */ + class AttachGLLayerCmd implements Runnable { + final OffscreenLayerSurface ols; + final long ctx; + final int shaderProgram; + final long pfmt; + final long pbuffer; + final int texID; + final boolean isOpaque; + final int width; + final int height; + /** Synchronized by instance's monitor */ + long nsOpenGLLayer; + /** Synchronized by instance's monitor */ + boolean valid; + + AttachGLLayerCmd(OffscreenLayerSurface ols, long ctx, int shaderProgram, long pfmt, long pbuffer, int texID, boolean isOpaque, int width, int height) { + this.ols = ols; + this.ctx = ctx; + this.shaderProgram = shaderProgram; + this.pfmt = pfmt; + this.pbuffer = pbuffer; + this.texID = texID; + this.isOpaque = isOpaque; + this.width = width; + this.height = height; + this.valid = false; + this.nsOpenGLLayer = 0; } - if(fixedCaps.isPBuffer()) { - // Must now associate the pbuffer with our newly-created context - CGL.setContextPBuffer(ctx, drawable.getHandle()); + + public final String contentToString() { + return "valid "+valid+", size "+width+"x"+height+", ctx "+toHexString(ctx)+", opaque "+isOpaque+", texID "+texID+", pbuffer "+toHexString(pbuffer)+", nsOpenGLLayer "+toHexString(nsOpenGLLayer); } - // - // handled layered surface - // - if(null != backingLayerHost) { - nsOpenGLLayerPFmt = pixelFormat; - pixelFormat = 0; - final int texWidth, texHeight; - if(drawable instanceof MacOSXPbufferCGLDrawable) { - final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable; - texWidth = osxPDrawable.getTextureWidth(); - texHeight = osxPDrawable.getTextureHeight(); - } else { - texWidth = drawable.getWidth(); - texHeight = drawable.getHeight(); - } - nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight); - if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) { - throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable); - } - if (DEBUG) { - System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable); - } - backingLayerHost.attachSurfaceLayer(nsOpenGLLayer); - setSwapInterval(1); // enabled per default in layered surface + + @Override + public final String toString() { + return "AttachGLLayerCmd["+contentToString()+"]"; } - } finally { - if(0!=pixelFormat) { - CGL.deletePixelFormat(pixelFormat); + + @Override + public void run() { + synchronized(this) { + if( !valid ) { + try { + final int maxwait = screenVSyncTimeout/2000; // TO 1/2 of current screen-vsync in [ms] + final RecursiveLock surfaceLock = ols.getLock(); + if( surfaceLock.tryLock( maxwait ) ) { + try { + if( MacOSXCGLContext.this.lock.tryLock( maxwait ) ) { + try { + nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, shaderProgram, pfmt, pbuffer, texID, isOpaque, width, height); + ols.attachSurfaceLayer(nsOpenGLLayer); + final int currentInterval = MacOSXCGLContext.this.getSwapInterval(); + final int interval = 0 <= currentInterval ? currentInterval : 1; + setSwapIntervalImpl(nsOpenGLLayer, interval); // enabled per default in layered surface + valid = true; + if (DEBUG) { + System.err.println("NSOpenGLLayer.Attach: OK, layer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbuffer)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", drawableHandle "+toHexString(drawable.getHandle())+" - "+getThreadName()); + } + } finally { + MacOSXCGLContext.this.lock.unlock(); + } + } + } finally { + surfaceLock.unlock(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + if( !valid ) { + // could not acquire lock, re-queue + if (DEBUG) { + System.err.println("NSOpenGLLayer.Attach: Re-Queue, drawableHandle "+toHexString(drawable.getHandle())+" - "+getThreadName()); + } + OSXUtil.RunLater(true /* onMain */, this, 1); + } + } + } } + } + AttachGLLayerCmd attachGLLayerCmd = null; + + class DetachGLLayerCmd implements Runnable { + final AttachGLLayerCmd cmd; + + DetachGLLayerCmd(AttachGLLayerCmd cmd) { + this.cmd = cmd; + } + + @Override + public final String toString() { + return "DetachGLLayerCmd["+cmd.contentToString()+"]"; + } + + @Override + public void run() { + synchronized( cmd ) { + if( cmd.valid ) { + // still having a valid OLS attached to surface (parent OLS could have been removed) + try { + final OffscreenLayerSurface ols = cmd.ols; + final long l = ols.getAttachedSurfaceLayer(); + if( 0 != l ) { + ols.detachSurfaceLayer(); + } + } catch(Throwable t) { + System.err.println("Catched Exception on thread "+getThreadName()); + t.printStackTrace(); + } + CGL.releaseNSOpenGLLayer(cmd.nsOpenGLLayer); + if(DEBUG) { + System.err.println("NSOpenGLLayer.Detach: OK, layer "+toHexString(cmd.nsOpenGLLayer)+" - "+getThreadName()); + } + cmd.nsOpenGLLayer = 0; + cmd.valid = false; + } else if(DEBUG) { + System.err.println("NSOpenGLLayer.Detach: Skipped "+toHexString(cmd.nsOpenGLLayer)+" - "+getThreadName()); + } + } } - return ctx; - } - - public boolean destroy(long ctx) { - if(0 != nsOpenGLLayer) { - final NativeSurface surface = drawable.getNativeSurface(); - if (DEBUG) { - System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)); - } - final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true); - if(null == ols) { - throw new InternalError("XXX: "+ols); - } - CGL.releaseNSOpenGLLayer(nsOpenGLLayer); - ols.detachSurfaceLayer(nsOpenGLLayer); - CGL.deletePixelFormat(nsOpenGLLayerPFmt); - nsOpenGLLayerPFmt = 0; - nsOpenGLLayer = 0; } - return CGL.deleteContext(ctx, true); - } - public boolean copyImpl(long src, int mask) { - CGL.copyContext(contextHandle, src, mask); - return true; - } - - public boolean makeCurrent(long ctx) { - final long cglCtx = CGL.getCGLContext(ctx); - if(0 == cglCtx) { - throw new InternalError("Null CGLContext for: "+this); + @Override + public void associateDrawable(boolean bound) { + backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(drawable.getNativeSurface(), true); + + if(DEBUG) { + System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable: "+bound+", ctx "+toHexString(contextHandle)+ + ", hasBackingLayerHost "+(null!=backingLayerHost)+", attachGLLayerCmd "+attachGLLayerCmd); + // Thread.dumpStack(); + } + + if( bound ) { + if( null != backingLayerHost ) { + final GLCapabilitiesImmutable chosenCaps; + final long ctx; + final int texID; + final long pbufferHandle; + final int gl3ShaderProgramName; + + // + // handled layered surface + // + chosenCaps = drawable.getChosenGLCapabilities(); + ctx = MacOSXCGLContext.this.getHandle(); + final long drawableHandle = drawable.getHandle(); + if(drawable instanceof GLFBODrawableImpl) { + final GLFBODrawableImpl fbod = (GLFBODrawableImpl)drawable; + texID = fbod.getTextureBuffer(GL.GL_FRONT).getName(); + pbufferHandle = 0; + fbod.setSwapBufferContext(new GLFBODrawableImpl.SwapBufferContext() { + @Override + public void swapBuffers(boolean doubleBuffered) { + MacOSXCGLContext.NSOpenGLImpl.this.swapBuffers(); + } } ) ; + } else if( CGL.isNSOpenGLPixelBuffer(drawableHandle) ) { + texID = 0; + pbufferHandle = drawableHandle; + if(0 != drawableHandle) { // complete 'validatePBufferConfig(..)' procedure + CGL.setContextPBuffer(ctx, pbufferHandle); + needsSetContextPBuffer = false; + } + } else { + throw new GLException("BackingLayerHost w/ unknown handle (!FBO, !PBuffer): "+drawable); + } + lastWidth = drawable.getWidth(); + lastHeight = drawable.getHeight(); + if(0>=lastWidth || 0>=lastHeight || !drawable.isRealized()) { + throw new GLException("Drawable not realized yet or invalid texture size, texSize "+lastWidth+"x"+lastHeight+", "+drawable); + } + if( MacOSXCGLContext.this.isGL3core() ) { + if( null == gl3ShaderProgram) { + gl3ShaderProgram = createCALayerShader(MacOSXCGLContext.this.gl.getGL3ES3()); + } + gl3ShaderProgramName = gl3ShaderProgram.program(); + } else { + gl3ShaderProgramName = 0; + } + + // All CALayer lifecycle ops are deferred on main-thread + attachGLLayerCmd = new AttachGLLayerCmd( + backingLayerHost, ctx, gl3ShaderProgramName, pixelFormat, pbufferHandle, texID, + chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight ); + if(DEBUG) { + System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(true): "+attachGLLayerCmd); + } + OSXUtil.RunOnMainThread(false, attachGLLayerCmd); + } else { // -> null == backingLayerHost + lastWidth = drawable.getWidth(); + lastHeight = drawable.getHeight(); + boolean[] isPBuffer = { false }; + boolean[] isFBO = { false }; + CGL.setContextView(contextHandle, getNSViewHandle(isPBuffer, isFBO)); + } + } else { // -> !bound + if( null != backingLayerHost ) { + final AttachGLLayerCmd cmd = attachGLLayerCmd; + attachGLLayerCmd = null; + if( null == cmd ) { + throw new GLException("Null attachGLLayerCmd: "+drawable); + } + if( 0 != cmd.pbuffer ) { + CGL.setContextPBuffer(contextHandle, 0); + } + synchronized(cmd) { + if( !cmd.valid ) { + cmd.valid = true; // skip pending creation + } else { + // All CALayer lifecycle ops are deferred on main-thread + final DetachGLLayerCmd dCmd = new DetachGLLayerCmd(cmd); + if(DEBUG) { + System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(false): "+dCmd); + } + OSXUtil.RunOnMainThread(false, dCmd); + if( null != gl3ShaderProgram ) { + gl3ShaderProgram.destroy(MacOSXCGLContext.this.gl.getGL3()); + gl3ShaderProgram = null; + } + } + } + } + CGL.clearDrawable(contextHandle); + backingLayerHost = null; + } } - int err = CGL.CGLLockContext(cglCtx); - if(CGL.kCGLNoError == err) { - return CGL.makeCurrentContext(ctx); - } else if(DEBUG) { - System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this); + + private final void validatePBufferConfig(long ctx) { + final long drawableHandle = drawable.getHandle(); + if( needsSetContextPBuffer && 0 != drawableHandle && CGL.isNSOpenGLPixelBuffer(drawableHandle) ) { + // Must associate the pbuffer with our newly-created context + needsSetContextPBuffer = false; + CGL.setContextPBuffer(ctx, drawableHandle); + if(DEBUG) { + System.err.println("NS.validateDrawableConfig bind pbuffer "+toHexString(drawableHandle)+" -> ctx "+toHexString(ctx)); + } + } } - return false; - } - public boolean release(long ctx) { - try { - gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze - } catch (GLException gle) { - if(DEBUG) { - System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:"); - gle.printStackTrace(); + /** Returns true if size has been updated, otherwise false (same size). */ + private final boolean validateDrawableSizeConfig(long ctx) { + final int width = drawable.getWidth(); + final int height = drawable.getHeight(); + if( lastWidth != width || lastHeight != height ) { + lastWidth = drawable.getWidth(); + lastHeight = drawable.getHeight(); + if(DEBUG) { + System.err.println("NS.validateDrawableConfig size changed"); + } + return true; } + return false; } - final boolean res = CGL.clearCurrentContext(ctx); - final long cglCtx = CGL.getCGLContext(ctx); - if(0 == cglCtx) { - throw new InternalError("Null CGLContext for: "+this); + + @Override + public boolean copyImpl(long src, int mask) { + CGL.copyContext(contextHandle, src, mask); + return true; } - final int err = CGL.CGLUnlockContext(cglCtx); - if(DEBUG && CGL.kCGLNoError != err) { - System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this); - } - return res && CGL.kCGLNoError == err; - } - public boolean setSwapInterval(int interval) { - if(0 != nsOpenGLLayer) { - CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval); - vsyncTimeout = interval * (int)screenVSyncTimeout; - if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); } + @Override + public boolean makeCurrent(long ctx) { + final long cglCtx = CGL.getCGLContext(ctx); + if(0 == cglCtx) { + throw new InternalError("Null CGLContext for: "+this); + } + final int err = CGL.CGLLockContext(cglCtx); + if(CGL.kCGLNoError == err) { + validatePBufferConfig(ctx); // required to handle pbuffer change ASAP + return CGL.makeCurrentContext(ctx); + } else if(DEBUG) { + System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this); + } + return false; } - CGL.setSwapInterval(contextHandle, interval); - return true; - } - - public boolean swapBuffers() { - if( 0 != nsOpenGLLayer ) { - // If v-sync is disabled, frames will be drawn as quickly as possible - // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync). - CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout); + + @Override + public boolean release(long ctx) { + try { + if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) { + gl.glFlush(); + } + } catch (GLException gle) { + if(DEBUG) { + System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:"); + gle.printStackTrace(); + } + } + final boolean res = CGL.clearCurrentContext(ctx); + final long cglCtx = CGL.getCGLContext(ctx); + if(0 == cglCtx) { + throw new InternalError("Null CGLContext for: "+this); + } + final int err = CGL.CGLUnlockContext(cglCtx); + if(DEBUG && CGL.kCGLNoError != err) { + System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this); + } + return res && CGL.kCGLNoError == err; + } + + @Override + public boolean detachPBuffer() { + needsSetContextPBuffer = true; + // CGL.setContextPBuffer(contextHandle, 0); // doesn't work, i.e. not taking nil + return true; } - if(CGL.flushBuffer(contextHandle)) { - if(0 != nsOpenGLLayer) { - // trigger CALayer to update - CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer); + + @Override + public boolean setSwapInterval(int interval) { + final AttachGLLayerCmd cmd = attachGLLayerCmd; + if(null != cmd) { + synchronized(cmd) { + if( cmd.valid && 0 != cmd.nsOpenGLLayer) { + setSwapIntervalImpl(cmd.nsOpenGLLayer, interval); + return true; + } + } } + setSwapIntervalImpl(0, interval); return true; } - return false; - } + + private void setSwapIntervalImpl(final long l, int interval) { + if( 0 != l ) { + CGL.setNSOpenGLLayerSwapInterval(l, interval); + if( 0 < interval ) { + vsyncTimeout = interval * screenVSyncTimeout + 1000; // +1ms + } else { + vsyncTimeout = 1 * screenVSyncTimeout + 1000; // +1ms + } + if(DEBUG) { System.err.println("NS setSwapInterval: "+interval+" -> "+vsyncTimeout+" micros"); } + } + if(DEBUG) { System.err.println("CGL setSwapInterval: "+interval); } + CGL.setSwapInterval(contextHandle, interval); + } + + private int skipSync=0; + /** TODO: Remove after discussion + private boolean perfIterReset = false; + private int perfIter = 0; + private long waitGLS = 0; + private long finishGLS = 0; + private long frameXS = 0; + private long lastFrameStart = 0; + */ + + @Override + public boolean swapBuffers() { + final AttachGLLayerCmd cmd = attachGLLayerCmd; + if(null != cmd) { + synchronized(cmd) { + if( cmd.valid && 0 != cmd.nsOpenGLLayer) { + if( validateDrawableSizeConfig(contextHandle) ) { + // skip wait-for-vsync for a few frames if size has changed, + // allowing to update the texture IDs ASAP. + skipSync = 10; + } + + final boolean res; + final int texID; + final boolean valid; + final boolean isFBO = drawable instanceof GLFBODrawableImpl; + if( isFBO ){ + texID = ((GLFBODrawableImpl)drawable).getTextureBuffer(GL.GL_FRONT).getName(); + valid = 0 != texID; + } else { + texID = 0; + valid = 0 != drawable.getHandle(); + } + if(valid) { + res = CGL.flushBuffer(contextHandle); + if(res) { + if(0 == skipSync) { + /** TODO: Remove after discussion + perfIter++; + if( !perfIterReset && 100 == perfIter ) { + perfIterReset = true; + perfIter = 1; + waitGLS = 0; + finishGLS = 0; + frameXS = 0; + } + final long lastFramePeriod0 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + gl.glFinish(); // Require to finish previous GL rendering to give CALayer proper result + final long lastFramePeriod1 = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, + // while still synchronizing w/ CALayer. + // If v-sync is enabled wait until next swap interval (v-sync). + CGL.waitUntilNSOpenGLLayerIsReady(cmd.nsOpenGLLayer, vsyncTimeout); + final long lastFramePeriodX = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()) - lastFrameStart; + + final long finishGL = lastFramePeriod1 - lastFramePeriod0; + final long waitGL = lastFramePeriodX - lastFramePeriod1; + finishGLS += finishGL; + waitGLS += waitGL; + frameXS += lastFramePeriodX; + + System.err.println("XXX["+perfIter+"] TO "+vsyncTimeout/1000+" ms, "+ + "lFrame0 "+lastFramePeriod0/1000+" ms, "+ + "lFrameX "+lastFramePeriodX/1000+" / "+frameXS/1000+" ~"+(frameXS/perfIter)/1000.0+" ms, "+ + "finishGL "+finishGL/1000+" / "+finishGLS/1000+" ~"+(finishGLS/perfIter)/1000.0+" ms, "+ + "waitGL "+waitGL/1000+" / "+waitGLS/1000+" ~"+(waitGLS/perfIter)/1000.0+" ms"); + */ + // + // Required(?) to finish previous GL rendering to give CALayer proper result, + // i.e. synchronize both threads each w/ their GLContext sharing same resources. + // + // FIXME: IMHO this synchronization should be implicitly performed via 'CGL.flushBuffer(contextHandle)' above, + // in case this will be determined a driver bug - use a QUIRK entry in GLRendererQuirks! + gl.glFinish(); + + // If v-sync is disabled, frames will be drawn as quickly as possible w/o delay, + // while still synchronizing w/ CALayer. + // If v-sync is enabled wait until next swap interval (v-sync). + CGL.waitUntilNSOpenGLLayerIsReady(cmd.nsOpenGLLayer, vsyncTimeout); + } else { + skipSync--; + } + if(isFBO) { + // trigger CALayer to update incl. possible surface change (texture) + CGL.setNSOpenGLLayerNeedsDisplayFBO(cmd.nsOpenGLLayer, texID); + } else { + // trigger CALayer to update incl. possible surface change (new pbuffer handle) + CGL.setNSOpenGLLayerNeedsDisplayPBuffer(cmd.nsOpenGLLayer, drawable.getHandle()); + } + // lastFrameStart = TimeUnit.NANOSECONDS.toMicros(System.nanoTime()); + } + } else { + res = true; + } + return res; + } + } + } + return CGL.flushBuffer(contextHandle); + } + } class CGLImpl implements GLBackendImpl { - public boolean isNSContext() { return false; } - - public long create(long share, int ctp, int major, int minor) { - long ctx = 0; - MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); - GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor); - if (pixelFormat == 0) { - throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); - } - config.setChosenPixelFormat(pixelFormat); - try { - // Create new context - PointerBuffer ctxPB = PointerBuffer.allocateDirect(1); - if (DEBUG) { - System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share)); - } - int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB); - if (res != CGL.kCGLNoError) { - throw new GLException("Error code " + res + " while creating context"); + @Override + public boolean isNSContext() { return false; } + + @Override + public long create(long share, int ctp, int major, int minor) { + long ctx = 0; + final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration(); + final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + final long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(config.getScreen().getDevice(), + chosenCaps, ctp, major, minor); + if (pixelFormat == 0) { + throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); } - if(chosenCaps.isPBuffer()) { - // Attach newly-created context to the pbuffer - res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0); + try { + // Create new context + PointerBuffer ctxPB = PointerBuffer.allocateDirect(1); + if (DEBUG) { + System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share)); + } + int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB); if (res != CGL.kCGLNoError) { - throw new GLException("Error code " + res + " while attaching context to pbuffer"); + throw new GLException("Error code " + res + " while creating context"); } + ctx = ctxPB.get(0); + + if (0 != ctx) { + GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat); + fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque()); + { // determine on-/offscreen caps, since pformat is ambiguous + fixedCaps.setFBO( false ); // n/a for CGLImpl + fixedCaps.setPBuffer( fixedCaps.isPBuffer() && !chosenCaps.isOnscreen() ); + fixedCaps.setBitmap( false ); // n/a in our OSX impl. + fixedCaps.setOnscreen( !fixedCaps.isPBuffer() ); + } + config.setChosenCapabilities(fixedCaps); + if(DEBUG) { + System.err.println("CGL create fixedCaps: "+fixedCaps); + } + if(fixedCaps.isPBuffer()) { + // Must now associate the pbuffer with our newly-created context + res = CGL.CGLSetPBuffer(ctx, drawable.getHandle(), 0, 0, 0); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while attaching context to pbuffer"); + } + } + } + } finally { + CGL.CGLDestroyPixelFormat(pixelFormat); } - ctx = ctxPB.get(0); - if(0!=ctx) { - if(DEBUG) { - GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat); - System.err.println("NS created: "+caps0); - } - } - } finally { - CGL.CGLDestroyPixelFormat(pixelFormat); + return ctx; } - return ctx; - } - - public boolean destroy(long ctx) { - return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError; - } - public boolean copyImpl(long src, int mask) { - CGL.CGLCopyContext(src, contextHandle, mask); - return true; - } - - public boolean makeCurrent(long ctx) { - int err = CGL.CGLLockContext(ctx); - if(CGL.kCGLNoError == err) { - err = CGL.CGLSetCurrentContext(ctx); + @Override + public boolean destroy(long ctx) { + return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError; + } + + @Override + public void associateDrawable(boolean bound) { + } + + @Override + public boolean copyImpl(long src, int mask) { + CGL.CGLCopyContext(src, contextHandle, mask); + return true; + } + + @Override + public boolean makeCurrent(long ctx) { + int err = CGL.CGLLockContext(ctx); if(CGL.kCGLNoError == err) { - return true; + err = CGL.CGLSetCurrentContext(ctx); + if(CGL.kCGLNoError == err) { + return true; + } else if(DEBUG) { + System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this); + } } else if(DEBUG) { - System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this); + System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this); } - } else if(DEBUG) { - System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this); + return false; } - return false; - } - public boolean release(long ctx) { - try { - gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze - } catch (GLException gle) { - if(DEBUG) { - System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:"); - gle.printStackTrace(); + @Override + public boolean release(long ctx) { + try { + if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != MacOSXCGLContext.this.getGLProcAddressTable() ) { + gl.glFlush(); + } + } catch (GLException gle) { + if(DEBUG) { + System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:"); + gle.printStackTrace(); + } } + int err = CGL.CGLSetCurrentContext(0); + if(DEBUG && CGL.kCGLNoError != err) { + System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this); + } + int err2 = CGL.CGLUnlockContext(ctx); + if(DEBUG && CGL.kCGLNoError != err2) { + System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this); + } + return CGL.kCGLNoError == err && CGL.kCGLNoError == err2; } - int err = CGL.CGLSetCurrentContext(0); - if(DEBUG && CGL.kCGLNoError != err) { - System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this); + + @Override + public boolean detachPBuffer() { + /* Doesn't work, i.e. not taking NULL + final int res = CGL.CGLSetPBuffer(contextHandle, 0, 0, 0, 0); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while detaching context from pbuffer"); + } */ + return true; } - int err2 = CGL.CGLUnlockContext(ctx); - if(DEBUG && CGL.kCGLNoError != err2) { - System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this); + + @Override + public boolean setSwapInterval(int interval) { + final IntBuffer lval = Buffers.newDirectIntBuffer(1); + lval.put(0, interval); + CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval); + return true; } - return CGL.kCGLNoError == err && CGL.kCGLNoError == err2; - } - - public boolean setSwapInterval(int interval) { - int[] lval = new int[] { interval } ; - CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0); - return true; - } - public boolean swapBuffers() { - return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle); - } - } + @Override + public boolean swapBuffers() { + return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle); + } + } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java index 7b5efc31a..448e3e221 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -42,10 +42,10 @@ package jogamp.opengl.macosx.cgl; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -82,62 +82,75 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { // 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. + // be enough to get things off the ground. public enum GLBackendType { - NSOPENGL(0), CGL(1); - + /** Default OpenGL Backend */ + NSOPENGL(0), + /** Alternative OpenGL Backend, only used for external context! */ + CGL(1); + public final int id; GLBackendType(int id){ this.id = id; } } - private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>(); - + /* pp */ List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>(); + private boolean haveSetOpenGLMode = false; private GLBackendType openGLMode = GLBackendType.NSOPENGL; - + public MacOSXCGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) { super(factory, comp, realized); initOpenGLImpl(getOpenGLMode()); } - + + @Override protected void setRealizedImpl() { } - protected long getNSViewHandle() { - return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0; - } - - protected void registerContext(MacOSXCGLContext ctx) { + @Override + protected void associateContext(GLContext ctx, boolean bound) { // 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 (createdContexts) { - createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx)); + if(bound) { + final MacOSXCGLContext osxCtx = (MacOSXCGLContext)ctx; + createdContexts.add(new WeakReference<MacOSXCGLContext>(osxCtx)); + } else { + for(int i=0; i<createdContexts.size(); ) { + final MacOSXCGLContext _ctx = createdContexts.get(i).get(); + if( _ctx == null || _ctx == ctx) { + createdContexts.remove(i); + } else { + i++; + } + } + } } } - protected final void swapBuffersImpl() { - // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers() - synchronized (createdContexts) { - for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) { - WeakReference<MacOSXCGLContext> ref = iter.next(); - MacOSXCGLContext ctx = ref.get(); - if (ctx != null) { - ctx.swapBuffers(); - } else { - iter.remove(); - } + + @Override + protected final void swapBuffersImpl(boolean doubleBuffered) { + if(doubleBuffered) { + synchronized (createdContexts) { + for(int i=0; i<createdContexts.size(); ) { + final MacOSXCGLContext ctx = createdContexts.get(i).get(); + if (ctx != null) { + ctx.swapBuffers(); + i++; + } else { + createdContexts.remove(i); + } + } } } - } - - public GLDynamicLookupHelper getGLDynamicLookupHelper() { - return getFactoryImpl().getGLDynamicLookupHelper(0); } - protected static String getThreadName() { - return Thread.currentThread().getName(); + @Override + public GLDynamicLookupHelper getGLDynamicLookupHelper() { + return getFactoryImpl().getGLDynamicLookupHelper(0); } // Support for "mode switching" as described in MacOSXCGLDrawable @@ -148,17 +161,16 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { if (haveSetOpenGLMode) { throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); } - - destroyImpl(); + setRealized(false); if (DEBUG) { System.err.println("MacOSXCGLDrawable: Switching context mode " + openGLMode + " -> " + mode); } initOpenGLImpl(mode); openGLMode = mode; - haveSetOpenGLMode = true; + haveSetOpenGLMode = true; } public final GLBackendType getOpenGLMode() { return openGLMode; } protected void initOpenGLImpl(GLBackendType backend) { /* nop */ } - + } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index 71c0d5539..9ce71cfe9 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -41,17 +41,17 @@ package jogamp.opengl.macosx.cgl; import java.nio.Buffer; +import java.nio.FloatBuffer; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; +import javax.media.nativewindow.UpstreamSurfaceHook; import javax.media.opengl.GL; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; @@ -60,21 +60,27 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLProfile.ShutdownType; +import jogamp.nativewindow.WrappedSurface; +import jogamp.nativewindow.macosx.OSXDummyUpstreamSurfaceHook; import jogamp.opengl.DesktopGLDynamicLookupHelper; +import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLDynamicLookupHelper; +import jogamp.opengl.GLGraphicsConfigurationUtil; +import jogamp.opengl.SharedResourceRunner; -import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.nio.Buffers; import com.jogamp.common.util.ReflectionUtil; -import com.jogamp.nativewindow.WrappedSurface; +import com.jogamp.nativewindow.MutableGraphicsConfiguration; import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; +import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLRendererQuirks; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null; - + public MacOSXCGLDrawableFactory() { super(); @@ -90,31 +96,40 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } if(null!=tmp && tmp.isLibComplete()) { macOSXCGLDynamicLookupHelper = tmp; - /** FIXME ?? + /** FIXME ?? CGL.getCGLProcAddressTable().reset(macOSXCGLDynamicLookupHelper); */ } } } - + defaultDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - + if(null!=macOSXCGLDynamicLookupHelper) { // Register our GraphicsConfigurationFactory implementations // The act of constructing them causes them to be registered MacOSXCGLGraphicsConfigurationFactory.registerFactory(); if(GLProfile.isAWTAvailable()) { try { - ReflectionUtil.callStaticMethod("jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", - "registerFactory", null, null, getClass().getClassLoader()); - } catch (JogampRuntimeException jre) { /* n/a .. */ } + ReflectionUtil.callStaticMethod("jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", + "registerFactory", null, null, getClass().getClassLoader()); + } catch (Exception jre) { /* n/a .. */ } } - + sharedMap = new HashMap<String, SharedResource>(); - } + } + } + + @Override + protected final boolean isComplete() { + return null != macOSXCGLDynamicLookupHelper; } - protected final void destroy(ShutdownType shutdownType) { + @Override + protected final void shutdownImpl() { + if( DEBUG ) { + System.err.println("MacOSXCGLDrawableFactory.shutdown"); + } if(null != sharedMap) { sharedMap.clear(); sharedMap = null; @@ -122,13 +137,13 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { defaultDevice = null; /** * Pulling away the native library may cause havoc .. - * - if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) { - macOSXCGLDynamicLookupHelper.destroy(); - macOSXCGLDynamicLookupHelper = null; - } */ + * + macOSXCGLDynamicLookupHelper.destroy(); + */ + macOSXCGLDynamicLookupHelper = null; } + @Override public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { return macOSXCGLDynamicLookupHelper; } @@ -136,37 +151,62 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private HashMap<String, SharedResource> sharedMap = new HashMap<String, SharedResource>(); private MacOSXGraphicsDevice defaultDevice; - static class SharedResource { + static class SharedResource implements SharedResourceRunner.Resource { // private MacOSXCGLDrawable drawable; // private MacOSXCGLContext context; + private final GLRendererQuirks glRendererQuirks; MacOSXGraphicsDevice device; - boolean wasContextCreated; + boolean valid; boolean hasNPOTTextures; boolean hasRECTTextures; boolean hasAppleFloatPixels; - SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated, + SharedResource(MacOSXGraphicsDevice device, boolean valid, boolean hasNPOTTextures, boolean hasRECTTextures, boolean hasAppletFloatPixels - /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) { + /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */, GLRendererQuirks glRendererQuirks) { // drawable = draw; - // context = ctx; + // this.context = ctx; + this.glRendererQuirks = glRendererQuirks; this.device = device; - this.wasContextCreated = wasContextCreated; + this.valid = valid; this.hasNPOTTextures = hasNPOTTextures; this.hasRECTTextures = hasRECTTextures; this.hasAppleFloatPixels = hasAppletFloatPixels; } - final MacOSXGraphicsDevice getDevice() { return device; } - final boolean wasContextAvailable() { return wasContextCreated; } + @Override + public final boolean isValid() { + return valid; + } + @Override + public final MacOSXGraphicsDevice getDevice() { return device; } + // final MacOSXCGLContext getContext() { return context; } final boolean isNPOTTextureAvailable() { return hasNPOTTextures; } final boolean isRECTTextureAvailable() { return hasRECTTextures; } final boolean isAppleFloatPixelsAvailable() { return hasAppleFloatPixels; } + @Override + public final AbstractGraphicsScreen getScreen() { + return null; + } + @Override + public final GLDrawableImpl getDrawable() { + return null; + } + @Override + public GLContextImpl getContext() { + return null; + } + @Override + public GLRendererQuirks getRendererQuirks() { + return glRendererQuirks; + } } + @Override public final AbstractGraphicsDevice getDefaultDevice() { return defaultDevice; } + @Override public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { if(null!=macOSXCGLDynamicLookupHelper && device instanceof MacOSXGraphicsDevice) { return true; @@ -174,7 +214,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return false; } - private HashSet<String> devicesTried = new HashSet<String>(); + private final HashSet<String> devicesTried = new HashSet<String>(); private boolean getDeviceTried(String connection) { synchronized (devicesTried) { @@ -191,8 +231,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { devicesTried.remove(connection); } } - - /* package */ SharedResource getOrCreateOSXSharedResource(AbstractGraphicsDevice adevice) { + + @Override + protected final SharedResource getOrCreateSharedResourceImpl(AbstractGraphicsDevice adevice) { final String connection = adevice.getConnection(); SharedResource sr; synchronized(sharedMap) { @@ -201,7 +242,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { if(null==sr && !getDeviceTried(connection)) { addDeviceTried(connection); final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID()); - boolean madeCurrent = false; + GLRendererQuirks glRendererQuirks = null; + boolean isValid = false; boolean hasNPOTTextures = false; boolean hasRECTTextures = false; boolean hasAppleFloatPixels = false; @@ -209,96 +251,68 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false); if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); - } - final GLCapabilities caps = new GLCapabilities(glp); - caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0); - caps.setDepthBits(5); - caps.setDoubleBuffered(false); - caps.setOnscreen(false); - caps.setPBuffer(true); - final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) ); - if(null!=drawable) { - drawable.setRealized(true); - final GLContext context = drawable.createContext(null); - if (null != context) { - try { - context.makeCurrent(); // could cause exception - madeCurrent = context.isCurrent(); - if(madeCurrent) { - GL gl = context.getGL(); - hasNPOTTextures = gl.isNPOTTextureAvailable(); - hasRECTTextures = gl.isExtensionAvailable("GL_EXT_texture_rectangle"); - hasAppleFloatPixels = gl.isExtensionAvailable("GL_APPLE_float_pixels"); - } - } catch (GLException gle) { - if (DEBUG) { - System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:"); - gle.printStackTrace(); - } - } finally { - try { - context.destroy(); - } catch (GLException gle) { - if (DEBUG) { - System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:"); - gle.printStackTrace(); - } - } + } + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); + sharedDrawable.setRealized(true); + + final MacOSXCGLContext sharedContext = (MacOSXCGLContext) sharedDrawable.createContext(null); + if (null == sharedContext) { + throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); + } + + try { + sharedContext.makeCurrent(); // could cause exception + isValid = sharedContext.isCurrent(); + if(isValid) { + GL gl = sharedContext.getGL(); + hasNPOTTextures = gl.isNPOTTextureAvailable(); + hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle); + hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels); + glRendererQuirks = sharedContext.getRendererQuirks(); + } + } catch (GLException gle) { + if (DEBUG) { + System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:"); + gle.printStackTrace(); + } + } finally { + try { + sharedContext.destroy(); + } catch (GLException gle) { + if (DEBUG) { + System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:"); + gle.printStackTrace(); } } - drawable.destroy(); } + sharedDrawable.setRealized(false); } - sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels); + sr = new SharedResource(sharedDevice, isValid, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels, glRendererQuirks); synchronized(sharedMap) { sharedMap.put(connection, sr); } removeDeviceTried(connection); if (DEBUG) { System.err.println("MacOSXCGLDrawableFactory.createShared: device: " + sharedDevice); - System.err.println("MacOSXCGLDrawableFactory.createShared: context: madeCurrent " + madeCurrent + ", NPOT "+hasNPOTTextures+ - ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels); - } + System.err.println("MacOSXCGLDrawableFactory.createShared: context: madeCurrent " + isValid + ", NPOT "+hasNPOTTextures+ + ", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels+", "+glRendererQuirks); + } } return sr; } - + + @Override protected final Thread getSharedResourceThread() { return null; } - - protected final boolean createSharedResource(AbstractGraphicsDevice device) { - try { - SharedResource sr = getOrCreateOSXSharedResource(device); - if(null!=sr) { - return sr.wasContextAvailable(); - } - } catch (GLException gle) { - if(DEBUG) { - System.err.println("Catched Exception while MaxOSXCGL Shared Resource initialization:"); - gle.printStackTrace(); - } - } - return false; - } - - protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { - // FIXME: not implemented .. needs a dummy OSX surface - return null; - } - - protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateOSXSharedResource(device); - if(null!=sr) { - return sr.getDevice(); - } - return null; - } + @Override protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device); } + @Override protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -306,54 +320,81 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return new MacOSXOnscreenCGLDrawable(this, target); } + @Override protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { - AbstractGraphicsConfiguration config = target.getGraphicsConfiguration(); - GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration(); + final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); if(!caps.isPBuffer()) { + // Actual implementation is using PBuffer ... + final GLCapabilities modCaps = (GLCapabilities) caps.cloneMutable(); + modCaps.setPBuffer(true); + modCaps.setBitmap(false); + config.setChosenCapabilities(modCaps); return new MacOSXOffscreenCGLDrawable(this, target); } return new MacOSXPbufferCGLDrawable(this, target); } - public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - return true; + @Override + public boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp) { + if( glp.isGL2() ) { + // OSX only supports pbuffer w/ compatible, non-core, context. + return true; + } else { + return false; + } + } + + @Override + protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { + final MacOSXGraphicsDevice device; + if( createNewDevice || !(deviceReq instanceof MacOSXGraphicsDevice) ) { + device = new MacOSXGraphicsDevice(deviceReq.getUnitID()); + } else { + device = (MacOSXGraphicsDevice)deviceReq; + } + final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); + final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true); + if(null == config) { + throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); + } + return new WrappedSurface(config, 0, upstreamHook, createNewDevice); + } + + @Override + public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); + return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, + new OSXDummyUpstreamSurfaceHook(width, height)); } - protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX); - WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true)); - ns.surfaceSizeChanged(width, height); - return ns; + @Override + protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { + final MacOSXGraphicsDevice device = new MacOSXGraphicsDevice(deviceReq.getUnitID()); + final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx); + final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true); + return new WrappedSurface(config, windowHandle, upstream, true); } - protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { - AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); - WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true), windowHandle); - return ns; - } - + @Override protected GLContext createExternalGLContextImpl() { return MacOSXExternalCGLContext.create(this); } + @Override public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { return false; } + @Override protected GLDrawable createExternalGLDrawableImpl() { // FIXME throw new GLException("Not yet implemented"); } - public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { - return false; - } - - public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) - throws GLException { - throw new GLException("not supported in non AWT enviroment"); - } - //------------------------------------------------------ // Gamma-related functionality // @@ -362,21 +403,24 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { /** Returns the length of the computed gamma ramp for this OS and hardware. Returns 0 if gamma changes are not supported. */ + @Override protected int getGammaRampLength() { return GAMMA_RAMP_LENGTH; } + @Override protected boolean setGammaRamp(float[] ramp) { - return CGL.setGammaRamp(ramp.length, - ramp, 0, - ramp, 0, - ramp, 0); + final FloatBuffer rampNIO = Buffers.newDirectFloatBuffer(ramp); + + return CGL.setGammaRamp(ramp.length, rampNIO, rampNIO, rampNIO); } + @Override protected Buffer getGammaRamp() { return null; } + @Override protected void resetGammaRamp(Buffer originalGammaRamp) { CGL.resetGammaRamp(); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java index 03ec94db6..cda8307c7 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions 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. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,35 +20,35 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package jogamp.opengl.macosx.cgl; import jogamp.opengl.*; import java.util.*; -public class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { +public final class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { protected MacOSXCGLDynamicLibraryBundleInfo() { super(); } @Override - public List<List<String>> getToolLibNames() { + public final List<List<String>> getToolLibNames() { final List<List<String>> libsList = new ArrayList<List<String>>(); final List<String> libsGL = new ArrayList<String>(); libsGL.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"); libsGL.add("GL"); - libsList.add(libsGL); + libsList.add(libsGL); return libsList; } - + @Override public final List<String> getToolGetProcAddressFuncNameList() { - return null; + return null; /** OSX manual says: NSImage use is discouraged List res = new ArrayList(); res.add("GetProcAddress"); // dummy @@ -59,7 +59,7 @@ public class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBu public final long toolGetProcAddress(long toolGetProcAddressHandle, String funcName) { return 0; /** OSX manual says: NSImage use is discouraged - return CGL.getProcAddress(glFuncName); // manual implementation + return CGL.getProcAddress(glFuncName); // manual implementation */ } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java index 8393a688e..481c0b94b 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,13 +29,14 @@ * 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. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ package jogamp.opengl.macosx.cgl; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; @@ -46,40 +47,34 @@ import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; - +import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.nativewindow.MutableGraphicsConfiguration; public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable { - long pixelformat; - MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - long pixelformat) { + MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested) { super(screen, capsChosen, capsRequested); - this.pixelformat=pixelformat; } + @Override public Object clone() { return super.clone(); } - void setChosenPixelFormat(long pixelformat) { - this.pixelformat=pixelformat; - } - protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) { - MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device); + MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device); if(null == sharedResource) { throw new GLException("Shared resource for device n/a: "+device); } // MacOSXGraphicsDevice osxDevice = sharedResource.getDevice(); return new ArrayList<GLCapabilitiesImmutable>(0); } - - static final int[] cglInternalAttributeToken = new int[] { + + static final IntBuffer cglInternalAttributeToken = Buffers.newDirectIntBuffer(new int[] { CGL.kCGLPFAOpenGLProfile, // >= lion - CGL.NSOpenGLPFAAccelerated, // query only (prefer accelerated, but allow non accelerated), ignored for createPixelformat + CGL.NSOpenGLPFAAccelerated, // query only (prefer accelerated, but allow non accelerated), ignored for createPixelformat CGL.NSOpenGLPFANoRecovery, CGL.kCGLPFAColorFloat, CGL.NSOpenGLPFAPixelBuffer, @@ -91,70 +86,66 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration CGL.NSOpenGLPFAAccumSize, CGL.NSOpenGLPFAStencilSize, CGL.NSOpenGLPFASampleBuffers, - CGL.NSOpenGLPFASamples }; + CGL.NSOpenGLPFASamples }); - static int[] GLCapabilities2NSAttribList(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { - int len = cglInternalAttributeToken.length; - int off = 0; - if ( !MacOSXCGLContext.isLionOrLater ) { - // no OpenGLProfile - off++; - len--; - } - int[] ivalues = new int[len]; + static IntBuffer GLCapabilities2NSAttribList(AbstractGraphicsDevice device, IntBuffer attrToken, GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + final int len = attrToken.remaining(); + final int off = attrToken.position(); + final IntBuffer ivalues = Buffers.newDirectIntBuffer(len); for (int idx = 0; idx < len; idx++) { - final int attr = cglInternalAttributeToken[idx+off]; + final int attr = attrToken.get(idx+off); switch (attr) { - case CGL.kCGLPFAOpenGLProfile: - ivalues[idx] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor); + case CGL.kCGLPFAOpenGLProfile: + ivalues.put(idx, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(device, ctp, major, minor)); break; case CGL.NSOpenGLPFANoRecovery: - ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0; + ivalues.put(idx, caps.getHardwareAccelerated() ? 1 : 0); break; - + case CGL.kCGLPFAColorFloat: - ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0; + // ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() && caps.getPbufferFloatingPointBuffers() ) ? 1 : 0); + ivalues.put(idx, 0); break; case CGL.NSOpenGLPFAPixelBuffer: - ivalues[idx] = caps.isPBuffer() ? 1 : 0; + ivalues.put(idx, ( !caps.isOnscreen() && caps.isPBuffer() ) ? 1 : 0); break; case CGL.NSOpenGLPFADoubleBuffer: - ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0); + ivalues.put(idx, (caps.getDoubleBuffered() ? 1 : 0)); break; case CGL.NSOpenGLPFAStereo: - ivalues[idx] = (caps.getStereo() ? 1 : 0); + ivalues.put(idx, (caps.getStereo() ? 1 : 0)); break; case CGL.NSOpenGLPFAColorSize: - ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); + ivalues.put(idx, (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits())); break; case CGL.NSOpenGLPFAAlphaSize: - ivalues[idx] = caps.getAlphaBits(); + ivalues.put(idx, caps.getAlphaBits()); break; case CGL.NSOpenGLPFADepthSize: - ivalues[idx] = caps.getDepthBits(); + ivalues.put(idx, caps.getDepthBits()); break; case CGL.NSOpenGLPFAAccumSize: - ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits()); + ivalues.put(idx, (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits())); break; case CGL.NSOpenGLPFAStencilSize: - ivalues[idx] = caps.getStencilBits(); + ivalues.put(idx, caps.getStencilBits()); break; case CGL.NSOpenGLPFASampleBuffers: - ivalues[idx] = caps.getSampleBuffers() ? 1 : 0; + ivalues.put(idx, caps.getSampleBuffers() ? 1 : 0); break; case CGL.NSOpenGLPFASamples: - ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0; + ivalues.put(idx, caps.getNumSamples()); break; default: @@ -164,152 +155,158 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration return ivalues; } - static long GLCapabilities2NSPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { - int len = cglInternalAttributeToken.length; - int off = 0; + static long GLCapabilities2NSPixelFormat(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + final IntBuffer attrToken = cglInternalAttributeToken.duplicate(); if ( !MacOSXCGLContext.isLionOrLater ) { // no OpenGLProfile - off++; - len--; - } - int[] ivalues = GLCapabilities2NSAttribList(caps, ctp, major, minor); - return CGL.createPixelFormat(cglInternalAttributeToken, off, len, ivalues, 0); + attrToken.position(1); + } + final IntBuffer ivalues = GLCapabilities2NSAttribList(device, attrToken, caps, ctp, major, minor); + return CGL.createPixelFormat(attrToken, attrToken.remaining(), ivalues); } - static GLCapabilitiesImmutable NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { + static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { return PixelFormat2GLCapabilities(glp, pixelFormat, true); } - static long GLCapabilities2CGLPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + static long GLCapabilities2CGLPixelFormat(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps, int ctp, int major, int minor) { // Set up pixel format attributes - int[] attrs = new int[256]; + final IntBuffer attrs = Buffers.newDirectIntBuffer(256); int i = 0; if(MacOSXCGLContext.isLionOrLater) { - attrs[i++] = CGL.kCGLPFAOpenGLProfile; - attrs[i++] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor); - } - if(caps.isPBuffer()) { - attrs[i++] = CGL.kCGLPFAPBuffer; - } - if (caps.getPbufferFloatingPointBuffers()) { - attrs[i++] = CGL.kCGLPFAColorFloat; + attrs.put(i++, CGL.kCGLPFAOpenGLProfile); + attrs.put(i++, MacOSXCGLContext.GLProfile2CGLOGLProfileValue(device, ctp, major, minor)); } + /** + if(!caps.isOnscreen() && caps.isPBuffer()) { + attrs.put(i++, CGL.kCGLPFAPBuffer); + if (caps.getPbufferFloatingPointBuffers()) { + attrs.put(i++, CGL.kCGLPFAColorFloat); + } + } */ if (caps.getDoubleBuffered()) { - attrs[i++] = CGL.kCGLPFADoubleBuffer; + attrs.put(i++, CGL.kCGLPFADoubleBuffer); } if (caps.getStereo()) { - attrs[i++] = CGL.kCGLPFAStereo; + attrs.put(i++, CGL.kCGLPFAStereo); } - attrs[i++] = CGL.kCGLPFAColorSize; - attrs[i++] = (caps.getRedBits() + - caps.getGreenBits() + - caps.getBlueBits()); - attrs[i++] = CGL.kCGLPFAAlphaSize; - attrs[i++] = caps.getAlphaBits(); - attrs[i++] = CGL.kCGLPFADepthSize; - attrs[i++] = caps.getDepthBits(); + attrs.put(i++, CGL.kCGLPFAColorSize); + attrs.put(i++, ( caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits() ) ); + attrs.put(i++, CGL.kCGLPFAAlphaSize); + attrs.put(i++, caps.getAlphaBits()); + attrs.put(i++, CGL.kCGLPFADepthSize); + attrs.put(i++, caps.getDepthBits()); // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m - attrs[i++] = CGL.kCGLPFAStencilSize; - attrs[i++] = caps.getStencilBits(); - attrs[i++] = CGL.kCGLPFAAccumSize; - attrs[i++] = (caps.getAccumRedBits() + - caps.getAccumGreenBits() + - caps.getAccumBlueBits() + - caps.getAccumAlphaBits()); + attrs.put(i++, CGL.kCGLPFAStencilSize); + attrs.put(i++, caps.getStencilBits()); + attrs.put(i++, CGL.kCGLPFAAccumSize); + attrs.put(i++, ( caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits() + + caps.getAccumAlphaBits() ) ); if (caps.getSampleBuffers()) { - attrs[i++] = CGL.kCGLPFASampleBuffers; - attrs[i++] = 1; - attrs[i++] = CGL.kCGLPFASamples; - attrs[i++] = caps.getNumSamples(); + attrs.put(i++, CGL.kCGLPFASampleBuffers); + attrs.put(i++, 1); + attrs.put(i++, CGL.kCGLPFASamples); + attrs.put(i++, caps.getNumSamples()); } // Use attribute array to select pixel format PointerBuffer fmt = PointerBuffer.allocateDirect(1); - int[] numScreens = new int[1]; - int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0); + IntBuffer numScreens = Buffers.newDirectIntBuffer(1); + int res = CGL.CGLChoosePixelFormat(attrs, fmt, numScreens); if (res != CGL.kCGLNoError) { throw new GLException("Error code " + res + " while choosing pixel format"); } return fmt.get(0); } - - static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) { + + static GLCapabilities CGLPixelFormat2GLCapabilities(long pixelFormat) { return PixelFormat2GLCapabilities(null, pixelFormat, false); } - private static GLCapabilitiesImmutable PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) { - int len = cglInternalAttributeToken.length; - int off = 0; + private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) { + final IntBuffer attrToken = cglInternalAttributeToken.duplicate(); + final int off; if ( !MacOSXCGLContext.isLionOrLater ) { // no OpenGLProfile - off++; - len--; - } - int[] ivalues = new int[len]; + off = 1; + } else { + off = 0; + } + attrToken.position(off); + final int len = attrToken.remaining(); + final IntBuffer ivalues = Buffers.newDirectIntBuffer(len); // 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 - // NativeSurface's AbstractGraphicsConfiguration, + // NativeSurface's AbstractGraphicsConfiguration, // since the public API doesn't provide for a different GLCapabilities per context. // Note: These restrictions of the platform's API might be considered as a bug anyways. // Figure out what attributes we really got if(nsUsage) { - CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0); + CGL.queryPixelFormat(pixelFormat, attrToken, len, ivalues); } else { - CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0); + CGL.CGLQueryPixelFormat(pixelFormat, attrToken, len, ivalues); } + if(null == glp && MacOSXCGLContext.isLionOrLater) { // pre-scan for OpenGL Profile for (int i = 0; i < len; i++) { - if(CGL.kCGLPFAOpenGLProfile == cglInternalAttributeToken[i+off]) { - switch(ivalues[i]) { - case CGL.kCGLOGLPVersion_3_2_Core: + final int ivalue = ivalues.get(i); + if(CGL.kCGLPFAOpenGLProfile == attrToken.get(i+off)) { + switch(ivalue) { + case CGL.kCGLOGLPVersion_GL4_Core: + glp = GLProfile.get(GLProfile.GL4); + break; + case CGL.kCGLOGLPVersion_GL3_Core: glp = GLProfile.get(GLProfile.GL3); break; case CGL.kCGLOGLPVersion_Legacy: glp = GLProfile.get(GLProfile.GL2); - break; + break; default: - throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalues[i])); + throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalue)); } - } + } } } if(null == glp) { glp = GLProfile.get(GLProfile.GL2); } - GLCapabilities caps = new GLCapabilities(glp); + final GLCapabilities caps = new GLCapabilities(glp); + int alphaBits = 0; for (int i = 0; i < len; i++) { - int attr = cglInternalAttributeToken[i+off]; + final int attr = attrToken.get(i+off); + final int ivalue = ivalues.get(i); switch (attr) { case CGL.NSOpenGLPFAAccelerated: - caps.setHardwareAccelerated(ivalues[i] != 0); + caps.setHardwareAccelerated(ivalue != 0); break; - + case CGL.kCGLPFAColorFloat: - caps.setPbufferFloatingPointBuffers(ivalues[i] != 0); + // caps.setPbufferFloatingPointBuffers(ivalue != 0); break; case CGL.NSOpenGLPFAPixelBuffer: - caps.setPBuffer(ivalues[i] != 0); + caps.setPBuffer(ivalue != 0); break; case CGL.NSOpenGLPFADoubleBuffer: - caps.setDoubleBuffered(ivalues[i] != 0); + caps.setDoubleBuffered(ivalue != 0); break; case CGL.NSOpenGLPFAStereo: - caps.setStereo(ivalues[i] != 0); + caps.setStereo(ivalue != 0); break; case CGL.NSOpenGLPFAColorSize: { - int bitSize = ivalues[i]; - if (bitSize == 32) - bitSize = 24; - bitSize /= 3; + final int bitSize = ( 32 == ivalue ? 24 : ivalue ) / 3; caps.setRedBits(bitSize); caps.setGreenBits(bitSize); caps.setBlueBits(bitSize); @@ -317,16 +314,17 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration break; case CGL.NSOpenGLPFAAlphaSize: - caps.setAlphaBits(ivalues[i]); + // ALPHA shall be set at last - due to it's auto setting by !opaque / samples + alphaBits = ivalue; break; case CGL.NSOpenGLPFADepthSize: - caps.setDepthBits(ivalues[i]); + caps.setDepthBits(ivalue); break; case CGL.NSOpenGLPFAAccumSize: { - int bitSize = ivalues[i] / 4; + final int bitSize = ivalue / 4; caps.setAccumRedBits(bitSize); caps.setAccumGreenBits(bitSize); caps.setAccumBlueBits(bitSize); @@ -335,21 +333,22 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration break; case CGL.NSOpenGLPFAStencilSize: - caps.setStencilBits(ivalues[i]); + caps.setStencilBits(ivalue); break; case CGL.NSOpenGLPFASampleBuffers: - caps.setSampleBuffers(ivalues[i] != 0); + caps.setSampleBuffers(ivalue != 0); break; case CGL.NSOpenGLPFASamples: - caps.setNumSamples(ivalues[i]); + caps.setNumSamples(ivalue); break; default: break; } } + caps.setAlphaBits(alphaBits); return caps; } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index 1a9070aef..db2a1df68 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -34,13 +34,17 @@ package jogamp.opengl.macosx.cgl; import jogamp.opengl.GLGraphicsConfigurationFactory; +import jogamp.opengl.GLGraphicsConfigurationUtil; + import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -50,21 +54,16 @@ import javax.media.opengl.GLCapabilitiesImmutable; public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { static void registerFactory() { - GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice.class, new MacOSXCGLGraphicsConfigurationFactory()); + GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice.class, GLCapabilitiesImmutable.class, new MacOSXCGLGraphicsConfigurationFactory()); } - private MacOSXCGLGraphicsConfigurationFactory() { + private MacOSXCGLGraphicsConfigurationFactory() { } + @Override protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, - CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, absScreen, false); - } + CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { - static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(CapabilitiesImmutable capsChosen, - CapabilitiesImmutable capsRequested, - CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen, boolean usePBuffer) { if (absScreen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } @@ -77,11 +76,23 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested"); } - if (chooser != null && - !(chooser instanceof GLCapabilitiesChooser)) { + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } - return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, 0); + return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen, false); + } + + static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + final AbstractGraphicsDevice device = absScreen.getDevice(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), device); + + return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested); } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java index 58cea4ade..ebb0fc6d1 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -49,23 +49,21 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; -import com.jogamp.nativewindow.WrappedSurface; - -import jogamp.opengl.GLContextImpl; +import jogamp.nativewindow.WrappedSurface; import jogamp.opengl.GLContextShareSet; import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; public class MacOSXExternalCGLContext extends MacOSXCGLContext { - private GLContext lastContext; private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) { super(drawable, null); setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL ); - drawable.registerContext(this); this.contextHandle = handle; GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT); + if( !setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT, false /* strictMatch */, false /* withinGLVersionsMapping */) ) { // use GL_VERSION + throw new InternalError("setGLFunctionAvailability !strictMatch failed"); + } getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } @@ -108,44 +106,30 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX); - MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat); + MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps); if(0 == currentDrawable) { // set a fake marker stating a valid drawable - currentDrawable = 1; + currentDrawable = 1; } - WrappedSurface ns = new WrappedSurface(cfg); - ns.setSurfaceHandle(currentDrawable); + WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, true); return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle); } - protected boolean createImpl(GLContextImpl shareWith) throws GLException { + @Override + protected boolean createImpl(final long shareWithHandle) throws GLException { 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; - } - + @Override protected void makeCurrentImpl() throws GLException { } + @Override protected void releaseImpl() throws GLException { } + @Override protected void destroyImpl() throws GLException { } @@ -155,14 +139,17 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { super(factory, comp, true); } + @Override public GLContext createContext(GLContext shareWith) { throw new GLException("Should not call this"); } + @Override public int getWidth() { throw new GLException("Should not call this"); } + @Override public int getHeight() { throw new GLException("Should not call this"); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java deleted file mode 100644 index 949963fa0..000000000 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLContext.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 jogamp.opengl.macosx.cgl; - -import javax.media.opengl.*; -import jogamp.opengl.*; - -public class MacOSXOffscreenCGLContext extends MacOSXPbufferCGLContext -{ - public MacOSXOffscreenCGLContext(MacOSXPbufferCGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } - - public int getOffscreenContextPixelDataType() { - GL gl = getGL(); - return gl.isGL2GL3()?GL2GL3.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/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java index f81cd725e..446a834b9 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -51,7 +51,8 @@ public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable { super(factory, target); } + @Override public GLContext createContext(GLContext shareWith) { - return new MacOSXOffscreenCGLContext(this, shareWith); + return new MacOSXCGLContext(this, shareWith); } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java deleted file mode 100644 index 9e051311c..000000000 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 jogamp.opengl.macosx.cgl; - -import javax.media.opengl.GLContext; -import javax.media.opengl.GLException; - -import jogamp.opengl.GLContextImpl; - -public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { - - public MacOSXOnscreenCGLContext(MacOSXOnscreenCGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } - - @Override - protected void makeCurrentImpl() throws GLException { - super.makeCurrentImpl(); - drawableUpdatedNotify(); - } - - @Override - protected void drawableUpdatedNotify() throws GLException { - final int w = drawable.getWidth(); - final int h = drawable.getHeight(); - final boolean updateContext = ( 0!=updateHandle && CGL.updateContextNeedsUpdate(updateHandle) ) || - w != lastWidth || h != lastHeight; - if(updateContext) { - lastWidth = w; - lastHeight = h; - if (contextHandle == 0) { - throw new GLException("Context not created"); - } - CGL.updateContext(contextHandle); - } - } - - @Override - protected boolean createImpl(GLContextImpl sharedWith) { - boolean res = super.createImpl(sharedWith); - lastWidth = -1; - lastHeight = -1; - if(res && isNSContext()) { - if(0 != updateHandle) { - throw new InternalError("XXX1"); - } - updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle()); - if(0 == updateHandle) { - throw new InternalError("XXX2"); - } - } - return res; - } - - @Override - protected void destroyImpl() throws GLException { - if ( 0 != updateHandle ) { - CGL.updateContextUnregister(updateHandle); - updateHandle = 0; - } - super.destroyImpl(); - } - - private long updateHandle = 0; - private int lastWidth, lastHeight; -} diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java index 80c54042f..c6f0c1383 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,11 +29,11 @@ * 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. */ @@ -45,15 +45,14 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable { - + protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeSurface component) { super(factory, component, false); } + @Override public GLContext createContext(GLContext shareWith) { - final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith); - registerContext(ctx); - return ctx; + return new MacOSXCGLContext(this, shareWith); } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java deleted file mode 100644 index 7ba7d2d5a..000000000 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. 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. - */ - -package jogamp.opengl.macosx.cgl; - -import javax.media.opengl.GL; -import javax.media.opengl.GLContext; -import javax.media.opengl.GLException; -import javax.media.opengl.GLPbuffer; - -import jogamp.opengl.GLContextImpl; - -public class MacOSXPbufferCGLContext extends MacOSXCGLContext { - - // State for render-to-texture and render-to-texture-rectangle support - private int texture; // actual texture object - - public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable, - GLContext shareWith) { - super(drawable, shareWith); - } - - public void bindPbufferToTexture() { - GL gl = getGL(); - gl.glBindTexture(((MacOSXPbufferCGLDrawable)drawable).getTextureTarget(), 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(contextHandle, drawable.getHandle(), GL.GL_FRONT); - } - - public void releasePbufferFromTexture() { - } - - protected boolean createImpl(GLContextImpl shareWith) { - boolean res = super.createImpl(shareWith); - if(res) { - // Initialize render-to-texture support if requested - final GL gl = getGL(); - final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable; - final int textureTarget = osxPDrawable.getTextureTarget(); - - 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.glTexImage2D(textureTarget, 0, GL.GL_RGB, osxPDrawable.getTextureWidth(), osxPDrawable.getTextureHeight(), - 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, null); - gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, drawable.getWidth(), drawable.getHeight()); - } - return res; - } - - public int getFloatingPointMode() { - return GLPbuffer.APPLE_FLOAT; - } -} diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java index 1e49d1fc9..f6e8b8fa3 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -29,20 +29,22 @@ * 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 jogamp.opengl.macosx.cgl; +import java.lang.ref.WeakReference; + import javax.media.nativewindow.DefaultGraphicsConfiguration; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.SurfaceChangeable; +import javax.media.nativewindow.MutableSurface; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLCapabilitiesImmutable; @@ -54,7 +56,7 @@ import javax.media.opengl.GLProfile; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opengl.util.GLBuffers; -public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { +public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { // Abstract interface for implementation of this drawable (either // NSOpenGL-based or CGL-based) interface GLBackendImpl { @@ -64,24 +66,18 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { // Implementation object (either NSOpenGL-based or CGL-based) protected GLBackendImpl impl; - + // 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 - // Note that we can not store this in the NativeSurface because the - // semantic is that contains an NSView - protected long pBuffer; protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight; public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) { super(factory, target, false); } - protected void destroyImpl() { - setRealized(false); - } - + @Override protected void setRealizedImpl() { if(realized) { createPbuffer(); @@ -90,45 +86,45 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { } } + @Override public GLContext createContext(GLContext shareWith) { - final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith); - registerContext(ctx); - return ctx; + return new MacOSXCGLContext(this, shareWith); } - @Override - protected long getNSViewHandle() { - // pbuffer handle is NSOpenGLPixelBuffer - return 0; - } - - @Override - public long getHandle() { - return pBuffer; - } - protected int getTextureTarget() { return pBufferTexTarget; } protected int getTextureWidth() { return pBufferTexWidth; } protected int getTextureHeight() { return pBufferTexHeight; } - + protected void destroyPbuffer() { - if (this.pBuffer != 0) { - NativeSurface ns = getNativeSurface(); + final MutableSurface ms = (MutableSurface) getNativeSurface(); + final long pBuffer = ms.getSurfaceHandle(); + if (0 != pBuffer) { + synchronized (createdContexts) { + for(int i=0; i<createdContexts.size(); ) { + final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i); + final MacOSXCGLContext ctx = ref.get(); + if (ctx != null) { + ctx.detachPBuffer(); + i++; + } else { + createdContexts.remove(i); + } + } + } impl.destroy(pBuffer); - this.pBuffer = 0; - ((SurfaceChangeable)ns).setSurfaceHandle(0); + ms.setSurfaceHandle(0); } } private void createPbuffer() { - final NativeSurface ns = getNativeSurface(); - final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration(); + final MutableSurface ms = (MutableSurface) getNativeSurface(); + final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ms.getGraphicsConfiguration(); final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities(); final GLProfile glProfile = capabilities.getGLProfile(); - MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice()); - + MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateSharedResourceImpl(config.getScreen().getDevice()); + if (DEBUG) { - System.out.println("Pbuffer config: " + config); + System.out.println(getThreadName()+": Pbuffer config: " + config); if(null != sr) { System.out.println("Pbuffer NPOT Texure avail: "+sr.isNPOTTextureAvailable()); System.out.println("Pbuffer RECT Texture avail: "+sr.isRECTTextureAvailable()); @@ -137,12 +133,8 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { } } - if ( capabilities.getPbufferRenderToTextureRectangle() && null!=sr && sr.isRECTTextureAvailable() ) { - pBufferTexTarget = GL2.GL_TEXTURE_RECTANGLE; - } else { - pBufferTexTarget = GL.GL_TEXTURE_2D; - } - if ( GL2.GL_TEXTURE_RECTANGLE == pBufferTexTarget || ( null!=sr && sr.isNPOTTextureAvailable() ) ) { + pBufferTexTarget = GL.GL_TEXTURE_2D; + if ( null!=sr && sr.isNPOTTextureAvailable() ) { pBufferTexWidth = getWidth(); pBufferTexHeight = getHeight(); } else { @@ -150,19 +142,8 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { pBufferTexHeight = GLBuffers.getNextPowerOf2(getHeight()); } - int internalFormat = GL.GL_RGBA; - if (capabilities.getPbufferFloatingPointBuffers()) { - if(!glProfile.isGL2GL3() || null==sr || sr.isAppleFloatPixelsAvailable()) { - throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available"); - } - 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)"); - } - } - - pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight()); + final int internalFormat = GL.GL_RGBA; + final long pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight()); if(DEBUG) { System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+ ", pbufferSize "+getWidth()+"x"+getHeight()+ @@ -175,14 +156,16 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { throw new GLException("pbuffer creation error: CGL.createPBuffer() failed"); } - ((SurfaceChangeable)ns).setSurfaceHandle(pBuffer); + ms.setSurfaceHandle(pBuffer); } + @Override public void setOpenGLMode(GLBackendType mode) { super.setOpenGLMode(mode); createPbuffer(); // recreate } + @Override protected void initOpenGLImpl(GLBackendType backend) { switch (backend) { case NSOPENGL: @@ -194,14 +177,16 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { default: throw new InternalError("Illegal implementation mode " + backend); } - } - + } + // NSOpenGLPixelBuffer implementation class NSOpenGLImpl implements GLBackendImpl { + @Override public long create(int renderTarget, int internalFormat, int width, int height) { return CGL.createPBuffer(renderTarget, internalFormat, width, height); } + @Override public void destroy(long pbuffer) { CGL.destroyPBuffer(pbuffer); } @@ -209,6 +194,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { // CGL implementation class CGLImpl implements GLBackendImpl { + @Override public long create(int renderTarget, int internalFormat, int width, int height) { PointerBuffer pbuffer = PointerBuffer.allocateDirect(1); int res = CGL.CGLCreatePBuffer(width, height, renderTarget, internalFormat, 0, pbuffer); @@ -218,12 +204,13 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { return pbuffer.get(0); } + @Override public void destroy(long pbuffer) { int res = CGL.CGLDestroyPBuffer(pbuffer); if (res != CGL.kCGLNoError) { throw new GLException("Error destroying CGL-based pbuffer: error code " + res); } } - } - + } + } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java deleted file mode 100644 index fe60710f0..000000000 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 jogamp.opengl.macosx.cgl.awt; - -import javax.media.nativewindow.*; -import javax.media.opengl.*; -import jogamp.opengl.macosx.cgl.*; - -public class MacOSXAWTCGLDrawableFactory extends MacOSXCGLDrawableFactory { - - public MacOSXAWTCGLDrawableFactory() { - super(); - } - - public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { - return true; - } - - public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) - throws GLException { - return new MacOSXJava2DCGLContext(shareWith); - } -} diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index a6fa01bad..21923531f 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. 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 @@ -58,14 +58,15 @@ import jogamp.opengl.macosx.cgl.MacOSXCGLGraphicsConfiguration; public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { public static void registerFactory() { - GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, new MacOSXAWTCGLGraphicsConfigurationFactory()); - } + GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, GLCapabilitiesImmutable.class, new MacOSXAWTCGLGraphicsConfigurationFactory()); + } private MacOSXAWTCGLGraphicsConfigurationFactory() { } + @Override protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, - CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { + CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) { GraphicsDevice device = null; if (absScreen != null && !(absScreen instanceof AWTGraphicsScreen)) { @@ -103,9 +104,9 @@ public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigur GraphicsConfiguration gc = device.getDefaultConfiguration(); MacOSXCGLGraphicsConfiguration macConfig = (MacOSXCGLGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(macDevice).chooseGraphicsConfiguration(capsChosen, + GraphicsConfigurationFactory.getFactory(macDevice, capsChosen).chooseGraphicsConfiguration(capsChosen, capsRequested, - chooser, macScreen); + chooser, macScreen, nativeVisualID); if (macConfig == null) { throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+macScreen); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java deleted file mode 100644 index f41400d83..000000000 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 jogamp.opengl.macosx.cgl.awt; - -import java.awt.Graphics; - -import javax.media.opengl.GLContext; -import javax.media.opengl.GLException; - -import jogamp.opengl.GLContextImpl; -import jogamp.opengl.awt.Java2D; -import jogamp.opengl.awt.Java2DGLContext; -import jogamp.opengl.macosx.cgl.MacOSXCGLContext; -import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; - - -/** MacOSXCGLContext 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 MacOSXJava2DCGLContext extends MacOSXCGLContext 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 - - MacOSXJava2DCGLContext(GLContext shareWith) { - super(null, shareWith); - } - - public void setGraphics(Graphics g) { - this.graphics = g; - } - - protected void makeCurrentImpl() throws GLException { - if (!Java2D.makeOGLContextCurrentOnSurface(graphics, contextHandle)) { - throw new GLException("Error making context current"); - } - } - - protected boolean createImpl(GLContextImpl shareWith) { - long share = createImplPreset(shareWith); - - long ctx = Java2D.createOGLContextOnSurface(graphics, share); - if (ctx == 0) { - if(DEBUG) { - System.err.println("Error creating current: "+this); - } - return false; - } - if (!Java2D.makeOGLContextCurrentOnSurface(graphics, contextHandle)) { - Java2D.destroyOGLContext(ctx); - if(DEBUG) { - System.err.println("Error making created context current: "+this); - } - return false; - } - setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT); // use GL_VERSION - contextHandle = 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 { - Java2D.destroyOGLContext(contextHandle); - } - - public void setOpenGLMode(GLBackendType mode) { - if (mode != GLBackendType.CGL) { - throw new GLException("OpenGL mode switching not supported for Java2D GLContexts"); - } - super.setOpenGLMode(mode); - } -} |