summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-09-15 16:54:52 +0200
committerSven Gothel <[email protected]>2012-09-15 16:54:52 +0200
commit4dd44b985fe0541be3a3bcd9045d201ed3ca2cc5 (patch)
treee14c927a1da9f089297aa291dcd69f2f39b4f15e /src/jogl/classes/javax
parent9036376b7806a5fc61590bf49404eb71830de92f (diff)
Seamless Integration of an FBObject based GLFBODrawable as GLOffscreenAutoDrawable.FBO and as an OffscreenLayerSurface's drawable (OSX) - Fix Bugs 569 and 599
Summary: ========= The new FBObject based GLFBODrawable implementation allows the seamless utilization of FBO offscreen rendering in single buffer, double buffer and MSAA mode. The GLFBODrawable uses a parent drawable based on a dummy surface to allow a GLOffscreenAutoDrawable.FBO creation or a mutable surface supporting an existing offscreen layer surface (OSX CALayer). Offscreen GLDrawable's and GLOffscreenAutoDrawable's can be selected via the GLCapabilities. If simply !onscreen is selected in the caps instance w/o enabling FBO, PBuffer or Bitmap, the factory will automatically choose regarding availability: FBO > PBuffer > Bitmap Double buffering is supported in MSAA more (intrinsic) and explicit in non MSAA. It is preferred when delivering resources (texture id's or framebuffer names) to a shared GLContext. This is demonstrated in (emulates our OSX CALayer implementation): TestFBOOffThreadSharedContextMix2DemosES2NEWT, TestFBOOnThreadSharedContext1DemoES2NEWT and with the OSX JAWT OffscreenLayerSurface itself. FBO is the preferred choice. +++ Offscreen drawables can be resized while maintaining a bound GLContext (e.g. w/ GLAutoDrawable). Previously both, drawable and context, needed to be destroyed and recreated at offscreen resize. Common implementation in GLDrawableHelper is used in the implementations (NEWT's GLWindow, AWT GLCanvas, SWT GLCanvas). +++ Tested: ======= Manually run all unit tests on: - Linux x86_64 NVidia/AMD/Mesa3d(ES) - OSX x86_64 NVidia - Windows x86_64 NVidia - Android arm Mali-400/Tegra-2 No regressions. Disclaimer: =========== This feature is committed almost in one patch. Both previous commits were introducing / fixing the capabilities behavior: 90d45928186f2be99999461cfe45f76a783cc961 9036376b7806a5fc61590bf49404eb71830de92f I have to appologize for the huge size and impact (files and platforms) of this commit however, I could not find a better way to inject this feature in one sane piece. NativeWindow Details: ===================== Complete decoupling of platform impl. detail of surfaces implementing ProxySurface. Used to generalize dummy surfaces and EGL surfaces on top of a native platform surface. - ProxySurface.UpstreamSurfaceHook -> UpstreamSurfaceHook - abstract class ProxySurface -> interface ProxySurface + ProxySurfaceImpl - Misc. implementations JOGL Details: ===================== FBOObject: API Change / Simplification & Usability - Removed reference counter to remove complexity, allow user to choose. - Add 'dispose' flag for detachColorbuffer(..), allowing to keep attachment alive - Fix equals operation of Attachment - Check pre-exising GL errors - Interface Colobuffer gets lifecycle methods - Add static factory methods to create Attachments w/o FBObject instance - Reset: - Clip min size to 1 - Keep alive samplingSink, i.e. don't issue resetMSAATexture2DSink(..). It gets called at syncFramebuffer()/use(..) later on before actual usage. This allows the consumer to utilize the GL_FRONT buffer until (e.g.) swap. - misc bugfixes GLOffscreenAutoDrawable: API Change - Reloc and interfacing - class com.jogamp.opengl.OffscreenAutoDrawable -> javax.media.opengl.* interfaces GLOffscreenAutoDrawable extends GLAutoDrawable GLOffscreenAutoDrawable.FBO extends GLOffscreenAutoDrawable, GLFBODrawable - Added general implementation and FBO specialization - Replacing GLPBuffer (deprecated) .. usable for any offscreen GLDrawable via factory GLAutoDrawable: - Add 'GLDrawable getDelegatedDrawable()' - Refine documentation of setContext(..), remove disclaimer and fixme tags GLDrawableFactory: - Refine API doc and it's selection mechanism for offscreen. - Add createOffscreenDrawable(..) - Add createOffscreenAutoDrawable(..) - Add canCreateFBO(..) - Mark createGLPbuffer(..) deprectated Mark GLPBuffer deprecated New: GLFBODrawable extends GLDrawable GLCanvas (AWT and SWT): Add offscreen resize support w/o GLContext recreation GLAutoDrawableBase .. GLWindow: - Add offscreen resize support w/o GLContext recreation - Remove double swapBuffer call - GLBase/GLContext: - Add: - boolean hasBasicFBOSupport() - boolean hasFullFBOSupport() - int getMaxRenderbufferSamples() - boolean isTextureFormatBGRA8888Available() GLContext: Fix version detection and hasGLSL() - Version detection in setGLFunctionAvailability(..) - Query GL_VERSION ASAP and parse it and compare w/ given major/minor - Use parsed version if valid and lower than given _or_ given is invalid. - Use validated version for caching (procaddr, ..), version number, etc. - Fix hasGLSL() Since 'isGL2ES2()' is true if 'isGL2()' and the latter simply alows GL 1.*, we confine the result to a GL >= 2.0 on desktops. FIXME: May consider GL 1.5 w/ extensions. - return isGL2ES2(); + return isGLES2() || + isGL3() || + isGL2() && ctxMajorVersion>1 ; GLDrawableImpl: - Add 'associateContext(GLContext, boolean)' allowing impl. to have a (weak) reference list of bound context. This is was pulled up from the OSX specific drawable impl. - swapBuffersImpl() -> swapBuffersImpl(boolean doubleBuffered) and call it regardless of single buffering. This is required to propagate this event to impl. properly, i.e. FBODrawable requires a swap notification. - Clarify 'contextMadeCurrent(..)' protocol GLDrawableHelper: - Add resize and recreate offscreen drawable util method - Simplify required init/reshape calls for GLEventListener - GLGraphicsConfigurationUtil: - fixWinAttribBitsAndHwAccel: Reflect sharede context hw-accel bits - OSX has no offscreen bitmap, use pbuffer - use proper offscreen auto selection if offscreen and no modes are set EGL Context/Drawable/DrawableFactory: Abstract native platform code out of base classes - Use EGLWrappedSurface w/ UpstreamSurfaceHook to handle upstream (X11, WGL, ..) lifecycle - in case the EGL resource is hooked up on it. Invisible dummy surfaces: All platforms - size is now reduced to 64x64 and decoupled of actual generic mutable size - fix device lifecycle, no more leaks +++ OSX ==== Enable support for GLFBODrawableImpl in offscreen CALayer mode - NSOpenGLImpl: hooks to calayer native code - calayer code: - allows pbuffer and texures (FBO) - decouple size and draw calls avoiding flickering - enable auto resize of calayer tree MacOSXCGLContext: - NSOpenGLImpl: - Fix false pbuffer 'usage', validate the pointer - If !pbuffer, copy other window mode bits of caps - MacOSXCGLGraphicsConfiguration: - Only assume pbuffer if !onscreen - Remove reference of native pixelformat pointer Native code: - use 'respondsToSelector:' query before calling 'new' methods avoiding an error message where unsuported (prev. OSX versions) - if monitor refresh-rate is queried 0, set to default 60hz - add missing NSAutoreleasePool decoration +++ Android / NEWT: =============== Issue setVisible(..) w/o wait, i.e. queue on EDT, @Android surfaceChanged() callback. Otherwise we could deadlock: setVisible(..) -> EDT -> setVisibleImpl(..) -> 'GL-display'. the latter may may cause havoc while Android-EDT is blocked [until it's return].
Diffstat (limited to 'src/jogl/classes/javax')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java38
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java144
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java38
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java97
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java128
-rw-r--r--src/jogl/classes/javax/media/opengl/GLFBODrawable.java173
-rw-r--r--src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java63
-rw-r--r--src/jogl/classes/javax/media/opengl/GLPbuffer.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java119
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java13
10 files changed, 570 insertions, 249 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 0b2c664fe..38f1746f9 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -115,6 +115,12 @@ public interface GLAutoDrawable extends GLDrawable {
public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
/**
+ * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+ * otherwise return <code>this</code> instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
+ /**
* Returns the context associated with this drawable. The returned
* context will be synchronized.
* Don't rely on it's identity, the context may change.
@@ -124,23 +130,31 @@ public interface GLAutoDrawable extends GLDrawable {
/**
* Associate a new context to this drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * <code>drawable</code> might be an inner GLDrawable instance if using such a delegation pattern,
- * or this GLAutoDrawable itself.
- * <p>
- * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
- * is being cleared by calling
- * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
- * </p>
+ * <code>drawable</code> might be an inner GLDrawable instance if using a delegation pattern,
+ * or this GLAutoDrawable instance.
* <p>
* If the old or new context was current on this thread, it is being released before switching the drawable.
* The new context will be made current afterwards, if it was current before.
- * However the user shall take extra care that not other thread
- * attempts to make this context current. Otherwise a race condition may happen.
+ * However the user shall take extra care that no other thread
+ * attempts to make this context current.
+ * </p>
+ * <p>
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only be bound to one drawable at one time!
* </p>
* <p>
- * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary
- * switching the drawable of an already established GLContext, i.e. which is already made current once.
- * FIXME: Validate functionality!
+ * In case you do not intend to use the old context anymore, i.e.
+ * not assigning it to another drawable, it shall be
+ * destroyed before setting the new context, i.e.:
+ * <pre>
+ GLContext oldCtx = glad.getContext();
+ if(null != oldCtx) {
+ oldCtx.destroy();
+ }
+ glad.setContext(newCtx);
+ * </pre>
+ * This is required, since a context must have a valid drawable at all times
+ * and this API shall not restrict the user in any way.
* </p>
*
* @param newCtx the new context
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
deleted file mode 100644
index 67e81270d..000000000
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Copyright 2012 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.opengl;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
-
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
-
-import jogamp.opengl.Debug;
-import jogamp.opengl.GLAutoDrawableBase;
-import jogamp.opengl.GLContextImpl;
-import jogamp.opengl.GLDrawableImpl;
-
-
-/**
- * Fully functional {@link GLAutoDrawable} implementation
- * utilizing already created created {@link GLDrawable} and {@link GLContext} instances.
- * <p>
- * Since no native windowing system events are being processed, it is recommended
- * to handle at least:
- * <ul>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #defaultWindowRepaintOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #defaultWindowResizedOp()}</li>
- * <li>{@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #defaultWindowDestroyNotifyOp()}</li>
- * </ul>
- * </p>
- * <p>
- * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
- * </p>
- */
-public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
-
- /**
- * @param drawable a valid {@link GLDrawable}, may not be realized yet.
- * @param context a valid {@link GLContext}, may not be made current (created) yet.
- * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
- * @param ownDevice pass <code>true</code> if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass <code>false</code>. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
- super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
- this.upstreamWidget = null;
- }
-
- //
- // expose default methods
- //
-
- public final void windowRepaintOp() {
- super.defaultWindowRepaintOp();
- }
-
- public final void windowResizedOp() {
- super.defaultWindowResizedOp();
- }
-
- public final void windowDestroyNotifyOp() {
- super.defaultWindowDestroyNotifyOp();
- }
-
- //
- // Complete GLAutoDrawable
- //
-
- private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
- private final Object upstreamWidget;
-
- @Override
- protected final RecursiveLock getLock() { return lock; }
-
- @Override
- public final Object getUpstreamWidget() {
- return upstreamWidget;
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * This implementation calls {@link #defaultDestroy()}.
- * </p>
- * <p>
- * User still needs to destroy the upstream window, which details are hidden from this aspect.
- * This can be performed by overriding {@link #destroyImplInLock()}.
- * </p>
- */
- @Override
- public final void destroy() {
- defaultDestroy();
- }
-
- @Override
- public void display() {
- defaultDisplay();
- }
-
- //
- // GLDrawable delegation
- //
-
- @Override
- public final GLDrawableFactory getFactory() {
- return drawable.getFactory();
- }
-
- @Override
- public final void setRealized(boolean realized) {
- }
-
- @Override
- public final void swapBuffers() throws GLException {
- defaultSwapBuffers();
- }
-
-}
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f5831a72d..9bcee819a 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -273,6 +273,42 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>.
+ * </p>
+ * <p>
+ * Basic FBO support may only include one color attachment and no multisampling,
+ * as well as limited internal formats for renderbuffer.
+ * </p>
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public boolean hasBasicFBOSupport();
+
+ /**
+ * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * <code>ARB_framebuffer_object</code>, or all of
+ * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
+ * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+ * </p>
+ * <p>
+ * Full FBO support includes multiple color attachments and multisampling.
+ * </p>
+ * @see GLContext#hasFullFBOSupport()
+ */
+ public boolean hasFullFBOSupport();
+
+ /**
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
+ * @see GLContext#getMaxRenderbufferSamples()
+ */
+ public int getMaxRenderbufferSamples();
+
/**
* Returns true if the GL context supports non power of two (NPOT) textures,
* otherwise false.
@@ -284,6 +320,8 @@ public interface GLBase {
*/
public boolean isNPOTTextureAvailable();
+ public boolean isTextureFormatBGRA8888Available();
+
/** Provides a platform-independent way to specify the minimum swap
interval for buffer swaps. An argument of 0 disables
sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index c2f94b9af..a5e639c74 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -96,6 +96,9 @@ public abstract class GLContext {
*/
public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true);
+ protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true);
+ protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+
public static final boolean DEBUG = Debug.debug("GLContext");
public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true);
@@ -127,9 +130,9 @@ public abstract class GLContext {
/** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_IMPL_ES2_COMPAT = 1 << 8;
- /** Context supports basic FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
- * @see #hasFBO()
+ * @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
protected static final int CTX_IMPL_FBO = 1 << 9;
@@ -178,11 +181,6 @@ public abstract class GLContext {
* and made current afterwards. However the user shall take extra care that not other thread
* attempts to make this context current. Otherwise a race condition may happen.
* </p>
- * <p>
- * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary
- * switching the drawable of an already established GLContext, i.e. which is already made current once.
- * FIXME: Validate functionality!
- * </p>
* @param readWrite the read/write drawable for framebuffer operations.
* @param setWriteOnly if <code>true</code> and if the current read-drawable differs
* from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}),
@@ -603,12 +601,23 @@ public abstract class GLContext {
/**
* @return true if impl. is a hardware rasterizer, otherwise false.
+ * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
*/
public final boolean isHardwareRasterizer() {
return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
}
+ /**
+ * @return true if context supports GLSL, i.e. is either {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} <i>and</i> major-version > 1.
+ * @see GLProfile#hasGLSL()
+ */
+ public final boolean hasGLSL() {
+ return isGLES2() ||
+ isGL3() ||
+ isGL2() && ctxMajorVersion>1 ;
+ }
+
/**
* Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
* <p>
@@ -620,21 +629,54 @@ public abstract class GLContext {
* as well as limited internal formats for renderbuffer.
* </p>
* @see #CTX_IMPL_FBO
- * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
- * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
*/
- public final boolean hasFBO() {
+ public final boolean hasBasicFBOSupport() {
return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
}
+ /**
+ * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
+ * <p>
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * <code>ARB_framebuffer_object</code>, or all of
+ * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>,
+ * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+ * </p>
+ * <p>
+ * Full FBO support includes multiple color attachments and multisampling.
+ * </p>
+ */
+ public final boolean hasFullFBOSupport() {
+ return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() &&
+ ( isGL3() || // GL >= 3.0
+ isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
+ ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+ isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil)
+ )
+ ) ;
+ }
+
/**
- * @return true if context supports GLSL
- * @see GLProfile#hasGLSL()
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
*/
- public final boolean hasGLSL() {
- return isGL2ES2() ;
+ public final int getMaxRenderbufferSamples() {
+ if( hasFullFBOSupport() ) {
+ final GL gl = getGL();
+ final int[] val = new int[] { 0 } ;
+ gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+ final int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ return val[0];
+ } else if(DEBUG) {
+ System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ }
+ return 0;
}
-
+
/** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns <code>true</code>. */
public boolean isNPOTTextureAvailable() {
return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
@@ -1014,6 +1056,9 @@ public abstract class GLContext {
validateProfileBits(profile, "profile");
validateProfileBits(resCtp, "resCtp");
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
if(DEBUG) {
System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
// Thread.dumpStack();
@@ -1197,18 +1242,36 @@ public abstract class GLContext {
* FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
* </p>
* <p>
- * FBO support is queried as described in {@link #hasFBO()}.
+ * FBO support is queried as described in {@link #hasBasicFBOSupport()}.
* </p>
*
* @param device the device to request whether FBO is available for
* @param glp {@link GLProfile} to check for FBO capabilities
- * @see GLContext#hasFBO()
+ * @see GLContext#hasBasicFBOSupport()
*/
public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
}
/**
+ * @return <code>1</code> if using a hardware rasterizer, <code>0</code> if using a software rasterizer and <code>-1</code> if not determined yet.
+ * @see GLContext#isHardwareRasterizer()
+ * @see GLProfile#isHardwareRasterizer()
+ */
+ public static final int isHardwareRasterizer(AbstractGraphicsDevice device, GLProfile glp) {
+ final int r;
+ final int ctp = getAvailableContextProperties(device, glp);
+ if(0 == ctp) {
+ r = -1;
+ } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ return r;
+ }
+
+ /**
* @param device the device to request whether the profile is available for
* @param reqMajor Key Value either 1, 2, 3 or 4
* @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 9fd895c1f..b6e7b0576 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -48,13 +48,16 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import jogamp.opengl.Debug;
@@ -373,44 +376,63 @@ public abstract class GLDrawableFactory {
// Methods to create high-level objects
/**
- * Returns a GLDrawable according to it's chosen Capabilities,<br>
+ * Returns a GLDrawable according to it's chosen {@link GLCapabilitiesImmutable},<br>
* which determines pixel format, on- and offscreen incl. PBuffer type.
* <p>
- * The native platform's chosen Capabilties are referenced within the target
- * NativeSurface's AbstractGraphicsConfiguration.<p>
- *
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,<br>
- * an onscreen GLDrawable will be realized.
+ * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
+ * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.<p>
+ * </p>
* <p>
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,<br>
- * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,<br>
- * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.<br>
+ * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
+ * </p>
* <p>
- *
+ * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ * </p>
+ * <p>
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * </p>
+ * <p>
+ * If not onscreen and neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * </p>
+ *
* @throws IllegalArgumentException if the passed target is null
* @throws GLException if any window system-specific errors caused
* the creation of the GLDrawable to fail.
*
+ * @see #canCreateGLPbuffer(AbstractGraphicsDevice)
+ * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile)
+ * @see javax.media.opengl.GLCapabilities#isOnscreen()
+ * @see javax.media.opengl.GLCapabilities#isFBO()
+ * @see javax.media.opengl.GLCapabilities#isPBuffer()
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
public abstract GLDrawable createGLDrawable(NativeSurface target)
throws IllegalArgumentException, GLException;
-
+
/**
- * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * Creates an {@link GLOffscreenAutoDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
* <p>
- * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+ * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is realized and it's {@link GLContext} assigned but not yet made current.
* </p>
* <p>
- * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+ * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
+ * </p>
+ * <p>
+ * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
* and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
* </p>
* <p>
- * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
* </p>
* <p>
- * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated.
* </p>
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
@@ -418,17 +440,55 @@ public abstract class GLDrawableFactory {
* @param chooser the custom chooser, may be null for default
* @param width the requested offscreen width
* @param height the requested offscreen height
+ * @return the created and initialized offscreen {@link GLOffscreenAutoDrawable} instance
*
- * @return the created offscreen GLDrawable
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+ */
+ public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) throws GLException;
+ /**
+ * Creates a offscreen {@link GLDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * <p>
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
+ * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
+ * </p>
+ * <p>
+ * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ * </p>
+ * <p>
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * </p>
+ * <p>
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated.
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param width the requested offscreen width
+ * @param height the requested offscreen height
+ *
+ * @return the created offscreen {@link GLDrawable}
*
* @throws GLException if any window system-specific errors caused
* the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
*/
public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesImmutable caps,
GLCapabilitiesChooser chooser,
- int width, int height)
- throws GLException;
+ int width, int height) throws GLException;
/**
* Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
@@ -459,6 +519,21 @@ public abstract class GLDrawableFactory {
GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
/**
+ * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
+ * <p>
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+ * </p>
+ * <p>
+ * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}.
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
+ /**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
*
@@ -467,7 +542,10 @@ public abstract class GLDrawableFactory {
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
/**
- * Creates a GLPbuffer with the given capabilites and dimensions. <P>
+ * Creates a GLPbuffer {@link GLAutoDrawable} with the given capabilites and dimensions.
+ * <p>
+ * The GLPbuffer drawable is realized and initialized eagerly.
+ * </p>
*
* See the note in the overview documentation on
* <a href="../../../overview-summary.html#SHARING">context sharing</a>.
@@ -479,10 +557,12 @@ public abstract class GLDrawableFactory {
* @param initialHeight initial height of pbuffer
* @param shareWith a shared GLContext this GLPbuffer shall use
*
- * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable}
+ * @return the created and initialized {@link GLPbuffer} instance
*
* @throws GLException if any window system-specific errors caused
* the creation of the GLPbuffer to fail.
+ *
+ * @deprecated {@link GLPbuffer} is deprecated, use {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)}
*/
public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device,
GLCapabilitiesImmutable capabilities,
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
new file mode 100644
index 000000000..45fd3b686
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -0,0 +1,173 @@
+/**
+ * Copyright 2012 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.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/**
+ * Platform-independent {@link GLDrawable} specialization,
+ * exposing {@link FBObject} functionality.
+ *
+ * <p>
+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound
+ * and made current the first time.
+ * </p>
+ *
+ * <p>
+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}.
+ * </p>
+ * <p>
+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}.
+ * </p>
+ * <p>
+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}.
+ * Hence double buffering is always the case w/ MSAA.
+ * </p>
+ * <p>
+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used.
+ * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection
+ * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}.
+ * This method also allows usage of both textures seperately.
+ * </p>
+ * <p>
+ * It would be possible to implement double buffering simply using
+ * {@link FBObject.TextureAttachment texture attachment}s with one {@link FBObject framebuffer}.
+ * This would require mode selection and hence complicate the API. Besides, it would
+ * not support differentiation of read and write framebuffer and hence not be spec compliant.
+ * </p>
+ * <p>
+ * Actual swapping of the {@link FBObject.TextureAttachment texture}s or {@link FBObject framebuffer}
+ * is performed either in the {@link #contextMadeCurrent(boolean) context current hook}
+ * or when {@link #swapBuffersImpl(boolean) swapping buffers}, whatever comes first.<br/>
+ * </p>
+ */
+public interface GLFBODrawable extends GLDrawable {
+ // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * @return <code>true</code> if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise <code>false</code>.
+ */
+ public boolean isInitialized();
+
+ /**
+ * Notify this instance about upstream size change
+ * to reconfigure the {@link FBObject}.
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @throws GLException if resize operation failed
+ */
+ void resetSize(GL gl) throws GLException;
+
+ /**
+ * @return the used texture unit
+ */
+ int getTextureUnit();
+
+ /**
+ *
+ * @param unit the texture unit to be used
+ */
+ void setTextureUnit(int unit);
+
+ /**
+ * Set a new sample size
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @param newSamples new sample size
+ * @throws GLException if resetting the FBO failed
+ */
+ void setNumSamples(GL gl, int newSamples) throws GLException;
+
+ /**
+ * @return the number of sample buffers if using MSAA, otherwise 0
+ */
+ int getNumSamples();
+
+ /**
+ * @return the used {@link DoubleBufferMode}
+ */
+ // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+ * otherwise an exception is thrown.
+ * <p>
+ * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}.
+ * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}
+ * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored.
+ * </p>
+ * <p>
+ * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect.
+ * </p>
+ * @throws GLException if already initialized, see {@link #isInitialized()}.
+ */
+ // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * If MSAA is being used and {@link GL#GL_FRONT} is requested,
+ * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned.
+ *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link FBObject}
+ * @throws IllegalArgumentException if an illegal buffer name is being used
+ */
+ FBObject getFBObject(int bufferName) throws IllegalArgumentException;
+
+ /**
+ * Returns the named texture buffer.
+ * <p>
+ * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible
+ * and an exception is being thrown if {@link GL#GL_BACK} is being requested.
+ * </p>
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link TextureAttachment}
+ * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used
+ */
+ FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException;
+
+ /** Resizeable {@link GLFBODrawable} specialization */
+ public interface Resizeable extends GLFBODrawable {
+ /**
+ * Resize this drawable.
+ * <p>
+ * This drawable is being locked during operation.
+ * </p>
+ * @param context the {@link GLContext} bound to this drawable, will be made current during operation
+ * A prev. current context will be make current after operation.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case an error during the resize operation occurred
+ */
+ void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException;
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
new file mode 100644
index 000000000..6fe76a3f4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2012 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.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+
+/**
+ * Platform-independent {@link GLAutoDrawable} specialization,
+ * exposing offscreen functionality.
+ * <p>
+ * This class distinguishes itself from {@link GLAutoDrawable}
+ * with it's {@link #setSize(int, int)} functionality.
+ * </p>
+ */
+public interface GLOffscreenAutoDrawable extends GLAutoDrawable {
+
+ /**
+ * Resize this auto drawable.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case of an error during the resize operation
+ */
+ void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException;
+
+ /**
+ * Set the upstream UI toolkit object.
+ * @see #getUpstreamWidget()
+ */
+ void setUpstreamWidget(Object newUpstreamWidget);
+
+ /** {@link FBObject} based {@link GLOffscreenAutoDrawable} specialization */
+ public interface FBO extends GLOffscreenAutoDrawable, GLFBODrawable {
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
index 273a992cf..de7731a3b 100644
--- a/src/jogl/classes/javax/media/opengl/GLPbuffer.java
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -45,7 +45,11 @@ package javax.media.opengl;
contains experimental methods for accessing the pbuffer's contents
as a texture map and enabling rendering to floating-point frame
buffers. These methods are not guaranteed to be supported on all
- platforms and may be deprecated in a future release. */
+ platforms and may be deprecated in a future release.
+
+ @deprecated Use {@link GLOffscreenAutoDrawable} w/ {@link GLCapabilities#setFBO(boolean)}
+ via {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext) GLDrawableFactory.createOffscreenAutoDrawable(..)}.
+ */
public interface GLPbuffer extends GLAutoDrawable {
/** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 033591fe3..329cf9e3f 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -98,6 +98,7 @@ import jogamp.common.awt.AWTEDTExecutor;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on our
@@ -109,6 +110,16 @@ import jogamp.opengl.GLDrawableHelper;
interfaces when adding a heavyweight doesn't work either because
of Z-ordering or LayoutManager problems.
*
+ * <h5><A NAME="java2dgl">Offscreen Layer Remarks</A></h5>
+ *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing
+ * the underlying JAWT mechanism to composite the image, if supported.
+ * <p>
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * is being called if {@link GLCapabilitiesImmutable#isOnscreen()} is <code>false</code>.
+ * </p>
+ *
* <h5><A NAME="java2dgl">Java2D OpenGL Remarks</A></h5>
*
* To avoid any conflicts with a potential Java2D OpenGL context,<br>
@@ -145,7 +156,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
private AWTGraphicsConfiguration awtConfig;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
private volatile JAWTWindow jawtWindow; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private GLContextImpl context;
private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
@@ -237,6 +248,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// don't allow the user to change data
capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
}
+ if(!capsReqUser.isOnscreen()) {
+ setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
+ }
if(null==device) {
GraphicsConfiguration gc = super.getGraphicsConfiguration();
@@ -451,11 +465,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
/** Overridden to cause OpenGL rendering to be performed during
repaint cycles. Subclasses which override this method must call
super.paint() in their paint() method in order to function
- properly. <P>
-
- <B>Overrides:</B>
- <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- @Override
+ properly.
+ */
+ @Override
public void paint(Graphics g) {
if (Beans.isDesignTime()) {
// Make GLCanvas behave better in NetBeans GUI builder
@@ -544,7 +556,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
jawtWindow.lockSurface();
try {
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
context = (GLContextImpl) drawable.createContext(shareWith);
context.setContextCreationFlags(additionalCtxCreationFlags);
} finally {
@@ -561,13 +573,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if (!Beans.isDesignTime() &&
0 < _drawable.getWidth() * _drawable.getHeight() ) {
// make sure drawable realization happens on AWT EDT, due to AWTTree lock
- AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
- sendReshape=true; // ensure a reshape is being send ..
- if(DEBUG) {
- System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
- Thread.dumpStack();
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, setRealizedOnEDTAction);
+ if( _drawable.isRealized() ) {
+ sendReshape=true; // ensure a reshape is being send ..
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
+ Thread.dumpStack();
+ }
+ return true;
}
- return true;
}
}
return false;
@@ -575,7 +589,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private Runnable setRealizedOnEDTAction = new Runnable() {
@Override
public void run() {
- drawable.setRealized(true);
+ final GLDrawable _drawable = drawable;
+ if ( null != _drawable && 0 < _drawable.getWidth() * _drawable.getHeight() ) {
+ _drawable.setRealized(true);
+ }
} };
/** <p>Overridden to track when this component is removed from a
@@ -620,22 +637,37 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
- super.reshape(x, y, width, height);
- final GLDrawable _drawable = drawable;
- if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) {
- dispose(true);
- } else {
- sendReshape = true;
+ synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape
+ super.reshape(x, y, width, height);
+
+ GLDrawableImpl _drawable = drawable;
+ if( null != _drawable ) {
+ if(DEBUG) {
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, width, height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
}
}
- /** <B>Overrides:</B>
- <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
/**
* Overridden from Canvas to prevent the AWT's clearing of the
* canvas from interfering with the OpenGL rendering.
*/
- @Override
+ @Override
public void update(Graphics g) {
paint(g);
}
@@ -681,7 +713,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -693,6 +725,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
+ @Override
public GLContext getContext() {
return context;
}
@@ -866,7 +903,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if(!disposeRegenerate) {
if(null != awtConfig) {
- disposeAbstractGraphicsDevice();
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, disposeAbstractGraphicsDeviceActionOnEDT);
}
awtConfig=null;
}
@@ -881,7 +918,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
};
- private final Runnable disposeAbstractGraphicsDeviceAction = new Runnable() {
+ /**
+ * Disposes the AbstractGraphicsDevice within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+ */
+ private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
@Override
public void run() {
if(null != awtConfig) {
@@ -900,27 +943,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
};
-
- /**
- * Disposes the AbstractGraphicsDevice within EDT,
- * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
- *
- * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
- */
- private void disposeAbstractGraphicsDevice() {
- if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
- disposeAbstractGraphicsDeviceAction.run();
- } else {
- try {
- EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
- } catch (InvocationTargetException e) {
- throw new GLException(e.getTargetException());
- } catch (InterruptedException e) {
- throw new GLException(e);
- }
- }
- }
-
+
private final Runnable initAction = new Runnable() {
@Override
public void run() {
@@ -1046,7 +1069,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* @param device
* @return the chosen AWTGraphicsConfiguration
*
- * @see #disposeAbstractGraphicsDevice()
+ * @see #disposeAbstractGraphicsDeviceActionOnEDT
*/
private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsRequested,
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index acb8f2183..6d4a5861f 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -121,7 +121,7 @@ import com.jogamp.opengl.util.GLBuffers;
* </P>
*/
-@SuppressWarnings("serial")
+@SuppressWarnings({ "serial", "deprecation" })
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
@@ -396,7 +396,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
their reshape() method in order to function properly. <P>
<DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- @SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
@@ -471,7 +470,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return null;
}
final GLContext oldCtx = backend.getContext();
- final boolean newCtxCurrent = helper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
backend.setContext(newCtx);
if(newCtxCurrent) {
newCtx.makeCurrent();
@@ -481,6 +480,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ if (backend == null) {
+ return null;
+ }
+ return backend.getDrawable();
+ }
+
+ @Override
public GLContext getContext() {
if (backend == null) {
return null;