summaryrefslogtreecommitdiffstats
path: root/src/newt/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/newt/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/newt/classes/jogamp')
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java31
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java34
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/WindowDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java24
4 files changed, 39 insertions, 52 deletions
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index ba98ca3af..c6c1814f6 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -39,20 +39,16 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
public class OffscreenWindow extends WindowImpl implements MutableSurface {
- long surfaceHandle = 0;
- ProxySurface.UpstreamSurfaceHook upstreamHook;
- ProxySurface dummySurface;
+ long surfaceHandle;
public OffscreenWindow() {
- upstreamHook = null;
- dummySurface = null;
+ surfaceHandle = 0;
}
static long nextWindowHandle = 0x100; // start here - a marker
@@ -62,17 +58,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
throw new NativeWindowException("Capabilities is onscreen");
}
final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- /** Cannot use OpenGL here ..
- if(capsRequested instanceof GLCapabilitiesImmutable) {
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested;
- if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) {
- final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile());
- final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps);
- final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64);
- upstreamHook = dummySurface.getUpstreamSurfaceHook();
- dummySurface.createNotify();
- }
- } */
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice(), capsRequested).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
@@ -83,6 +68,7 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
synchronized(OffscreenWindow.class) {
setWindowHandle(nextWindowHandle++);
}
+ visibleChanged(false, true);
}
protected void closeNativeImpl() {
@@ -92,11 +78,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
@Override
public synchronized void destroy() {
super.destroy();
- if(null != dummySurface) {
- dummySurface.destroyNotify();
- dummySurface = null;
- upstreamHook = null;
- }
surfaceHandle = 0;
}
@@ -106,10 +87,6 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
@Override
public long getSurfaceHandle() {
- if(null != dummySurface) {
- return dummySurface.getSurfaceHandle();
- // return upstreamHook.getWidth();
- }
return surfaceHandle;
}
@@ -128,8 +105,8 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ sizeChanged(false, width, height, false);
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- sizeChanged(false, width, height, false);
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
} else {
/**
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index ad7195944..c1ac87d38 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -767,11 +767,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void setVisible(boolean visible) {
+ protected void setVisible(boolean wait, boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
}
- runOnEDTIfAvail(true, new VisibleAction(visible));
+ runOnEDTIfAvail(wait, new VisibleAction(visible));
+ }
+
+ public void setVisible(boolean visible) {
+ setVisible(true, visible);
}
private class SetSizeAction implements Runnable {
@@ -783,21 +787,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final void run() {
- boolean recreate = false;
final RecursiveLock _lock = windowLock;
_lock.lock();
try {
if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) {
- recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
- }
- if(recreate) {
- // will trigger visibleAction:=2 -> create if wasVisible
- final boolean wasVisible = WindowImpl.this.visible;
- screen.addReference(); // retain screen
- destroyAction.run();
- WindowImpl.this.visible = wasVisible;
+ System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
}
int visibleAction; // 0 nop, 1 invisible, 2 visible (create)
if ( isNativeValid() && 0>=width*height && visible ) {
@@ -823,9 +818,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- if(recreate) {
- screen.removeReference(); // bring back ref-count
- }
_lock.unlock();
}
}
@@ -940,11 +932,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
boolean ofs = false;
- if( null != cWin.getGraphicsConfiguration() ) {
- ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ final AbstractGraphicsConfiguration cWinCfg = cWin.getGraphicsConfiguration();
+ if( null != cWinCfg ) {
+ ofs = !cWinCfg.getChosenCapabilities().isOnscreen();
}
- if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
- ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ if( !ofs && null != pWin ) {
+ final AbstractGraphicsConfiguration pWinCfg = pWin.getGraphicsConfiguration();
+ if( null != pWinCfg ) {
+ ofs = !pWinCfg.getChosenCapabilities().isOnscreen();
+ }
}
return ofs;
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 276b0d070..f18520630 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -428,7 +428,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible());
if(isVisible()) {
- setVisible(true);
+ setVisible(false, true);
}
}
sizeChanged(false, aWidth, aHeight, false);
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index ea48569bf..d0c0b8b20 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -117,6 +117,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
}
+ @Override
public void setSurfaceHandle(long surfaceHandle) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
@@ -170,13 +171,22 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- final Point pS = getTopLevelLocationOnScreen(x, y);
- isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent());
+ final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
+ isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
+ final PointImmutable pS = isOffscreenInstance ? new Point(0, 0) : getTopLevelLocationOnScreen(x, y);
if(DEBUG_IMPLEMENTATION) {
+ final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
+ final NativeWindow pWin = getParent();
+ final AbstractGraphicsConfiguration pWinCfg = null != pWin ? pWin.getGraphicsConfiguration() : null;
System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
- ", offscreenInstance "+isOffscreenInstance+
- ", "+getReconfigureFlagsAsString(null, flags));
+ ",\n\t parent type "+(null != pWin ? pWin.getClass().getName() : null)+
+ ",\n\t this-chosenCaps "+(null != cWinCfg ? cWinCfg.getChosenCapabilities() : null)+
+ ",\n\t parent-chosenCaps "+(null != pWinCfg ? pWinCfg.getChosenCapabilities() : null)+
+ ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+
+ ", ioi: "+_isOffscreenInstance+
+ ") -> "+isOffscreenInstance+
+ "\n\t, "+getReconfigureFlagsAsString(null, flags));
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
@@ -190,7 +200,11 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
0 != ( FLAG_CHANGE_DECORATION & flags) ||
0 != ( FLAG_CHANGE_PARENTING & flags) ||
0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ if(isOffscreenInstance) {
+ createWindow(true, 0 != getWindowHandle(), pS, 64, 64, false);
+ } else {
+ createWindow(false, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ }
if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
}
if(x>=0 && y>=0) {