diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java | 234 |
1 files changed, 169 insertions, 65 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java index e5c44a8d4..897d3fcaf 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 JogAmp Community. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A @@ -29,11 +29,11 @@ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * + * * You acknowledge that this software is not designed or intended for use * in the design, construction, operation or maintenance of any nuclear * facility. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ @@ -47,7 +47,8 @@ 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.nativewindow.MutableSurface; +import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; @@ -88,7 +89,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { return null; } protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device); - + /** * Returns the shared device mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}, * either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br> @@ -115,7 +116,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } protected abstract AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device); - /** + /** * Returns the GLDynamicLookupHelper * @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2, * otherwise the profile is ignored. @@ -125,6 +126,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { //--------------------------------------------------------------------------- // Dispatching GLDrawable construction in respect to the NativeSurface Capabilities // + @Override public GLDrawable createGLDrawable(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -132,23 +134,37 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration(); final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + final boolean isFBOAvailable = GLContext.isFBOAvailable(adevice, chosenCaps.getGLProfile()); GLDrawable result = null; adevice.lock(); try { final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true); if(null != ols) { - // layered surface -> Offscreen/PBuffer + // layered surface -> Offscreen/[FBO|PBuffer] final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable(); chosenCapsMod.setOnscreen(false); - chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice)); + if( isFBOAvailable ) { + chosenCapsMod.setFBO(true); + } else if(canCreateGLPbuffer(adevice)) { + chosenCapsMod.setPBuffer(true); + } else { + chosenCapsMod.setFBO(false); + chosenCapsMod.setPBuffer(false); + } config.setChosenCapabilities(chosenCapsMod); if(DEBUG) { System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target); } - if( ! ( target instanceof SurfaceChangeable ) ) { + if( ! ( target instanceof MutableSurface ) ) { throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target); + } + if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) { + // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO .. + final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target); + result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */); + } else { + result = createOffscreenDrawableImpl(target); } - result = createOffscreenDrawableImpl(target); } else if(chosenCaps.isOnscreen()) { // onscreen if(DEBUG) { @@ -158,12 +174,18 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } else { // offscreen if(DEBUG) { - System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target); + System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target); } - if( ! ( target instanceof SurfaceChangeable ) ) { + if( ! ( target instanceof MutableSurface ) ) { throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target); } - result = createOffscreenDrawableImpl(target); + if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) { + // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO .. + final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target); + result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */); + } else { + result = createOffscreenDrawableImpl(target); + } } } finally { adevice.unlock(); @@ -176,43 +198,42 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { //--------------------------------------------------------------------------- // - // Onscreen GLDrawable construction + // Onscreen GLDrawable construction // protected abstract GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target); //--------------------------------------------------------------------------- // - // PBuffer Offscreen GLDrawable construction + // PBuffer Offscreen GLDrawable construction // - + + @Override public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device); + @Override public GLPbuffer createGLPbuffer(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height, GLContext shareWith) { - if(height<=0 || height<=0) { - throw new GLException("Width and height of pbuffer must be positive (were (" + - width + ", " + height + "))"); + if(width<=0 || height<=0) { + throw new GLException("initial size must be positive (were (" + width + " x " + height + "))"); } - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - - if (!canCreateGLPbuffer(device)) { - throw new GLException("Pbuffer support not available with device: "+device); + if ( !canCreateGLPbuffer(device) ) { + throw new GLException("Pbuffer not available with device: "+device); } - - GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested); + + final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested); GLDrawableImpl drawable = null; device.lock(); try { - drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); + drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) ); if(null != drawable) { drawable.setRealized(true); } @@ -228,75 +249,155 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { //--------------------------------------------------------------------------- // - // Offscreen GLDrawable construction + // Offscreen GLDrawable construction // - protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ; - + @Override public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - int width, - int height) { + int width, int height) { if(width<=0 || height<=0) { - throw new GLException("Width and height of pbuffer must be positive (were (" + - width + ", " + height + "))"); + throw new GLException("initial size must be positive (were (" + width + " x " + height + "))"); } - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); + final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - + + if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) { + device.lock(); + try { + return createFBODrawableImpl(device, capsRequested, chooser, width, height); + } finally { + device.unlock(); + } + } + + final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device)); device.lock(); try { - return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); + return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) ); } finally { device.unlock(); } } - public NativeSurface createOffscreenSurface(AbstractGraphicsDevice deviceReq, - GLCapabilitiesImmutable capsRequested, - GLCapabilitiesChooser chooser, - int width, int height) { - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); + /** Creates a platform independent offscreen FBO GLDrawable implementation */ + protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, + int initialWidth, int initialHeight) { + final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64); + final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface); + + return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */); + } + + /** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */ + protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ; + + /** + * Creates a mutable {@link ProxySurface} w/o defined surface handle. + * <p> + * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}. + * </p> + * <p> + * Lifecycle (destruction) of the TBD surface handle shall be handled by the caller. + * </p> + * @param device a valid platform dependent target device. + * @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details, + * otherwise <code>device</code> instance is used as-is. + * @param capsChosen + * @param capsRequested + * @param chooser the custom chooser, may be null for default + * @param width the initial width + * @param height the initial height + * @param lifecycleHook optional control of the surface's lifecycle + * @return the created {@link MutableSurface} instance w/o defined surface handle + */ + protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, + GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook); + + /** + * A dummy surface is not visible on screen and will not be used to render directly to, + * it maybe on- or offscreen. + * <p> + * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information. + * It also allows creation of framebuffer objects which are used for rendering. + * </p> + * @param deviceReq 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 requestedCaps + * @param chooser the custom chooser, may be null for default + * @param width the initial width + * @param height the initial height + * + * @return the created {@link MutableSurface} instance w/o defined surface handle + */ + public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, + int width, int height) { + final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - device.lock(); try { - return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height); + return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height); } finally { device.unlock(); } } - + /** - * creates an offscreen NativeSurface, which must implement SurfaceChangeable as well, - * so the windowing system related implementation is able to set the surface handle. + * A dummy surface is not visible on screen and will not be used to render directly to, + * it maybe on- or offscreen. + * <p> + * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information. + * It also allows creation of framebuffer objects which are used for rendering. + * </p> + * @param device a valid platform dependent target device. + * @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details, + * otherwise <code>device</code> instance is used as-is. + * @param requestedCaps + * @param chooser the custom chooser, may be null for default + * @param width the initial width + * @param height the initial height + * @return the created {@link MutableSurface} instance w/o defined surface handle */ - protected abstract NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, - GLCapabilitiesImmutable capabilities, GLCapabilitiesImmutable capsRequested, - GLCapabilitiesChooser chooser, - int width, int height); + public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, + GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height); - public ProxySurface createProxySurface(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + //--------------------------------------------------------------------------- + // + // ProxySurface (Wrapped pre-existing native surface) construction + // + + @Override + public ProxySurface createProxySurface(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, + GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { + final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { - throw new GLException("No shared device for requested: "+device); + throw new GLException("No shared device for requested: "+deviceReq); } device.lock(); try { - return createProxySurfaceImpl(device, windowHandle, capsRequested, chooser); + return createProxySurfaceImpl(device, screenIdx, windowHandle, capsRequested, chooser, upstream); } finally { device.unlock(); } - } - - protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser); + } + + /** + * Creates a {@link ProxySurface} with a set surface handle. + * <p> + * Implementation is also required to allocate it's own {@link AbstractGraphicsDevice} instance. + * </p> + * @param upstream TODO + */ + protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, + GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream); //--------------------------------------------------------------------------- // @@ -304,7 +405,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // protected abstract GLContext createExternalGLContextImpl(); - + + @Override public GLContext createExternalGLContext() { NativeWindowFactory.getDefaultToolkitLock().lock(); try { @@ -316,6 +418,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { protected abstract GLDrawable createExternalGLDrawableImpl(); + @Override public GLDrawable createExternalGLDrawable() { NativeWindowFactory.getDefaultToolkitLock().lock(); try { @@ -398,7 +501,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { * normal ahead of time, use resetDisplayGamma(). Throws * IllegalArgumentException if any of the parameters were * out-of-bounds. - * + * * @param gamma The gamma value, typically > 1.0 (default value is * 1.0) * @param brightness The brightness value between -1.0 and 1.0, @@ -484,7 +587,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { return; if (gammaShutdownHook == null) { gammaShutdownHook = new Thread(new Runnable() { - public void run() { + @Override + public void run() { synchronized (GLDrawableFactoryImpl.this) { resetGammaRamp(originalGammaRamp); } |