summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp
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/jogamp
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/jogamp')
-rw-r--r--src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java76
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java175
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java127
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java185
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java80
-rw-r--r--src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java496
-rw-r--r--src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java28
-rw-r--r--src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java123
-rw-r--r--src/jogl/classes/jogamp/opengl/GLPbufferImpl.java31
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java135
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java163
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java49
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java9
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java145
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java26
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java716
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java48
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java71
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java21
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java7
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java42
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java43
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java58
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java29
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java28
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java7
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java17
44 files changed, 1951 insertions, 1138 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index cc4e1b434..07029f143 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -30,16 +30,15 @@ package jogamp.opengl;
import java.io.PrintStream;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
import javax.media.opengl.FPSCounter;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -49,6 +48,7 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.util.Animator;
@@ -61,38 +61,36 @@ import com.jogamp.opengl.util.Animator;
* @see GLWindow
*/
public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawable");
+ public static final boolean DEBUG = GLDrawableImpl.DEBUG;
protected final GLDrawableHelper helper = new GLDrawableHelper();
protected final FPSCounterImpl fpsCounter = new FPSCounterImpl();
protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
- protected final boolean ownDevice;
+ protected final boolean ownsDevice;
protected int additionalCtxCreationFlags = 0;
protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
/**
- * @param drawable a valid {@link GLDrawableImpl}, may not be realized yet.
- * @param context a valid {@link GLContextImpl}, may not be made current (created) yet.
- * @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.
+ * @param drawable upstream {@link GLDrawableImpl} instance, may be null for lazy initialization
+ * @param context upstream {@link GLContextImpl} instance, may be null for lazy initialization
+ * @param ownsDevice 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 GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
+ public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
this.drawable = drawable;
this.context = context;
- this.ownDevice = ownDevice;
+ this.ownsDevice = ownsDevice;
resetFPSCounter();
}
+ /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */
protected abstract RecursiveLock getLock();
- /** Returns the delegated GLDrawable */
- public final GLDrawable getDelegatedDrawable() { return drawable; }
-
/** Default implementation to handle repaint events from the windowing system */
protected final void defaultWindowRepaintOp() {
final GLDrawable _drawable = drawable;
@@ -103,29 +101,43 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
}
- /** Default implementation to handle resize events from the windowing system */
- protected final void defaultWindowResizedOp() {
- final GLDrawable _drawable = drawable;
+ /** Default implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ GLDrawableImpl _drawable = drawable;
if( null!=_drawable ) {
if(DEBUG) {
- System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight);
+ if(_drawable != _drawableNew) {
+ // write back
+ _drawable = _drawableNew;
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
if( _drawable.isRealized() ) {
if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
display();
}
- }
+ }
}
}
-
+
/**
* Default implementation to handle destroy notifications from the windowing system.
*
* <p>
* If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
* or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
- * {@link #defaultDestroy()} is being called.
+ * a thread safe destruction is being induced.
* </p>
*/
protected final void defaultWindowDestroyNotifyOp() {
@@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
ctrl.resume();
}
} else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
- // surface is locked by another thread
+ // Surface is locked by another thread.
// Flag that destroy should be performed on the next
// attempt to display.
sendDestroy = true; // async, but avoiding deadlock
@@ -225,7 +237,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
_drawable.setRealized(false);
}
- if( ownDevice ) {
+ if( ownsDevice ) {
_drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close();
}
}
@@ -238,7 +250,6 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
_lock.lock();
try {
if(drawable!=null && context != null) {
- drawable.swapBuffers();
helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction);
}
} finally {
@@ -276,7 +287,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
destroy();
return;
}
- final RecursiveLock _lock = getLock();
+ final RecursiveLock _lock = getLock();
_lock.lock();
try {
if( null != context ) {
@@ -295,6 +306,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
} } ;
@Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
+ @Override
public final GLContext getContext() {
return context;
}
@@ -305,7 +321,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
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();
@@ -529,4 +545,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
final GLDrawable _drawable = drawable;
return null != _drawable ? _drawable.getHandle() : 0;
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + /** ", \n\tWindow: "+window+ ", \n\tFactory: "+factory+ */ "]";
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index e82756022..050c619fd 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -47,6 +47,7 @@ import java.util.Map;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
@@ -85,6 +86,7 @@ public abstract class GLContextImpl extends GLContext {
private String glRenderer;
private String glRendererLowerCase;
+ private String glVersion;
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
@@ -126,6 +128,9 @@ public abstract class GLContextImpl extends GLContext {
GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
this.drawable = drawable;
+ if(null != drawable) {
+ drawable.associateContext(this, true);
+ }
this.drawableRead = drawable;
this.glDebugHandler = new GLDebugMessageHandler(this);
@@ -205,8 +210,10 @@ public abstract class GLContextImpl extends GLContext {
if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable
drawableRead = (GLDrawableImpl) readWrite;
}
- final GLDrawable old = drawable;
+ final GLDrawableImpl old = drawable;
+ old.associateContext(this, false);
drawable = (GLDrawableImpl) readWrite ;
+ drawable.associateContext(this, true);
if(lockHeld) {
makeCurrent();
}
@@ -272,7 +279,7 @@ public abstract class GLContextImpl extends GLContext {
if( actualRelease ) {
if( !inDestruction ) {
try {
- drawable.contextMadeCurrent(this, false);
+ contextMadeCurrent(false);
} catch (Throwable t) {
drawableContextMadeCurrentException = t;
}
@@ -331,7 +338,8 @@ public abstract class GLContextImpl extends GLContext {
makeCurrent();
}
try {
- drawable.contextRealized(this, false);
+ contextRealized(false);
+ drawable.associateContext(this, false);
} catch (Throwable t) {
drawableContextRealizedException = t;
}
@@ -514,19 +522,17 @@ public abstract class GLContextImpl extends GLContext {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
}
- drawable.contextRealized(this, true);
+ contextRealized(true);
if(DEBUG || TRACE_SWITCH) {
System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
}
- } else {
- drawable.contextMadeCurrent(this, true);
-
- if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
- }
+ } else if(TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
}
+ contextMadeCurrent(true);
+
/* FIXME: refactor dependence on Java 2D / JOGL bridge
// Try cleaning up any stale server-side OpenGL objects
@@ -609,6 +615,20 @@ public abstract class GLContextImpl extends GLContext {
protected abstract void makeCurrentImpl() throws GLException;
/**
+ * @see GLDrawableImpl#contextRealized(GLContext, boolean)
+ */
+ protected void contextRealized(boolean realized) {
+ drawable.contextRealized(this, realized);
+ }
+
+ /**
+ * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
+ */
+ protected void contextMadeCurrent(boolean current) {
+ drawable.contextMadeCurrent(this, current);
+ }
+
+ /**
* Platform dependent entry point for context creation.<br>
*
* This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .<br>
@@ -934,52 +954,43 @@ public abstract class GLContextImpl extends GLContext {
/**
* If major > 0 || minor > 0 : Use passed values, determined at creation time
- * If major==0 && minor == 0 : Use GL_VERSION
* Otherwise .. don't touch ..
*/
private final void setContextVersion(int major, int minor, int ctp, boolean setVersionString) {
- if (0==ctp) {
+ if ( 0 == ctp ) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
- if(major>0 || minor>0) {
- if (!GLContext.isValidGLVersion(major, minor)) {
- GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
- throw e;
- }
- ctxMajorVersion = major;
- ctxMinorVersion = minor;
- ctxOptions = ctp;
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
- }
- return;
+
+ if (!GLContext.isValidGLVersion(major, minor)) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
-
- if(major==0 && minor==0) {
- String versionStr = getGL().glGetString(GL.GL_VERSION);
- if(null==versionStr) {
- throw new GLException("GL_VERSION is NULL: "+this);
- }
- ctxOptions = ctp;
-
- // Set version
- GLVersionNumber version = new GLVersionNumber(versionStr);
+ ctxMajorVersion = major;
+ ctxMinorVersion = minor;
+ ctxOptions = ctp;
+ if(setVersionString) {
+ ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
+ }
+ }
+
+ private static final VersionNumber getGLVersionNumber(int ctp, String glVersionStr) {
+ if( null != glVersionStr ) {
+ final GLVersionNumber version = new GLVersionNumber(glVersionStr);
if (version.isValid()) {
- ctxMajorVersion = version.getMajor();
- ctxMinorVersion = version.getMinor();
- // We cannot promote a non ARB context to >= 3.1,
- // reduce it to 3.0 then.
- if ( ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
- && 0 == (ctxOptions & CTX_IS_ARB_CREATED) ) {
- ctxMajorVersion = 3;
- ctxMinorVersion = 0;
- }
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
- }
- return;
+ int major = version.getMajor();
+ int minor = version.getMinor();
+ // We cannot promote a non ARB context to >= 3.1,
+ // reduce it to 3.0 then.
+ if ( 0 == (ctp & CTX_IS_ARB_CREATED) &&
+ ( major > 3 || major == 3 && minor >= 1 ) ) {
+ major = 3;
+ minor = 0;
+ }
+ if ( GLContext.isValidGLVersion(major, minor) ) {
+ return new VersionNumber(major, minor, 0);
+ }
}
}
+ return null;
}
//----------------------------------------------------------------------
@@ -1019,14 +1030,18 @@ public abstract class GLContextImpl extends GLContext {
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, binds this pbuffer to its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void bindPbufferToTexture();
+ public void bindPbufferToTexture() { throw new GLException("not implemented"); }
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, releases this pbuffer from its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void releasePbufferFromTexture();
+ public void releasePbufferFromTexture() { throw new GLException("not implemented"); }
public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
@@ -1064,7 +1079,7 @@ public abstract class GLContextImpl extends GLContext {
table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
}
- private final boolean initGLRendererStrings() {
+ private final boolean initGLRendererAndGLVersionStrings() {
final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
if(0 == _glGetString) {
@@ -1083,14 +1098,27 @@ public abstract class GLContextImpl extends GLContext {
Thread.dumpStack();
}
return false;
- } else {
- glRenderer = _glRenderer;
- glRendererLowerCase = glRenderer.toLowerCase();
- return true;
}
+ glRenderer = _glRenderer;
+ glRendererLowerCase = glRenderer.toLowerCase();
+
+ final String _glVersion = glGetStringInt(GL.GL_VERSION, _glGetString);
+ if(null == _glVersion) {
+ // FIXME
+ if(DEBUG) {
+ System.err.println("Warning: GL_VERSION is NULL.");
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ glVersion = _glVersion;
+ return true;
}
}
+ protected final String getGLVersionString() {
+ return glVersion;
+ }
protected final String getGLRendererString(boolean lowerCase) {
return lowerCase ? glRendererLowerCase : glRenderer;
}
@@ -1128,17 +1156,44 @@ public abstract class GLContextImpl extends GLContext {
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- if( !initGLRendererStrings() && DEBUG) {
- System.err.println("Warning: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ {
+ final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+ if(DEBUG) {
+ if( !initGLRendererAndGLVersionStringsOK ) {
+ System.err.println("Warning: setGLFunctionAvailability: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ } else {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Given "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
+ }
+ }
}
if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
-
+
+ // Pick the version from the GL-version string,
+ // if smaller _or_ given major == 0.
+ final VersionNumber glVersionNumber;
+ {
+ final VersionNumber setGLVersionNumber = new VersionNumber(major, minor, 0);
+ final VersionNumber strGLVersionNumber = getGLVersionNumber(ctxProfileBits, glVersion);
+ if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) <= 0 || 0 == major ) ) {
+ glVersionNumber = strGLVersionNumber;
+ major = glVersionNumber.getMajor();
+ minor = glVersionNumber.getMinor();
+ } else {
+ glVersionNumber = setGLVersionNumber;
+ }
+ }
+ if ( !GLContext.isValidGLVersion(major, minor) ) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctxProfileBits)+", "+glVersion+", "+glVersionNumber);
+ }
+ if( 2 > major ) { // there is no ES2-compat for a profile w/ major < 2
+ ctxProfileBits &= ~GLContext.CTX_IMPL_ES2_COMPAT;
+ }
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion) + ", "+glVersionNumber);
}
//
@@ -1201,6 +1256,10 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits |= CTX_IMPL_FBO;
}
+ if(FORCE_NO_FBO_SUPPORT) {
+ ctxProfileBits &= ~CTX_IMPL_FBO ;
+ }
+
//
// Set GL Version (complete w/ version string)
//
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index e1e253d35..4f965f620 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -48,18 +48,21 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.MutableSurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.opengl.GLCapabilities;
+import javax.media.nativewindow.UpstreamSurfaceHook;
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.GLFBODrawable;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.DelegatedUpstreamSurfaceHookWithSurfaceSize;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
/** Extends GLDrawableFactory with a few methods for handling
@@ -67,6 +70,7 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
Independent Bitmaps on Windows, pixmaps on X11). Direct access to
these GLDrawables is not supplied directly to end users, though
they may be instantiated by the GLJPanel implementation. */
+@SuppressWarnings("deprecation")
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
@@ -141,55 +145,53 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
if(null != ols) {
// layered surface -> Offscreen/[FBO|PBuffer]
- final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
- chosenCapsMod.setOnscreen(false);
- chosenCapsMod.setDoubleBuffered(false);
- /* if( isFBOAvailable ) { // FIXME JAU: FBO n/a yet
- chosenCapsMod.setFBO(true);
- } else */
- if( canCreateGLPbuffer(adevice) ) {
- chosenCapsMod.setPBuffer(true);
- } else {
- chosenCapsMod.setFBO(false);
- chosenCapsMod.setPBuffer(false);
+ final boolean isPbufferAvailable = canCreateGLPbuffer(adevice) ;
+ if(!isPbufferAvailable && !isFBOAvailable) {
+ throw new GLException("Neither FBO nor Pbuffer is available for "+target);
}
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, isFBOAvailable, isPbufferAvailable);
config.setChosenCapabilities(chosenCapsMod);
+ ols.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer");
+ System.err.println("chosenCaps: "+chosenCaps);
+ System.err.println("chosenCapsMod: "+chosenCapsMod);
+ System.err.println("OffscreenLayerSurface: **** "+ols);
+ System.err.println("Target: **** "+target);
+ Thread.dumpStack();
}
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 */);
+ if( chosenCapsMod.isFBO() && isFBOAvailable ) {
+ // target surface is already a native one
+ result = createFBODrawableImpl(target, chosenCapsMod, 0);
} else {
result = createOffscreenDrawableImpl(target);
}
} else if(chosenCaps.isOnscreen()) {
// onscreen
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ config.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
}
result = createOnscreenDrawableImpl(target);
} else {
// offscreen
- final GLCapabilitiesImmutable reqCaps = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO req / chosen - avail, PBuffer: "+reqCaps.isFBO()+" / "+chosenCaps.isFBO()+" - "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO chosen / avail, PBuffer: "+
+ chosenCaps.isFBO()+" / "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
}
if( ! ( target instanceof MutableSurface ) ) {
- throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
+ throw new IllegalArgumentException("Passed NativeSurface must implement MutableSurface for offscreen: "+target);
}
- if( reqCaps.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 */);
+ if( chosenCaps.isFBO() && isFBOAvailable ) {
+ // need to hook-up a native dummy surface since source may not have
+ final ProxySurface dummySurface = createDummySurfaceImpl(adevice, true, chosenCaps, null, 64, 64);
+ dummySurface.setUpstreamSurfaceHook(new DelegatedUpstreamSurfaceHookWithSurfaceSize(dummySurface.getUpstreamSurfaceHook(), target));
+ result = createFBODrawableImpl(dummySurface, chosenCaps, 0);
} else {
- final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
- chosenCapsMod.setDoubleBuffered(false);
- config.setChosenCapabilities(chosenCapsMod);
result = createOffscreenDrawableImpl(target);
}
}
@@ -211,7 +213,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // PBuffer Offscreen GLDrawable construction
+ // PBuffer Offscreen GLAutoDrawable construction
//
@Override
@@ -239,7 +241,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLDrawableImpl drawable = null;
device.lock();
try {
- drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ drawable = createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
if(null != drawable) {
drawable.setRealized(true);
}
@@ -247,10 +250,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.unlock();
}
- if(null==drawable) {
- throw new GLException("Could not create Pbuffer drawable for: "+device+", "+capsChosen+", "+width+"x"+height);
- }
- return new GLPbufferImpl( drawable, shareWith, true);
+ return new GLPbufferImpl( drawable, (GLContextImpl) drawable.createContext(shareWith) );
}
//---------------------------------------------------------------------------
@@ -258,6 +258,29 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// Offscreen GLDrawable construction
//
+ public final boolean canCreateFBO(AbstractGraphicsDevice deviceReq, GLProfile glp) {
+ AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ if(null == device) {
+ throw new GLException("No shared device for requested: "+deviceReq);
+ }
+ return GLContext.isFBOAvailable(device, glp);
+ }
+
+ @Override
+ public GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice deviceReq,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) {
+ final GLDrawable drawable = createOffscreenDrawable( deviceReq, capsRequested, chooser, width, height );
+ drawable.setRealized(true);
+ final GLContext context = drawable.createContext(shareWith);
+ if(drawable instanceof GLFBODrawableImpl) {
+ return new GLOffscreenAutoDrawableImpl.FBOImpl( (GLFBODrawableImpl)drawable, context, null, null );
+ }
+ return new GLOffscreenAutoDrawableImpl( drawable, context, null, null);
+ }
+
@Override
public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
@@ -274,10 +297,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested,
GLContext.isFBOAvailable(device, capsRequested.getGLProfile()),
canCreateGLPbuffer(device));
+
if( capsChosen.isFBO() ) {
device.lock();
try {
- return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+ final ProxySurface dummySurface = createDummySurfaceImpl(device, true, capsRequested, null, width, height);
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+ return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, dummySurface, capsChosen, 0);
} finally {
device.unlock();
}
@@ -285,20 +311,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.lock();
try {
- return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
} finally {
device.unlock();
}
}
- /** 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);
+ /** Creates a platform independent FBO offscreen GLDrawable */
+ protected GLFBODrawable createFBODrawableImpl(NativeSurface dummySurface, GLCapabilitiesImmutable fboCaps, int textureUnit) {
final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
-
- return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+ return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, fboCaps, textureUnit);
}
/** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */
@@ -318,15 +341,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @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
+ * @param upstreamHook surface size information and 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);
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook);
/**
* A dummy surface is not visible on screen and will not be used to render directly to,
@@ -341,9 +362,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param width the initial width
* @param height the initial height
*
- * @return the created {@link MutableSurface} instance w/o defined surface handle
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
- public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ public ProxySurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
int width, int height) {
final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
@@ -369,9 +390,11 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* 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
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()}, not the actual dummy surface height,
+ * The latter is platform specific and small
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 090c5fe69..bdf0b6d74 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -43,12 +43,19 @@ package jogamp.opengl;
import java.util.ArrayList;
import java.util.HashSet;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import javax.media.opengl.GLRunnable;
import com.jogamp.opengl.util.Animator;
@@ -108,24 +115,27 @@ public class GLDrawableHelper {
/**
* Associate a new context to the drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * <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>
* <p>
* If the old or new context was current on this thread, it is being released before switching the drawable.
* </p>
+ * <p>
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only bound to one drawable at one time!
+ * </p>
+ * <p>
+ * No locking is being performed on the drawable, caller is required to take care of it.
+ * </p>
*
* @param drawable the drawable which context is changed
- * @param newCtx the new context
* @param oldCtx the old context
- * @return true if the newt context was current, otherwise false
+ * @param newCtx the new context
+ * @param newCtxCreationFlags additional creation flags if newCtx is not null and not been created yet, see {@link GLContext#setContextCreationFlags(int)}
+ * @return true if the new context was current, otherwise false
*
* @see GLAutoDrawable#setContext(GLContext)
*/
- public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) {
- if(null != oldCtx && oldCtx.isCurrent()) {
+ public static final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int newCtxCreationFlags) {
+ if( null != oldCtx && oldCtx.isCurrent() ) {
oldCtx.release();
}
final boolean newCtxCurrent;
@@ -134,17 +144,135 @@ public class GLDrawableHelper {
if(newCtxCurrent) {
newCtx.release();
}
- newCtx.setContextCreationFlags(additionalCtxCreationFlags);
+ newCtx.setContextCreationFlags(newCtxCreationFlags);
newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch
} else {
newCtxCurrent = false;
}
- if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) {
- ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null);
- }
return newCtxCurrent;
}
+ /**
+ * If the drawable is not realized, OP is a NOP.
+ * <ul>
+ * <li>release context if current</li>
+ * <li>destroy old drawable</li>
+ * <li>create new drawable</li>
+ * <li>attach new drawable to context</li>
+ * <li>make context current, if it was current</li>
+ * </ul>
+ * <p>
+ * No locking is being performed, caller is required to take care of it.
+ * </p>
+ *
+ * @param drawable
+ * @param context maybe null
+ * @return the new drawable
+ */
+ public static final GLDrawableImpl recreateGLDrawable(GLDrawableImpl drawable, GLContext context) {
+ if( ! drawable.isRealized() ) {
+ return drawable;
+ }
+ final boolean contextCurrent = null != context && context.isCurrent();
+ final GLDrawableFactory factory = drawable.getFactory();
+ final NativeSurface surface = drawable.getNativeSurface();
+ final ProxySurface proxySurface = (surface instanceof ProxySurface) ? (ProxySurface)surface : null;
+
+ if(contextCurrent) {
+ context.release();
+ }
+
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(false);
+ }
+ try {
+ drawable.setRealized(false);
+ drawable = (GLDrawableImpl) factory.createGLDrawable(surface); // [2]
+ drawable.setRealized(true);
+ } finally {
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(true);
+ }
+ }
+
+ if(null != context) {
+ context.setGLDrawable(drawable, true); // re-association
+ }
+
+ if(contextCurrent) {
+ context.makeCurrent();
+ }
+ return drawable;
+ }
+
+ /**
+ * Performs resize operation on the given drawable, assuming it is offscreen.
+ * <p>
+ * The {@link GLDrawableImpl}'s {@link NativeSurface} is being locked during operation.
+ * In case the holder is an auto drawable or similar, it's lock shall be claimed by the caller.
+ * </p>
+ * <p>
+ * May recreate the drawable via {@link #recreateGLDrawable(GLDrawableImpl, GLContext)}
+ * in case of a a pbuffer- or pixmap-drawable.
+ * </p>
+ * <p>
+ * FBO drawables are resized w/o drawable destruction.
+ * </p>
+ * <p>
+ * Offscreen resize operation is validated w/ drawable size in the end.
+ * An exception is thrown if not successful.
+ * </p>
+ *
+ * @param drawable
+ * @param context
+ * @param newWidth the new width, it's minimum is capped to 1
+ * @param newHeight the new height, it's minimum is capped to 1
+ * @return the new drawable in case of an pbuffer/pixmap drawable, otherwise the passed drawable is being returned.
+ * @throws NativeWindowException is drawable is not offscreen or it's surface lock couldn't be claimed
+ * @throws GLException may be thrown a resize operation
+ */
+ public static final GLDrawableImpl resizeOffscreenDrawable(GLDrawableImpl drawable, GLContext context, int newWidth, int newHeight)
+ throws NativeWindowException, GLException
+ {
+ if(drawable.getChosenGLCapabilities().isOnscreen()) {
+ throw new NativeWindowException("Drawable is not offscreen: "+drawable);
+ }
+ final NativeSurface ns = drawable.getNativeSurface();
+ final int lockRes = ns.lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface of drawable: "+drawable);
+ }
+ try {
+ if(0>=newWidth) { newWidth = 1; }
+ if(0>=newHeight) { newHeight = 1; }
+ // propagate new size
+ if(ns instanceof ProxySurface) {
+ final ProxySurface ps = (ProxySurface) ns;
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else if(DEBUG) { // we have to assume UpstreamSurfaceHook contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen ProxySurface n.a. UpstreamSurfaceHook.MutableSize, but "+ush.getClass().getName()+": "+ush);
+ }
+ } else if(DEBUG) { // we have to assume surface contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen surface n.a. ProxySurface, but "+ns.getClass().getName()+": "+ns);
+ }
+ if(drawable instanceof GLFBODrawable) {
+ if( null != context && context.isCreated() ) {
+ ((GLFBODrawable) drawable).resetSize(context.getGL());
+ }
+ } else {
+ drawable = GLDrawableHelper.recreateGLDrawable(drawable, context);
+ }
+ } finally {
+ ns.unlockSurface();
+ }
+ if(drawable.getWidth() != newWidth || drawable.getHeight() != newHeight) {
+ throw new InternalError("Incomplete resize operation: expected "+newWidth+"x"+newHeight+", has: "+drawable);
+ }
+ return drawable;
+ }
+
public final void addGLEventListener(GLEventListener listener) {
addGLEventListener(-1, listener);
}
@@ -196,15 +324,11 @@ public class GLDrawableHelper {
}
}
- private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
- if(listenersToBeInit.remove(l)) {
- l.init(drawable);
- if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
- }
- return true;
+ private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
+ l.init(drawable);
+ if(sendReshape) {
+ reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
}
- return false;
}
/** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */
@@ -214,14 +338,11 @@ public class GLDrawableHelper {
for (int i=0; i < _listeners.size(); i++) {
final GLEventListener listener = _listeners.get(i) ;
- // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
+ // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called.
// This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
- // hence the must always be initialized unconditional.
- listenersToBeInit.add(listener);
-
- if ( ! init( listener, drawable, true /* sendReshape */) ) {
- throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
- }
+ // hence it must be called unconditional, always.
+ listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init
+ init( listener, drawable, true /* sendReshape */);
}
}
}
@@ -239,7 +360,9 @@ public class GLDrawableHelper {
final GLEventListener listener = _listeners.get(i) ;
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
- init( listener, drawable, true /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, true /* sendReshape */) ;
+ }
listener.display(drawable);
}
}
@@ -251,7 +374,9 @@ public class GLDrawableHelper {
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
synchronized(listenersLock) {
- init( listener, drawable, false /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, false /* sendReshape */) ;
+ }
}
}
if(setViewport) {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index abf2bf557..311690f1d 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -43,6 +43,7 @@ package jogamp.opengl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -76,31 +77,46 @@ public abstract class GLDrawableImpl implements GLDrawable {
if( !realized ) {
return; // destroyed already
}
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
- if ( caps.getDoubleBuffered() ) {
- if(!surface.surfaceSwap()) {
- int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
- if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
- return;
+ int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
+ if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
+ return;
+ }
+ try {
+ if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
+ updateHandle();
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!surface.surfaceSwap()) {
+ swapBuffersImpl(true);
}
- try {
- if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
- updateHandle();
- }
- swapBuffersImpl();
- } finally {
- unlockSurface();
+ } else {
+ final GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFlush();
}
+ swapBuffersImpl(false);
}
- } else {
- GLContext ctx = GLContext.getCurrent();
- if(null!=ctx && ctx.getGLDrawable()==this) {
- ctx.getGL().glFinish();
- }
- }
+ } finally {
+ unlockSurface();
+ }
surface.surfaceUpdated(this, surface, System.currentTimeMillis());
}
- protected abstract void swapBuffersImpl();
+
+ /**
+ * Platform and implementation depending surface swap.
+ * <p>The surface is locked.</p>
+ * <p>
+ * If <code>doubleBuffered</code> is <code>true</code>,
+ * an actual platform dependent surface swap shall be executed.
+ * </p>
+ * <p>
+ * If <code>doubleBuffered</code> is <code>false</code>,
+ * {@link GL#glFlush()} has been called already and
+ * the implementation may execute implementation specific code.
+ * </p>
+ */
+ protected abstract void swapBuffersImpl(boolean doubleBuffered);
public final static String toHexString(long hex) {
return "0x" + Long.toHexString(hex);
@@ -181,6 +197,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
System.err.println(getThreadName() + ": setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg);
}
}
+ /**
+ * Platform specific realization of drawable
+ */
protected abstract void setRealizedImpl();
/**
@@ -189,7 +208,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
* If <code>realized</code> is <code>true</code>, the context has just been created and made current.
* </p>
* <p>
- * If <code>realized</code> is <code>false</code>, the context is still current and will be release and destroyed after this method returns.
+ * If <code>realized</code> is <code>false</code>, the context is still current and will be released and destroyed after this method returns.
* </p>
* <p>
* @see #contextMadeCurrent(GLContext, boolean)
@@ -199,18 +218,27 @@ public abstract class GLDrawableImpl implements GLDrawable {
/**
* Callback for special implementations, allowing GLContext to trigger GL related lifecycle: <code>makeCurrent</code>, <code>release</code>.
* <p>
- * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
- * </p>
- * <p>
* If <code>current</code> is <code>true</code>, the context has just been made current.
* </p>
* <p>
* If <code>current</code> is <code>false</code>, the context is still current and will be release after this method returns.
* </p>
+ * <p>
+ * Note: Will also be called after {@link #contextRealized(GLContext, boolean) contextRealized(ctx, true)}
+ * but not at context destruction, i.e. {@link #contextRealized(GLContext, boolean) contextRealized(ctx, false)}.
+ * </p>
* @see #contextRealized(GLContext, boolean)
*/
protected void contextMadeCurrent(GLContext glc, boolean current) { }
+ /**
+ * Callback for special implementations, allowing to associate bound context to this drawable (bound == true)
+ * or to remove such association (bound == false).
+ * @param ctx the just bounded or unbounded context
+ * @param bound if <code>true</code> create an association, otherwise remove it
+ */
+ protected void associateContext(GLContext ctx, boolean bound) { }
+
/** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
protected int getDefaultDrawFramebuffer() { return 0; }
/** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
@@ -245,8 +273,8 @@ public abstract class GLDrawableImpl implements GLDrawable {
public String toString() {
return getClass().getSimpleName()+"[Realized "+isRealized()+
",\n\tFactory "+getFactory()+
- ",\n\thandle "+toHexString(getHandle())+
- ",\n\tWindow "+getNativeSurface()+"]";
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tSurface "+getNativeSurface()+"]";
}
protected static String getThreadName() {
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 03bc26cbc..de45466f3 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -1,142 +1,476 @@
package jogamp.opengl;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.TextureAttachment;
/**
- * Offscreen GLDrawable implementation using framebuffer object (FBO)
- * as it's offscreen rendering mechanism.
+ * {@link FBObject} offscreen GLDrawable implementation, i.e. {@link GLFBODrawable}.
+ * <p>
+ * It utilizes the context lifecycle hook {@link #contextRealized(GLContext, boolean)}
+ * to initialize the {@link FBObject} instance.
+ * </p>
+ * <p>
+ * It utilizes the context current hook {@link #contextMadeCurrent(GLContext, boolean) contextMadeCurrent(context, true)}
+ * to {@link FBObject#bind(GL) bind} the FBO.
+ * </p>
+ * See {@link GLFBODrawable} for double buffering details.
*
* @see GLDrawableImpl#contextRealized(GLContext, boolean)
* @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
* @see GLDrawableImpl#getDefaultDrawFramebuffer()
* @see GLDrawableImpl#getDefaultReadFramebuffer()
*/
-public class GLFBODrawableImpl extends GLDrawableImpl {
- final GLDrawableImpl parent;
- final FBObject fbo;
- int texUnit;
- int samplesTexUnit = 0;
- int width=0, height=0, samples=0;
-
- protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent,
- NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) {
+public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
+ protected static final boolean DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject");
+
+ private final GLDrawableImpl parent;
+
+ private boolean initialized;
+ private int texUnit;
+ private int samples;
+
+ private FBObject[] fbos;
+ private int fboIBack; // points to GL_BACK buffer
+ private int fboIFront; // points to GL_FRONT buffer
+ private FBObject pendingFBOReset = null;
+ private boolean fboBound;
+ private static final int bufferCount = 2; // number of FBOs for double buffering. TODO: Possible to configure!
+
+ // private DoubleBufferMode doubleBufferMode; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ private SwapBufferContext swapBufferContext;
+
+ public static interface SwapBufferContext {
+ public void swapBuffers(boolean doubleBuffered);
+ }
+
+ protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, NativeSurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
super(factory, surface, false);
+ this.initialized = false;
+
+ // Replace the chosen caps of dummy-surface w/ it's clone and copied values of orig FBO caps request.
+ // The dummy-surface has already been configured, hence value replace is OK
+ // and due to cloning, the native GLCapability portion is being preserved.
+ final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilities fboCapsNative = (GLCapabilities) msConfig.getChosenCapabilities().cloneMutable();
+ fboCapsNative.copyFrom(fboCaps);
+ msConfig.setChosenCapabilities(fboCapsNative);
+
this.parent = parent;
this.texUnit = textureUnit;
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- this.width = initialWidth;
- this.height = initialHeight;
- this.samples = caps.getNumSamples();
- this.fbo = new FBObject();
+ this.samples = fboCaps.getNumSamples();
+
+ // default .. // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ // this.doubleBufferMode = ( samples > 0 || fboCaps.getDoubleBuffered() ) ? DoubleBufferMode.FBO : DoubleBufferMode.NONE ;
+
+ this.swapBufferContext = null;
}
- @Override
- protected void contextRealized(GLContext glc, boolean realized) {
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- final GL gl = glc.getGL();
- if(realized) {
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ private final void initialize(boolean realize, GL gl) {
+ if(realize) {
+ final int maxSamples = gl.getMaxRenderbufferSamples();
+ samples = samples <= maxSamples ? samples : maxSamples;
+
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ final int fbosN;
if(samples > 0) {
- fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
+ } else if( caps.getDoubleBuffered() ) {
+ fbosN = bufferCount;
} else {
- fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
}
- if( caps.getStencilBits() > 0 ) {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
- } else {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+
+ fbos = new FBObject[fbosN];
+ fboIBack = 0; // head
+ fboIFront = fbos.length - 1; // tail
+
+ for(int i=0; i<fbosN; i++) {
+ fbos[i] = new FBObject();
+ fbos[i].reset(gl, getWidth(), getHeight(), samples);
+ if(fbos[i].getNumSamples() != samples) {
+ throw new InternalError("Sample number mismatch: "+samples+", fbos["+i+"] "+fbos[i]);
+ }
+ if(samples > 0) {
+ fbos[i].attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ } else {
+ fbos[i].attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ }
+ if( caps.getStencilBits() > 0 ) {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+ } else {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ }
}
- } else if(null != fbo) {
- fbo.destroy(gl);
- }
- }
-
- @Override
- protected void contextMadeCurrent(GLContext glc, boolean current) {
- final GL gl = glc.getGL();
- if(current) {
- fbo.bind(gl);
+ fbos[fboIFront].syncFramebuffer(gl);
+ fboBound = false;
+ final GLCapabilities fboCapsNative = (GLCapabilities) surface.getGraphicsConfiguration().getChosenCapabilities();
+ fbos[0].formatToGLCapabilities(fboCapsNative);
+ fboCapsNative.setDoubleBuffered( fboCapsNative.getDoubleBuffered() || samples > 0 );
+
+ initialized = true;
} else {
- fbo.unbind(gl);
- final TextureAttachment attachment = samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) ;
- if(null == attachment) {
- throw new GLException("Null texture colorbuffer, samples "+samples+", "+fbo.toString());
- }
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
- fbo.use(gl, attachment );
- if( samples > 0) {
- gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+ initialized = false;
+
+ for(int i=0; i<fbos.length; i++) {
+ fbos[i].destroy(gl);
}
+ fbos=null;
+ fboBound = false;
+ pendingFBOReset = null;
+ }
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.initialize("+realize+"): "+this);
+ Thread.dumpStack();
}
}
- @Override
- protected int getDefaultDrawFramebuffer() { return fbo.getWriteFramebuffer(); }
-
- @Override
- protected int getDefaultReadFramebuffer() { return fbo.getReadFramebuffer(); }
-
- public FBObject getFBObject() { return fbo; }
-
- public void setSize(GL gl, int newWidth, int newHeight) throws GLException {
- width = newWidth;
- height = newHeight;
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ public final void setSwapBufferContext(SwapBufferContext sbc) {
+ swapBufferContext = sbc;
+ }
+
+ private static final void reset(GL gl, FBObject fbo, int fboIdx, int width, int height, int samples) {
+ fbo.reset(gl, width, height, samples); // implicit glClear(..)
+ if(fbo.getNumSamples() != samples) {
+ throw new InternalError("Sample number mismatch: "+samples+", fbos["+fboIdx+"] "+fbo);
+ }
}
- public void setSamples(GL gl, int newSamples) throws GLException {
- samples = newSamples;
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ private final void reset(GL gl, int newSamples) throws GLException {
+ if(!initialized) {
+ // NOP if not yet initializes
+ return;
+ }
+
+ final GLContext curContext = GLContext.getCurrent();
+ final GLContext ourContext = gl.getContext();
+ final boolean ctxSwitch = null != curContext && curContext != ourContext;
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): BEGIN - ctxSwitch "+ctxSwitch+", "+this);
+ Thread.dumpStack();
+ }
+ Throwable tFBO = null;
+ Throwable tGL = null;
+ ourContext.makeCurrent();
+ fboBound = false; // clear bound-flag immediatly, caused by contextMadeCurrent(..) - otherwise we would swap @ release
+ try {
+ final int maxSamples = gl.getMaxRenderbufferSamples();
+ newSamples = newSamples <= maxSamples ? newSamples : maxSamples;
+
+ if(0==samples && 0<newSamples || 0<samples && 0==newSamples) {
+ // MSAA on/off switch
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(): samples [on/off] reconfig: "+samples+" -> "+newSamples);
+ }
+ initialize(false, gl);
+ samples = newSamples;
+ initialize(true, gl);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(): simple reconfig: "+samples+" -> "+newSamples);
+ }
+ final int nWidth = getWidth();
+ final int nHeight = getHeight();
+ samples = newSamples;
+ pendingFBOReset = ( 1 < fbos.length ) ? fbos[fboIFront] : null; // pending-front reset only w/ double buffering (or zero samples)
+ for(int i=0; i<fbos.length; i++) {
+ if(1 == fbos.length || fboIFront != i) {
+ reset(gl, fbos[i], i, nWidth, nHeight, samples);
+ }
+ }
+ final GLCapabilities fboCapsNative = (GLCapabilities) surface.getGraphicsConfiguration().getChosenCapabilities();
+ fbos[0].formatToGLCapabilities(fboCapsNative);
+ }
+ } catch (Throwable t) {
+ tFBO = t;
+ } finally {
+ try {
+ ourContext.release();
+ if(ctxSwitch) {
+ curContext.makeCurrent();
+ }
+ } catch (Throwable t) {
+ tGL = t;
+ }
+ }
+ if(null != tFBO) {
+ throw new GLException("GLFBODrawableImpl.reset(..) FBObject.reset(..) exception", tFBO);
+ }
+ if(null != tGL) {
+ throw new GLException("GLFBODrawableImpl.reset(..) GLContext.release() exception", tGL);
+ }
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(newSamples "+newSamples+"): END "+this);
+ }
}
+ //
+ // GLDrawable
+ //
@Override
- public GLContext createContext(GLContext shareWith) {
+ public final GLContext createContext(GLContext shareWith) {
final GLContext ctx = parent.createContext(shareWith);
ctx.setGLDrawable(this, false);
return ctx;
}
+ //
+ // GLDrawableImpl
+ //
+
@Override
- public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper() {
return parent.getGLDynamicLookupHelper();
}
@Override
- protected void swapBuffersImpl() {
- }
+ protected final int getDefaultDrawFramebuffer() { return initialized ? fbos[fboIBack].getWriteFramebuffer() : 0; }
+
+ @Override
+ protected final int getDefaultReadFramebuffer() { return initialized ? fbos[fboIFront].getReadFramebuffer() : 0; }
@Override
- protected void setRealizedImpl() {
+ protected final void setRealizedImpl() {
parent.setRealized(realized);
- if(realized) {
- final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
- final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
- final GLCapabilitiesImmutable chosenFBOCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, true /*FBO*/, false /*PBO*/);
- msConfig.setChosenCapabilities(chosenFBOCaps);
+ }
+
+ @Override
+ protected final void contextRealized(GLContext glc, boolean realized) {
+ initialize(realized, glc.getGL());
+ }
+
+ @Override
+ protected final void contextMadeCurrent(GLContext glc, boolean current) {
+ final GL gl = glc.getGL();
+ if(current) {
+ fbos[fboIBack].bind(gl);
+ fboBound = true;
+ } else {
+ if(fboBound) {
+ swapFBOImpl(glc);
+ fboBound=false;
+ if(DEBUG) {
+ System.err.println("Post FBO swap(@release): done");
+ }
+ }
}
}
-
+
@Override
- public int getWidth() {
- return width;
+ protected void swapBuffersImpl(boolean doubleBuffered) {
+ final GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ if(fboBound) {
+ swapFBOImpl(ctx);
+ fboBound=false;
+ if(DEBUG) {
+ System.err.println("Post FBO swap(@swap): done");
+ }
+ }
+ }
+ if(null != swapBufferContext) {
+ swapBufferContext.swapBuffers(doubleBuffered);
+ }
+ }
+
+ private final void swapFBOImpl(GLContext glc) {
+ final GL gl = glc.getGL();
+ fbos[fboIBack].markUnbound(); // fast path, use(gl,..) is called below
+
+ // Safely reset the previous front FBO
+ if(null != pendingFBOReset) {
+ reset(gl, pendingFBOReset, fboIFront, getWidth(), getHeight(), samples);
+ pendingFBOReset = null;
+ }
+
+ if(DEBUG) {
+ int _fboIFront = ( fboIFront + 1 ) % fbos.length;
+ if(_fboIFront != fboIBack) { throw new InternalError("XXX: "+_fboIFront+"!="+fboIBack); }
+ }
+ fboIFront = fboIBack;
+ fboIBack = ( fboIBack + 1 ) % fbos.length;
+
+ final Colorbuffer colorbuffer = samples > 0 ? fbos[fboIFront].getSamplingSink() : fbos[fboIFront].getColorbuffer(0);
+ final TextureAttachment texAttachment;
+ if(colorbuffer instanceof TextureAttachment) {
+ texAttachment = (TextureAttachment) colorbuffer;
+ } else {
+ if(null == colorbuffer) {
+ throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
+ } else {
+ throw new GLException("Front colorbuffer is not a texture: "+colorbuffer.getClass().getName()+": samples "+samples+", "+colorbuffer+", "+this);
+ }
+ }
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+ fbos[fboIFront].use(gl, texAttachment);
+
+ /* Included in above use command:
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, fbos[fboIBack].getDrawFramebuffer());
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbos[fboIFront].getReadFramebuffer());
+ } */
+
+ if(DEBUG) {
+ System.err.println("Post FBO swap(X): fboI back "+fboIBack+", front "+fboIFront+", num "+fbos.length);
+ }
}
+ //
+ // GLFBODrawable
+ //
+
+ @Override
+ public final boolean isInitialized() {
+ return initialized;
+ }
+
@Override
- public int getHeight() {
- return height;
+ public final void resetSize(GL gl) throws GLException {
+ reset(gl, samples);
}
+
+ @Override
+ public final int getTextureUnit() { return texUnit; }
+
+ @Override
+ public final void setTextureUnit(int u) { texUnit = u; }
+
+ @Override
+ public final int getNumSamples() { return samples; }
+
+ @Override
+ public void setNumSamples(GL gl, int newSamples) throws GLException {
+ if(samples != newSamples) {
+ reset(gl, newSamples);
+ }
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public final DoubleBufferMode getDoubleBufferMode() {
+ return doubleBufferMode;
+ }
+
+ @Override
+ public final void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ if(initialized) {
+ throw new GLException("Not allowed past initialization: "+this);
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ if(0 == samples && caps.getDoubleBuffered() && DoubleBufferMode.NONE != mode) {
+ doubleBufferMode = mode;
+ }
+ } */
+
+ @Override
+ public FBObject getFBObject(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final FBObject res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSinkFBO();
+ } else {
+ res = fbos[fboIFront];
+ }
+ break;
+ case GL.GL_BACK:
+ res = fbos[fboIBack];
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+
+ @Override
+ public final TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final TextureAttachment res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSink();
+ } else {
+ res = (TextureAttachment) fbos[fboIFront].getColorbuffer(0);
+ }
+ break;
+ case GL.GL_BACK:
+ if( samples > 0 ) {
+ throw new IllegalArgumentException("Cannot access GL_BACK buffer of MSAA FBO: "+this);
+ } else {
+ res = (TextureAttachment) fbos[fboIBack].getColorbuffer(0);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+ private static final String illegalBufferName = "Only GL_FRONT and GL_BACK buffer are allowed, passed ";
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[Initialized "+initialized+", realized "+isRealized()+", texUnit "+texUnit+", samples "+samples+
+ ",\n\tFactory "+getFactory()+
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tCaps "+surface.getGraphicsConfiguration().getChosenCapabilities()+
+ ",\n\tfboI back "+fboIBack+", front "+fboIFront+", num "+(initialized ? fbos.length : 0)+
+ ",\n\tFBO front read "+getDefaultReadFramebuffer()+", "+getFBObject(GL.GL_FRONT)+
+ ",\n\tFBO back write "+getDefaultDrawFramebuffer()+", "+getFBObject(GL.GL_BACK)+
+ ",\n\tSurface "+getNativeSurface()+
+ "]";
+ }
+
+ public static class ResizeableImpl extends GLFBODrawableImpl implements GLFBODrawable.Resizeable {
+ protected ResizeableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, ProxySurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
+ super(factory, parent, surface, fboCaps, textureUnit);
+ }
+
+ @Override
+ public final void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface: "+this);
+ }
+ try {
+ // propagate new size
+ final ProxySurface ps = (ProxySurface) getNativeSurface();
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else {
+ throw new InternalError("GLFBODrawableImpl.ResizableImpl's ProxySurface doesn't hold a UpstreamSurfaceHookMutableSize but "+ush.getClass().getName()+", "+ps+", ush");
+ }
+ if( null != context && context.isCreated() ) {
+ resetSize(context.getGL());
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 768fc6892..79f96b64a 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,8 +28,12 @@
package jogamp.opengl;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+
+import com.jogamp.common.os.Platform;
public class GLGraphicsConfigurationUtil {
public static final String NV_coverage_sample = "NV_coverage_sample";
@@ -119,26 +123,34 @@ public class GLGraphicsConfigurationUtil {
return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
}
- public static final GLCapabilities setWinAttributeBits(GLCapabilities caps, int winattrbits) {
+ public static final GLCapabilities fixWinAttribBitsAndHwAccel(AbstractGraphicsDevice device, int winattrbits, GLCapabilities caps) {
caps.setBitmap ( 0 != ( BITMAP_BIT & winattrbits ) );
caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
caps.setFBO ( 0 != ( FBO_BIT & winattrbits ) );
// we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
- caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
- return caps;
- }
+ caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
+ final int accel = GLContext.isHardwareRasterizer( device, caps.getGLProfile() );
+ if(0 == accel && caps.getHardwareAccelerated() ) {
+ caps.setHardwareAccelerated(false);
+ }
+
+ return caps;
+ }
+
public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
{
if( !capsRequested.isOnscreen() ) {
return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
- }
+ } /* we maintain the offscreen mode flags in onscreen mode - else {
+ return fixOnscreenGLCapabilities(capsRequested);
+ } */
return capsRequested;
}
public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( !capsRequested.isOnscreen() ) {
+ if( !capsRequested.isOnscreen() || capsRequested.isFBO() || capsRequested.isPBuffer() || capsRequested.isBitmap() ) {
// fix caps ..
final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setBitmap (false);
@@ -157,9 +169,11 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable) {
final boolean auto = !capsRequested.isFBO() && !capsRequested.isPBuffer() && !capsRequested.isBitmap() ;
+
+ final boolean requestedPBuffer = capsRequested.isPBuffer() || Platform.getOSType() == Platform.OSType.MACOS ; // no native bitmap for OSX
final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
- final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+ final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || requestedPBuffer ) ;
final boolean useBitmap = !useFBO && !usePbuffer && ( auto || capsRequested.isBitmap() ) ;
if( capsRequested.isOnscreen() ||
diff --git a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
new file mode 100644
index 000000000..7701f209f
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
@@ -0,0 +1,123 @@
+/**
+ * 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 jogamp.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+public class GLOffscreenAutoDrawableImpl extends GLAutoDrawableDelegate implements GLOffscreenAutoDrawable {
+
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @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 lock optional upstream lock, may be null
+ */
+ public GLOffscreenAutoDrawableImpl(GLDrawable drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, true, lock);
+ }
+
+ @Override
+ public void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ this.defaultWindowResizedOp(newWidth, newHeight);
+ }
+
+ public static class FBOImpl extends GLOffscreenAutoDrawableImpl implements GLOffscreenAutoDrawable.FBO {
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @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 lock optional upstream lock, may be null
+ */
+ public FBOImpl(GLFBODrawableImpl drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, lock);
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return ((GLFBODrawableImpl)drawable).isInitialized();
+ }
+
+ @Override
+ public final int getTextureUnit() {
+ return ((GLFBODrawableImpl)drawable).getTextureUnit();
+ }
+
+ @Override
+ public final void setTextureUnit(int unit) {
+ ((GLFBODrawableImpl)drawable).setTextureUnit(unit);
+ }
+
+ @Override
+ public final int getNumSamples() {
+ return ((GLFBODrawableImpl)drawable).getNumSamples();
+ }
+
+ @Override
+ public final void setNumSamples(GL gl, int newSamples) throws GLException {
+ ((GLFBODrawableImpl)drawable).setNumSamples(gl, newSamples);
+ windowRepaintOp();
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public DoubleBufferMode getDoubleBufferMode() {
+ return ((GLFBODrawableImpl)drawable).getDoubleBufferMode();
+ }
+
+ @Override
+ public void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ ((GLFBODrawableImpl)drawable).setDoubleBufferMode(mode);
+ } */
+
+ @Override
+ public final FBObject getFBObject(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getFBObject(bufferName);
+ }
+
+ public final FBObject.TextureAttachment getTextureBuffer(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getTextureBuffer(bufferName);
+ }
+
+ @Override
+ public void resetSize(GL gl) throws GLException {
+ ((GLFBODrawableImpl)drawable).resetSize(gl);
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index 32f4cb696..b438131bc 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -40,9 +40,6 @@
package jogamp.opengl;
-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;
@@ -50,36 +47,18 @@ import javax.media.opengl.GLPbuffer;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-/** Platform-independent class exposing pbuffer functionality to
- applications. This class is not exposed in the public API as it
- would probably add no value; however it implements the GLDrawable
- interface so can be interacted with via its display() method. */
-
+@SuppressWarnings("deprecation")
public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
private int floatMode;
- public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext, boolean ownDevice) {
- super(pbufferDrawable, null, ownDevice); // drawable := pbufferDrawable
-
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
- if(caps.isOnscreen()) {
- if(caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
- }
- throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
- } else {
- if(!caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
- }
- }
- context = (GLContextImpl) drawable.createContext(sharedContext);
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContextImpl pbufferContext) {
+ super(pbufferDrawable, pbufferContext, true); // drawable := pbufferDrawable, context := pbufferContext
}
//
// pbuffer specifics
- //
-
+ //
+
@Override
public void bindTexture() {
// Doesn't make much sense to try to do this on the event dispatch
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 03d0d650f..06953a8e1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -282,12 +282,6 @@ public abstract class EGLContext extends GLContextImpl {
return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
- @Override
- public abstract void bindPbufferToTexture();
-
- @Override
- public abstract void releasePbufferFromTexture();
-
//
// Accessible ..
//
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index 0dba4bb09..167eebf3a 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,7 +36,8 @@
package jogamp.opengl.egl;
-import javax.media.nativewindow.MutableSurface;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.ProxySurface;
@@ -46,10 +47,10 @@ import javax.media.opengl.GLException;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public abstract class EGLDrawable extends GLDrawableImpl {
- private boolean ownEGLSurface = false; // for destruction
protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
super(factory, component, false);
@@ -58,21 +59,14 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
public abstract GLContext createContext(GLContext shareWith);
- protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
+ protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);
- private final void recreateSurface() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if(DEBUG) {
- System.err.println(getThreadName() + ": createSurface using "+eglConfig);
- }
- if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
- EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
- }
+ private final long createEGLSurface() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();
+ final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
- final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
- final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
- long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+ long eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), upstreamSurface.getSurfaceHandle());
int eglError0;
if (EGL.EGL_NO_SURFACE == eglSurface) {
@@ -86,7 +80,7 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if(DEBUG) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
}
- eglSurface = createSurface(eglConfig, nw.getWindowHandle());
+ eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), nw.getWindowHandle());
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
}
@@ -99,34 +93,53 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
}
-
if(DEBUG) {
- System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": createEGLSurface handle "+toHexString(eglSurface));
}
-
- ((MutableSurface)surface).setSurfaceHandle(eglSurface);
+ return eglSurface;
}
@Override
protected final void updateHandle() {
- if(ownEGLSurface) {
- recreateSurface();
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": updateHandle of "+eglws);
+ }
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) {
+ throw new InternalError("Set surface but claimed to be invalid: "+eglws);
+ }
+ eglws.setSurfaceHandle( createEGLSurface() );
+ } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ }
+
+ protected void destroyHandle() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+ }
+ if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglws.getGraphicsConfiguration().getScreen().getDevice();
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), eglws.getSurfaceHandle());
+ eglws.setSurfaceHandle(EGL.EGL_NO_SURFACE);
}
}
- protected static boolean isValidEGLSurface(EGLGraphicsDevice eglDevice, NativeSurface surface) {
- final long eglDisplayHandle = eglDevice.getHandle();
- if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
- throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+ protected static boolean isValidEGLSurface(long eglDisplayHandle, long surfaceHandle) {
+ if( 0 == surfaceHandle ) {
+ return false;
}
- boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
- if(eglSurfaceValid) {
- int[] tmp = new int[1];
- eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
- if(!eglSurfaceValid) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
- }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surfaceHandle, EGL.EGL_CONFIG_ID, val);
+ if( !eglSurfaceValid ) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
}
}
return eglSurfaceValid;
@@ -134,55 +147,19 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
protected final void setRealizedImpl() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if (realized) {
- final boolean eglSurfaceValid = isValidEGLSurface(eglDevice, surface);
- if(eglSurfaceValid) {
- // surface holds valid EGLSurface
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle()));
- }
- ownEGLSurface=false;
- } else {
- // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
- // However .. let's validate the surface object first
- if( ! (surface instanceof ProxySurface) ) {
- throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface);
- }
- final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
- if( null == upstreamHook ) {
- throw new InternalError("null upstreamHook of: "+surface);
- }
- if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
- throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
- }
- if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
- throw new InternalError("null upstream surface");
- }
- ownEGLSurface=true;
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
- }
- }
- } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
- }
- // Destroy the window surface
- if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error destroying window surface (eglDestroySurface)");
- }
- ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealized("+realized+"): NOP - "+surface);
}
}
@Override
- protected final void swapBuffersImpl() {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
+ throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 292eb17c8..e98d69140 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -52,8 +52,7 @@ import javax.media.nativewindow.MutableSurface;
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.VisualIDHolder.VIDType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
@@ -65,6 +64,7 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
@@ -76,10 +76,11 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+ protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG;
+
/* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true);
/* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
@@ -112,7 +113,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ defaultDevice = new EGLGraphicsDevice();
// FIXME: Probably need to move EGL from a static model
// to a dynamic one, where there can be 2 instances
@@ -310,6 +311,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
try {
final GLCapabilities reqCapsAny = new GLCapabilities(glp);
reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(sharedEGLDevice, reqCapsPBuffer);
hasPBuffer[0] = availablePBufferCapsL.size() > 0;
@@ -324,18 +326,20 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} else {
final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
if(capsAnyL.size() > 0) {
- final GLCapabilitiesImmutable caps = capsAnyL.get(0);
- EGLContext.mapStaticGLESVersion(eglDevice, caps);
+ final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
if(eglDevice != adevice) {
- EGLContext.mapStaticGLESVersion(adevice, caps);
+ EGLContext.mapStaticGLESVersion(adevice, chosenCaps);
}
+ final EGLGraphicsDevice adeviceEGLDevice = new EGLGraphicsDevice(adevice.getHandle(), EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), null);
+ EGLContext.mapStaticGLESVersion(adeviceEGLDevice, chosenCaps);
success = true;
}
if(DEBUG) {
System.err.println("EGLDrawableFactory.isEGLContextAvailable() no pbuffer config available, detected !pbuffer config: "+success);
EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
}
- }
+ }
} else {
surface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
@@ -361,6 +365,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(eglDevice != adevice) {
context.mapCurrentAvailableGLVersion(adevice);
}
+ final EGLGraphicsDevice adeviceEGLDevice = new EGLGraphicsDevice(adevice.getHandle(), EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), null);
+ context.mapCurrentAvailableGLVersion(adeviceEGLDevice);
success = true;
} else {
// Oops .. something is wrong
@@ -538,70 +544,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, getEGLSurface(target));
+ return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
}
- protected static NativeSurface getEGLSurface(NativeSurface surface) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
- AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
- if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
- if(surface instanceof WrappedSurface) {
- // already wrapped surface - no wrapped recursion
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already wrapped surface - use as-is: "+surface);
- }
- return surface;
- }
- if(EGLDrawable.isValidEGLSurface((EGLGraphicsDevice)aDevice, surface)) {
- // already in native EGL format
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already valid EGL surface - use as-is: "+surface);
- }
- return surface;
- }
- }
- // create EGL instance out of platform native types
- final EGLGraphicsDevice eglDevice;
- if( aDevice instanceof EGLGraphicsDevice ) {
- eglDevice = (EGLGraphicsDevice) aDevice;
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Reusing eglDevice: "+eglDevice);
- }
- if(0 == eglDevice.getHandle()) {
- eglDevice.open();
- }
- } else {
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
- }
- final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
- final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
- final EGLGraphicsConfiguration eglConfig;
- if( aConfig instanceof EGLGraphicsConfiguration ) {
- // Config is already in EGL type - reuse ..
- final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
- if( 0 == capsChosen.getEGLConfig() ) {
- // 'refresh' the native EGLConfig handle
- capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
- if( 0 == capsChosen.getEGLConfig() ) {
- throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
- }
- }
- eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig);
- }
- } else {
- eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
-
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
- } else if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig);
- }
- }
- return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface));
- }
static String getThreadName() { return Thread.currentThread().getName(); }
@Override
@@ -615,7 +560,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Non pbuffer not yet implemented");
}
// PBuffer GLDrawable Creation
- return new EGLPbufferDrawable(this, getEGLSurface(target));
+ return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
}
@Override
@@ -628,20 +573,24 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
+ final boolean ownDevice;
final EGLGraphicsDevice device;
- if(createNewDevice) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ if(createNewDevice || ! ( deviceReq instanceof EGLGraphicsDevice ) ) {
+ final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
+ ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ ownDevice = true;
} else {
device = (EGLGraphicsDevice) deviceReq;
+ ownDevice = false;
}
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, ownDevice);
}
@Override
@@ -649,54 +598,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
final GLCapabilitiesImmutable chosenCaps =
GLGraphicsConfigurationUtil.fixDoubleBufferedGLCapabilities(
- GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)),
- false);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)), false);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
- if(0 == eglDevice.getHandle()) {
- eglDevice.open();
- s.setImplBitfield(ProxySurface.OWN_DEVICE);
- }
- createPBufferSurfaceImpl(s, false);
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
- EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
- s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
- if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
- eglDevice.close();
- }
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
- @Override
- public String toString() {
- return "EGLSurfaceLifecycleHook[]";
- }
-
- };
/**
* @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface.
@@ -705,7 +609,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
* @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
*/
protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration();
+ return null;
+ }
+ protected static long createPBufferSurfaceImpl(EGLGraphicsConfiguration config, int width, int height, boolean useTexture) {
final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final int texFormat;
@@ -720,15 +626,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.out.println("Pbuffer config: " + config);
}
- final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat);
+ final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat);
final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0);
if (EGL.EGL_NO_SURFACE==surf) {
- throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+width+"x"+height+", "+eglDevice+", "+config+", error 0x"+Integer.toHexString(EGL.eglGetError()));
} else if(DEBUG) {
System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
}
- ms.setSurfaceHandle(surf);
- return ms;
+ return surf;
}
@Override
@@ -737,7 +642,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..b172d4f35
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -0,0 +1,49 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public EGLDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ s.setSurfaceHandle( EGLDrawableFactory.createPBufferSurfaceImpl((EGLGraphicsConfiguration)s.getGraphicsConfiguration(), 64, 64, false) );
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no EGL surface: "+s);
+ }
+ EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 585638d21..84bd705db 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -79,15 +79,4 @@ public class EGLExternalContext extends EGLContext {
@Override
protected void destroyImpl() throws GLException {
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index e513a86cf..f857c6b5c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -57,8 +57,8 @@ public class EGLGLCapabilities extends GLCapabilities {
this.eglcfg = eglcfg;
this.eglcfgid = eglcfgid;
if(!isCompatible(glp, renderableType)) {
- throw new GLException("Incompatible "+glp+
- " with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
+ throw new GLException("Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
}
this.renderableType = renderableType;
this.nativeVisualID = visualID;
@@ -131,6 +131,7 @@ public class EGLGLCapabilities extends GLCapabilities {
sink = new StringBuilder();
}
boolean first=true;
+ sink.append("0x").append(Integer.toHexString(renderableType)).append(": ");
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
sink.append("GL"); first=false;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 8ee98072f..7bf201238 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -211,6 +211,13 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(null == glp) {
glp = EGLGLCapabilities.getCompatible(device, rType);
}
+ if(!EGLGLCapabilities.isCompatible(glp, rType)) {
+ if(DEBUG) {
+ System.err.println("config "+toHexString(config)+": Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
+ }
+ return null;
+ }
caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
} catch (GLException gle) {
if(DEBUG) {
@@ -288,7 +295,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return null;
}
- return (EGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(caps, drawableTypeBits);
+ return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps);
}
public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
index eae47fa92..325ad6142 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
@@ -41,16 +41,5 @@ public class EGLOnscreenContext extends EGLContext {
public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
super(drawable, shareWith);
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index d54057775..6440cf1e5 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -54,8 +54,8 @@ public class EGLOnscreenDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
index 7175d516f..bb9eeb892 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
@@ -46,15 +46,5 @@ public class EGLPbufferContext extends EGLContext {
public int getFloatingPointMode() {
return 0; // FIXME ??
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Not yet implemented");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Not yet implemented");
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 4a36625bd..eb7e320c8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -52,12 +52,8 @@ public class EGLPbufferDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
- final MutableSurface ms = (MutableSurface)getNativeSurface();
- if(config != ms.getGraphicsConfiguration()) {
- throw new InternalError("Not same: "+config.hashCode()+", "+ms.getGraphicsConfiguration()+": "+config+", "+ms.getGraphicsConfiguration());
- }
- return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+ return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index 42c6e100e..342c4c417 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -1,38 +1,163 @@
package jogamp.opengl.egl;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
+ protected static final boolean DEBUG = EGLDrawableFactory.DEBUG;
private final NativeSurface upstreamSurface;
+ private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize;
public EGLUpstreamSurfaceHook(NativeSurface upstream) {
upstreamSurface = upstream;
+ if(upstreamSurface instanceof ProxySurface) {
+ final UpstreamSurfaceHook ush = ((ProxySurface)upstreamSurface).getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ // offscreen NativeSurface w/ MutableSize (default)
+ upstreamSurfaceHookMutableSize = (UpstreamSurfaceHook.MutableSize) ush;
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
}
public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+ static String getThreadName() { return Thread.currentThread().getName(); }
+
+ public final void setSize(int width, int height) {
+ if(null != upstreamSurfaceHookMutableSize) {
+ upstreamSurfaceHookMutableSize.setSize(width, height);
+ }
+ }
+
@Override
public final void create(ProxySurface surface) {
+ final String dbgPrefix;
+ if(DEBUG) {
+ dbgPrefix = getThreadName() + ": EGLUpstreamSurfaceHook.create("+surface.getClass().getSimpleName()+"): ";
+ System.err.println(dbgPrefix+this);
+ } else {
+ dbgPrefix = null;
+ }
+
if(upstreamSurface instanceof ProxySurface) {
+ // propagate createNotify(..) so upstreamSurface will be created
((ProxySurface)upstreamSurface).createNotify();
- if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
- throw new GLException("Could not lock: "+upstreamSurface);
+ }
+
+ // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+ throw new GLException("Could not lock: "+upstreamSurface);
+ }
+ try {
+ evalUpstreamSurface(dbgPrefix, surface);
+ } finally {
+ upstreamSurface.unlockSurface();
+ }
+ }
+
+ private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
+ //
+ // evaluate nature of upstreamSurface, may create EGL instances if required
+ //
+
+ boolean isEGLSurfaceValid = true; // assume yes
+
+ final AbstractGraphicsConfiguration aConfig = upstreamSurface.getGraphicsConfiguration();
+ final AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+
+ final EGLGraphicsDevice eglDevice;
+ if( aDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) aDevice;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglDevice: "+eglDevice);
+ }
+ if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+ eglDevice.open();
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ } else {
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+
+ final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+ final EGLGraphicsConfiguration eglConfig;
+ if( aConfig instanceof EGLGraphicsConfiguration ) {
+ // Config is already in EGL type - reuse ..
+ final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+ if( !isEGLSurfaceValid || !EGLGraphicsConfiguration.isEGLConfigValid(eglDevice.getHandle(), capsChosen.getEGLConfig()) ) {
+ // 'refresh' the native EGLConfig handle
+ capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
+ if( 0 == capsChosen.getEGLConfig() ) {
+ throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
+ }
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Refreshing eglConfig: "+eglConfig);
+ }
+ isEGLSurfaceValid = false;
+ } else {
+ eglConfig = (EGLGraphicsConfiguration) aConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglConfig: "+eglConfig);
+ }
+ }
+ } else {
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
+
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+ } else if(DEBUG) {
+ System.err.println(dbgPrefix+"Chosen eglConfig: "+eglConfig);
}
+ isEGLSurfaceValid = false;
}
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.open();
+ surface.setGraphicsConfiguration(eglConfig);
+
+ if(isEGLSurfaceValid) {
+ isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+ }
+ if(isEGLSurfaceValid) {
+ surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: Already valid EGL surface - use as-is: "+upstreamSurface);
+ }
+ } else {
+ surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); // create/destroy in EGLDrawable
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: EGL surface n/a - TBD: "+upstreamSurface);
+ }
+ }
}
@Override
public final void destroy(ProxySurface surface) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.close();
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this);
+ }
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
if(upstreamSurface instanceof ProxySurface) {
- upstreamSurface.unlockSurface();
((ProxySurface)upstreamSurface).destroyNotify();
}
}
@@ -49,8 +174,8 @@ public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook
@Override
public String toString() {
- final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil";
- return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+ final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": 0x" + Long.toHexString(upstreamSurface.getSurfaceHandle()) ) : "nil";
+ return "EGLUpstreamSurfaceHook[ "+ upstreamSurface.getWidth() + "x" + upstreamSurface.getHeight() + ", " + us_s+ "]";
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
new file mode 100644
index 000000000..b36303392
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
@@ -0,0 +1,26 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+
+import jogamp.nativewindow.WrappedSurface;
+
+public class EGLWrappedSurface extends WrappedSurface {
+
+ public static EGLWrappedSurface get(NativeSurface surface) {
+ if(surface instanceof EGLWrappedSurface) {
+ return (EGLWrappedSurface)surface;
+ }
+ return new EGLWrappedSurface(surface);
+ }
+
+ public EGLWrappedSurface(NativeSurface surface) {
+ super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLWrappedSurface.ctor(): "+this);
+ }
+ }
+
+ public final NativeSurface getUpstreamSurface() {
+ return ((EGLUpstreamSurfaceHook)super.getUpstreamSurfaceHook()).getUpstreamSurface();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 55aea3a98..ec29558d1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -49,6 +49,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -58,6 +59,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLFBODrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -76,9 +78,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
boolean isNSContext();
long create(long share, int ctp, int major, int minor);
boolean destroy(long ctx);
+ boolean contextRealized(boolean realized);
boolean copyImpl(long src, int mask);
boolean makeCurrent(long ctx);
boolean release(long ctx);
+ boolean detachPBuffer();
boolean setSwapInterval(int interval);
boolean swapBuffers();
}
@@ -279,7 +283,24 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Error destroying OpenGL Context: "+this);
}
}
+
+ @Override
+ protected void contextRealized(boolean realized) {
+ // context stuff depends on drawable stuff
+ if(realized) {
+ super.contextRealized(true); // 1) init drawable stuff
+ impl.contextRealized(true); // 2) init context stuff
+ } else {
+ impl.contextRealized(false); // 1) free context stuff
+ super.contextRealized(false); // 2) free drawable stuff
+ }
+ }
+
+ /* pp */ void detachPBuffer() {
+ impl.detachPBuffer();
+ }
+
@Override
protected void copyImpl(GLContext source, int mask) throws GLException {
if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) {
@@ -365,16 +386,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Should not call this");
}
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
// Support for "mode switching" as described in MacOSXCGLDrawable
public void setOpenGLMode(GLBackendType mode) {
if (mode == openGLMode) {
@@ -421,323 +432,486 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// NSOpenGLContext-based implementation
class NSOpenGLImpl implements GLBackendImpl {
- long nsOpenGLLayer = 0;
- long nsOpenGLLayerPFmt = 0;
- float screenVSyncTimeout; // microSec
- int vsyncTimeout; // microSec - for nsOpenGLLayer mode
-
- @Override
- public boolean isNSContext() { return true; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- final long nsViewHandle;
- if(drawable instanceof MacOSXCGLDrawable) {
- // we allow null here! (special pbuffer case)
- nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
- } else {
- // we only allow a valid NSView here
- final long aHandle = drawable.getHandle();
- if( OSXUtil.isNSView(aHandle) ) {
- nsViewHandle = aHandle;
- } else {
- throw new RuntimeException("Anonymous drawable instance's handle not of type NSView: "+drawable.getClass().getName()+", "+drawable);
- }
- }
- final NativeSurface surface = drawable.getNativeSurface();
- final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
-
- boolean allowIncompleteView = null != backingLayerHost;
- if( !allowIncompleteView && surface instanceof ProxySurface ) {
- allowIncompleteView = 0 != ( ProxySurface.INVISIBLE_WINDOW & ((ProxySurface)surface).getImplBitfield() ) ;
- }
- final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- if(DEBUG) {
- System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
- }
- return 0;
- }
- config.setChosenPixelFormat(pixelFormat);
- int sRefreshRate = CGL.getScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
- screenVSyncTimeout = 1000000f / sRefreshRate;
- if(DEBUG) {
- System.err.println("NS create OSX>=lion "+isLionOrLater);
- System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
- System.err.println("NS create backingLayerHost: "+backingLayerHost);
- System.err.println("NS create share: "+share);
- System.err.println("NS create chosenCaps: "+chosenCaps);
- System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
- System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
- System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
- System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
- // Thread.dumpStack();
- }
- try {
- int[] viewNotReady = new int[1];
- // Try to allocate a context with this
- ctx = CGL.createContext(share,
- nsViewHandle, allowIncompleteView,
- pixelFormat,
- chosenCaps.isBackgroundOpaque(),
- viewNotReady, 0);
- if (0 == ctx) {
- if(DEBUG) {
- System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
- }
- return 0;
- }
+ private OffscreenLayerSurface backingLayerHost = null;
+ private long nsOpenGLLayer = 0;
+ private long nsOpenGLLayerPFmt = 0;
+ private float screenVSyncTimeout; // microSec
+ private int vsyncTimeout; // microSec - for nsOpenGLLayer mode
+ private int lastWidth=0, lastHeight=0; // allowing to detect size change
+ private long lastPBufferHandle = 0; // allowing to detect pbuffer recreation
+
+ @Override
+ public boolean isNSContext() { return true; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ final NativeSurface surface = drawable.getNativeSurface();
+ final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final long nsViewHandle;
+ final boolean isPBuffer;
+ final boolean isFBO;
+ if(drawable instanceof GLFBODrawableImpl) {
+ nsViewHandle = 0;
+ isPBuffer = false;
+ isFBO = true;
+ if(DEBUG) {
+ System.err.println("NS create GLFBODrawableImpl drawable: isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else if(drawable instanceof MacOSXCGLDrawable) {
+ // we allow null here! (special pbuffer case)
+ nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawable.getHandle());
+ isFBO = false;
+ if(DEBUG) {
+ System.err.println("NS create MacOSXCGLDrawable drawable handle isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else {
+ // we only allow a valid NSView here
+ final long drawableHandle = drawable.getHandle();
+ final boolean isNSView = OSXUtil.isNSView(drawableHandle);
+ final boolean isNSWindow = OSXUtil.isNSWindow(drawableHandle);
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawableHandle);
+ isFBO = false;
- if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) {
- // Set the context opacity
- CGL.setContextOpacity(ctx, 0);
+ if(DEBUG) {
+ System.err.println("NS create Anonymous drawable handle "+toHexString(drawableHandle)+": isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ if( isNSView ) {
+ nsViewHandle = drawableHandle;
+ } else if( isNSWindow ) {
+ nsViewHandle = OSXUtil.GetNSView(drawableHandle);
+ } else if( isPBuffer ) {
+ nsViewHandle = 0;
+ } else {
+ throw new RuntimeException("Anonymous drawable instance's handle neither NSView, NSWindow nor PBuffer: "+toHexString(drawableHandle)+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
}
+ backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ boolean allowIncompleteView = null != backingLayerHost;
+ if( !allowIncompleteView && surface instanceof ProxySurface ) {
+ allowIncompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+ }
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ if(DEBUG) {
+ System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
+ }
+ return 0;
+ }
GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
- fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
- if(!fixedCaps.isPBuffer()) {
+ if(chosenCaps.isOnscreen() || !fixedCaps.isPBuffer()) {
// not handled, so copy them
fixedCaps.setFBO(chosenCaps.isFBO());
+ fixedCaps.setPBuffer(chosenCaps.isPBuffer());
fixedCaps.setBitmap(chosenCaps.isBitmap());
fixedCaps.setOnscreen(chosenCaps.isOnscreen());
}
- config.setChosenCapabilities(fixedCaps);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ int sRefreshRate = OSXUtil.GetScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
+ screenVSyncTimeout = 1000000f / sRefreshRate;
if(DEBUG) {
+ System.err.println("NS create OSX>=lion "+isLionOrLater);
+ System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create drawable type: "+drawable.getClass().getName());
+ System.err.println("NS create drawable handle: isPBuffer "+isPBuffer+", isFBO "+isFBO);
+ System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+ System.err.println("NS create chosenCaps: "+chosenCaps);
System.err.println("NS create fixedCaps: "+fixedCaps);
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
+ System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
+ // Thread.dumpStack();
}
if(fixedCaps.isPBuffer()) {
- // Must now associate the pbuffer with our newly-created context
- CGL.setContextPBuffer(ctx, drawable.getHandle());
+ if(!isPBuffer) {
+ throw new InternalError("fixedCaps is PBuffer, handle not: "+drawable);
+ }
+ } else {
+ if(isPBuffer) {
+ throw new InternalError("handle is PBuffer, fixedCaps not: "+drawable);
+ }
}
- //
- // handled layered surface
- //
+ config.setChosenCapabilities(fixedCaps);
+ /**
if(null != backingLayerHost) {
- nsOpenGLLayerPFmt = pixelFormat;
- pixelFormat = 0;
- final int texWidth, texHeight;
- if(drawable instanceof MacOSXPbufferCGLDrawable) {
- final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
- texWidth = osxPDrawable.getTextureWidth();
- texHeight = osxPDrawable.getTextureHeight();
- } else {
- texWidth = drawable.getWidth();
- texHeight = drawable.getHeight();
+ backingLayerHost.setChosenCapabilities(fixedCaps);
+ } */
+
+ try {
+ int[] viewNotReady = new int[1];
+ // Try to allocate a context with this
+ ctx = CGL.createContext(share,
+ nsViewHandle, allowIncompleteView,
+ pixelFormat,
+ chosenCaps.isBackgroundOpaque(),
+ viewNotReady, 0);
+ if (0 == ctx) {
+ if(DEBUG) {
+ System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
+ }
+ return 0;
}
- if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) {
- throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if(null != backingLayerHost) {
+ nsOpenGLLayerPFmt = pixelFormat;
+ pixelFormat = 0;
}
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if (chosenCaps.isOnscreen() && !chosenCaps.isBackgroundOpaque()) {
+ // Set the context opacity
+ CGL.setContextOpacity(ctx, 0);
+ }
+ } finally {
+ if(0!=pixelFormat) {
+ CGL.deletePixelFormat(pixelFormat);
+ pixelFormat = 0;
}
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
- }
- } finally {
- if(0!=pixelFormat) {
- CGL.deletePixelFormat(pixelFormat);
- }
- }
- return ctx;
- }
-
- @Override
- public boolean destroy(long ctx) {
- if(0 != nsOpenGLLayer) {
- final NativeSurface surface = drawable.getNativeSurface();
- if (DEBUG) {
- System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
- }
- final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
- if(null != ols && ols.isSurfaceLayerAttached()) {
- // still having a valid OLS attached to surface (parent OLS could have been removed)
- ols.detachSurfaceLayer();
}
- CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
- CGL.deletePixelFormat(nsOpenGLLayerPFmt);
- nsOpenGLLayerPFmt = 0;
- nsOpenGLLayer = 0;
+ return ctx;
}
- return CGL.deleteContext(ctx, true);
- }
-
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.copyContext(contextHandle, src, mask);
- return true;
- }
- @Override
- public boolean makeCurrent(long ctx) {
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+ @Override
+ public boolean destroy(long ctx) {
+ lastPBufferHandle = 0;
+ return CGL.deleteContext(ctx, true);
}
- int err = CGL.CGLLockContext(cglCtx);
- if(CGL.kCGLNoError == err) {
- return CGL.makeCurrentContext(ctx);
- } else if(DEBUG) {
- System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean contextRealized(boolean realized) {
+ if( realized ) {
+ if( null != backingLayerHost ) {
+ //
+ // handled layered surface
+ //
+ final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+ final long ctx = MacOSXCGLContext.this.getHandle();
+ final int texID;
+ final long drawableHandle = drawable.getHandle();
+ if(drawable instanceof GLFBODrawableImpl) {
+ final GLFBODrawableImpl fbod = (GLFBODrawableImpl)drawable;
+ texID = fbod.getTextureBuffer(GL.GL_FRONT).getName();
+ fbod.setSwapBufferContext(new GLFBODrawableImpl.SwapBufferContext() {
+ public void swapBuffers(boolean doubleBuffered) {
+ MacOSXCGLContext.NSOpenGLImpl.this.swapBuffers();
+ } } ) ;
+ lastPBufferHandle = 0;
+ } else if( chosenCaps.isPBuffer() && CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+ texID = 0;
+ lastPBufferHandle = drawableHandle;
+ } else {
+ throw new GLException("BackingLayerHost w/ unknown handle (!FBO, !PBuffer): "+drawable);
+ }
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(0>=lastWidth || 0>=lastHeight || !drawable.isRealized()) {
+ throw new GLException("Drawable not realized yet or invalid texture size, texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, lastPBufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(lastPBufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
+ } else {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ }
+ } else {
+ if( 0 != nsOpenGLLayer ) {
+ final NativeSurface surface = drawable.getNativeSurface();
+ if (DEBUG) {
+ System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", "+drawable);
+ }
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ if(null != ols && ols.isSurfaceLayerAttached()) {
+ // still having a valid OLS attached to surface (parent OLS could have been removed)
+ ols.detachSurfaceLayer();
+ }
+ CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+ nsOpenGLLayer = 0;
+ }
+ if(0 != nsOpenGLLayerPFmt) {
+ CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+ nsOpenGLLayerPFmt = 0;
+ }
+ lastPBufferHandle = 0;
+ }
+ backingLayerHost = null;
+ return true;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ private final void validatePBufferConfig(long ctx) {
+ final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+ final long drawableHandle = drawable.getHandle();
+ if(chosenCaps.isPBuffer() && CGL.isNSOpenGLPixelBuffer(drawableHandle) && lastPBufferHandle != drawableHandle) {
+ // Must associate the pbuffer with our newly-created context
+ lastPBufferHandle = drawableHandle;
+ if(0 != drawableHandle) {
+ CGL.setContextPBuffer(ctx, drawableHandle);
+ }
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig bind pbuffer "+toHexString(drawableHandle)+" -> ctx "+toHexString(ctx));
+ }
}
}
- final boolean res = CGL.clearCurrentContext(ctx);
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+
+ /** Returns true if size has been updated, otherwise false (same size). */
+ private final boolean validateDrawableSizeConfig(long ctx) {
+ final int width = drawable.getWidth();
+ final int height = drawable.getHeight();
+ if( lastWidth != width || lastHeight != height ) {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig size changed");
+ }
+ return true;
+ }
+ return false;
}
- final int err = CGL.CGLUnlockContext(cglCtx);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.copyContext(contextHandle, src, mask);
+ return true;
}
- return res && CGL.kCGLNoError == err;
- }
- @Override
- public boolean setSwapInterval(int interval) {
- if(0 != nsOpenGLLayer) {
- CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
- vsyncTimeout = interval * (int)screenVSyncTimeout;
- if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
+ @Override
+ public boolean makeCurrent(long ctx) {
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ int err = CGL.CGLLockContext(cglCtx);
+ if(CGL.kCGLNoError == err) {
+ validatePBufferConfig(ctx); // required to handle pbuffer change ASAP
+ return CGL.makeCurrentContext(ctx);
+ } else if(DEBUG) {
+ System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
+ }
+ final boolean res = CGL.clearCurrentContext(ctx);
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final int err = CGL.CGLUnlockContext(cglCtx);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return res && CGL.kCGLNoError == err;
}
- CGL.setSwapInterval(contextHandle, interval);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- if( 0 != nsOpenGLLayer ) {
- // If v-sync is disabled, frames will be drawn as quickly as possible
- // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
- CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ @Override
+ public boolean detachPBuffer() {
+ if(0 != lastPBufferHandle) {
+ lastPBufferHandle = 0;
+ if(0 != nsOpenGLLayer) {
+ CGL.flushNSOpenGLLayerPBuffer(nsOpenGLLayer); // notify invalid pbuffer
+ }
+ // CGL.setContextPBuffer(contextHandle, 0); // doesn't work, i.e. not taking nil
+ }
+ return true;
}
- if(CGL.flushBuffer(contextHandle)) {
+
+ @Override
+ public boolean setSwapInterval(int interval) {
if(0 != nsOpenGLLayer) {
- // trigger CALayer to update
- CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+ CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+ vsyncTimeout = interval * (int)screenVSyncTimeout + 1000; // +1ms
+ if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
}
+ CGL.setSwapInterval(contextHandle, interval);
return true;
}
- return false;
- }
+
+ private int skipSync=0;
+
+ @Override
+ public boolean swapBuffers() {
+ final boolean res;
+ if( 0 != nsOpenGLLayer ) {
+ if( validateDrawableSizeConfig(contextHandle) ) {
+ // skip wait-for-vsync for a few frames if size has changed,
+ // allowing to update the texture IDs ASAP.
+ skipSync = 10;
+ }
+
+ final int texID;
+ final boolean valid;
+ if(drawable instanceof GLFBODrawableImpl) {
+ texID = ((GLFBODrawableImpl)drawable).getTextureBuffer(GL.GL_FRONT).getName();
+ valid = 0 != texID;
+ } else {
+ texID = 0;
+ valid = 0 != lastPBufferHandle;
+ }
+ if(valid) {
+ if(0 == skipSync) {
+ // If v-sync is disabled, frames will be drawn as quickly as possible
+ // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
+ CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ } else {
+ skipSync--;
+ }
+ res = CGL.flushBuffer(contextHandle);
+ if(res) {
+ // trigger CALayer to update incl. possible surface change
+ CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer, lastPBufferHandle, texID, lastWidth, lastHeight);
+ }
+ } else {
+ res = true;
+ }
+ } else {
+ res = CGL.flushBuffer(contextHandle);
+ }
+ return res;
+ }
+
}
class CGLImpl implements GLBackendImpl {
- @Override
- public boolean isNSContext() { return false; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
- }
- config.setChosenPixelFormat(pixelFormat);
- try {
- // Create new context
- PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
- if (DEBUG) {
- System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ @Override
+ public boolean isNSContext() { return false; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
}
- int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
- if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while creating context");
- }
- if(chosenCaps.isPBuffer()) {
- // Attach newly-created context to the pbuffer
- res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0);
+ try {
+ // Create new context
+ PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
+ if (DEBUG) {
+ System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ }
+ int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ throw new GLException("Error code " + res + " while creating context");
}
- }
- ctx = ctxPB.get(0);
- if(0!=ctx) {
- if(DEBUG) {
- GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
- System.err.println("NS created: "+caps0);
+ ctx = ctxPB.get(0);
+
+ if (0 != ctx) {
+ GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ if(chosenCaps.isOnscreen() || !fixedCaps.isPBuffer()) {
+ // not handled, so copy them
+ fixedCaps.setFBO(chosenCaps.isFBO());
+ fixedCaps.setPBuffer(chosenCaps.isPBuffer());
+ fixedCaps.setBitmap(chosenCaps.isBitmap());
+ fixedCaps.setOnscreen(chosenCaps.isOnscreen());
+ }
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("CGL create fixedCaps: "+fixedCaps);
+ }
+ if(fixedCaps.isPBuffer()) {
+ // Must now associate the pbuffer with our newly-created context
+ res = CGL.CGLSetPBuffer(ctx, drawable.getHandle(), 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ }
+ }
}
+ } finally {
+ CGL.CGLDestroyPixelFormat(pixelFormat);
}
- } finally {
- CGL.CGLDestroyPixelFormat(pixelFormat);
+ return ctx;
}
- return ctx;
- }
- @Override
- public boolean destroy(long ctx) {
- return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
- }
+ @Override
+ public boolean destroy(long ctx) {
+ return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
+ }
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.CGLCopyContext(src, contextHandle, mask);
- return true;
- }
+ @Override
+ public boolean contextRealized(boolean realized) {
+ return true;
+ }
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.CGLCopyContext(src, contextHandle, mask);
+ return true;
+ }
- @Override
- public boolean makeCurrent(long ctx) {
- int err = CGL.CGLLockContext(ctx);
- if(CGL.kCGLNoError == err) {
- err = CGL.CGLSetCurrentContext(ctx);
+ @Override
+ public boolean makeCurrent(long ctx) {
+ int err = CGL.CGLLockContext(ctx);
if(CGL.kCGLNoError == err) {
- return true;
+ err = CGL.CGLSetCurrentContext(ctx);
+ if(CGL.kCGLNoError == err) {
+ return true;
+ } else if(DEBUG) {
+ System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ }
} else if(DEBUG) {
- System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
}
- } else if(DEBUG) {
- System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ return false;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
}
+ int err = CGL.CGLSetCurrentContext(0);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ int err2 = CGL.CGLUnlockContext(ctx);
+ if(DEBUG && CGL.kCGLNoError != err2) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ }
+ return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
+ }
+
+ @Override
+ public boolean detachPBuffer() {
+ /* Doesn't work, i.e. not taking NULL
+ final int res = CGL.CGLSetPBuffer(contextHandle, 0, 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while detaching context from pbuffer");
+ } */
+ return true;
}
- int err = CGL.CGLSetCurrentContext(0);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean setSwapInterval(int interval) {
+ int[] lval = new int[] { interval } ;
+ CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
+ return true;
}
- int err2 = CGL.CGLUnlockContext(ctx);
- if(DEBUG && CGL.kCGLNoError != err2) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ @Override
+ public boolean swapBuffers() {
+ return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
}
- return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
- }
-
- @Override
- public boolean setSwapInterval(int interval) {
- int[] lval = new int[] { interval } ;
- CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
- }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index af767f0c3..cc727c8e1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -42,10 +42,10 @@ package jogamp.opengl.macosx.cgl;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -92,7 +92,7 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
this.id = id;
}
}
- private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
+ /* pp */ List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
@@ -110,26 +110,42 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
}
- protected void registerContext(MacOSXCGLContext ctx) {
+ @Override
+ protected void associateContext(GLContext ctx, boolean bound) {
// NOTE: we need to keep track of the created contexts in order to
// implement swapBuffers() because of how Mac OS X implements its
// OpenGL window interface
synchronized (createdContexts) {
- createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
- }
+ if(bound) {
+ createdContexts.add(new WeakReference<MacOSXCGLContext>((MacOSXCGLContext)ctx));
+ } else {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext _ctx = ref.get();
+ if( _ctx == null || _ctx == ctx) {
+ createdContexts.remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
}
+
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- synchronized (createdContexts) {
- for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
- WeakReference<MacOSXCGLContext> ref = iter.next();
- MacOSXCGLContext ctx = ref.get();
- if (ctx != null) {
- ctx.swapBuffers();
- } else {
- iter.remove();
- }
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ synchronized (createdContexts) {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.swapBuffers();
+ i++;
+ } else {
+ createdContexts.remove(i);
+ }
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 591fafc68..e174d38f4 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -51,7 +51,7 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -61,7 +61,8 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.macosx.OSXDummyUpstreamSurfaceHook;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -71,7 +72,7 @@ import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.opengl.GLExtensions;
@@ -320,9 +321,14 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!caps.isPBuffer()) {
+ // Actual implementation is using PBuffer ...
+ final GLCapabilities modCaps = (GLCapabilities) caps.cloneMutable();
+ modCaps.setPBuffer(true);
+ modCaps.setBitmap(false);
+ config.setChosenCapabilities(modCaps);
return new MacOSXOffscreenCGLDrawable(this, target);
}
return new MacOSXPbufferCGLDrawable(this, target);
@@ -336,7 +342,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final MacOSXGraphicsDevice device;
if(createNewDevice) {
device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
@@ -348,68 +354,23 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser,
+ new OSXDummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- long nsWindow = 0;
- @Override
- public final void create(ProxySurface s) {
- if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
- nsWindow = OSXUtil.CreateNSWindow(0, 0, s.getWidth(), s.getHeight());
- if(0 == nsWindow) {
- throw new GLException("Error NS window 0");
- }
- long nsView = OSXUtil.GetNSView(nsWindow);
- if(0 == nsView) {
- throw new GLException("Error NS view 0");
- }
- s.setSurfaceHandle(nsView);
- s.setImplBitfield(ProxySurface.INVISIBLE_WINDOW);
- if(DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if(0 != nsWindow && 0 != s.getSurfaceHandle()) {
- OSXUtil.DestroyNSWindow(nsWindow);
- nsWindow = 0;
- s.setSurfaceHandle(0);
- if(DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
-
- @Override
- public String toString() {
- return "MacOSXLSurfaceLifecycleHook[]";
- }
-
- };
@Override
protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
final MacOSXGraphicsDevice device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true);
- return new WrappedSurface(config, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(config, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 149927160..8866c7ce6 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -51,23 +51,16 @@ import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
- long pixelformat;
MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen,
- GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- long pixelformat) {
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested) {
super(screen, capsChosen, capsRequested);
- this.pixelformat=pixelformat;
}
public Object clone() {
return super.clone();
}
- void setChosenPixelFormat(long pixelformat) {
- this.pixelformat=pixelformat;
- }
-
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) {
MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device);
if(null == sharedResource) {
@@ -114,11 +107,11 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
break;
case CGL.kCGLPFAColorFloat:
- ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
+ ivalues[idx] = ( !caps.isOnscreen() && caps.isPBuffer() && caps.getPbufferFloatingPointBuffers() ) ? 1 : 0;
break;
case CGL.NSOpenGLPFAPixelBuffer:
- ivalues[idx] = caps.isPBuffer() ? 1 : 0;
+ ivalues[idx] = ( !caps.isOnscreen() && caps.isPBuffer() ) ? 1 : 0;
break;
case CGL.NSOpenGLPFADoubleBuffer:
@@ -188,11 +181,11 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
attrs[i++] = CGL.kCGLPFAOpenGLProfile;
attrs[i++] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor);
}
- if(caps.isPBuffer()) {
+ if(!caps.isOnscreen() && caps.isPBuffer()) {
attrs[i++] = CGL.kCGLPFAPBuffer;
- }
- if (caps.getPbufferFloatingPointBuffers()) {
- attrs[i++] = CGL.kCGLPFAColorFloat;
+ if (caps.getPbufferFloatingPointBuffers()) {
+ attrs[i++] = CGL.kCGLPFAColorFloat;
+ }
}
if (caps.getDoubleBuffered()) {
attrs[i++] = CGL.kCGLPFADoubleBuffer;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index 13faf7090..43a9d0d1a 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -96,6 +96,6 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(device) );
- return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, 0);
+ return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 6be9e386d..65ed5fc15 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -49,8 +49,8 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextShareSet;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -62,7 +62,6 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) {
super(drawable, null);
setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
- drawable.registerContext(this);
this.contextHandle = handle;
GLContextShareSet.contextCreated(this);
setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT);
@@ -108,13 +107,13 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
}
AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
- MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat);
+ MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps);
if(0 == currentDrawable) {
// set a fake marker stating a valid drawable
currentDrawable = 1;
}
- WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, null);
+ WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, true);
return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
index b1e283ebc..ec9628004 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -52,9 +52,7 @@ public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
@Override
public GLContext createContext(GLContext shareWith) {
- final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
- registerContext(ctx);
- return ctx;
+ return new MacOSXOnscreenCGLContext(this, shareWith);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
index 88886ddd2..7e2d8cf10 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -39,6 +39,7 @@ import javax.media.opengl.GLPbuffer;
import jogamp.opengl.GLContextImpl;
+@SuppressWarnings("deprecation")
public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
// State for render-to-texture and render-to-texture-rectangle support
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 8f2f386af..668e463a2 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -40,6 +40,8 @@
package jogamp.opengl.macosx.cgl;
+import java.lang.ref.WeakReference;
+
import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.MutableSurface;
@@ -70,9 +72,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
// private int texture; // actual texture object
- // Note that we can not store this in the NativeSurface because the
- // semantic is that contains an NSView
- protected long pBuffer;
protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight;
public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) {
@@ -90,9 +89,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
@Override
public GLContext createContext(GLContext shareWith) {
- final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith);
- registerContext(ctx);
- return ctx;
+ return new MacOSXPbufferCGLContext(this, shareWith);
}
@Override
@@ -101,27 +98,34 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
return 0;
}
- @Override
- public long getHandle() {
- return pBuffer;
- }
-
protected int getTextureTarget() { return pBufferTexTarget; }
protected int getTextureWidth() { return pBufferTexWidth; }
protected int getTextureHeight() { return pBufferTexHeight; }
protected void destroyPbuffer() {
- if (this.pBuffer != 0) {
- NativeSurface ns = getNativeSurface();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final long pBuffer = ms.getSurfaceHandle();
+ if (0 != pBuffer) {
+ synchronized (createdContexts) {
+ for(int i=0; i<createdContexts.size(); ) {
+ final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
+ final MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.detachPBuffer();
+ i++;
+ } else {
+ createdContexts.remove(i);
+ }
+ }
+ }
impl.destroy(pBuffer);
- this.pBuffer = 0;
- ((MutableSurface)ns).setSurfaceHandle(0);
+ ms.setSurfaceHandle(0);
}
}
private void createPbuffer() {
- final NativeSurface ns = getNativeSurface();
- final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ms.getGraphicsConfiguration();
final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
final GLProfile glProfile = capabilities.getGLProfile();
MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
@@ -161,7 +165,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
}
}
- pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
+ final long pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
if(DEBUG) {
System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+
", pbufferSize "+getWidth()+"x"+getHeight()+
@@ -174,7 +178,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
}
- ((MutableSurface)ns).setSurfaceHandle(pBuffer);
+ ms.setSurfaceHandle(pBuffer);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index 96c1187d3..f6cc2956d 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -50,8 +50,8 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextShareSet;
@@ -102,7 +102,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg);
}
}
- return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null)), ctx, cfg);
+ return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true)), ctx, cfg);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
index 15bd005dc..f8c237c9e 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -49,10 +49,10 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.GDIUtil;
-import com.jogamp.nativewindow.WrappedSurface;
public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
@@ -72,7 +72,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
- return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null));
+ return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, true));
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index ca7886e7f..3b3f0c123 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -73,27 +73,28 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
}
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- final long t0;
- if (PROFILING) {
- t0 = System.currentTimeMillis();
- } else {
- t0 = 0;
- }
-
- if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
- throw new GLException("Error swapping buffers");
- }
-
- if (PROFILING) {
- profilingSwapBuffersTime += System.currentTimeMillis() - t0;
- if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
- System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" +
- ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
- profilingSwapBuffersTime = 0;
- profilingSwapBuffersTicks = 0;
- }
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final long t0;
+ if (PROFILING) {
+ t0 = System.currentTimeMillis();
+ } else {
+ t0 = 0;
+ }
+
+ if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
+ throw new GLException("Error swapping buffers");
+ }
+
+ if (PROFILING) {
+ profilingSwapBuffersTime += System.currentTimeMillis() - t0;
+ if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
+ profilingSwapBuffersTime = 0;
+ profilingSwapBuffersTicks = 0;
+ }
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 7ea487523..91d5c225a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -52,7 +52,7 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -62,9 +62,10 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIDummyUpstreamSurfaceHook;
import jogamp.nativewindow.windows.GDISurface;
-import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.RegisteredClassFactory;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
import jogamp.opengl.GLContextImpl;
@@ -79,7 +80,6 @@ import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.opengl.GLExtensions;
@@ -541,7 +541,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final WindowsGraphicsDevice device;
if(createNewDevice) {
device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
@@ -553,7 +553,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
@Override
@@ -571,57 +571,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen);
}
- return new GDISurface(config, 0, width, height, dummySurfaceLifecycleHook);
- }
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- final GDISurface ms = (GDISurface)s;
- if(0 == ms.getWindowHandle()) {
- final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, s.getWidth(), s.getHeight());
- if(0 == windowHandle) {
- throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
- }
- ms.setWindowHandle(windowHandle);
- if(DEBUG) {
- System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.create: "+ms);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- final GDISurface ms = (GDISurface)s;
- if(0 != ms.getWindowHandle()) {
- GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
- GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
- ms.setWindowHandle(0);
- if(DEBUG) {
- System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+ms);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
-
- @Override
- public String toString() {
- return "GDISurfaceLifecycleHook[]";
- }
- };
-
+ return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice);
+ }
@Override
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
final WindowsGraphicsDevice device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
- return new GDISurface(cfg, windowHandle, 0, 0, upstream);
+ return new GDISurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 4d1069e6b..058f4e336 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -107,7 +107,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if(hasARB) {
caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
} else {
- caps = PFD2GLCapabilities(glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
+ caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
}
if(null==caps) {
throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+
@@ -325,7 +325,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID +
" of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
}
- return AttribList2GLCapabilities(glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
+ return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
}
static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device,
@@ -390,7 +390,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
for(int i = 0; i<numFormats; i++) {
if ( pfdIDs[i] >= 1 &&
((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
- final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
if(null != caps) {
bucket.add(caps);
if(DEBUG) {
@@ -398,7 +398,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> "+j+"]: "+caps);
}
} else if(DEBUG) {
- GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS);
+ GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS);
System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
}
} else if (DEBUG) {
@@ -616,9 +616,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return val;
}
- static WGLGLCapabilities AttribList2GLCapabilities(final GLProfile glp,
- final long hdc, final int pfdID, final int[] iattribs,
- final int niattribs, final int[] iresults, final int winattrmask) {
+ static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device,
+ final GLProfile glp, final long hdc, final int pfdID,
+ final int[] iattribs, final int niattribs, final int[] iresults, final int winattrmask) {
final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
@@ -637,7 +637,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByARB(iattribs, niattribs, iresults);
- return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
//
@@ -672,7 +672,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return val;
}
- static WGLGLCapabilities PFD2GLCapabilities(final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
if(null == pfd) {
return null;
@@ -689,21 +689,22 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByGDI();
- return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits );
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
- static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(final GLProfile glp, final long hdc, final int pfdID) {
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID) {
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
- return PFD2GLCapabilitiesNoCheck(glp, pfd, pfdID);
+ return PFD2GLCapabilitiesNoCheck(device, glp, pfd, pfdID);
}
- static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) {
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) {
if(null == pfd) {
return null;
}
final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByGDI();
- return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, PFD2DrawableTypeBits(pfd));
+
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, PFD2DrawableTypeBits(pfd), res);
}
static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 41c9bba02..d2d1dafc8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -113,13 +113,14 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) {
- WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
if(null == sharedResource) {
throw new GLException("Shared resource for device n/a: "+device);
}
- GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
- GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- GLContext sharedContext = sharedResource.getContext();
+ final GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
+ final GLContext sharedContext = sharedResource.getContext();
+ final GLProfile glp = GLProfile.getDefault(device);
+
List<GLCapabilitiesImmutable> availableCaps = null;
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -135,10 +136,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
throw new GLException("Error: HDC is null");
}
if (sharedResource.hasARBPixelFormat()) {
- availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), capsChosen.getGLProfile(), hdc);
+ availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), glp, hdc);
}
if( null == availableCaps || availableCaps.isEmpty() ) {
- availableCaps = getAvailableGLCapabilitiesGDI(device, capsChosen.getGLProfile(), hdc);
+ availableCaps = getAvailableGLCapabilitiesGDI(device, glp, hdc);
}
} finally {
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -165,7 +166,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
int numFormats = pformats.length;
List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(numFormats);
for (int i = 0; i < numFormats; i++) {
- final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
if(null != caps) {
bucket.add(caps);
}
@@ -439,7 +440,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc,
boolean extHDC, int[] pformats) {
GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- if(capsChosen.isPBuffer()) {
+ if( !capsChosen.isOnscreen() && capsChosen.isPBuffer() ) {
if (DEBUG) {
System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen);
}
@@ -454,6 +455,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
System.err.println("updateGraphicsConfigurationGDI: capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString());
}
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
int pfdID; // chosen or preset PFD ID
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
@@ -468,7 +470,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + pfdID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, winattrmask);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
if(null == pixelFormatCaps) {
throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+pfdID);
}
@@ -480,7 +482,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
for (int i = 0; i < pformats.length; i++) {
- final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], winattrmask);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], winattrmask);
if(null != caps) {
availableCaps.add(caps);
if(DEBUG) {
@@ -488,7 +490,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps);
}
} else if(DEBUG) {
- GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(glProfile, hdc, pformats[i]);
+ GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, hdc, pformats[i]);
System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped);
}
}
@@ -505,8 +507,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
recommendedIndex--)
{ /* nop */ }
if(DEBUG && 0 > recommendedIndex) {
- final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(glProfile, pfd, pfdID);
- final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, winattrmask);
+ final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(device, glProfile, pfd, pfdID);
+ final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pfdID, winattrmask);
System.err.println("Chosen PFDID "+pfdID+", but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index 1f3edbd8a..03a0eefbf 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -48,10 +48,10 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextShareSet;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11ExternalGLXContext extends X11GLXContext {
@@ -105,7 +105,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
}
- final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, null);
+ final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, true);
return new X11ExternalGLXContext(new Drawable(factory, ns), ctx);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index 8652e2d4a..ac78c6f4a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -45,7 +45,8 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import com.jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.WrappedSurface;
+
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -87,7 +88,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")");
}
}
- return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, null));
+ return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, true));
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index e9912ce9d..8c642777d 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -69,9 +69,10 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
}
@Override
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ }
}
//---------------------------------------------------------------------------
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index bc3e5b793..fb11f8bba 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -49,7 +49,7 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
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 javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -59,6 +59,8 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.x11.X11DummyUpstreamSurfaceHook;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -70,7 +72,6 @@ import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
import com.jogamp.common.util.VersionNumber;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -505,7 +506,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
final X11GraphicsDevice device;
if(createNewDevice) {
// Null X11 locking, due to private non-shared Display handle
@@ -518,65 +519,15 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface( config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
}
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- if( 0 == s.getSurfaceHandle() ) {
- final X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
- final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
- final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
- if(0 == device.getHandle()) {
- device.open();
- s.setImplBitfield(ProxySurface.OWN_DEVICE);
- }
- final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), s.getWidth(), s.getHeight());
- if(0 == windowHandle) {
- throw new GLException("Creating dummy window failed w/ "+cfg+", "+s.getWidth()+"x"+s.getHeight());
- }
- s.setSurfaceHandle(windowHandle);
- if(DEBUG) {
- System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if(0 != s.getSurfaceHandle()) {
- final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
- final X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
- X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
- s.setSurfaceHandle(0);
- if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
- device.close();
- }
- if(DEBUG) {
- System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
- @Override
- public String toString() {
- return "X11SurfaceLifecycleHook[]";
- }
- };
-
@Override
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
@@ -593,7 +544,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if(DEBUG) {
System.err.println("X11GLXDrawableFactory.createProxySurfaceImpl 0x"+Long.toHexString(windowHandle)+": "+cfg);
}
- return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index 866fcbbe4..96c3c4123 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -307,7 +307,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return null; // no RGBA -> color index not supported
}
- X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
+ final X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
if (isMultisampleAvailable) {
res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
@@ -342,7 +342,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
} catch (Exception e) {}
- return (X11GLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
private static String glXGetFBConfigErrorCode(int err) {
@@ -462,7 +462,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
- return (X11GLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, res);
}
private static String glXGetConfigErrorCode(int err) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 8086cd26a..431706e24 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -129,9 +129,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice());
- final X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
- final GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- final GLProfile glp = capsChosen.getGLProfile();
+ final GLProfile glp = GLProfile.getDefault(device);
List<GLCapabilitiesImmutable> availableCaps = null;
@@ -217,7 +215,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(x11Device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(x11Device) );
- boolean usePBuffer = capsChosen.isPBuffer();
+ boolean usePBuffer = !capsChosen.isOnscreen() && capsChosen.isPBuffer();
X11GLXGraphicsConfiguration res = null;
if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index e1fe2f27e..bba2b3513 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -81,10 +81,11 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
private void createPbuffer() {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration();
- AbstractGraphicsScreen aScreen = config.getScreen();
- AbstractGraphicsDevice aDevice = aScreen.getDevice();
- long display = aDevice.getHandle();
+ final MutableSurface ms = (MutableSurface) getNativeSurface();
+ final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ms.getGraphicsConfiguration();
+ final AbstractGraphicsScreen aScreen = config.getScreen();
+ final AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ final long display = aDevice.getHandle();
if (DEBUG) {
System.out.println("Pbuffer config: " + config);
@@ -94,8 +95,6 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
throw new GLException("Null display");
}
- NativeSurface ns = getNativeSurface();
-
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
if (chosenCaps.getPbufferRenderToTexture()) {
@@ -111,9 +110,9 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
int[] iattributes = new int[7];
iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
- iattributes[niattribs++] = ns.getWidth();
+ iattributes[niattribs++] = ms.getWidth();
iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
- iattributes[niattribs++] = ns.getHeight();
+ iattributes[niattribs++] = ms.getHeight();
iattributes[niattribs++] = GLX.GLX_LARGEST_PBUFFER; // exact
iattributes[niattribs++] = 0;
iattributes[niattribs++] = 0;
@@ -125,7 +124,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
// Set up instance variables
- ((MutableSurface)ns).setSurfaceHandle(pbuffer);
+ ms.setSurfaceHandle(pbuffer);
if (DEBUG) {
System.err.println("Created pbuffer " + this);