diff options
author | Sven Gothel <[email protected]> | 2011-11-12 16:15:54 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-11-12 16:15:54 +0100 |
commit | 8a16d590fe2c739badbabe4906cbe9d60b20e2b9 (patch) | |
tree | 57d7c0794437d2025aae7c29b340af952b5043bb | |
parent | 33aaa037e31ec7d411f4acaeea63a383037f027d (diff) |
OS X Layered View Part8: Generalize OffscreenLayerSurface ; Use local JAWT instance ; Applet's on OS X are working
Generalize OffscreenLayerSurface
- Using new OffscreenLayerSurface allows using this functionality in a clean manner,
ie. no 'dirty' usage of MacOSXJAWTWindow in a JOGL GL class.
- 'Promoting' OffscreenLayerSurface functionality to JAWTWindow
and it's handling to GLDrawableFactoryImpl::createGLDrawable().
- Move MacOSXCGLDrawableFactory's "MacOSXJAWTWindow getLayeredSurfaceHost(NativeSurface surface)"
to NativeWindowFactory "OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled)"
Use local JAWT instance
- Only w/ a local JAWT instance per JAWTWindow it is possible to switch between
offscreen-layer and onscreen. We also have to determing offscreen-layer lazy
at surface lock, since only at that time we have knowledge whether it's an Applet
or not.
+++
ContextUpdater:
Use local pthread mutex, add DEBUG output
JAWTWindow/NewtCanvasAWT:
Adding methods to request offscreen-layer-surface (if supported),
besides 'if applet' this may trigger the new functionality.
+++
Applet's on OS X are working:
- OS X 10.6.4
- Safari:
- Hangs for a while at start .. whole screen freezes .. approx. 10s
- Sometimes crashes when Applet stops - after all our resources are released!
- Keyboard input isn't assigned sometimes.
- Otherwise .. works well, incl. offscreen/onscreen parenting
- Firefox 8.0:
- Hangs for a while at start .. whole screen freezes .. approx. 10s
- Sometimes crashes when Applet stops - after all our resources are released!
- Keyboard input is never assigned.
- Otherwise .. works well, incl. offscreen/onscreen parenting
- OS X 10.7
- Safari:
- Sometimes crashes when Applet stops - after all our resources are released!
- Keyboard input isn't assigned sometimes.
- Otherwise .. works well, incl. offscreen/onscreen parenting
- Firefox 8.0:
- Sometimes crashes when Applet stops - after all our resources are released!
- Keyboard input is never assigned.
- Otherwise .. works well, incl. offscreen/onscreen parenting
23 files changed, 569 insertions, 363 deletions
diff --git a/make/config/nativewindow/jawt-CustomJavaCode.java b/make/config/nativewindow/jawt-CustomJavaCode.java index 090dcb31f..d3dc3845f 100644 --- a/make/config/nativewindow/jawt-CustomJavaCode.java +++ b/make/config/nativewindow/jawt-CustomJavaCode.java @@ -2,63 +2,37 @@ public static final int JAWT_MACOSX_USE_CALAYER = 0x80000000; public static final VersionNumber JAWT_MacOSXCALayerMinVersion = new VersionNumber(10,6,4); -private static volatile JAWT jawt = null; -private static int jawt_version_flags = 0; - private int jawt_version_cached = 0; -public final int getVersionCached() { +public final int getCachedVersion() { return jawt_version_cached; } -public static void setJAWTVersionFlags(int versionFlags) { - synchronized (JAWT.class) { - if (jawt != null) { - throw new RuntimeException("JAWT already instantiated"); - } - jawt_version_flags = versionFlags; - } -} - -public static boolean isJAWTInstantiated() { - synchronized (JAWT.class) { - return jawt != null; - } -} - /** Helper routine for all users to call to access the JAWT. */ -public static JAWT getJAWT() { - if (jawt == null) { - synchronized (JAWT.class) { - if (jawt == null) { - JAWTUtil.initSingleton(); - // Workaround for 4845371. - // Make sure the first reference to the JNI GetDirectBufferAddress is done - // from a privileged context so the VM's internal class lookups will succeed. - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - JAWT j = JAWT.create(); - if( 0 != ( jawt_version_flags & JAWT_MACOSX_USE_CALAYER ) ) { - j.setVersion(jawt_version_flags); - if (JAWTFactory.JAWT_GetAWT(j)) { - jawt = j; - jawt.jawt_version_cached = jawt.getVersion(); - return null; - } - jawt_version_flags &= ~JAWT_MACOSX_USE_CALAYER; - System.err.println("MacOSX "+Platform.OS_VERSION_NUMBER+" >= "+JAWT_MacOSXCALayerMinVersion+": Failed to use JAWT_MACOSX_USE_CALAYER"); - } - j.setVersion(jawt_version_flags); - if (!JAWTFactory.JAWT_GetAWT(j)) { - throw new RuntimeException("Unable to initialize JAWT: 0x"+Integer.toHexString(jawt_version_flags)); +public static JAWT getJAWT(final int jawt_version_flags) { + JAWTUtil.initSingleton(); + // Workaround for 4845371. + // Make sure the first reference to the JNI GetDirectBufferAddress is done + // from a privileged context so the VM's internal class lookups will succeed. + return AccessController.doPrivileged(new PrivilegedAction<JAWT>() { + public JAWT run() { + int jawt_version_flags_mod = jawt_version_flags; + JAWT jawt = JAWT.create(); + if( 0 != ( jawt_version_flags_mod & JAWT_MACOSX_USE_CALAYER ) ) { + jawt.setVersion(jawt_version_flags_mod); + if (JAWTFactory.JAWT_GetAWT(jawt)) { + jawt.jawt_version_cached = jawt.getVersion(); + return jawt; } - jawt = j; - jawt.jawt_version_cached = jawt.getVersion(); - return null; - } - }); - } - } - } - return jawt; + jawt_version_flags_mod &= ~JAWT_MACOSX_USE_CALAYER; + System.err.println("MacOSX "+Platform.OS_VERSION_NUMBER+" >= "+JAWT_MacOSXCALayerMinVersion+": Failed to use JAWT_MACOSX_USE_CALAYER"); + } + jawt.setVersion(jawt_version_flags_mod); + if (!JAWTFactory.JAWT_GetAWT(jawt)) { + throw new RuntimeException("Unable to initialize JAWT: 0x"+Integer.toHexString(jawt_version_flags_mod)); + } + jawt.jawt_version_cached = jawt.getVersion(); + return jawt; + } + }); } diff --git a/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java b/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java index cab6c93d4..4ff3a45b0 100644 --- a/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java +++ b/make/config/nativewindow/jawt-DrawingSurfaceInfo-CustomJavaCode.java @@ -1,19 +1,19 @@ -public JAWT_PlatformInfo platformInfo() { - return newPlatformInfo(platformInfo0(getBuffer())); +public JAWT_PlatformInfo platformInfo(final JAWT jawt) { + return newPlatformInfo(jawt, platformInfo0(getBuffer())); } private native ByteBuffer platformInfo0(Buffer jthis0); private static java.lang.reflect.Method platformInfoFactoryMethod; -private static JAWT_PlatformInfo newPlatformInfo(ByteBuffer buf) { +private static JAWT_PlatformInfo newPlatformInfo(JAWT jawt, ByteBuffer buf) { if (platformInfoFactoryMethod == null) { try { Class<?> factoryClass; if (Platform.OS_TYPE == Platform.OSType.WINDOWS) { factoryClass = Class.forName("jogamp.nativewindow.jawt.windows.JAWT_Win32DrawingSurfaceInfo"); } else if (Platform.OS_TYPE == Platform.OSType.MACOS) { - if( 0 != ( JAWT.getJAWT().getVersionCached() & JAWT.JAWT_MACOSX_USE_CALAYER ) ) { + if( 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER ) ) { factoryClass = Class.forName("jogamp.nativewindow.jawt.macosx.JAWT_SurfaceLayers"); } else { factoryClass = Class.forName("jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo"); diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java index 704f71457..4f0b11789 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java @@ -40,9 +40,26 @@ package jogamp.opengl; -import java.nio.*; -import javax.media.nativewindow.*; -import javax.media.opengl.*; +import java.nio.Buffer; + +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.nativewindow.SurfaceChangeable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; +import javax.media.opengl.GLPbuffer; +import javax.media.opengl.GLProfile; +import javax.media.opengl.Threading; + +import jogamp.nativewindow.MutableGraphicsConfiguration; import com.jogamp.common.util.VersionNumber; @@ -103,24 +120,43 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { if (target == null) { throw new IllegalArgumentException("Null target"); } - AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); AbstractGraphicsDevice adevice = config.getScreen().getDevice(); GLDrawable result = null; adevice.lock(); try { - if(caps.isOnscreen()) { - if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target); + if(chosenCaps.isOnscreen()) { + // onscreen + final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true); + if(null == ols) { + // traditional onscreen + if(DEBUG) { + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target); + } + result = createOnscreenDrawableImpl(target); + } else { + // layered surface -> offscreen/PBuffer + final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable(); + chosenCapsMod.setOnscreen(false); + chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice)); + config.setChosenCapabilities(chosenCapsMod); + if(DEBUG) { + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target); + } + if( ! ( target instanceof SurfaceChangeable ) ) { + throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target); + } + result = createOffscreenDrawableImpl(target); } - result = createOnscreenDrawableImpl(target); } else { + // offscreen + if(DEBUG) { + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target); + } if( ! ( target instanceof SurfaceChangeable ) ) { throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target); } - if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+caps.isPBuffer()+"): "+target); - } result = createOffscreenDrawableImpl(target); } } finally { diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index b75d2f927..f5970fad9 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -46,18 +46,18 @@ import java.util.Map; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.OffscreenLayerSurface; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLContextShareSet; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; -import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.LayeredSurfaceType; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.os.Platform; @@ -407,7 +407,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.drawable; final NativeSurface surface = drawable.getNativeSurface(); final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - final boolean isBackingLayerView = LayeredSurfaceType.None != drawable.getLayeredSurfaceType(); + final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true); final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor); if (pixelFormat == 0) { @@ -416,7 +416,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl config.setChosenPixelFormat(pixelFormat); if(DEBUG) { System.err.println("NS create OSX>=lion "+isLionOrLater); - System.err.println("NS create drawable layeredType: "+drawable.getLayeredSurfaceType()+", backingLayerView "+isBackingLayerView); + 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)); @@ -428,7 +428,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl int[] viewNotReady = new int[1]; // Try to allocate a context with this ctx = CGL.createContext(share, - drawable.getNSViewHandle(), isBackingLayerView, + drawable.getNSViewHandle(), null!=backingLayerHost, pixelFormat, chosenCaps.isBackgroundOpaque(), viewNotReady, 0); @@ -459,16 +459,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl CGL.setContextPBuffer(ctx, drawable.getHandle()); } // - // handled layered surface (same path for direct and parented) + // handled layered surface // - if(isBackingLayerView) { - final MacOSXJAWTWindow lsh = MacOSXCGLDrawableFactory.getLayeredSurfaceHost(surface); + if(null != backingLayerHost) { nsOpenGLLayerPFmt = pixelFormat; pixelFormat = 0; - /* - final long nsView = drawable.getNSViewHandle(); - nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, nsView, fixedCaps.isBackgroundOpaque()); - */ final int texWidth, texHeight; if(drawable instanceof MacOSXPbufferCGLDrawable) { final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable; @@ -482,7 +477,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)); } - lsh.attachSurfaceLayer(nsOpenGLLayer); + backingLayerHost.attachSurfaceLayer(nsOpenGLLayer); } } finally { if(0!=pixelFormat) { @@ -495,12 +490,15 @@ public abstract class MacOSXCGLContext extends GLContextImpl public boolean destroy(long ctx) { if(0 != nsOpenGLLayer) { final NativeSurface surface = drawable.getNativeSurface(); - final MacOSXJAWTWindow lsh = MacOSXCGLDrawableFactory.getLayeredSurfaceHost(surface); 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); - lsh.detachSurfaceLayer(nsOpenGLLayer); + ols.detachSurfaceLayer(nsOpenGLLayer); CGL.deletePixelFormat(nsOpenGLLayerPFmt); nsOpenGLLayerPFmt = 0; nsOpenGLLayer = 0; diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java index 7ee0d4fbe..12d480fd1 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java @@ -49,7 +49,6 @@ import javax.media.nativewindow.NativeSurface; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; -import jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow; import jogamp.opengl.GLDrawableImpl; import jogamp.opengl.GLDynamicLookupHelper; @@ -93,29 +92,16 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { this.id = id; } } - public enum LayeredSurfaceType { - None(0), Direct(1), Parented(2); - - public final int id; - - LayeredSurfaceType(int id){ - this.id = id; - } - } - private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>(); private boolean haveSetOpenGLMode = false; private GLBackendType openGLMode = GLBackendType.NSOPENGL; - protected LayeredSurfaceType layeredSurfaceType = LayeredSurfaceType.None; public MacOSXCGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) { super(factory, comp, realized); initOpenGLImpl(getOpenGLMode()); } - public final LayeredSurfaceType getLayeredSurfaceType() { return layeredSurfaceType; } - protected void setRealizedImpl() { } @@ -123,32 +109,6 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { return GLBackendType.NSOPENGL == openGLMode ? getHandle() : null; } - @Override - protected void updateHandle() { - final MacOSXJAWTWindow lsh = MacOSXCGLDrawableFactory.getLayeredSurfaceHost(surface); - if (null != lsh) { - if(lsh == surface) { - // direct surface host, eg. AWT GLCanvas - layeredSurfaceType = LayeredSurfaceType.Direct; - if (DEBUG) { - System.err.println("updateHandle: layerType " + layeredSurfaceType + ", backingLayer "+toHexString(lsh.getSurfaceHandle())); - } - } else { - // parent surface host, eg. via native parenting w/ NewtCanvasAWT - layeredSurfaceType = LayeredSurfaceType.Parented; - if (DEBUG) { - System.err.println("updateHandle: layerType " + layeredSurfaceType + ", backingLayer "+toHexString(getHandle())); - } - } - } else { - layeredSurfaceType = LayeredSurfaceType.None; - if (DEBUG) { - System.err.println("updateHandle: layerType " + layeredSurfaceType); - } - } - super.updateHandle(); - } - protected void registerContext(MacOSXCGLContext ctx) { // NOTE: we need to keep track of the created contexts in order to // implement swapBuffers() because of how Mac OS X implements its diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index 3c2b7aed6..30917476e 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -50,7 +50,6 @@ import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; @@ -64,7 +63,6 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import jogamp.nativewindow.WrappedSurface; -import jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow; import jogamp.opengl.DesktopGLDynamicLookupHelper; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableImpl; @@ -259,38 +257,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device); } - protected static MacOSXJAWTWindow getLayeredSurfaceHost(NativeSurface surface) { - if(surface instanceof NativeWindow) { - final NativeWindow nwThis = (NativeWindow) surface; - if( nwThis instanceof MacOSXJAWTWindow) { - // direct surface host, eg. via AWT GLCanvas - final MacOSXJAWTWindow r = (MacOSXJAWTWindow) nwThis; - return r.isOffscreenLayerSurface() ? r : null; - } else { - NativeWindow nwParent = nwThis.getParent(); - if(null != nwParent && nwParent instanceof MacOSXJAWTWindow) { - final MacOSXJAWTWindow r = (MacOSXJAWTWindow) nwParent; - return r.isOffscreenLayerSurface() ? r : null; - } - } - } - return null; - } - protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); } - final MacOSXJAWTWindow lsh = MacOSXCGLDrawableFactory.getLayeredSurfaceHost(target); - if(null != lsh) { - // layered surface -> PBuffer - final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - final GLCapabilities chosenCaps = (GLCapabilities) config.getChosenCapabilities().cloneMutable(); - chosenCaps.setOnscreen(false); - chosenCaps.setPBuffer(true); - config.setChosenCapabilities(chosenCaps); - return new MacOSXPbufferCGLDrawable(this, target, false); - } return new MacOSXOnscreenCGLDrawable(this, target); } @@ -300,21 +270,6 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { if(!caps.isPBuffer()) { return new MacOSXOffscreenCGLDrawable(this, target); } - - // PBuffer GLDrawable Creation - /** - * FIXME: Think about this .. - * should not be necessary ? .. - final List returnList = new ArrayList(); - final GLDrawableFactory factory = this; - Runnable r = new Runnable() { - public void run() { - returnList.add(new MacOSXPbufferCGLDrawable(factory, target)); - } - }; - maybeDoSingleThreadedWorkaround(r); - return (GLDrawableImpl) returnList.get(0); - */ return new MacOSXPbufferCGLDrawable(this, target, true); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java index de3e90c4c..4fe6fa484 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -74,6 +74,8 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { @Override protected boolean createImpl() { boolean res = super.createImpl(); + lastWidth = -1; + lastHeight = -1; if(res && isNSContext()) { if(0 != updateHandle) { throw new InternalError("XXX1"); @@ -83,9 +85,6 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { throw new InternalError("XXX2"); } } - updateHandle = 0; - lastWidth = -1; - lastHeight = -1; return res; } @@ -98,6 +97,6 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { super.destroyImpl(); } - private long updateHandle; + private long updateHandle = 0; private int lastWidth, lastHeight; } diff --git a/src/jogl/native/macosx/ContextUpdater.h b/src/jogl/native/macosx/ContextUpdater.h index 3cf7315af..f00b2be57 100644 --- a/src/jogl/native/macosx/ContextUpdater.h +++ b/src/jogl/native/macosx/ContextUpdater.h @@ -25,17 +25,13 @@ This notification is sent whenever an NSView that has an attached NSSurface chan @interface ContextUpdater : NSObject { @protected + pthread_mutex_t resourceLock; NSView * view; NSRect viewRect; NSOpenGLContext *ctx; BOOL viewUpdated; } -- (void) lock; -- (void) lockInFunction:(char *)func atLine:(int)line; -- (void) unlock; -- (void) unlockInFunction:(char *)func atLine:(int)line; - - (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView; - (void) update:(NSNotification *)notification; diff --git a/src/jogl/native/macosx/ContextUpdater.m b/src/jogl/native/macosx/ContextUpdater.m index e0668352c..a3b9b5c8c 100644 --- a/src/jogl/native/macosx/ContextUpdater.m +++ b/src/jogl/native/macosx/ContextUpdater.m @@ -1,43 +1,26 @@ #import "ContextUpdater.h" #import <pthread.h> -@implementation ContextUpdater -{ -} +#define VERBOSE_ON 1 -static pthread_mutex_t resourceLock = PTHREAD_MUTEX_INITIALIZER; +#ifdef VERBOSE_ON + #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) + // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) +#else + #define DBG_PRINT(...) +#endif -static void printLockDebugInfo(char *message, char *func, int line) -{ - fprintf(stderr, "%s in function: \"%s\" at line: %d\n", message, func, line); - fflush(NULL); -} +#ifndef CGL_VERSION_1_3 + #warning this SDK doesn't support OpenGL profile +#endif -- (void) lock -{ - pthread_mutex_lock(&resourceLock); -} - -- (void) lockInFunction:(char *)func atLine:(int)line -{ - printLockDebugInfo("locked ", func, line); - [self lock]; -} - -- (void) unlock -{ - pthread_mutex_unlock(&resourceLock); -} - -- (void) unlockInFunction:(char *)func atLine:(int)line +@implementation ContextUpdater { - printLockDebugInfo("unlocked", func, line); - [self unlock]; } - (void) update:(NSNotification *)notification { - [self lock]; + pthread_mutex_lock(&resourceLock); NSRect r = [view frame]; if(viewRect.origin.x != r.origin.x || @@ -48,24 +31,26 @@ static void printLockDebugInfo(char *message, char *func, int line) viewRect = r; } - [self unlock]; + pthread_mutex_unlock(&resourceLock); } - (BOOL) needsUpdate { BOOL r; - [self lock]; + pthread_mutex_lock(&resourceLock); r = viewUpdated; viewUpdated = FALSE; - [self unlock]; + pthread_mutex_unlock(&resourceLock); return r; } - (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView { + DBG_PRINT("ContextUpdater::init.0 view %p, ctx %p\n", view, ctx); + pthread_mutex_init(&resourceLock, NULL); // fast non-recursive ctx = context; view = nsView; [ctx retain]; @@ -73,15 +58,19 @@ static void printLockDebugInfo(char *message, char *func, int line) viewRect = [view frame]; viewUpdated = TRUE; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view]; + DBG_PRINT("ContextUpdater::init.X\n"); return [super init]; } - (void) dealloc { + DBG_PRINT("ContextUpdater::dealloc.0 view %p, ctx %p\n", view, ctx); [[NSNotificationCenter defaultCenter] removeObserver:self]; [view release]; [ctx release]; + pthread_mutex_destroy(&resourceLock); + DBG_PRINT("ContextUpdater::dealloc.X\n"); [super dealloc]; } diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.h b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h index 3625cfbde..b2d7f9db8 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.h +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h @@ -3,11 +3,11 @@ #import <OpenGL/CGLTypes.h> #import <jni.h> -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #ifdef VERBOSE_ON - // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__) - #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) + #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) + // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #else #define DBG_PRINT(...) #endif diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 60ce07f09..b6c850098 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -475,4 +475,33 @@ public abstract class NativeWindowFactory { NativeWindow. Implementors of concrete NativeWindowFactory subclasses should override this method. */ protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException; + + /** + * Returns the {@link OffscreenLayerSurface} instance of this {@link NativeSurface}. + * <p> + * In case this surface is a {@link NativeWindow}, we traverse from the given surface + * up to root until a {@link OffscreenLayerSurface} is found. + * </p> + * + * @param surface The surface to query. + * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerSurface#isOffscreenLayerSurfaceEnabled()}. + * @return + */ + public static OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled) { + if(surface instanceof OffscreenLayerSurface) { + final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface; + return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null; + } + if(surface instanceof NativeWindow) { + NativeWindow nw = ((NativeWindow) surface).getParent(); + while(null != nw) { + if(nw instanceof OffscreenLayerSurface) { + final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw; + return ( !ifEnabled || ols.isOffscreenLayerSurfaceEnabled() ) ? ols : null; + } + nw = nw.getParent(); + } + } + return null; + } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java new file mode 100644 index 000000000..82ae0f39e --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java @@ -0,0 +1,51 @@ +/** + * Copyright 2011 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: + * + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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 javax.media.nativewindow; + +/** + * Interface specifying the offscreen layer surface protocol. + */ +public interface OffscreenLayerSurface { + /** Returns true if this instance uses an offscreen layer, otherwise false. */ + public boolean isOffscreenLayerSurfaceEnabled(); + + /** + * Attach the offscreen layer to this offscreen layer surface. + * @see #isOffscreenLayerSurfaceEnabled() + * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false + */ + public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException; + + /** + * Detaches a previously attached offscreen layer from this offscreen layer surface. + * @see #attachSurfaceLayer(long) + * @see #isOffscreenLayerSurfaceEnabled() + * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false + */ + public void detachSurfaceLayer(final long layerHandle) throws NativeWindowException; +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index 4435c4f8f..ddf453bab 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -57,6 +57,7 @@ public class JAWTUtil { // See whether we're running in headless mode private static final boolean headlessMode; + private static final JAWT jawtLockObject; // Java2D magic .. private static final Method isQueueFlusherThread; @@ -85,29 +86,26 @@ public class JAWTUtil { return Platform.OS_TYPE == Platform.OSType.MACOS && Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0; } - + /** - * - * FIXME: Need to get rid of the cached JAWT instance, - * in case we like to have dual usage of offscreenLayeredSurface and onscreen. - * This would be done implicit by using NEWT .. hence low prio. - * * @param useOffscreenLayerIfAvailable * @return */ - public static boolean setCachedJAWTVersionFlags(boolean useOffscreenLayerIfAvailable) { - if(JAWT.isJAWTInstantiated()) { return false; } // already instantiated - - if(useOffscreenLayerIfAvailable && isOffscreenLayerSupported()) { - JAWT.setJAWTVersionFlags(JAWTFactory.JAWT_VERSION_1_4 | JAWT.JAWT_MACOSX_USE_CALAYER); - return true; + public static JAWT getJAWT(boolean useOffscreenLayerIfAvailable) { + int jawt_version_flags = JAWTFactory.JAWT_VERSION_1_4; + if(useOffscreenLayerIfAvailable) { + switch(Platform.OS_TYPE) { + case MACOS: + if(Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0) { + jawt_version_flags |= JAWT.JAWT_MACOSX_USE_CALAYER; + } + } } - JAWT.setJAWTVersionFlags(JAWTFactory.JAWT_VERSION_1_4); - return !useOffscreenLayerIfAvailable; // n/a + return JAWT.getJAWT(jawt_version_flags); } - public static boolean isCachedJAWTUsingOffscreenLayer() { - return 0 != ( JAWT.getJAWT().getVersionCached() & JAWT.JAWT_MACOSX_USE_CALAYER ); + public static boolean isJAWTUsingOffscreenLayer(JAWT jawt) { + return 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER ); } static { @@ -115,19 +113,19 @@ public class JAWTUtil { JAWTJNILibLoader.loadNativeWindow("awt"); headlessMode = GraphicsEnvironment.isHeadless(); - if(!headlessMode) { - JAWT.setJAWTVersionFlags(JAWTFactory.JAWT_VERSION_1_4); - } boolean ok = false; Class<?> jC = null; Method m = null; if (!headlessMode) { + jawtLockObject = getJAWT(false); // don't care for offscreen layer here try { jC = Class.forName("jogamp.opengl.awt.Java2D"); m = jC.getMethod("isQueueFlusherThread", (Class[])null); ok = true; } catch (Exception e) { } + } else { + jawtLockObject = null; // headless ! } isQueueFlusherThread = m; j2dExist = ok; @@ -166,21 +164,21 @@ public class JAWTUtil { jawtToolkitLock = new JAWTToolkitLock(); // trigger native AWT toolkit / properties initialization - Map desktophints = null; + Map<?,?> desktophints = null; try { if(EventQueue.isDispatchThread()) { - desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); } else { - final ArrayList desktophintsBucket = new ArrayList(1); + final ArrayList<Map<?,?>> desktophintsBucket = new ArrayList<Map<?,?>>(1); EventQueue.invokeAndWait(new Runnable() { public void run() { - Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + Map<?,?> _desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); if(null!=_desktophints) { desktophintsBucket.add(_desktophints); } } }); - desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ; + desktophints = ( desktophintsBucket.size() > 0 ) ? desktophintsBucket.get(0) : null ; } } catch (InterruptedException ex) { ex.printStackTrace(); @@ -226,7 +224,7 @@ public class JAWTUtil { * JAWT's native Lock() function calls SunToolkit.awtLock(), * which just uses AWT's global ReentrantLock.<br> */ - public static void awtLock() { + private static void awtLock() { if(hasSunToolkitAWTLock) { try { sunToolkitAWTLockMethod.invoke(null, (Object[])null); @@ -234,7 +232,7 @@ public class JAWTUtil { throw new NativeWindowException("SunToolkit.awtLock failed", e); } } else { - JAWT.getJAWT().Lock(); + jawtLockObject.Lock(); } } @@ -244,7 +242,7 @@ public class JAWTUtil { * JAWT's native Unlock() function calls SunToolkit.awtUnlock(), * which just uses AWT's global ReentrantLock.<br> */ - public static void awtUnlock() { + private static void awtUnlock() { if(hasSunToolkitAWTLock) { try { sunToolkitAWTUnlockMethod.invoke(null, (Object[])null); @@ -252,7 +250,7 @@ public class JAWTUtil { throw new NativeWindowException("SunToolkit.awtUnlock failed", e); } } else { - JAWT.getJAWT().Unlock(); + jawtLockObject.Unlock(); } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java index efd3522b8..4d5fac891 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.OffscreenLayerSurface; import javax.media.nativewindow.SurfaceUpdatedListener; import javax.media.nativewindow.awt.AWTGraphicsConfiguration; import javax.media.nativewindow.util.Insets; @@ -58,16 +59,21 @@ import javax.media.nativewindow.util.RectangleImmutable; import jogamp.nativewindow.SurfaceUpdatedHelper; -public abstract class JAWTWindow implements NativeWindow { +public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface { protected static final boolean DEBUG = JAWTUtil.DEBUG; + // user properties + protected boolean shallUseOffscreenLayer = false; + // lifetime: forever protected Component component; - protected boolean isApplet; protected AWTGraphicsConfiguration config; private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper(); - // lifetime: valid after lock, forever until invalidate + // lifetime: valid after lock but may change with each 1st lock, purges after invalidate + private boolean isApplet; + private JAWT jawt; + private boolean isOffscreenLayerSurface; protected long drawable; protected Rectangle bounds; @@ -93,16 +99,25 @@ public abstract class JAWTWindow implements NativeWindow { invalidate(); this.component = windowObject; this.isApplet = false; - while(!isApplet && null != windowObject) { - isApplet = windowObject instanceof Applet; - windowObject = windowObject.getParent(); - } - if(isApplet) { - JAWTUtil.setCachedJAWTVersionFlags(true); // useOffScreenLayerIfAvailable := true - } validateNative(); } + /** + * Request an JAWT offscreen layer if supported. + * Shall be called before {@link #lockSurface()}. + * + * @see #getShallUseOffscreenLayer() + * @see #isOffscreenLayerSurfaceEnabled() + */ + public void setShallUseOffscreenLayer(boolean v) { + shallUseOffscreenLayer = v; + } + + /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */ + public final boolean getShallUseOffscreenLayer() { + return shallUseOffscreenLayer; + } + /** * Implementors shall ensure that all native handles are valid, eg. the {@link javax.media.nativewindow.awt.AWTGraphicsDevice AWTGraphicsDevice}'s * subtype via {@link javax.media.nativewindow.awt.AWTGraphicsDevice#setSubType(String, long) awtGraphicsDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle)}. @@ -116,6 +131,8 @@ public abstract class JAWTWindow implements NativeWindow { protected synchronized void invalidate() { invalidateNative(); + jawt = null; + isOffscreenLayerSurface = false; drawable= 0; bounds = new Rectangle(); } @@ -137,10 +154,71 @@ public abstract class JAWTWindow implements NativeWindow { return component; } + /** + * Returns true if the AWT component is parented to an {@link java.applet.Applet}, + * otherwise false. This information is valid only after {@link #lockSurface()}. + */ public final boolean isApplet() { return isApplet; } + /** Returns the underlying JAWT instance created @ {@link #lockSurface()}. */ + public final JAWT getJAWT() { + return jawt; + } + + /** + * {@inheritDoc} + * @see #setShallUseOffscreenLayer(boolean) + */ + public final boolean isOffscreenLayerSurfaceEnabled() { + return isOffscreenLayerSurface; + } + + /** + * {@inheritDoc} + */ + public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException { + if( !isOffscreenLayerSurfaceEnabled() ) { + throw new NativeWindowException("Not an offscreen layer surface"); + } + int lockRes = lockSurface(); + if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + throw new NativeWindowException("Could not lock (offscreen layer): "+this); + } + try { + if(DEBUG) { + System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle)); + } + attachSurfaceLayerImpl(layerHandle); + } finally { + unlockSurface(); + } + } + protected abstract void attachSurfaceLayerImpl(final long layerHandle); + + /** + * {@inheritDoc} + */ + public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException { + if( !isOffscreenLayerSurfaceEnabled() ) { + throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface"); + } + int lockRes = lockSurface(); + if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { + throw new NativeWindowException("Could not lock (offscreen layer): "+this); + } + try { + if(DEBUG) { + System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle)); + } + detachSurfaceLayerImpl(layerHandle); + } finally { + unlockSurface(); + } + } + protected abstract void detachSurfaceLayerImpl(final long layerHandle); + // // SurfaceUpdateListener // @@ -167,6 +245,24 @@ public abstract class JAWTWindow implements NativeWindow { private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); + private void determineIfApplet() { + Component c = component; + while(!isApplet && null != c) { + isApplet = c instanceof Applet; + c = c.getParent(); + } + } + + /** + * If JAWT offscreen layer is supported, + * implementation shall respect {@link #getShallUseOffscreenLayer()} + * and may respect {@link #isApplet()}. + * + * @return The JAWT instance reflecting offscreen layer support, etc. + * + * @throws NativeWindowException + */ + protected abstract JAWT fetchJAWTImpl() throws NativeWindowException; protected abstract int lockSurfaceImpl() throws NativeWindowException; public final int lockSurface() throws NativeWindowException { @@ -175,10 +271,13 @@ public abstract class JAWTWindow implements NativeWindow { int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ? if ( LOCK_SURFACE_NOT_READY == res ) { + determineIfApplet(); try { final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); adevice.lock(); try { + jawt = fetchJAWTImpl(); + isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt); res = lockSurfaceImpl(); } finally { if (LOCK_SURFACE_NOT_READY >= res) { diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index c19569606..de7feb3b8 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -63,8 +63,9 @@ import jogamp.nativewindow.macosx.OSXUtil; public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) { super(comp, config); - isOffscreenLayerSurface = JAWTUtil.isCachedJAWTUsingOffscreenLayer(); - dumpInfo(); + if(DEBUG) { + dumpInfo(); + } } protected void validateNative() throws NativeWindowException { @@ -72,7 +73,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { protected void invalidateNative() { surfaceHandle=0; - if(isOffscreenLayerSurface) { + if(isOffscreenLayerSurfaceEnabled()) { if(0 != drawable) { OSXUtil.DestroyNSWindow(drawable); drawable = 0; @@ -80,50 +81,20 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { } } - public final boolean isOffscreenLayerSurface() { - return isOffscreenLayerSurface; - } - public void attachSurfaceLayer(final long layerHandle) { - if( !isOffscreenLayerSurface() ) { - throw new NativeWindowException("Not using CALAYER"); - } - int lockRes = lockSurface(); - if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { - throw new NativeWindowException("Could not lock layeredSurfaceHost: "+this); - } - try { - if(DEBUG) { - System.err.println("MacOSXJAWTWindow.attachSurfaceLayer(): 0x"+Long.toHexString(layerHandle)); - } - OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle); - } finally { - unlockSurface(); - } + protected void attachSurfaceLayerImpl(final long layerHandle) { + OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle); } - public void detachSurfaceLayer(final long layerHandle) { - if( !isOffscreenLayerSurface() ) { - throw new NativeWindowException("Not using CALAYER"); - } - int lockRes = lockSurface(); - if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) { - throw new NativeWindowException("Could not lock layeredSurfaceHost: "+this); - } - try { - if(DEBUG) { - System.err.println("MacOSXJAWTWindow.detachSurfaceLayer(): 0x"+Long.toHexString(layerHandle)); - } - OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle); - } finally { - unlockSurface(); - } + + protected void detachSurfaceLayerImpl(final long layerHandle) { + OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle); } public long getSurfaceHandle() { - return isOffscreenLayerSurface ? surfaceHandle : super.getSurfaceHandle() ; + return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ; } public void setSurfaceHandle(long surfaceHandle) { - if( !isOffscreenLayerSurface() ) { + if( !isOffscreenLayerSurfaceEnabled() ) { throw new java.lang.UnsupportedOperationException("Not using CALAYER"); } if(DEBUG) { @@ -147,11 +118,14 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { return sscSet ? sscHeight: super.getHeight(); } + protected JAWT fetchJAWTImpl() throws NativeWindowException { + // use offscreen if supported and [ applet or requested ] + return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet()); + } protected int lockSurfaceImpl() throws NativeWindowException { int ret = NativeWindow.LOCK_SURFACE_NOT_READY; if(null == ds) { - final JAWT jawt = JAWT.getJAWT(); - ds = jawt.GetDrawingSurface(component); + ds = getJAWT().GetDrawingSurface(component); if (ds == null) { // Widget not yet realized unlockSurfaceImpl(); @@ -189,12 +163,12 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { } } updateBounds(dsi.getBounds()); - if (DEBUG && firstLock) { + if (DEBUG && firstLock ) { dumpInfo(); } firstLock = false; - if( !isOffscreenLayerSurface ) { - macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(); + if( !isOffscreenLayerSurfaceEnabled() ) { + macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(getJAWT()); if (macosxdsi == null) { unlockSurfaceImpl(); return NativeWindow.LOCK_SURFACE_NOT_READY; @@ -257,7 +231,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { if (dsLocked) { ds.Unlock(); } - JAWT.getJAWT().FreeDrawingSurface(ds); + getJAWT().FreeDrawingSurface(ds); } ds = null; dsi = null; @@ -265,10 +239,13 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { private void dumpInfo() { System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName()); - // System.err.println(this); - System.err.println("JAWT version: 0x"+Integer.toHexString(JAWT.getJAWT().getVersionCached())+ - ", CA_LAYER: "+ (0!=(JAWT.getJAWT().getVersionCached() & JAWT.JAWT_MACOSX_USE_CALAYER))+ - ", isLayeredSurface "+isOffscreenLayerSurface()+", bounds "+bounds); + if(null != getJAWT()) { + System.err.println("JAWT version: 0x"+Integer.toHexString(getJAWT().getCachedVersion())+ + ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(getJAWT())+ + ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds); + } else { + System.err.println("JAWT n/a, bounds "+bounds); + } // Thread.dumpStack(); } @@ -291,7 +268,6 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; - private final boolean isOffscreenLayerSurface; private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer private long surfaceHandle = 0; diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java index 610ce0f15..581e2337c 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java @@ -47,6 +47,7 @@ import javax.media.nativewindow.util.Point; import jogamp.nativewindow.jawt.JAWT; import jogamp.nativewindow.jawt.JAWTFactory; +import jogamp.nativewindow.jawt.JAWTUtil; import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.nativewindow.jawt.JAWT_DrawingSurface; import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; @@ -65,9 +66,20 @@ public class WindowsJAWTWindow extends JAWTWindow { windowHandle = 0; } + protected void attachSurfaceLayerImpl(final long layerHandle) { + throw new UnsupportedOperationException("offscreen layer not supported"); + } + protected void detachSurfaceLayerImpl(final long layerHandle) { + throw new UnsupportedOperationException("offscreen layer not supported"); + } + + protected JAWT fetchJAWTImpl() throws NativeWindowException { + return JAWTUtil.getJAWT(false); // no offscreen + } + protected int lockSurfaceImpl() throws NativeWindowException { int ret = NativeWindow.LOCK_SUCCESS; - ds = JAWT.getJAWT().GetDrawingSurface(component); + ds = getJAWT().GetDrawingSurface(component); if (ds == null) { // Widget not yet realized unlockSurfaceImpl(); @@ -92,7 +104,8 @@ public class WindowsJAWTWindow extends JAWTWindow { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; } - win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(); + updateBounds(dsi.getBounds()); + win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT()); if (win32dsi == null) { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; @@ -102,14 +115,11 @@ public class WindowsJAWTWindow extends JAWTWindow { if (windowHandle == 0 || drawable == 0) { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; - } else { - updateBounds(dsi.getBounds()); } return ret; } protected void unlockSurfaceImpl() throws NativeWindowException { - long startTime = 0; if(null!=ds) { if (null!=dsi) { ds.FreeDrawingSurfaceInfo(dsi); @@ -117,7 +127,7 @@ public class WindowsJAWTWindow extends JAWTWindow { if (dsLocked) { ds.Unlock(); } - JAWT.getJAWT().FreeDrawingSurface(ds); + getJAWT().FreeDrawingSurface(ds); } ds = null; dsi = null; diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java index 16dcf11fe..e469fe337 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.util.Point; import jogamp.nativewindow.jawt.JAWT; import jogamp.nativewindow.jawt.JAWTFactory; +import jogamp.nativewindow.jawt.JAWTUtil; import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.nativewindow.jawt.JAWT_DrawingSurface; import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; @@ -88,9 +89,20 @@ public class X11JAWTWindow extends JAWTWindow { protected void invalidateNative() { } + protected void attachSurfaceLayerImpl(final long layerHandle) { + throw new UnsupportedOperationException("offscreen layer not supported"); + } + protected void detachSurfaceLayerImpl(final long layerHandle) { + throw new UnsupportedOperationException("offscreen layer not supported"); + } + + protected JAWT fetchJAWTImpl() throws NativeWindowException { + return JAWTUtil.getJAWT(false); // no offscreen + } + protected int lockSurfaceImpl() throws NativeWindowException { int ret = NativeWindow.LOCK_SUCCESS; - ds = JAWT.getJAWT().GetDrawingSurface(component); + ds = getJAWT().GetDrawingSurface(component); if (ds == null) { // Widget not yet realized unlockSurfaceImpl(); @@ -115,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; } - x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(); + updateBounds(dsi.getBounds()); + x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT()); if (x11dsi == null) { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; @@ -124,8 +137,6 @@ public class X11JAWTWindow extends JAWTWindow { if (drawable == 0) { unlockSurfaceImpl(); return LOCK_SURFACE_NOT_READY; - } else { - updateBounds(dsi.getBounds()); } return ret; } @@ -138,7 +149,7 @@ public class X11JAWTWindow extends JAWTWindow { if (dsLocked) { ds.Unlock(); } - JAWT.getJAWT().FreeDrawingSurface(ds); + getJAWT().FreeDrawingSurface(ds); } ds = null; dsi = null; diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 1ce8f09ca..8a0cb8d6c 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -47,6 +47,7 @@ import javax.media.nativewindow.awt.AWTWindowClosingProtocol; import javax.swing.MenuSelectionManager; import jogamp.nativewindow.awt.AWTMisc; +import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.newt.Debug; import jogamp.newt.awt.event.AWTParentWindowAdapter; import jogamp.newt.awt.event.NewtFactoryAWT; @@ -64,7 +65,7 @@ import com.jogamp.newt.event.awt.AWTMouseAdapter; public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol { public static final boolean DEBUG = Debug.debug("Window"); - NativeWindow nativeWindow = null; + JAWTWindow jawtWindow = null; Window newtChild = null; boolean isNewtChildOnscreen = true; int newtChildCloseOp; @@ -130,7 +131,38 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } private final void createNativeWindow(CapabilitiesImmutable caps) { - nativeWindow = NewtFactoryAWT.getNativeWindow(this, caps); + jawtWindow = NewtFactoryAWT.getNativeWindow(this, caps); + } + + /** + * Request an JAWT offscreen layer if supported it. + * Shall be called before {@link #addNotify()} is issued, + * ie. before adding the component to the AWT tree and make it visible. + * + * @see #isOffscreenLayerSurface() + */ + public void setShallUseOffscreenLayer(boolean v) { + jawtWindow.setShallUseOffscreenLayer(v); + } + + /** + * Returns true if the underlying JAWT uses offscreen layering, + * otherwise false. This information is valid only after {@link #addNotify()} is issued, + * ie. before adding the component to the AWT tree and make it visible. + * + * @see #setShallUseOffscreenLayer(boolean) + */ + public boolean isOffscreenLayerSurface() { + return jawtWindow.isOffscreenLayerSurfaceEnabled(); + } + + /** + * Returns true if the AWT component is parented to an {@link java.applet.Applet}, + * otherwise false. This information is valid only after {@link #addNotify()} is issued, + * ie. before adding the component to the AWT tree and make it visible. + */ + public boolean isApplet() { + return jawtWindow.isApplet(); } class FocusAction implements Window.FocusRunnable { @@ -195,7 +227,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto /** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called, * or {@link #addNotify()} hasn't been called yet.*/ - public NativeWindow getNativeWindow() { return nativeWindow; } + public NativeWindow getNativeWindow() { return jawtWindow; } public int getDefaultCloseOperation() { return awtWindowClosingProtocol.getDefaultCloseOperation(); @@ -285,7 +317,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto newtChild.setFocusAction(null); // no AWT focus traversal .. if(add) { - NewtFactoryAWT.updateGraphicsConfiguration(nativeWindow, this); + NewtFactoryAWT.updateGraphicsConfiguration(jawtWindow, this); if(DEBUG) { System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild); } @@ -308,7 +340,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } setSize(w, h); newtChild.setSize(w, h); - newtChild.reparentWindow(nativeWindow); + newtChild.reparentWindow(jawtWindow); newtChild.setVisible(true); configureNewtChild(true); newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener @@ -338,9 +370,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont); } configureNewtChild(false); - if(null!=nativeWindow) { - nativeWindow.destroy(); - nativeWindow=null; + if(null!=jawtWindow) { + jawtWindow.destroy(); + jawtWindow=null; } newtChild.setVisible(false); newtChild.reparentWindow(null); diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java index 2e86cb512..7ba892b37 100755 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java @@ -1,20 +1,50 @@ +/** + * Copyright 2011 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: + * + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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 com.jogamp.newt.awt.applet; -import java.applet.*; +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.Button; import java.awt.Component; import java.awt.Container; -import java.awt.Label; +import java.awt.event.KeyListener; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; -import java.awt.event.KeyListener; -import javax.media.opengl.*; +import javax.media.opengl.FPSCounter; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLProfile; + +import jogamp.newt.Debug; import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.opengl.GLWindow; -import java.awt.BorderLayout; - -import jogamp.newt.Debug; /** * Simple GLEventListener deployment as an applet using JOGL. This demo must be @@ -62,7 +92,7 @@ import jogamp.newt.Debug; */ @SuppressWarnings("serial") public class JOGLNewtApplet1Run extends Applet { - public static final boolean DEBUG = Debug.debug("Applet"); + public static final boolean DEBUG = JOGLNewtAppletBase.DEBUG; GLWindow glWindow; NewtCanvasAWT newtCanvasAWT; @@ -72,6 +102,9 @@ public class JOGLNewtApplet1Run extends Applet { boolean glStandalone = false; public void init() { + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.init() START"); + } if(!(this instanceof Container)) { throw new RuntimeException("This Applet is not a AWT Container"); } @@ -88,6 +121,7 @@ public class JOGLNewtApplet1Run extends Applet { int glAlphaBits=0; int glNumMultisampleBuffer=0; boolean glNoDefaultKeyListener = false; + boolean appletDebugTestBorder = false; try { glEventListenerClazzName = getParameter("gl_event_listener_class"); glProfileName = getParameter("gl_profile"); @@ -104,6 +138,7 @@ public class JOGLNewtApplet1Run extends Applet { glWidth = JOGLNewtAppletBase.str2Int(getParameter("gl_width"), glWidth); glHeight = JOGLNewtAppletBase.str2Int(getParameter("gl_height"), glHeight); glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener); + appletDebugTestBorder = JOGLNewtAppletBase.str2Bool(getParameter("appletDebugTestBorder"), appletDebugTestBorder); } catch (Exception e) { e.printStackTrace(); } @@ -149,18 +184,19 @@ public class JOGLNewtApplet1Run extends Applet { glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err); glWindow.setUndecorated(glUndecorated); glWindow.setAlwaysOnTop(glAlwaysOnTop); + container.setLayout(new BorderLayout()); + if(appletDebugTestBorder) { + container.add(new Button("North"), BorderLayout.NORTH); + container.add(new Button("South"), BorderLayout.SOUTH); + container.add(new Button("East"), BorderLayout.EAST); + container.add(new Button("West"), BorderLayout.WEST); + } if(glStandalone) { newtCanvasAWT = null; } else { newtCanvasAWT = new NewtCanvasAWT(glWindow); - container.setLayout(new BorderLayout()); container.add(newtCanvasAWT, BorderLayout.CENTER); - } - if(DEBUG) { - container.add(new Label("North"), BorderLayout.NORTH); - container.add(new Label("South"), BorderLayout.SOUTH); - container.add(new Label("East"), BorderLayout.EAST); - container.add(new Label("West"), BorderLayout.WEST); + container.validate(); } base.init(glWindow); if(base.isValid()) { @@ -179,9 +215,15 @@ public class JOGLNewtApplet1Run extends Applet { } catch (Throwable t) { throw new RuntimeException(t); } + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.init() END"); + } } public void start() { + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.start() START"); + } this.validate(); this.setVisible(true); @@ -195,21 +237,35 @@ public class JOGLNewtApplet1Run extends Applet { while (null != topC.getParent()) { topC = topC.getParent(); } + System.err.println("JOGLNewtApplet1Run start:"); System.err.println("TopComponent: "+topC.getLocation()+" rel, "+topC.getLocationOnScreen()+" screen, visible "+topC.isVisible()+", "+topC); System.err.println("Applet Pos: "+this.getLocation()+" rel, "+p0+" screen, visible "+this.isVisible()+", "+this); if(null != newtCanvasAWT) { System.err.println("NewtCanvasAWT Pos: "+newtCanvasAWT.getLocation()+" rel, "+newtCanvasAWT.getLocationOnScreen()+" screen, visible "+newtCanvasAWT.isVisible()+", "+newtCanvasAWT); } System.err.println("GLWindow Pos: "+glWindow.getX()+"/"+glWindow.getY()+" rel, "+glWindow.getLocationOnScreen(null)+" screen"); + System.err.println("GLWindow: "+glWindow); } base.start(); + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.stop() END"); + } } public void stop() { + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.stop() START"); + } base.stop(); + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.stop() END"); + } } public void destroy() { + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.destroy() START"); + } glWindow.setVisible(false); // hide 1st if(!glStandalone) { glWindow.reparentWindow(null); // get out of newtCanvasAWT @@ -217,6 +273,9 @@ public class JOGLNewtApplet1Run extends Applet { } base.destroy(); // destroy glWindow unrecoverable base=null; + if(DEBUG) { + System.err.println("JOGLNewtApplet1Run.destroy() END"); + } } } diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java index b1061dd14..6b135976b 100755 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -1,18 +1,52 @@ +/** + * Copyright 2011 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: + * + * 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 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * 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 com.jogamp.newt.awt.applet; -import java.lang.reflect.*; +import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; import javax.media.nativewindow.NativeWindow; -import javax.media.opengl.*; +import javax.media.opengl.FPSCounter; +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLPipelineFactory; import jogamp.newt.Debug; -import com.jogamp.opengl.util.*; - -import com.jogamp.newt.event.*; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.KeyListener; +import com.jogamp.newt.event.MouseListener; +import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.util.Animator; + /** Shows how to deploy an applet using JOGL. This demo must be referenced from a web page via an <applet> tag. */ diff --git a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java index 9b812d22a..462cf899f 100644 --- a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java +++ b/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java @@ -53,7 +53,7 @@ public class NewtFactoryAWT extends NewtFactory { * * @param awtCompObject must be of type java.awt.Component */ - public static NativeWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) { + public static JAWTWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) { if(null==awtCompObject) { throw new NativeWindowException("Null AWT Component"); } @@ -63,19 +63,19 @@ public class NewtFactoryAWT extends NewtFactory { return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested ); } - public static NativeWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) { + public static JAWTWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) { AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested); - NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow + NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow + if(! ( nw instanceof JAWTWindow ) ) { + throw new NativeWindowException("Not an AWT NativeWindow: "+nw); + } if(DEBUG_IMPLEMENTATION) { - System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative); + System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+nw); } - return awtNative; + return (JAWTWindow)nw; } - public static void updateGraphicsConfiguration(NativeWindow nw, java.awt.Component awtComp) { - if(! ( nw instanceof JAWTWindow ) ) { - throw new NativeWindowException("Not an AWT NativeWindow: "+nw); - } + public static void updateGraphicsConfiguration(JAWTWindow nw, java.awt.Component awtComp) { if(DEBUG_IMPLEMENTATION) { System.err.println("NewtFactoryAWT.updateGraphicsConfiguration: (pre) "+awtComp+" -> "+nw); } diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index 7d6236059..861811b6c 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -37,11 +37,11 @@ #include "NewtCommon.h" -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #ifdef VERBOSE_ON - // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__) - #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) + #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) + // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #else #define DBG_PRINT(...) #endif diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java index 378d43049..d6bf192c0 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01AWT.java @@ -63,8 +63,6 @@ public class TestParentingOffscreenLayer01AWT extends UITestCase { @BeforeClass public static void initClass() { - // force offscreen layer JAWT, if available - JAWTUtil.setCachedJAWTVersionFlags(true); // useOffScreenLayerIfAvailable := true frameSize = new Dimension(500,300); preferredGLSize = new Dimension(400,200); minGLSize = new Dimension(200,100); @@ -105,7 +103,7 @@ public class TestParentingOffscreenLayer01AWT extends UITestCase { } } - @Test + // @Test public void testOffscreenLayerPath0_GLCanvas() throws InterruptedException, InvocationTargetException { final Frame frame1 = new Frame("AWT Parent Frame"); @@ -128,20 +126,21 @@ public class TestParentingOffscreenLayer01AWT extends UITestCase { } @Test + public void testOnscreenLayer() throws InterruptedException, InvocationTargetException { + testOffscreenLayerPath1_Impl(false, false); + } + + @Test public void testOffscreenLayerPath1_NewtOffscreen() throws InterruptedException, InvocationTargetException { - testOffscreenLayerPath1_Impl(true); + testOffscreenLayerPath1_Impl(true, true); } @Test public void testOffscreenLayerPath1_NewtOnscreen() throws InterruptedException, InvocationTargetException { - testOffscreenLayerPath1_Impl(false); + testOffscreenLayerPath1_Impl(true, false); } - private void testOffscreenLayerPath1_Impl(boolean newtOffscreenClass) throws InterruptedException, InvocationTargetException { - if( newtOffscreenClass && !JAWTUtil.isCachedJAWTUsingOffscreenLayer() ) { - System.err.println("JAWT OffscreenLayer n/a on this platform."); - return; - } + private void testOffscreenLayerPath1_Impl(boolean offscreenLayer, boolean newtOffscreenClass) throws InterruptedException, InvocationTargetException { final Frame frame1 = new Frame("AWT Parent Frame"); GLCapabilities glCaps = new GLCapabilities(null); @@ -152,7 +151,8 @@ public class TestParentingOffscreenLayer01AWT extends UITestCase { GLWindow glWindow1 = GLWindow.create(glCaps); - final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1); + final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1); + newtCanvasAWT1.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported newtCanvasAWT1.setPreferredSize(preferredGLSize); newtCanvasAWT1.setMinimumSize(minGLSize); |