From 4dd44b985fe0541be3a3bcd9045d201ed3ca2cc5 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sat, 15 Sep 2012 16:54:52 +0200
Subject: 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].
---
src/jogl/classes/jogamp/opengl/GLDrawableImpl.java | 80 +++++++++++++++-------
1 file changed, 54 insertions(+), 26 deletions(-)
(limited to 'src/jogl/classes/jogamp/opengl/GLDrawableImpl.java')
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.
+ * The surface is locked.
+ *
+ * If doubleBuffered
is true
,
+ * an actual platform dependent surface swap shall be executed.
+ *
+ *
+ * If doubleBuffered
is false
,
+ * {@link GL#glFlush()} has been called already and
+ * the implementation may execute implementation specific code.
+ *
+ */
+ 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 realized
is true
, the context has just been created and made current.
*
*
- * If realized
is false
, the context is still current and will be release and destroyed after this method returns.
+ * If realized
is false
, the context is still current and will be released and destroyed after this method returns.
*
*
* @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: makeCurrent
, release
.
*
- * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
- *
- *
* If current
is true
, the context has just been made current.
*
*
* If current
is false
, the context is still current and will be release after this method returns.
*
+ *
+ * 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)}.
+ *
* @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 true
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() {
--
cgit v1.2.3