From 20bf031db719f7baa4c6e74734fc999061e08fe2 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Thu, 19 Jul 2012 21:15:10 +0200
Subject: Bug 599 - FBObject / Offscreen Support - Part 1

- New FBObject implementation handling FBO and it's attachments  *** API CHANGE: Util -> Core ***
  while it's size and sample-count can be reconfigured on the fly.
    - com.jogamp.opengl.util.FBObject -> com.jogamp.opengl.FBObject
    - agnostic to texture unit
    - separate attachments using OO hierarchy reflecting FBO
    - handling MSAA and blitting
    - no FBO destruction for reconfig (attach/detach)

- New GLFBODrawableImpl impl. an FBObject based GLDrawable
   - Instantiated by a dummy native surface (onscreen and invisible)
     hooked up to a dummy GLDrawable, which is the delegation for context creation.

   - Utilizies ProxySurface.UpstreamSurfaceHook for dummy surface
     avoiding specialization for native platforms.

   - TODO: Allow to utilize common surface interface as a
     dummy-surface to supporting API seperation of
     windowing/GL. The latter allows impl. of createGLDrawable(NativeSurface)
     with FBO.

- New OffscreenAutoDrawable (extends GLAutoDrawableDelegate)
  for all offscreen drawables. Shall replace GLPbuffer.

- New GLCapabilities*.isFBO() / setFBO(boolean) to request FBO offscreen,
  similar to isPBuffer(). Rule: if both are requested, FBO shall be favored.

- GLContext adds raw FBO availability query (min. FBO avail),
  FBObject contains fine grained queries (TODO: Move parts to GLContext for efficiency).

- Add framebuffer tracking, allowing fast querying:
  - GLBase/GLContext:
      public int getBoundFramebuffer(int target);
      public int getDefaultDrawFramebuffer();
      public int getDefaultReadFramebuffer();

  - GLContextImpl
      public final void setBoundFramebuffer(int target, int framebufferName)
      .. called by GL impl bind framebuffer

- GL: getDefaultDrawFramebuffer(), getDefaultReadFramebuffer()
  Adding default framebuffer queries being issued by
  GL.glBindFramebuffer(target, 0) w/ a default framebuffer, o.e. zero.
  This allows a transparent use of a custom FBO even in case the applications
  attempts to reset FBO to zero.
    Value flow: GL <- GLContext <- GLDrawable,

- GLCapabilities handle fbo/pbuffer seperate, don't disable the other

- GLContext/GL track read/write framebuffer to be queried by FBObject
  to determine whether to bind/unbind  a framebuffer

- Test cases for multiple FBO w/ and w/o MSAA

Other Features:

- New interface ProxySurface.UpstreamSurfaceHook,
  allowing to hook an upstream surface of unknown type
  providing lifecycle and information (size, ..) callbacks.
  Used for all new dummy NativeSurface impl and SWT GLCanvas.

  - GLContext -> GLDrawable propagation context/drawable lifecycle
    via ProxySurface.UpstreamSurfaceHook allowing dynamic resources
    to react (create, init, ..)
    - contextRealized()
    - contextMadeCurrent()

- SurfaceChangeable -> MutableSurface
  currently only contains setting the surface handle.

  TODO: May need to move ProxySurface.UpstreamSurfaceHook -> MutableSurface.UpstreamSurfaceHook,
        allowing other impl. classes (NEWT OffscreenWindow) to utilize the new
        upstream hookup mechanism - will allow FBO/Dummy window to work.

- SWT GLCanvas using ProxySurface.UpstreamSurfaceHook for proper size
  propagation.

- New GLAutoDrawable::getUpstreamWidget(), allowing GLEventListener
  to fetch the owning Java side UI element (NEWT, SWT, AWT, ..).

- GLDrawableFactory: Removed createOffscreenSurface() - unused and not GL related

- EGLDrawableFactory handles device/profile avail. mapping
  while actually creating context/drawable.
  This allows us to learn whether the ES context is software/hardware as well as FBO avail.

- EGLDrawable: Removed secret buckets of EGL configs :)
  Employ native surface (X11, WGL, ..) to EGL 'mapping' in
  EGLDrawableFactory utilizing new EGLUpstreamSurfaceHook (implements ProxySurface.UpstreamSurfaceHook).

Other Bugs:

- Add CTX_OPTION_DEBUG to ctx/extension cache key since only a debug ctx
  may expose the ARB debug capability.
  This bug caused lack of ARB/AMD debug functionality.

- Fix GLProfile deadlock (debug mode, w/ EGL/ES, no X11),
  dump availability information _after_ lock.

- ImmModeSink draw(): Use GL's glDrawElements(..), don't cast for GL2ES1.
  Fixes use for GL2ES2.

- Fix KeyEvent.getKeyChar() comment (-> only stable for keyTyped(..))

Misc:

- Refined alot of API doc

- New GLExtensions holds commonly used GL extension strings,
  allows better referencing and usage lookup.

- Move GL (interface) decl. to GLBase

- GLBuffers: Cleanup API doc (format, types)

- TextureIO: Add PAM and PPM static suffix identifier

- GLCapabilities getNumSamples() returns 0 if sampleBuffers is disabled, this seems to be more natural.

- finalized a lot
---
 .gitignore                                         |    5 +-
 doc/Platform.GLES.txt                              |    4 +-
 doc/TODO.txt                                       |   11 +-
 etc/test.bat                                       |    2 +-
 etc/test_dbg.bat                                   |    2 +-
 make/config/jogl/gl-common.cfg                     |   13 +
 make/config/jogl/gl-if-CustomJavaCode-gl.java      |   26 -
 .../config/jogl/gl-impl-CustomJavaCode-common.java |   53 +-
 .../jogl/gl-impl-CustomJavaCode-desktop.java       |   25 +-
 .../jogl/gl-impl-CustomJavaCode-gl2_es2.java       |    6 +-
 make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java |   56 +-
 make/config/jogl/gl-impl-CustomJavaCode-gles1.java |   66 +-
 make/config/jogl/gl-impl-CustomJavaCode-gles2.java |   63 +-
 make/scripts/java-win32-dbg.bat                    |   13 +-
 make/scripts/java-win32.bat                        |    4 +-
 make/scripts/java-win64-dbg.bat                    |   12 +-
 make/scripts/java-win64.bat                        |    3 +-
 make/scripts/tests-x32.bat                         |    3 +-
 make/scripts/tests-x64.bat                         |    5 +-
 make/scripts/tests.sh                              |   41 +-
 make/stub_includes/opengl/macosx-window-system.h   |    2 +-
 .../jogamp/gluegen/opengl/BuildStaticGLInfo.java   |    4 +-
 .../com/jogamp/gluegen/opengl/GLConfiguration.java |   10 +-
 .../com/jogamp/gluegen/opengl/GLEmitter.java       |   18 +-
 .../gluegen/runtime/opengl/GLExtensionNames.java   |  190 --
 .../gluegen/runtime/opengl/GLNameResolver.java     |  191 ++
 .../runtime/opengl/GLProcAddressResolver.java      |    4 +-
 src/jogl/classes/com/jogamp/opengl/FBObject.java   | 1943 ++++++++++++++++++++
 .../classes/com/jogamp/opengl/GLExtensions.java    |   81 +
 .../classes/com/jogamp/opengl/JoglVersion.java     |   18 +-
 .../com/jogamp/opengl/OffscreenAutoDrawable.java   |   89 +
 .../classes/com/jogamp/opengl/swt/GLCanvas.java    |   72 +-
 .../classes/com/jogamp/opengl/util/FBObject.java   |  483 -----
 .../classes/com/jogamp/opengl/util/GLBuffers.java  |  179 +-
 .../com/jogamp/opengl/util/GLReadBufferUtil.java   |   12 +-
 .../com/jogamp/opengl/util/ImmModeSink.java        |   25 +-
 .../com/jogamp/opengl/util/awt/Screenshot.java     |    3 +-
 .../com/jogamp/opengl/util/awt/TextRenderer.java   |    3 +-
 .../com/jogamp/opengl/util/texture/Texture.java    |   25 +-
 .../com/jogamp/opengl/util/texture/TextureIO.java  |    8 +
 .../opengl/util/texture/TextureSequence.java       |    1 -
 .../util/texture/spi/NetPbmTextureWriter.java      |    6 +-
 .../media/opengl/DefaultGLCapabilitiesChooser.java |    5 +-
 .../classes/javax/media/opengl/GLAutoDrawable.java |   48 +-
 .../javax/media/opengl/GLAutoDrawableDelegate.java |   18 +-
 src/jogl/classes/javax/media/opengl/GLBase.java    |   55 +
 .../classes/javax/media/opengl/GLCapabilities.java |   31 +-
 .../media/opengl/GLCapabilitiesImmutable.java      |    6 +-
 src/jogl/classes/javax/media/opengl/GLContext.java |   94 +-
 .../javax/media/opengl/GLDrawableFactory.java      |   84 +-
 src/jogl/classes/javax/media/opengl/GLProfile.java |   52 +-
 .../classes/javax/media/opengl/awt/GLCanvas.java   |    7 +-
 .../classes/javax/media/opengl/awt/GLJPanel.java   |    7 +-
 .../jogamp/graph/curve/opengl/VBORegion2PES2.java  |   32 +-
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  |  190 +-
 .../jogamp/opengl/GLDebugMessageHandler.java       |   22 +-
 .../jogamp/opengl/GLDrawableFactoryImpl.java       |  234 ++-
 src/jogl/classes/jogamp/opengl/GLDrawableImpl.java |   47 +-
 .../classes/jogamp/opengl/GLFBODrawableImpl.java   |  138 ++
 .../jogamp/opengl/GLGraphicsConfigurationUtil.java |   66 +-
 src/jogl/classes/jogamp/opengl/GLPbufferImpl.java  |    8 +-
 src/jogl/classes/jogamp/opengl/egl/EGLContext.java |   76 +-
 .../classes/jogamp/opengl/egl/EGLDisplayUtil.java  |   27 +-
 .../classes/jogamp/opengl/egl/EGLDrawable.java     |  214 +--
 .../jogamp/opengl/egl/EGLDrawableFactory.java      |  307 +++-
 .../opengl/egl/EGLGraphicsConfiguration.java       |    2 +-
 .../egl/EGLGraphicsConfigurationFactory.java       |   65 +-
 .../jogamp/opengl/egl/EGLOnscreenDrawable.java     |    4 +-
 .../jogamp/opengl/egl/EGLPbufferDrawable.java      |   34 +-
 .../jogamp/opengl/egl/EGLUpstreamSurfaceHook.java  |   56 +
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java |   24 +-
 .../opengl/macosx/cgl/MacOSXCGLDrawable.java       |    4 -
 .../macosx/cgl/MacOSXCGLDrawableFactory.java       |  153 +-
 .../macosx/cgl/MacOSXCGLGraphicsConfiguration.java |    4 +-
 .../macosx/cgl/MacOSXExternalCGLContext.java       |    3 +-
 .../macosx/cgl/MacOSXPbufferCGLDrawable.java       |   12 +-
 .../jogamp/opengl/util/av/EGLMediaPlayerImpl.java  |    8 +-
 .../windows/wgl/WindowsBitmapWGLDrawable.java      |    6 +-
 .../windows/wgl/WindowsDummyWGLDrawable.java       |  109 --
 .../windows/wgl/WindowsExternalWGLContext.java     |    3 +-
 .../windows/wgl/WindowsExternalWGLDrawable.java    |    7 +-
 .../windows/wgl/WindowsPbufferWGLContext.java      |    4 +-
 .../windows/wgl/WindowsPbufferWGLDrawable.java     |   19 +-
 .../opengl/windows/wgl/WindowsWGLContext.java      |    6 +-
 .../windows/wgl/WindowsWGLDrawableFactory.java     |  130 +-
 .../wgl/WindowsWGLGraphicsConfiguration.java       |   22 +-
 .../WindowsWGLGraphicsConfigurationFactory.java    |   19 +-
 .../jogamp/opengl/x11/glx/X11DummyGLXDrawable.java |  102 -
 .../opengl/x11/glx/X11ExternalGLXContext.java      |   12 +-
 .../opengl/x11/glx/X11ExternalGLXDrawable.java     |    5 +-
 .../jogamp/opengl/x11/glx/X11GLXContext.java       |    9 +-
 .../opengl/x11/glx/X11GLXDrawableFactory.java      |  145 +-
 .../x11/glx/X11GLXGraphicsConfiguration.java       |   29 +-
 .../glx/X11GLXGraphicsConfigurationFactory.java    |   17 +-
 .../opengl/x11/glx/X11OnscreenGLXDrawable.java     |    7 +-
 .../opengl/x11/glx/X11PbufferGLXDrawable.java      |   18 +-
 .../opengl/x11/glx/X11PixmapGLXDrawable.java       |    6 +-
 .../macosx/MacOSXWindowSystemInterface-pbuffer.m   |    2 +-
 .../native/macosx/MacOSXWindowSystemInterface.m    |   12 +-
 .../com/jogamp/nativewindow/WrappedSurface.java    |   34 +-
 .../jogamp/nativewindow/egl/EGLGraphicsDevice.java |   42 +-
 .../com/jogamp/nativewindow/swt/SWTAccessor.java   |    3 -
 .../jogamp/nativewindow/x11/X11GraphicsDevice.java |   36 +-
 .../jogamp/nativewindow/x11/X11GraphicsScreen.java |    8 +-
 .../media/nativewindow/AbstractGraphicsDevice.java |   27 +-
 .../media/nativewindow/DefaultGraphicsDevice.java  |   13 +
 .../javax/media/nativewindow/MutableSurface.java   |   44 +
 .../javax/media/nativewindow/ProxySurface.java     |  127 +-
 .../media/nativewindow/SurfaceChangeable.java      |   54 -
 .../jogamp/nativewindow/SurfaceUpdatedHelper.java  |    4 +-
 .../nativewindow/jawt/macosx/MacOSXJAWTWindow.java |   21 +-
 .../jogamp/nativewindow/macosx/OSXUtil.java        |   13 +-
 .../jogamp/nativewindow/windows/GDISurface.java    |   51 +-
 src/nativewindow/native/macosx/OSXmisc.m           |   52 +-
 src/newt/classes/com/jogamp/newt/Window.java       |   16 +-
 .../classes/com/jogamp/newt/event/KeyEvent.java    |    2 +-
 .../classes/com/jogamp/newt/opengl/GLWindow.java   |    7 +-
 src/newt/classes/jogamp/newt/OffscreenWindow.java  |   41 +-
 .../classes/jogamp/newt/driver/android/MD.java     |    2 +-
 .../jogamp/newt/driver/macosx/MacWindow.java       |    8 +-
 src/newt/native/NewtMacWindow.m                    |    6 +-
 .../test/junit/graph/TestTextRendererNEWT00.java   |    2 +-
 .../graph/demos/GPURendererListenerBase01.java     |    2 +-
 .../junit/graph/demos/ui/UIListenerBase01.java     |    2 +-
 .../test/junit/jogl/acore/TestFBODrawableNEWT.java |  272 +++
 .../test/junit/jogl/acore/TestFBOMRTNEWT01.java    |  266 +++
 .../junit/jogl/acore/TestFBOMix2DemosES2NEWT.java  |  258 +++
 .../jogl/acore/TestGLAutoDrawableDelegateNEWT.java |    2 +-
 .../acore/TestGLContextDrawableSwitchNEWT.java     |    2 +-
 .../test/junit/jogl/acore/TestGLProfile01NEWT.java |    2 +-
 .../junit/jogl/acore/TestShutdownCompleteNEWT.java |    2 +-
 .../test/junit/jogl/caps/MultisampleDemoES1.java   |  154 --
 .../junit/jogl/caps/TestMultisampleES1AWT.java     |   19 +-
 .../junit/jogl/caps/TestMultisampleES1NEWT.java    |   20 +-
 .../junit/jogl/caps/TestMultisampleES2NEWT.java    |  143 ++
 .../opengl/test/junit/jogl/demos/es1/GearsES1.java |   19 +-
 .../junit/jogl/demos/es1/MultisampleDemoES1.java   |  123 ++
 .../test/junit/jogl/demos/es2/FBOMix2DemosES2.java |  309 ++++
 .../opengl/test/junit/jogl/demos/es2/GearsES2.java |   39 +-
 .../junit/jogl/demos/es2/MultisampleDemoES2.java   |  178 ++
 .../test/junit/jogl/demos/es2/RedSquareES2.java    |   48 +-
 .../jogl/demos/es2/TextureSequenceCubeES2.java     |    9 +-
 .../test/junit/jogl/demos/es2/av/MovieCube.java    |    5 +-
 .../test/junit/jogl/demos/es2/av/MovieSimple.java  |    5 +-
 .../jogl/demos/es2/newt/TestGearsES2NEWT.java      |    3 -
 .../jogl/demos/es2/newt/TestRedSquareES2NEWT.java  |    7 +-
 .../junit/jogl/demos/es2/shader/mgl_default_xxx.fp |   10 +
 .../junit/jogl/demos/es2/shader/mgl_default_xxx.vp |   14 +
 .../junit/jogl/demos/es2/shader/texture02_xxx.fp   |   20 +
 .../opengl/test/junit/jogl/demos/gl2/Gears.java    |   18 +-
 .../jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java  |  188 ++
 .../demos/gl2/awt/TestGearsGLJPanelAWTBug450.java  |  194 --
 .../test/junit/jogl/glsl/TestFBOMRTNEWT01.java     |  229 ---
 .../junit/jogl/glsl/TestGLSLShaderState01NEWT.java |    1 -
 .../junit/jogl/glsl/TestGLSLShaderState02NEWT.java |    1 -
 .../test/junit/jogl/offscreen/ReadBufferBase.java  |    4 +-
 .../test/junit/jogl/offscreen/Surface2File.java    |    2 +-
 .../test/junit/jogl/swt/TestSWTAccessor02GLn.java  |   41 +-
 .../TestGLReadBufferUtilTextureIOWrite01AWT.java   |   19 +-
 .../TestGLReadBufferUtilTextureIOWrite01NEWT.java  |   36 +-
 .../TestGLReadBufferUtilTextureIOWrite02AWT.java   |   20 +-
 .../TestGLReadBufferUtilTextureIOWrite02NEWT.java  |   20 +-
 .../util/texture/TestPNGTextureFromFileAWT.java    |   13 +-
 .../util/texture/TestPNGTextureFromFileNEWT.java   |   11 +-
 .../jogamp/opengl/test/junit/util/UITestCase.java  |   55 +-
 165 files changed, 6996 insertions(+), 3008 deletions(-)
 delete mode 100644 src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLExtensionNames.java
 create mode 100644 src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
 create mode 100644 src/jogl/classes/com/jogamp/opengl/FBObject.java
 create mode 100644 src/jogl/classes/com/jogamp/opengl/GLExtensions.java
 create mode 100644 src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
 delete mode 100644 src/jogl/classes/com/jogamp/opengl/util/FBObject.java
 create mode 100644 src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
 create mode 100644 src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
 delete mode 100644 src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
 delete mode 100644 src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
 create mode 100644 src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
 delete mode 100644 src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
 delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemoES1.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
 create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
 delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsGLJPanelAWTBug450.java
 delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java

diff --git a/.gitignore b/.gitignore
index 6e3af642b..1cd3375b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,7 @@ javadoc_public
 build-temp
 make/temp*
 .idea/workspace.xml
-**~
\ No newline at end of file
+.settings/*
+**~
+build*
+make/lib/external/*
diff --git a/doc/Platform.GLES.txt b/doc/Platform.GLES.txt
index 0bcd3bc8b..901e040c4 100644
--- a/doc/Platform.GLES.txt
+++ b/doc/Platform.GLES.txt
@@ -33,7 +33,7 @@ a request for e.g. GL2ES2 will utilize the highest common desktop profile.
 ...>
 
 Linux:
-    PVRVFrame 2.09.29.0649
+    PVRVFrame 2.09.29.0649, Version_REL_2.10
         Debian Wheezy/testing x64, NV 290.10, 32bit libraries: OK
             GL_VENDOR     Imagination Technologies (Host GL: `NVIDIA Corporation`)
             GL_RENDERER   PowerVR PVRVFrame 8.1 SGX (Host GL: `GeForce GTX 460/PCI/SSE2`)
@@ -75,7 +75,7 @@ Linux:
         Ubuntu 11.10 x64, AMD Catalyst 12.1, 64bit libraries, libgles2-mesa 7.11-0ubuntu3: Error (swrast error, null values)
 
 Windows:
-    PVRVFrame 2.09.29.0649
+    PVRVFrame 2.09.29.0649, Version_REL_2.10
        Windows7 64bit, NV 290.10, 32bit libraries: OK 
             GL_VENDOR     Imagination Technologies (Host GL: `NVIDIA Corporation`)
             GL_RENDERER   PowerVR PVRVFrame 8.1 SGX (Host GL: `GeForce GTX 460/PCIe/SSE2`)
diff --git a/doc/TODO.txt b/doc/TODO.txt
index f86d31e4c..82f013265 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -1,16 +1,15 @@
 WIP:
 
+- GLPbuffer -> GLOffscreenAutoDrawable
+    - GLPbuffer GLDrawableFactory.createPbuffer() ->
+      GLOffscreenAutoDrawable GLDrawableFactory.createOffsceenAutoDrawable()
+    - Mark both deprecated!
+
 Random, somewhat old to-do list:
 
 - Non-const array types must be properly released with JNI_COMMIT in
   order to see side effects if the array was copied.
 
-- figure out how to deal with WGL entry points:
-    WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC, int);
-    WINGDIAPI BOOL  WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD);
-    WINGDIAPI BOOL  WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD);
-  see commented-out section in make/stub_includes/win32/wingdi.h
-
 - Need a disciplined mechanism for converting char* argument types. For
   example, many C functions accept a "char*" argument with the semantic that
   output data will be written into the buffer pointed to by the
diff --git a/etc/test.bat b/etc/test.bat
index 0c82233ca..d635c7e8f 100755
--- a/etc/test.bat
+++ b/etc/test.bat
@@ -1,7 +1,7 @@
 
 set BLD_DIR=jar
 
-set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\jogl.all.jar
+set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\jogl-all.jar
 echo CP_ALL %CP_ALL%
 
 set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true"
diff --git a/etc/test_dbg.bat b/etc/test_dbg.bat
index 33bbb912b..209690758 100755
--- a/etc/test_dbg.bat
+++ b/etc/test_dbg.bat
@@ -1,7 +1,7 @@
 
 set BLD_DIR=jar
 
-set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\jogl.all.jar
+set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\jogl-all.jar
 echo CP_ALL %CP_ALL%
 
 set D_ARGS="-Djogamp.debug=all" "-Dnativewindow.debug=all" "-Djogl.debug=all" "-Dnewt.debug=all"
diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg
index 8af080ec8..9c5467583 100644
--- a/make/config/jogl/gl-common.cfg
+++ b/make/config/jogl/gl-common.cfg
@@ -481,6 +481,19 @@ JavaPrologue glGetString        return _context.getGLVersion();
 JavaPrologue glGetString    } */
 JavaPrologue glGetString  }
 
+#
+# Allow special FBO GLContext/GLDrawable to reset to it's
+# default FBO framebuffer.
+#
+JavaPrologue glBindFramebuffer  if( 0 == framebuffer ) {
+JavaPrologue glBindFramebuffer      if( GL_FRAMEBUFFER == target || 0x8CA9 /* GL_DRAW_FRAMEBUFFER */ == target ) {
+JavaPrologue glBindFramebuffer          framebuffer = _context.getDefaultDrawFramebuffer();
+JavaPrologue glBindFramebuffer      } else if( 0x8CA8 /* GL_READ_FRAMEBUFFER */ == target ) {
+JavaPrologue glBindFramebuffer          framebuffer = _context.getDefaultReadFramebuffer();
+JavaPrologue glBindFramebuffer      }
+JavaPrologue glBindFramebuffer  }
+JavaEpilogue glBindFramebuffer  _context.setBoundFramebuffer(target, framebuffer);
+
 #
 # Directives for Vertex Buffer Object and Pixel Buffer Object checking
 #
diff --git a/make/config/jogl/gl-if-CustomJavaCode-gl.java b/make/config/jogl/gl-if-CustomJavaCode-gl.java
index 77378aa45..9ea4f98b4 100644
--- a/make/config/jogl/gl-if-CustomJavaCode-gl.java
+++ b/make/config/jogl/gl-if-CustomJavaCode-gl.java
@@ -57,29 +57,3 @@
       earmarked for ES 3.0 (hence kept in GL while fixing Bug 590)  */
   public static final int GL_HALF_FLOAT = 0x140B;
 
-  public void glClearDepth( double depth );
-
-  public void glDepthRange(double zNear, double zFar);
-
-  /**
-   * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
-   * @return the GL buffer (VBO) name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
-   */
-  public int glGetBoundBuffer(int target);
-
-  /**
-   * @param buffer a GL buffer name, generated with {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} for example.
-   * @return the size of the given GL buffer
-   */
-  public long glGetBufferSize(int buffer);
-
-  /**
-   * @return true if a VBO is bound to {@link GL.GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
-   */
-  public boolean glIsVBOArrayEnabled();
-
-  /**
-   * @return true if a VBO is bound to {@link GL.GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
-   */
-  public boolean glIsVBOElementArrayEnabled();
-
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index d552bc6e4..b05ba2643 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -1,48 +1,57 @@
+    @Override
     public GLProfile getGLProfile() {
         return this.glProfile;
     }
     private final GLProfile glProfile;
 
-    public int glGetBoundBuffer(int target) {
+    @Override
+    public final int glGetBoundBuffer(int target) {
         return bufferStateTracker.getBoundBufferObject(target, this);
     }
 
-    public long glGetBufferSize(int buffer) {
+    @Override
+    public final long glGetBufferSize(int buffer) {
         return bufferSizeTracker.getDirectStateBufferSize(buffer, this);
     }
 
-    public boolean glIsVBOArrayEnabled() {
+    @Override
+    public final boolean glIsVBOArrayEnabled() {
         return checkArrayVBOEnabled(false);
     }
 
-    public boolean glIsVBOElementArrayEnabled() {
+    @Override
+    public final boolean glIsVBOElementArrayEnabled() {
         return checkElementVBOEnabled(false);
     }
 
+    @Override
     public final boolean isGL() {
         return true;
     }
       
+    @Override
     public final GL getGL() throws GLException {
         return this;
     }
 
-    public boolean isFunctionAvailable(String glFunctionName) {
+    @Override
+    public final boolean isFunctionAvailable(String glFunctionName) {
       return _context.isFunctionAvailable(glFunctionName);
     }
 
-    public boolean isExtensionAvailable(String glExtensionName) {
+    @Override
+    public final boolean isExtensionAvailable(String glExtensionName) {
       return _context.isExtensionAvailable(glExtensionName);
     }
 
-    public Object getExtension(String extensionName) {
+    @Override
+    public final Object getExtension(String extensionName) {
       // At this point we don't expose any extensions using this mechanism
       return null;
     }
 
-    /** Returns the context this GL object is associated with for better
-        error checking by DebugGL. */
-    public GLContext getContext() {
+    @Override
+    public final GLContext getContext() {
       return _context;
     }
 
@@ -51,18 +60,36 @@
     /**
      * @see javax.media.opengl.GLContext#setSwapInterval(int)
      */
-    public void setSwapInterval(int interval) {
+    @Override
+    public final void setSwapInterval(int interval) {
       _context.setSwapInterval(interval);
     }
 
     /**
      * @see javax.media.opengl.GLContext#getSwapInterval()
      */
-    public int getSwapInterval() {
+    @Override
+    public final int getSwapInterval() {
       return _context.getSwapInterval();
     }
 
-    public Object getPlatformGLExtensions() {
+    @Override
+    public final Object getPlatformGLExtensions() {
       return _context.getPlatformGLExtensions();
     }
 
+    @Override
+    public final int getBoundFramebuffer(int target) {
+      return _context.getBoundFramebuffer(target);
+    }
+
+    @Override
+    public final int getDefaultDrawFramebuffer() {
+      return _context.getDefaultDrawFramebuffer();
+    }
+
+    @Override
+    public final int getDefaultReadFramebuffer() {
+      return _context.getDefaultReadFramebuffer();
+    }
+
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java b/make/config/jogl/gl-impl-CustomJavaCode-desktop.java
index 33b0f1326..6a74b80a6 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-desktop.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-desktop.java
@@ -4,34 +4,42 @@
         return GLBuffers.sizeof(this, imageSizeTemp, format, type, width, height, depth, pack) ;                                    
     }
 
+    @Override
     public final boolean isGL4bc() {
         return _context.isGL4bc();
     }
 
+    @Override
     public final boolean isGL4() {
         return _context.isGL4();
     }
 
+    @Override
     public final boolean isGL3bc() {
         return _context.isGL3bc();
     }
 
+    @Override
     public final boolean isGL3() {
         return _context.isGL3();
     }
 
+    @Override
     public final boolean isGL2() {
         return _context.isGL2();
     }
       
+    @Override
     public final boolean isGL2ES1() {
         return _context.isGL2ES1();
     }
 
+    @Override
     public final boolean isGL2ES2() {
         return _context.isGL2ES2();
     }
 
+    @Override
     public final boolean isGLES2Compatible() {
         return _context.isGLES2Compatible();
     }
@@ -40,10 +48,12 @@
         return _context.isGL2GL3();
     }
 
+    @Override
     public final boolean hasGLSL() {
         return _context.hasGLSL();
     }
 
+    @Override
     public final GL4bc getGL4bc() throws GLException {
         if(!isGL4bc()) {
             throw new GLException("Not a GL4bc implementation");
@@ -51,6 +61,7 @@
         return this;
     }
 
+    @Override
     public final GL4 getGL4() throws GLException {
         if(!isGL4()) {
             throw new GLException("Not a GL4 implementation");
@@ -58,6 +69,7 @@
         return this;
     }
 
+    @Override
     public final GL3bc getGL3bc() throws GLException {
         if(!isGL3bc()) {
             throw new GLException("Not a GL3bc implementation");
@@ -65,6 +77,7 @@
         return this;
     }
 
+    @Override
     public final GL3 getGL3() throws GLException {
         if(!isGL3()) {
             throw new GLException("Not a GL3 implementation");
@@ -72,6 +85,7 @@
         return this;
     }
 
+    @Override
     public final GL2 getGL2() throws GLException {
         if(!isGL2()) {
             throw new GLException("Not a GL2 implementation");
@@ -79,6 +93,7 @@
         return this;
     }
 
+    @Override
     public final GL2ES1 getGL2ES1() throws GLException {
         if(!isGL2ES1()) {
             throw new GLException("Not a GL2ES1 implementation");
@@ -86,6 +101,7 @@
         return this;
     }
 
+    @Override
     public final GL2ES2 getGL2ES2() throws GLException {
         if(!isGL2ES2()) {
             throw new GLException("Not a GL2ES2 implementation");
@@ -93,6 +109,7 @@
         return this;
     }
 
+    @Override
     public final GL2GL3 getGL2GL3() throws GLException {
         if(!isGL2GL3()) {
             throw new GLException("Not a GL2GL3 implementation");
@@ -100,26 +117,32 @@
         return this;
     }
 
+    @Override
     public final boolean isGLES1() {
         return false;
     }
 
+    @Override
     public final boolean isGLES2() {
         return false;
     }
 
+    @Override
     public final boolean isGLES() {
         return false;
     }
 
+    @Override
     public final GLES1 getGLES1() throws GLException {
         throw new GLException("Not a GLES1 implementation");
     }
 
+    @Override
     public final GLES2 getGLES2() throws GLException {
         throw new GLException("Not a GLES2 implementation");
     }
 
-    public boolean isNPOTTextureAvailable() {
+    @Override
+    public final boolean isNPOTTextureAvailable() {
       return _context.isNPOTTextureAvailable();
     }
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl2_es2.java b/make/config/jogl/gl-impl-CustomJavaCode-gl2_es2.java
index b31a087e7..82b791208 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl2_es2.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl2_es2.java
@@ -1,4 +1,5 @@
-  public void glVertexAttribPointer(GLArrayData array) {
+  @Override
+  public final void glVertexAttribPointer(GLArrayData array) {
     if(array.getComponentCount()==0) return;
     if(array.isVBO()) {
         glVertexAttribPointer(array.getLocation(), array.getComponentCount(), array.getComponentType(), 
@@ -9,7 +10,8 @@
     }
   }
 
-  public void glUniform(GLUniformData data) {
+  @Override
+  public final void glUniform(GLUniformData data) {
     boolean done=false;
     if(data.isBuffer()) {
         Buffer buffer = data.getBuffer();
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
index 95aa7cc2c..e079a1a24 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
@@ -33,7 +33,7 @@ public GL4bcImpl(GLProfile glp, GLContextImpl context) {
  * Provides platform-independent access to the wglAllocateMemoryNV /
  * glXAllocateMemoryNV extension.
  */
-public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+public final java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
   return _context.glAllocateMemoryNV(arg0, arg1, arg2, arg3);
 }
 
@@ -52,7 +52,7 @@ private boolean haveGL15;
 private boolean haveGL21;
 private boolean haveARBVertexBufferObject;
 
-private void initBufferObjectExtensionChecks() {
+private final void initBufferObjectExtensionChecks() {
   if (bufferObjectExtensionsInitialized)
     return;
   bufferObjectExtensionsInitialized = true;
@@ -63,12 +63,12 @@ private void initBufferObjectExtensionChecks() {
   haveARBVertexBufferObject = isExtensionAvailable("GL_ARB_vertex_buffer_object");
 }
 
-private boolean checkBufferObject(boolean extension1,
-                                  boolean extension2,
-                                  boolean extension3,
-                                  boolean enabled,
-                                  int state,
-                                  String kind, boolean throwException) {
+private final boolean checkBufferObject(boolean extension1,
+                                        boolean extension2,
+                                        boolean extension3,
+                                        boolean enabled,
+                                        int state,
+                                        String kind, boolean throwException) {
   if (inBeginEndPair) {
     throw new GLException("May not call this between glBegin and glEnd");
   }
@@ -100,7 +100,7 @@ private boolean checkBufferObject(boolean extension1,
   return true;
 }  
 
-private boolean checkArrayVBODisabled(boolean throwException) { 
+private final boolean checkArrayVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveGL15,
                     haveARBVertexBufferObject,
@@ -110,7 +110,7 @@ private boolean checkArrayVBODisabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkArrayVBOEnabled(boolean throwException) { 
+private final boolean checkArrayVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveGL15,
                     haveARBVertexBufferObject,
@@ -120,7 +120,7 @@ private boolean checkArrayVBOEnabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBODisabled(boolean throwException) { 
+private final boolean checkElementVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveGL15,
                     haveARBVertexBufferObject,
@@ -130,7 +130,7 @@ private boolean checkElementVBODisabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBOEnabled(boolean throwException) { 
+private final boolean checkElementVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveGL15,
                     haveARBVertexBufferObject,
@@ -140,7 +140,7 @@ private boolean checkElementVBOEnabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkUnpackPBODisabled(boolean throwException) { 
+private final boolean checkUnpackPBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveARBPixelBufferObject,
                     haveEXTPixelBufferObject,
@@ -150,7 +150,7 @@ private boolean checkUnpackPBODisabled(boolean throwException) {
                     "unpack pixel_buffer_object", throwException);
 }
 
-private boolean checkUnpackPBOEnabled(boolean throwException) { 
+private final boolean checkUnpackPBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveARBPixelBufferObject,
                     haveEXTPixelBufferObject,
@@ -160,7 +160,7 @@ private boolean checkUnpackPBOEnabled(boolean throwException) {
                     "unpack pixel_buffer_object", throwException);
 }
 
-private boolean checkPackPBODisabled(boolean throwException) { 
+private final boolean checkPackPBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveARBPixelBufferObject,
                     haveEXTPixelBufferObject,
@@ -170,7 +170,7 @@ private boolean checkPackPBODisabled(boolean throwException) {
                     "pack pixel_buffer_object", throwException);
 }
 
-private boolean checkPackPBOEnabled(boolean throwException) { 
+private final boolean checkPackPBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(haveARBPixelBufferObject,
                     haveEXTPixelBufferObject,
@@ -180,18 +180,20 @@ private boolean checkPackPBOEnabled(boolean throwException) {
                     "pack pixel_buffer_object", throwException);
 }
 
-public boolean glIsPBOPackEnabled() {
+@Override
+public final boolean glIsPBOPackEnabled() {
     return checkPackPBOEnabled(false);
 }
 
-public boolean glIsPBOUnpackEnabled() {
+@Override
+public final boolean glIsPBOUnpackEnabled() {
     return checkUnpackPBOEnabled(false);
 }
 
-private HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
+private final HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
 
 /** Entry point to C language function: <br> <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code>    */
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
   final long __addr_ = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
   if (__addr_ == 0) {
     throw new GLException("Method \"glMapBuffer\" not available");
@@ -230,7 +232,7 @@ public java.nio.ByteBuffer glMapBuffer(int target, int access) {
 native private long dispatch_glMapBuffer(int target, int access, long glProcAddress);
 
 /** Entry point to C language function: <code> GLvoid *  {@native glMapNamedBufferEXT}(GLuint buffer, GLenum access); </code> <br>Part of <code>GL_EXT_direct_state_access</code>   */
-public java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access)  {
+public final java.nio.ByteBuffer glMapNamedBufferEXT(int bufferName, int access)  {
   final long __addr_ = ((GL4bcProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapNamedBufferEXT;
   if (__addr_ == 0) {
     throw new GLException("Method \"glMapNamedBufferEXT\" not available");
@@ -269,7 +271,8 @@ private native long dispatch_glMapNamedBufferEXT(int buffer, int access, long pr
 
 native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
 
-    public void glVertexPointer(GLArrayData array) {
+    @Override
+    public final void glVertexPointer(GLArrayData array) {
       if(array.getComponentCount()==0) return;
       if(array.isVBO()) {
           glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -277,7 +280,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
           glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
       }
     }
-    public void glColorPointer(GLArrayData array) {
+    @Override
+    public final void glColorPointer(GLArrayData array) {
       if(array.getComponentCount()==0) return;
       if(array.isVBO()) {
           glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -286,7 +290,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
       }
 
     }
-    public void glNormalPointer(GLArrayData array) {
+    @Override
+    public final void glNormalPointer(GLArrayData array) {
       if(array.getComponentCount()==0) return;
       if(array.getComponentCount()!=3) {
         throw new GLException("Only 3 components per normal allowed");
@@ -297,7 +302,8 @@ native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
           glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
       }
     }
-    public void glTexCoordPointer(GLArrayData array) {
+    @Override
+    public final void glTexCoordPointer(GLArrayData array) {
       if(array.getComponentCount()==0) return;
       if(array.isVBO()) {
           glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index dff33cf81..68eadc683 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -12,98 +12,122 @@ public GLES1Impl(GLProfile glp, GLContextImpl context) {
   this.glProfile = glp;
 }
 
+@Override
 public final boolean isGL4bc() {
     return false;
 }
 
+@Override
 public final boolean isGL4() {
     return false;
 }
 
+@Override
 public final boolean isGL3bc() {
     return false;
 }
 
+@Override
 public final boolean isGL3() {
     return false;
 }
 
+@Override
 public final boolean isGL2() {
     return false;
 }
 
+@Override
 public final boolean isGLES1() {
     return true;
 }
 
+@Override
 public final boolean isGLES2() {
     return false;
 }
 
+@Override
 public final boolean isGLES() {
     return true;
 }
 
+@Override
 public final boolean isGL2ES1() {
     return true;
 }
 
+@Override
 public final boolean isGL2ES2() {
     return false;
 }
 
+@Override
 public final boolean isGLES2Compatible() {
     return false;
 }
 
+@Override
 public final boolean isGL2GL3() {
     return false;
 }
 
+@Override
 public final boolean hasGLSL() {
     return false;
 }
 
+@Override
 public boolean isNPOTTextureAvailable() {
   return false;
 }
 
+@Override
 public final GL4bc getGL4bc() throws GLException {
     throw new GLException("Not a GL4bc implementation");
 }
 
+@Override
 public final GL4 getGL4() throws GLException {
     throw new GLException("Not a GL4 implementation");
 }
 
+@Override
 public final GL3bc getGL3bc() throws GLException {
     throw new GLException("Not a GL3bc implementation");
 }
 
+@Override
 public final GL3 getGL3() throws GLException {
     throw new GLException("Not a GL3 implementation");
 }
 
+@Override
 public final GL2 getGL2() throws GLException {
     throw new GLException("Not a GL2 implementation");
 }
 
+@Override
 public final GLES1 getGLES1() throws GLException {
     return this;
 }
 
+@Override
 public final GLES2 getGLES2() throws GLException {
     throw new GLException("Not a GLES2 implementation");
 }
 
+@Override
 public final GL2ES1 getGL2ES1() throws GLException {
     return this;
 }
 
+@Override
 public final GL2ES2 getGL2ES2() throws GLException {
     throw new GLException("Not a GL2ES2 implementation");
 }
 
+@Override
 public final GL2GL3 getGL2GL3() throws GLException {
     throw new GLException("Not a GL2GL3 implementation");
 }
@@ -119,17 +143,17 @@ private final GLStateTracker       glStateTracker;
 private boolean bufferObjectExtensionsInitialized = false;
 private boolean haveOESFramebufferObject;
 
-private void initBufferObjectExtensionChecks() {
+private final void initBufferObjectExtensionChecks() {
   if (bufferObjectExtensionsInitialized)
     return;
   bufferObjectExtensionsInitialized = true;
   haveOESFramebufferObject  = isExtensionAvailable("GL_OES_framebuffer_object");
 }
 
-private boolean checkBufferObject(boolean avail,
-                                  boolean enabled,
-                                  int state,
-                                  String kind, boolean throwException) {
+private final boolean checkBufferObject(boolean avail,
+                                        boolean enabled,
+                                        int state,
+                                        String kind, boolean throwException) {
   if (!avail) {
     if (!enabled)
       return true;
@@ -157,7 +181,7 @@ private boolean checkBufferObject(boolean avail,
   return true;
 }  
 
-private boolean checkArrayVBODisabled(boolean throwException) { 
+private final boolean checkArrayVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     false,
@@ -165,7 +189,7 @@ private boolean checkArrayVBODisabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkArrayVBOEnabled(boolean throwException) { 
+private final boolean checkArrayVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     true,
@@ -173,7 +197,7 @@ private boolean checkArrayVBOEnabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBODisabled(boolean throwException) { 
+private final boolean checkElementVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     false,
@@ -181,7 +205,7 @@ private boolean checkElementVBODisabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBOEnabled(boolean throwException) { 
+private final boolean checkElementVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     true,
@@ -189,30 +213,30 @@ private boolean checkElementVBOEnabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkUnpackPBODisabled(boolean throwException) { 
+private final boolean checkUnpackPBODisabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return true;
 }
 
-private boolean checkUnpackPBOEnabled(boolean throwException) { 
+private final boolean checkUnpackPBOEnabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return false;
 }
 
-private boolean checkPackPBODisabled(boolean throwException) { 
+private final boolean checkPackPBODisabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return true;
 }
 
-private boolean checkPackPBOEnabled(boolean throwException) { 
+private final boolean checkPackPBOEnabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return false;
 }
 
-private HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
+private final HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
 
 /** Entry point to C language function: <br> <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code>    */
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
   final long __addr_ = ((GLES1ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
   if (__addr_ == 0) {
     throw new GLException("Method \"glMapBuffer\" not available");
@@ -252,7 +276,8 @@ native private long dispatch_glMapBuffer(int target, int access, long glProcAddr
 
 native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
 
-public void glVertexPointer(GLArrayData array) {
+@Override
+public final void glVertexPointer(GLArrayData array) {
   if(array.getComponentCount()==0) return;
   if(array.isVBO()) {
       glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -260,7 +285,8 @@ public void glVertexPointer(GLArrayData array) {
       glVertexPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getBuffer());
   }
 }
-public void glColorPointer(GLArrayData array) {
+@Override
+public final void glColorPointer(GLArrayData array) {
   if(array.getComponentCount()==0) return;
   if(array.isVBO()) {
       glColorPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
@@ -269,7 +295,8 @@ public void glColorPointer(GLArrayData array) {
   }
 
 }
-public void glNormalPointer(GLArrayData array) {
+@Override
+public final void glNormalPointer(GLArrayData array) {
   if(array.getComponentCount()==0) return;
   if(array.getComponentCount()!=3) {
     throw new GLException("Only 3 components per normal allowed");
@@ -280,7 +307,8 @@ public void glNormalPointer(GLArrayData array) {
       glNormalPointer(array.getComponentType(), array.getStride(), array.getBuffer());
   }
 }
-public void glTexCoordPointer(GLArrayData array) {
+@Override
+public final void glTexCoordPointer(GLArrayData array) {
   if(array.getComponentCount()==0) return;
   if(array.isVBO()) {
       glTexCoordPointer(array.getComponentCount(), array.getComponentType(), array.getStride(), array.getVBOOffset());
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
index a4976f5ea..760287364 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
@@ -1,6 +1,3 @@
-// Tracks glBegin/glEnd calls to determine whether it is legal to
-// query Vertex Buffer Object state
-private boolean inBeginEndPair;
 
 public GLES2Impl(GLProfile glp, GLContextImpl context) {
   this._context = context; 
@@ -16,18 +13,22 @@ public GLES2Impl(GLProfile glp, GLContextImpl context) {
   this.glProfile = glp;
 }
 
+@Override
 public final boolean isGL4bc() {
     return false;
 }
 
+@Override
 public final boolean isGL4() {
     return false;
 }
 
+@Override
 public final boolean isGL3bc() {
     return false;
 }
 
+@Override
 public final boolean isGL3() {
     return false;
 }
@@ -36,78 +37,97 @@ public final boolean isGL2() {
     return false;
 }
 
+@Override
 public final boolean isGLES1() {
     return false;
 }
 
+@Override
 public final boolean isGLES2() {
     return true;
 }
 
+@Override
 public final boolean isGLES() {
     return true;
 }
 
+@Override
 public final boolean isGL2ES1() {
     return false;
 }
 
+@Override
 public final boolean isGL2ES2() {
     return true;
 }
 
+@Override
 public final boolean isGLES2Compatible() {
     return true;
 }
 
+@Override
 public final boolean isGL2GL3() {
     return false;
 }
 
+@Override
 public final boolean hasGLSL() {
     return true;
 }
 
+@Override
 public boolean isNPOTTextureAvailable() {
   return true;
 }
 
+@Override
 public final GL4bc getGL4bc() throws GLException {
     throw new GLException("Not a GL4bc implementation");
 }
 
+@Override
 public final GL4 getGL4() throws GLException {
     throw new GLException("Not a GL4 implementation");
 }
 
+@Override
 public final GL3bc getGL3bc() throws GLException {
     throw new GLException("Not a GL3bc implementation");
 }
 
+@Override
 public final GL3 getGL3() throws GLException {
     throw new GLException("Not a GL3 implementation");
 }
 
+@Override
 public final GL2 getGL2() throws GLException {
     throw new GLException("Not a GL2 implementation");
 }
 
+@Override
 public final GLES1 getGLES1() throws GLException {
     throw new GLException("Not a GLES1 implementation");
 }
 
+@Override
 public final GLES2 getGLES2() throws GLException {
     return this;
 }
 
+@Override
 public final GL2ES1 getGL2ES1() throws GLException {
     throw new GLException("Not a GL2ES1 implementation");
 }
 
+@Override
 public final GL2ES2 getGL2ES2() throws GLException {
     return this;
 }
 
+@Override
 public final GL2GL3 getGL2GL3() throws GLException {
     throw new GLException("Not a GL2GL3 implementation");
 }
@@ -123,17 +143,17 @@ private final GLStateTracker       glStateTracker;
 private boolean bufferObjectExtensionsInitialized = false;
 private boolean haveOESFramebufferObject;
 
-private void initBufferObjectExtensionChecks() {
+private final void initBufferObjectExtensionChecks() {
   if (bufferObjectExtensionsInitialized)
     return;
   bufferObjectExtensionsInitialized = true;
   haveOESFramebufferObject  = isExtensionAvailable("GL_OES_framebuffer_object");
 }
 
-private boolean checkBufferObject(boolean avail,
-                                  boolean enabled,
-                                  int state,
-                                  String kind, boolean throwException) {
+private final boolean checkBufferObject(boolean avail,
+                                        boolean enabled,
+                                        int state,
+                                        String kind, boolean throwException) {
   if (!avail) {
     if (!enabled)
       return true;
@@ -161,7 +181,7 @@ private boolean checkBufferObject(boolean avail,
   return true;
 }  
 
-private boolean checkArrayVBODisabled(boolean throwException) { 
+private final boolean checkArrayVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     false,
@@ -169,7 +189,7 @@ private boolean checkArrayVBODisabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkArrayVBOEnabled(boolean throwException) { 
+private final boolean checkArrayVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     true,
@@ -177,7 +197,7 @@ private boolean checkArrayVBOEnabled(boolean throwException) {
                     "array vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBODisabled(boolean throwException) { 
+private final boolean checkElementVBODisabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     false,
@@ -185,7 +205,7 @@ private boolean checkElementVBODisabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkElementVBOEnabled(boolean throwException) { 
+private final boolean checkElementVBOEnabled(boolean throwException) { 
   initBufferObjectExtensionChecks();
   return checkBufferObject(true,
                     true,
@@ -193,30 +213,31 @@ private boolean checkElementVBOEnabled(boolean throwException) {
                     "element vertex_buffer_object", throwException);
 }
 
-private boolean checkUnpackPBODisabled(boolean throwException) { 
+private final boolean checkUnpackPBODisabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return true;
 }
 
-private boolean checkUnpackPBOEnabled(boolean throwException) { 
+private final boolean checkUnpackPBOEnabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return false;
 }
 
-private boolean checkPackPBODisabled(boolean throwException) { 
+private final boolean checkPackPBODisabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return true;
 }
 
-private boolean checkPackPBOEnabled(boolean throwException) { 
+private final boolean checkPackPBOEnabled(boolean throwException) { 
     // PBO n/a for ES 1.1 or ES 2.0
     return false;
 }
 
-private HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
+private final HashMap<MemoryObject, MemoryObject> arbMemCache = new HashMap<MemoryObject, MemoryObject>();
 
 /** Entry point to C language function: <br> <code> LPVOID glMapBuffer(GLenum target, GLenum access); </code>    */
-public java.nio.ByteBuffer glMapBuffer(int target, int access) {
+@Override
+public final java.nio.ByteBuffer glMapBuffer(int target, int access) {
   final long __addr_ = ((GLES2ProcAddressTable)_context.getGLProcAddressTable())._addressof_glMapBuffer;
   if (__addr_ == 0) {
     throw new GLException("Method \"glMapBuffer\" not available");
@@ -256,11 +277,13 @@ native private long dispatch_glMapBuffer(int target, int access, long glProcAddr
 
 native private ByteBuffer newDirectByteBuffer(long addr, long capacity);
 
-public void glClearDepth(double depth) {
+@Override
+public final void glClearDepth(double depth) {
     glClearDepthf((float)depth); 
 }
 
-public void glDepthRange(double zNear, double zFar) {
+@Override
+public final void glDepthRange(double zNear, double zFar) {
     glDepthRangef((float)zNear, (float)zFar); 
 }
 
diff --git a/make/scripts/java-win32-dbg.bat b/make/scripts/java-win32-dbg.bat
index d1797bdbb..6f8206721 100755
--- a/make/scripts/java-win32-dbg.bat
+++ b/make/scripts/java-win32-dbg.bat
@@ -9,9 +9,9 @@ set BLD_DIR=..\%BLD_SUB%
 
 set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x32
 
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\angle\win32;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
 
 REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
 set LIB_DIR=%FFMPEG_LIB%
@@ -20,11 +20,14 @@ set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluege
 
 echo CP_ALL %CP_ALL%
 
-set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
+set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
+REM set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
 REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.ProcAddressHelper=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true"
 REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
 REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
-REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
 REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
 REM set D_ARGS="-Dnativewindow.debug.TraceLock"
 REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat
index 9d59c045e..1d8430280 100755
--- a/make/scripts/java-win32.bat
+++ b/make/scripts/java-win32.bat
@@ -8,8 +8,8 @@ set PROJECT_ROOT=D:\projects\jogamp\jogl
 set BLD_DIR=..\%BLD_SUB%
 
 REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
-REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\angle\win32;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\PVRVFrame\OGLES-2.0\Windows_x86_32;%PATH%
 
 set BLD_DIR=..\%BLD_SUB%
 REM set LIB_DIR=..\..\gluegen\%BLD_SUB%\obj;%BLD_DIR%\lib
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index d6b0435ea..109755d2e 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -9,7 +9,8 @@ set BLD_DIR=..\%BLD_SUB%
 
 set FFMPEG_LIB=%PROJECT_ROOT%\make\lib\ffmpeg\x64
 
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%FFMPEG_LIB%;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_64;%PATH%
 REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
 set LIB_DIR=%FFMPEG_LIB%
 
@@ -17,7 +18,13 @@ set CP_ALL=.;%BLD_DIR%\jar\jogl-all.jar;%BLD_DIR%\jar\jogl-test.jar;..\..\gluege
 
 echo CP_ALL %CP_ALL%
 
-set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
+set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.FBObject"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Djogl.debug.GLDrawable" "-Djogl.debug.EGLDrawableFactory.QueryNativeTK"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug=all" "-Djogl.debug.EGLDrawableFactory.DontQuery"
+REM set D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser -Djogl.debug.GLProfile"
+REM set D_ARGS="-Djogamp.debug.IOUtil" "-Djogl.debug.GLSLCode" "-Djogl.debug.GLMediaPlayer"
 REM set D_ARGS="-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLSLCode"
 REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.ProcAddressHelper=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true"
 REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
@@ -33,7 +40,6 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC
 REM set D_ARGS="-Dnewt.debug.Window"
 REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
 REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.GLSLCode"
-REM set D_ARGS="-Djogl.debug.GraphicsConfiguration" "-Djogl.debug.CapabilitiesChooser"
 REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
 REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
 REM set D_ARGS="-Dnativewindow.debug.TraceLock"
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat
index b8f438aab..2c09feedc 100755
--- a/make/scripts/java-win64.bat
+++ b/make/scripts/java-win64.bat
@@ -4,7 +4,8 @@ set J2RE_HOME=c:\jre1.6.0_30_x64
 set JAVA_HOME=c:\jdk1.6.0_30_x64
 set ANT_PATH=C:\apache-ant-1.8.2
 
-set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+REM set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
+set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;%PROJECT_ROOT%\make\lib\external\PVRVFrame\OGLES-2.0\Windows_x86_64;%PATH%
 
 set BLD_DIR=..\%BLD_SUB%
 REM set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
diff --git a/make/scripts/tests-x32.bat b/make/scripts/tests-x32.bat
index c29dcef39..7947759a4 100755
--- a/make/scripts/tests-x32.bat
+++ b/make/scripts/tests-x32.bat
@@ -51,7 +51,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode0
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT
 
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple %*
-scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube %*
+REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube %*
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.TexCubeES2 %*
 
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
@@ -94,6 +94,7 @@ REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
 
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
+scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
 REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
 
 REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 32729d235..0b3711784 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -72,7 +72,7 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingPr
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn %*
-scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000
 
@@ -96,7 +96,8 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMe
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
 
 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 %*
 
 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
 
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 0258187fd..591f5f9d2 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -53,10 +53,17 @@ function jrun() {
     swton=$1
     shift
 
+    #D_ARGS="-Djogl.debug.FBObject -Djogl.debug.DebugGL"
+    #D_ARGS="-Djogl.debug.FBObject"
+    #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
     #D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
     #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
     #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
+    #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
     #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
+    #D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.GLDrawable"
     #D_ARGS="-Djogl.debug=all -Dnewt.debug=all"
     #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL"
     #D_ARGS="-Djogl.debug.GLDebugMessageHandler"
@@ -71,6 +78,7 @@ function jrun() {
     #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
     #D_ARGS="-Djogl.debug.GLArrayData"
     #D_ARGS="-Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+    #D_ARGS="-Djogl.debug.GLDrawable"
     #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
     #D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
     #D_ARGS="-Dnewt.debug.MainThread"
@@ -85,7 +93,7 @@ function jrun() {
     #D_ARGS="-Dnativewindow.debug.NativeWindow"
     #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
     #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
-    #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
+    #D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
     #D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
     #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync"
     #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window"
@@ -100,9 +108,9 @@ function jrun() {
     #D_ARGS="-Djogl.debug.Animator -Dnewt.debug=all"
     #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas"
     #D_ARGS="-Djogl.debug.GLContext"
-    #D_ARGS="-Djogl.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
+    #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
     #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock"
-    #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GraphicsConfiguration"
+    #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.GraphicsConfiguration"
     #D_ARGS="-Dnewt.debug.EDT"
     #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.GLContext"
     #D_ARGS="-Dnewt.debug.Window -Djogl.debug.Animator -Dnewt.debug.Screen"
@@ -115,8 +123,6 @@ function jrun() {
     #D_ARGS="-Xprof"
     #D_ARGS="-Djogl.debug.Animator"
     #D_ARGS="-Dnativewindow.debug=all"
-    #D_ARGS="-Djogl.debug.GraphicsConfiguration"
-    #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GraphicsConfiguration"
     #D_ARGS="-Djogl.debug.GLCanvas"
     #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock"
     #D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
@@ -162,20 +168,20 @@ function jrun() {
             C_ARG="com.jogamp.newt.util.MainThread"
         fi
     fi
+    #export LD_LIBRARY_PATH=$spath/../lib/external/PVRVFrame/OGLES-2.0/Linux_x86_64:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=$spath/../lib/external/PVRVFrame/OGLES-2.0/Linux_x86_32:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=/usr/local/projects/Xorg.modular/build-x86_64/lib:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=/opt-linux-x86_64/x11lib-1.3:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH
+    #export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH
     echo
     echo "Test Start: $*"
     echo
     echo LD_LIBRARY_PATH $LD_LIBRARY_PATH
     echo
     echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
-    #LD_LIBRARY_PATH=/usr/local/projects/Xorg.modular/build-x86_64/lib:$LD_LIBRARY_PATH \
-    #LD_LIBRARY_PATH=/opt-linux-x86_64/x11lib-1.3:$LD_LIBRARY_PATH \
-    #LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH \
     #LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \
-    #LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH \
-    #LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH \
-    #LD_LIBRARY_PATH=$spath/../lib/PVRVFrame/OGLES-2.0/Linux_x86_64:$LD_LIBRARY_PATH \
-    #LD_LIBRARY_PATH=$spath/../lib/PVRVFrame/OGLES-2.0/Linux_x86_32:$LD_LIBRARY_PATH \
     #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
     $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $*
     echo
@@ -228,6 +234,7 @@ function testawtswt() {
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
 
 #testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
@@ -292,7 +299,7 @@ function testawtswt() {
 # swt (testswt)
 #
 #testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $*
-testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
+#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
 #testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
 #testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor02GLn $*
 
@@ -322,7 +329,8 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
 #testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
@@ -358,7 +366,9 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
 
 #
 # Graph
@@ -394,6 +404,7 @@ testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
 #testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
 
 #linux:
+#testnoawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES2NEWT $* # linux NV: cannot make ctx current ..
 
 # osx:
 #testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index e7fe13553..47b51a509 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -31,7 +31,7 @@ NSView* getNSView(NSOpenGLContext* ctx);
 
 NSOpenGLContext* createContext(NSOpenGLContext* shareContext,
                     NSView* nsView,
-                    Bool isBackingLayerView,
+                    Bool allowIncompleteView,
                     NSOpenGLPixelFormat* pixelFormat,
                     Bool opaque,
                     int* viewNotReady);
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
index 87a734e1f..482d35cae 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/BuildStaticGLInfo.java
@@ -293,9 +293,9 @@ public class BuildStaticGLInfo {
         output.println("  public static String getFunctionAssociation(String glFunctionName)");
         output.println("  {");
         output.println("    String mappedName = null;");
-        output.println("    int  funcNamePermNum = com.jogamp.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutationNumber(glFunctionName);");
+        output.println("    int  funcNamePermNum = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutationNumber(glFunctionName);");
         output.println("    for(int i = 0; null==mappedName && i < funcNamePermNum; i++) {");
-        output.println("        String tmp = com.jogamp.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutation(glFunctionName, i);");
+        output.println("        String tmp = com.jogamp.gluegen.runtime.opengl.GLNameResolver.getFuncNamePermutation(glFunctionName, i);");
         output.println("        try {");
         output.println("          mappedName = (String)funcToAssocMap.get(tmp);");
         output.println("        } catch (Exception e) { }");
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
index c1a4facd2..ba025e18c 100755
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLConfiguration.java
@@ -43,7 +43,7 @@ import com.jogamp.gluegen.GlueEmitterControls;
 import com.jogamp.gluegen.GlueGen;
 import com.jogamp.gluegen.MethodBinding;
 import com.jogamp.gluegen.procaddress.ProcAddressConfiguration;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -224,11 +224,11 @@ public class GLConfiguration extends ProcAddressConfiguration {
                     }
                 }
             }
-            boolean isGLEnum = GLExtensionNames.isGLEnumeration(symbol);
-            boolean isGLFunc = GLExtensionNames.isGLFunction(symbol);
+            boolean isGLEnum = GLNameResolver.isGLEnumeration(symbol);
+            boolean isGLFunc = GLNameResolver.isGLFunction(symbol);
             if (isGLFunc || isGLEnum) {
-                if (GLExtensionNames.isExtensionVEN(symbol, isGLFunc)) {
-                    String extSuffix = GLExtensionNames.getExtensionSuffix(symbol, isGLFunc);
+                if (GLNameResolver.isExtensionVEN(symbol, isGLFunc)) {
+                    String extSuffix = GLNameResolver.getExtensionSuffix(symbol, isGLFunc);
                     if (getDropUniqVendorExtensions(extSuffix)) {
                         if (DEBUG_IGNORES) {
                             System.err.println("Ignore UniqVendorEXT: " + symbol + ", vendor " + extSuffix);
diff --git a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
index f4658ad7b..809c6783d 100644
--- a/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
+++ b/src/jogl/classes/com/jogamp/gluegen/opengl/GLEmitter.java
@@ -51,7 +51,7 @@ import com.jogamp.gluegen.SymbolFilter;
 import com.jogamp.gluegen.cgram.types.FunctionSymbol;
 import com.jogamp.gluegen.procaddress.ProcAddressEmitter;
 import com.jogamp.gluegen.procaddress.ProcAddressJavaMethodBindingEmitter;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -110,13 +110,13 @@ public class GLEmitter extends ProcAddressEmitter {
             if (declarations != null) {
                 for (Iterator<String> iterator = declarations.iterator(); iterator.hasNext();) {
                     String decl = iterator.next();
-                    boolean isGLFunction = GLExtensionNames.isGLFunction(decl);
+                    boolean isGLFunction = GLNameResolver.isGLFunction(decl);
                     boolean isGLEnumeration = false;
                     if (!isGLFunction) {
-                        isGLEnumeration = GLExtensionNames.isGLEnumeration(decl);
+                        isGLEnumeration = GLNameResolver.isGLEnumeration(decl);
                     }
                     if (isGLFunction || isGLEnumeration) {
-                        String renamed = GLExtensionNames.normalize(decl, isGLFunction);
+                        String renamed = GLNameResolver.normalize(decl, isGLFunction);
                         if (!renamed.equals(decl)) {
                             config.addJavaSymbolRename(decl, renamed);
                         }
@@ -181,7 +181,7 @@ public class GLEmitter extends ProcAddressEmitter {
                 String cause = null;
                 for (String decl : declarations) {
                     boolean isFunc = !decl.startsWith("GL_");
-                    if (!GLExtensionNames.isExtension(decl, isFunc)) {
+                    if (!GLNameResolver.isExtension(decl, isFunc)) {
                         isExtension = false;
                         break;
                     }
@@ -199,7 +199,7 @@ public class GLEmitter extends ProcAddressEmitter {
                         }
                     }
                     cause = decl;
-                    String unifiedName = GLExtensionNames.normalize(decl, isFunc);
+                    String unifiedName = GLNameResolver.normalize(decl, isFunc);
                     // NOTE that we look up the unified name in the
                     // BuildStaticGLInfo's notion of the APIs -- since
                     // we might not be emitting glue code for the
@@ -472,12 +472,12 @@ public class GLEmitter extends ProcAddressEmitter {
         w.println("   *   it was statically linked.");
         w.println("   */");
         w.println("  public long getAddressFor(String functionNameUsr) {");
-        w.println("    String functionNameBase = "+GLExtensionNames.class.getName()+".normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLExtensionNames.normalizeARB(functionNameUsr, true), true);");
+        w.println("    String functionNameBase = "+GLNameResolver.class.getName()+".normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeARB(functionNameUsr, true), true);");
         w.println("    String addressFieldNameBase = PROCADDRESS_VAR_PREFIX + functionNameBase;");
         w.println("    java.lang.reflect.Field addressField = null;");
-        w.println("    int  funcNamePermNum = "+GLExtensionNames.class.getName()+".getFuncNamePermutationNumber(functionNameBase);");
+        w.println("    int  funcNamePermNum = "+GLNameResolver.class.getName()+".getFuncNamePermutationNumber(functionNameBase);");
         w.println("    for(int i = 0; null==addressField && i < funcNamePermNum; i++) {");
-        w.println("        String addressFieldName = "+GLExtensionNames.class.getName()+".getFuncNamePermutation(addressFieldNameBase, i);");
+        w.println("        String addressFieldName = "+GLNameResolver.class.getName()+".getFuncNamePermutation(addressFieldNameBase, i);");
         w.println("        try {");
         w.println("          addressField = getClass().getField(addressFieldName);");
         w.println("        } catch (Exception e) { }");
diff --git a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLExtensionNames.java b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLExtensionNames.java
deleted file mode 100644
index 426333034..000000000
--- a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLExtensionNames.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- * - Redistribution in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * 
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * 
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- * 
- */
-package com.jogamp.gluegen.runtime.opengl;
-
-public class GLExtensionNames {
-    //GL_XYZ : GL_XYZ, GL_XYZ_GL2, GL_XYZ_ARB, GL_XYZ_OES, GL_XYZ_OML
-    //GL_XYZ : GL_XYZ, GL_GL2_XYZ, GL_ARB_XYZ, GL_OES_XYZ, GL_OML_XYZ
-    //
-    // Pass-1 Unify ARB extensions with the same value
-    // Pass-2 Unify vendor extensions, 
-    //        if exist as an ARB extension with the same value.
-    // Pass-3 Emit
-
-    public static final String[] extensionsARB = { "ARB", "GL2", "OES", "KHR", "OML" };
-    public static final String[] extensionsVEN = { "3DFX", 
-                                                   "AMD",
-                                                   "ANGLE",
-                                                   "ARM",
-                                                   "APPLE",
-                                                   "ATI",
-                                                   "EXT",
-                                                   "HI",
-                                                   "HP",
-                                                   "IBM",
-                                                   "IMG",
-                                                   "MESA",
-                                                   "MESAX",
-                                                   "NV",
-                                                   "QCOM",
-                                                   "SGI",
-                                                   "SGIS",
-                                                   "SGIX",
-                                                   "SUN",
-                                                   "VIV",
-                                                   "WIN"
-                                                   };
-
-
-    public static final boolean isGLFunction(String str) {
-        return str.startsWith("gl")  || /* str.startsWith("glu") || str.startsWith("glX") || */
-               str.startsWith("egl") || str.startsWith("wgl") || str.startsWith("agl") ||
-               str.startsWith("cgl") ;
-    }
-
-    public static final boolean isGLEnumeration(String str) {
-        return str.startsWith("GL_")  || str.startsWith("GLU_") || str.startsWith("GLX_") ||
-               str.startsWith("EGL_") || str.startsWith("WGL_") || str.startsWith("AGL_") ||
-               str.startsWith("CGL_") ;
-    }
-
-    public static final int getExtensionIdx(String[] extensions, String str, boolean isGLFunc) {
-        if(isGLFunc) {
-            for(int i = extensions.length - 1 ; i>=0 ; i--) {
-                if( str.endsWith(extensions[i]) ) {
-                    return i;
-                }
-            }
-        } else {
-            for(int i = extensions.length - 1 ; i>=0 ; i--) {
-                if( str.endsWith("_"+extensions[i]) ) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    public static final boolean isExtension(String[] extensions, String str, boolean isGLFunc) {
-        return getExtensionIdx(extensions, str, isGLFunc)>=0;
-    }
-
-    public static final String getExtensionSuffix(String str, boolean isGLFunc) {
-        int idx = getExtensionIdx(extensionsARB, str, isGLFunc);
-        if(idx>=0) {
-            return extensionsARB[idx];
-        }
-        idx = getExtensionIdx(extensionsVEN, str, isGLFunc);
-        if(idx>=0) {
-            return extensionsVEN[idx];
-        }
-        return null;
-    }
-
-    public static final String normalize(String[] extensions, String str, boolean isGLFunc) {
-        boolean touched = false;
-        for(int i = extensions.length - 1 ; !touched && i>=0 ; i--) {
-            if(isGLFunc) {
-                if(str.endsWith(extensions[i])) {
-                    // functions
-                    str = str.substring(0, str.length()-extensions[i].length());
-                    touched=true;
-                }
-            } else {
-                if(str.endsWith("_"+extensions[i])) {
-                    // enums
-                    str = str.substring(0, str.length()-1-extensions[i].length());
-                    touched=true;
-                }
-            }
-        }
-        return str;
-    }
-    public static final String normalizeARB(String str, boolean isGLFunc) {
-        return normalize(extensionsARB, str, isGLFunc);
-    }
-    public static final boolean isExtensionARB(String str, boolean isGLFunc) {
-        return isExtension(extensionsARB, str, isGLFunc);
-    }
-    public static final String normalizeVEN(String str, boolean isGLFunc) {
-        return normalize(extensionsVEN, str, isGLFunc);
-    }
-    public static final boolean isExtensionVEN(String str, boolean isGLFunc) {
-        return isExtension(extensionsVEN, str, isGLFunc);
-    }
-    public static final String normalize(String str, boolean isGLFunc) {
-        if (isExtensionARB(str, isGLFunc)) {
-            return normalizeARB(str, isGLFunc);
-        }
-        if (isExtensionVEN(str, isGLFunc)) {
-            return normalizeVEN(str, isGLFunc);
-        }
-        return str;
-    }
-    public static final boolean isExtension(String str, boolean isGLFunc) {
-        return isExtension(extensionsARB, str, isGLFunc) || 
-               isExtension(extensionsVEN, str, isGLFunc);
-    }
-
-    public static final int getFuncNamePermutationNumber(String name) {
-        if(isExtensionARB(name, true) || isExtensionVEN(name, true)) {
-            // no name permutation, if it's already a known extension
-            return 1;
-        }
-        return 1 + extensionsARB.length + extensionsVEN.length;
-    }
-
-    public static final String getFuncNamePermutation(String name, int i) {
-        // identity
-        if(i==0) {
-            return name;
-        }
-        if(0>i || i>=(1+extensionsARB.length + extensionsVEN.length)) {
-            throw new RuntimeException("Index out of range [0.."+(1+extensionsARB.length+extensionsVEN.length-1)+"]: "+i);
-        }
-        // ARB
-        i-=1;
-        if(i<extensionsARB.length) {
-            return name+extensionsARB[i];
-        }
-        // VEN
-        i-=extensionsARB.length;
-        return name+extensionsVEN[i];
-    }
-}
-
diff --git a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
new file mode 100644
index 000000000..92554776a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLNameResolver.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ * 
+ */
+package com.jogamp.gluegen.runtime.opengl;
+
+/** Runtime utility identify and resolve extension names, which may be subsumed to core. */
+public class GLNameResolver {
+    //GL_XYZ : GL_XYZ, GL_XYZ_GL2, GL_XYZ_ARB, GL_XYZ_OES, GL_XYZ_OML
+    //GL_XYZ : GL_XYZ, GL_GL2_XYZ, GL_ARB_XYZ, GL_OES_XYZ, GL_OML_XYZ
+    //
+    // Pass-1 Unify ARB extensions with the same value
+    // Pass-2 Unify vendor extensions, 
+    //        if exist as an ARB extension with the same value.
+    // Pass-3 Emit
+
+    public static final String[] extensionsARB = { "ARB", "GL2", "OES", "KHR", "OML" };
+    public static final String[] extensionsVEN = { "3DFX", 
+                                                   "AMD",
+                                                   "ANGLE",
+                                                   "ARM",
+                                                   "APPLE",
+                                                   "ATI",
+                                                   "EXT",
+                                                   "HI",
+                                                   "HP",
+                                                   "IBM",
+                                                   "IMG",
+                                                   "MESA",
+                                                   "MESAX",
+                                                   "NV",
+                                                   "QCOM",
+                                                   "SGI",
+                                                   "SGIS",
+                                                   "SGIX",
+                                                   "SUN",
+                                                   "VIV",
+                                                   "WIN"
+                                                   };
+
+
+    public static final boolean isGLFunction(String str) {
+        return str.startsWith("gl")  || /* str.startsWith("glu") || str.startsWith("glX") || */
+               str.startsWith("egl") || str.startsWith("wgl") || str.startsWith("agl") ||
+               str.startsWith("cgl") ;
+    }
+
+    public static final boolean isGLEnumeration(String str) {
+        return str.startsWith("GL_")  || str.startsWith("GLU_") || str.startsWith("GLX_") ||
+               str.startsWith("EGL_") || str.startsWith("WGL_") || str.startsWith("AGL_") ||
+               str.startsWith("CGL_") ;
+    }
+
+    public static final int getExtensionIdx(String[] extensions, String str, boolean isGLFunc) {
+        if(isGLFunc) {
+            for(int i = extensions.length - 1 ; i>=0 ; i--) {
+                if( str.endsWith(extensions[i]) ) {
+                    return i;
+                }
+            }
+        } else {
+            for(int i = extensions.length - 1 ; i>=0 ; i--) {
+                if( str.endsWith("_"+extensions[i]) ) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    public static final boolean isExtension(String[] extensions, String str, boolean isGLFunc) {
+        return getExtensionIdx(extensions, str, isGLFunc)>=0;
+    }
+
+    public static final String getExtensionSuffix(String str, boolean isGLFunc) {
+        int idx = getExtensionIdx(extensionsARB, str, isGLFunc);
+        if(idx>=0) {
+            return extensionsARB[idx];
+        }
+        idx = getExtensionIdx(extensionsVEN, str, isGLFunc);
+        if(idx>=0) {
+            return extensionsVEN[idx];
+        }
+        return null;
+    }
+
+    public static final String normalize(String[] extensions, String str, boolean isGLFunc) {
+        boolean touched = false;
+        for(int i = extensions.length - 1 ; !touched && i>=0 ; i--) {
+            if(isGLFunc) {
+                if(str.endsWith(extensions[i])) {
+                    // functions
+                    str = str.substring(0, str.length()-extensions[i].length());
+                    touched=true;
+                }
+            } else {
+                if(str.endsWith("_"+extensions[i])) {
+                    // enums
+                    str = str.substring(0, str.length()-1-extensions[i].length());
+                    touched=true;
+                }
+            }
+        }
+        return str;
+    }
+    public static final String normalizeARB(String str, boolean isGLFunc) {
+        return normalize(extensionsARB, str, isGLFunc);
+    }
+    public static final boolean isExtensionARB(String str, boolean isGLFunc) {
+        return isExtension(extensionsARB, str, isGLFunc);
+    }
+    public static final String normalizeVEN(String str, boolean isGLFunc) {
+        return normalize(extensionsVEN, str, isGLFunc);
+    }
+    public static final boolean isExtensionVEN(String str, boolean isGLFunc) {
+        return isExtension(extensionsVEN, str, isGLFunc);
+    }
+    public static final String normalize(String str, boolean isGLFunc) {
+        if (isExtensionARB(str, isGLFunc)) {
+            return normalizeARB(str, isGLFunc);
+        }
+        if (isExtensionVEN(str, isGLFunc)) {
+            return normalizeVEN(str, isGLFunc);
+        }
+        return str;
+    }
+    public static final boolean isExtension(String str, boolean isGLFunc) {
+        return isExtension(extensionsARB, str, isGLFunc) || 
+               isExtension(extensionsVEN, str, isGLFunc);
+    }
+
+    public static final int getFuncNamePermutationNumber(String name) {
+        if(isExtensionARB(name, true) || isExtensionVEN(name, true)) {
+            // no name permutation, if it's already a known extension
+            return 1;
+        }
+        return 1 + extensionsARB.length + extensionsVEN.length;
+    }
+
+    public static final String getFuncNamePermutation(String name, int i) {
+        // identity
+        if(i==0) {
+            return name;
+        }
+        if(0>i || i>=(1+extensionsARB.length + extensionsVEN.length)) {
+            throw new RuntimeException("Index out of range [0.."+(1+extensionsARB.length+extensionsVEN.length-1)+"]: "+i);
+        }
+        // ARB
+        i-=1;
+        if(i<extensionsARB.length) {
+            return name+extensionsARB[i];
+        }
+        // VEN
+        i-=extensionsARB.length;
+        return name+extensionsVEN[i];
+    }
+}
+
diff --git a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLProcAddressResolver.java b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLProcAddressResolver.java
index fe9efebc7..9775de491 100644
--- a/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLProcAddressResolver.java
+++ b/src/jogl/classes/com/jogamp/gluegen/runtime/opengl/GLProcAddressResolver.java
@@ -45,10 +45,10 @@ public class GLProcAddressResolver implements FunctionAddressResolver {
     public long resolve(String name, DynamicLookupHelper lookup) {
 
         long newProcAddress = 0;
-        int permutations = GLExtensionNames.getFuncNamePermutationNumber(name);
+        int permutations = GLNameResolver.getFuncNamePermutationNumber(name);
 
         for (int i = 0; 0 == newProcAddress && i < permutations; i++) {
-            String funcName = GLExtensionNames.getFuncNamePermutation(name, i);
+            String funcName = GLNameResolver.getFuncNamePermutation(name, i);
             try {
                 newProcAddress = lookup.dynamicLookupFunction(funcName);
             } catch (Exception e) {
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
new file mode 100644
index 000000000..644d87b1a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -0,0 +1,1943 @@
+/**
+ * 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 com.jogamp.opengl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLBase;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.Debug;
+
+import com.jogamp.opengl.FBObject.Attachment.Type;
+
+/**
+ * Core utility class simplifying usage of framebuffer objects (FBO)
+ * with all {@link GLProfile}s. 
+ * <p>
+ * Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int)}
+ * while preserving the {@link Attachment} references.
+ * </p>
+ * <p>
+ * Integrates default read/write framebuffers via {@link GLContext#getDefaultReadFramebuffer()} and {@link GLContext#getDefaultReadFramebuffer()},
+ * which is being hooked at {@link GL#glBindFramebuffer(int, int)} when the default (<code>zero</code>) framebuffer is selected.
+ * </p>
+ * 
+ * <p>FIXME: Implement support for {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} .</p>
+ */
+public class FBObject {
+    protected static final boolean DEBUG = Debug.debug("FBObject");
+    
+    /** 
+     * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
+     * <p>
+     * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+     * <code>ARB_ES2_compatibility</code>, <code>ARB_framebuffer_object</code>, <code>EXT_framebuffer_object</code> or <code>OES_framebuffer_object</code>.
+     * </p>
+     * <p>
+     * Basic FBO support may only include one color attachment and no multisampling,
+     * as well as limited internal formats for renderbuffer.
+     * </p>
+     * @see GLContext#hasFBO()
+     */
+    public static final boolean supportsBasicFBO(GL gl) {
+        return gl.getContext().hasFBO();
+    }
+  
+    /** 
+     * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>.
+     * <p>
+     * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+     * <code>ARB_framebuffer_object</code>, or all of
+     * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>, 
+     * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+     * </p>
+     * <p>
+     * Full FBO support includes multiple color attachments and multisampling.
+     * </p>
+     */
+    public static final boolean supportsFullFBO(GL gl) {
+        return gl.isGL3() ||                                                         // GL >= 3.0
+                
+               gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) ||       // ARB_framebuffer_object
+               
+               ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) &&     // All EXT_framebuffer_object*
+                 gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+                 gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+                 gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ) ;
+    }
+    
+    public static final int getMaxSamples(GL gl) {
+        if( supportsFullFBO(gl) ) {
+            int[] val = new int[] { 0 } ;
+            gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+            return val[0];
+        } else {
+            return 0;
+        }
+    }
+    
+    /** Common super class of all attachments */
+    public static abstract class Attachment {
+        public enum Type { 
+            NONE, DEPTH, STENCIL, DEPTH_STENCIL, COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE;
+            
+            /** 
+             * Returns {@link #COLOR}, {@link #DEPTH}, {@link #STENCIL} or {@link #DEPTH_STENCIL}
+             * @throws IllegalArgumentException if <code>format</code> cannot be handled. 
+             */
+            public static Type determine(int format) throws IllegalArgumentException {
+                switch(format) {
+                    case GL.GL_RGBA4:
+                    case GL.GL_RGB5_A1:
+                    case GL.GL_RGB565:
+                    case GL.GL_RGB8:
+                    case GL.GL_RGBA8:
+                        return Type.COLOR;
+                    case GL.GL_DEPTH_COMPONENT16:
+                    case GL.GL_DEPTH_COMPONENT24:
+                    case GL.GL_DEPTH_COMPONENT32:
+                        return Type.DEPTH;
+                    case GL.GL_STENCIL_INDEX1:
+                    case GL.GL_STENCIL_INDEX4:
+                    case GL.GL_STENCIL_INDEX8:
+                        return Type.STENCIL;
+                    case GL.GL_DEPTH24_STENCIL8:
+                        return Type.DEPTH_STENCIL;
+                    default:
+                        throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+                }        
+            }
+        };
+                
+        /** immutable type [{@link #COLOR}, {@link #DEPTH}, {@link #STENCIL}, {@link #COLOR_TEXTURE}, {@link #DEPTH_TEXTURE}, {@link #STENCIL_TEXTURE} ] */
+        public final Type type;
+        
+        /** immutable the internal format */
+        public final int format;
+        
+        private int width, height;
+        
+        private int name;
+        
+        /** <code>true</code> if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
+        protected boolean resourceOwner;
+        
+        private int initCounter;
+        
+        protected Attachment(Type type, int iFormat, int width, int height, int name) {
+            this.type = type;
+            this.format = iFormat;
+            this.width = width;
+            this.height = height;
+            this.name = name;
+            this.resourceOwner = false;
+            this.initCounter = 0;
+        }
+        
+        /** width of attachment */
+        public final int getWidth() { return width; }
+        /** height of attachment */
+        public final int getHeight() { return height; }
+        /* pp */ final void setSize(int w, int h) { width = w; height = h; }
+        
+        /** buffer name [1..max], maybe a texture or renderbuffer name, depending on type. */
+        public final int getName() { return name; }        
+        /* pp */ final void setName(int n) { name = n; }
+        
+        public final int getInitCounter() { return initCounter; }
+        
+        /** 
+         * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+         * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.</p>
+         * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case. 
+         */
+        public void initialize(GL gl) throws GLException {
+            initCounter++;
+            /*
+            super.initialize(gl);
+            if(1 == getInitCounter() && 0 == getName()  ) {
+                do init ..
+                freeResources = true; // if all OK
+            }
+            */
+        }
+        
+        /** 
+         * Releases the attachment buffer if initialized, i.e. name is <code>zero</code>.
+         * <p>Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.</p>
+         * @throws GLException if buffer release fails. 
+         */
+        public void free(GL gl) throws GLException {
+            /*
+            if(1 == getInitCounter() && freeResources && .. ) {
+                do free ..
+            }
+            super.free(gl);
+            */
+            initCounter--;
+            if(0 == initCounter) {
+                resourceOwner = false;
+                name = 0;
+            }
+            if(DEBUG) {
+                System.err.println("Attachment.free: "+this);
+            }
+        }
+        
+        /**
+         * <p>
+         * Comparison by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
+         * </p>
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object o) {
+            if( this == o ) return true;
+            if( ! ( o instanceof Attachment ) ) return false;
+            final Attachment a = (Attachment)o;
+            return type == a.type &&
+                   format == a.format ||
+                   width == a.width   ||
+                   height== a.height  ||
+                   name == a.name     ;
+        }
+        
+        /**
+         * <p>
+         * Hashed by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
+         * </p>
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            // 31 * x == (x << 5) - x
+            int hash = 31 + type.ordinal();
+            hash = ((hash << 5) - hash) + format;
+            hash = ((hash << 5) - hash) + width;
+            hash = ((hash << 5) - hash) + height;
+            hash = ((hash << 5) - hash) + name;
+            return hash;
+        }
+        
+        int objectHashCode() { return super.hashCode(); }
+        
+        public String toString() {
+            return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
+                   ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+
+                   ", resOwner "+resourceOwner+", initCount "+initCounter+"]";
+        }
+        
+        public static Type getType(int attachmentPoint, int maxColorAttachments) {
+            if( GL.GL_COLOR_ATTACHMENT0 <= attachmentPoint && attachmentPoint < GL.GL_COLOR_ATTACHMENT0+maxColorAttachments ) {
+                return Type.COLOR;
+            }
+            switch(attachmentPoint) {
+                case GL.GL_DEPTH_ATTACHMENT:
+                    return Type.DEPTH;
+                case GL.GL_STENCIL_ATTACHMENT:            
+                    return Type.STENCIL;
+                default: 
+                    throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint));
+            }
+        }
+    }
+    
+    /** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
+    public static class RenderAttachment extends Attachment {
+        private int samples;
+        
+        /**
+         * @param type allowed types are {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
+         * @param iFormat
+         * @param samples
+         * @param width
+         * @param height
+         * @param name
+         */
+        public RenderAttachment(Type type, int iFormat, int samples, int width, int height, int name) {
+            super(validateType(type), iFormat, width, height, name);
+            this.samples = samples;
+        }
+        
+        /** number of samples, or zero for no multisampling */
+        public final int getSamples() { return samples; }
+        /* pp */ final void setSamples(int s) { samples = s; }
+        
+        private static Type validateType(Type type) {
+            switch(type) {
+                case DEPTH:
+                case STENCIL:
+                case COLOR:
+                    return type;
+                default: 
+                    throw new IllegalArgumentException("Invalid type: "+type);
+            }
+        }
+        
+        /**
+         * <p>
+         * Comparison by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
+         * </p>
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object o) {
+            if( this == o ) return true;
+            if( ! ( o instanceof RenderAttachment ) ) return false;
+            return super.equals(o) &&
+                   samples == ((RenderAttachment)o).samples;
+        }
+        
+        /**
+         * <p>
+         * Hashed by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
+         * </p>
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            // 31 * x == (x << 5) - x
+            int hash = super.hashCode();
+            hash = ((hash << 5) - hash) + samples;
+            return hash;
+        }
+
+        @Override
+        public void initialize(GL gl) throws GLException {
+            super.initialize(gl);
+            if( 1 == getInitCounter() && 0 == getName() ) {
+                final int[] name = new int[] { -1 };
+                gl.glGenRenderbuffers(1, name, 0);
+                if( 0 == name[0] ) {
+                    throw new GLException("null renderbuffer, "+this);
+                }
+                setName(name[0]);
+                
+                gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
+                if( samples > 0 ) {
+                    ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());            
+                } else {
+                    gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
+                }
+                int glerr = gl.glGetError();
+                if(GL.GL_NO_ERROR != glerr) {
+                    gl.glDeleteRenderbuffers(1, name, 0);
+                    setName(0);
+                    throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+                }
+                resourceOwner = true;
+                if(DEBUG) {
+                    System.err.println("Attachment.init: "+this);
+                }
+            }
+        }
+        
+        @Override
+        public void free(GL gl) {
+            if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
+                final int[] name = new int[] { getName() };
+                gl.glDeleteRenderbuffers(1, name, 0);
+            }
+            super.free(gl);
+        }
+        
+        public String toString() {
+            return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
+                   ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+
+                   ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]";
+        }
+    }
+    
+    /** 
+     * Marker interface, denotes a color buffer attachment.
+     * <p>Always an instance of {@link Attachment}.</p>
+     * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b> 
+     */
+    public static interface Colorbuffer {        
+    }
+    
+    /** Color render buffer attachment  */
+    public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
+        public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
+            super(Type.COLOR, iFormat, samples, width, height, name);
+        }    
+    }
+    
+    /** Texture attachment */
+    public static class TextureAttachment extends Attachment implements Colorbuffer  {
+        /** details of the texture setup */
+        public final int dataFormat, dataType, magFilter, minFilter, wrapS, wrapT;
+
+        /**
+         * @param type allowed types are [ {@link Type#COLOR_TEXTURE}, {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} ]
+         * @param iFormat
+         * @param width
+         * @param height
+         * @param dataFormat
+         * @param dataType
+         * @param magFilter
+         * @param minFilter
+         * @param wrapS
+         * @param wrapT
+         * @param name
+         */
+        public TextureAttachment(Type type, int iFormat, int width, int height, int dataFormat, int dataType, 
+                                 int magFilter, int minFilter, int wrapS, int wrapT, int name) {
+            super(validateType(type), iFormat, width, height, name);
+            this.dataFormat = dataFormat;
+            this.dataType = dataType;
+            this.magFilter = magFilter;
+            this.minFilter = minFilter;
+            this.wrapS = wrapS;
+            this.wrapT = wrapT;
+        }
+        
+        private static Type validateType(Type type) {
+            switch(type) {
+                case COLOR_TEXTURE:
+                case DEPTH_TEXTURE:
+                case STENCIL_TEXTURE:
+                    return type;
+                default: 
+                    throw new IllegalArgumentException("Invalid type: "+type);
+            }
+        }
+        
+        /** 
+         * Initializes the texture and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
+         * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case. 
+         */
+        @Override
+        public void initialize(GL gl) throws GLException {
+            super.initialize(gl);
+            if( 1 == getInitCounter() && 0 == getName() ) {
+                final int[] name = new int[] { -1 };            
+                gl.glGenTextures(1, name, 0);
+                if(0 == name[0]) {
+                    throw new GLException("null texture, "+this);
+                }
+                setName(name[0]);
+                
+                gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
+                gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+                if( 0 < magFilter ) {
+                    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
+                }
+                if( 0 < minFilter ) {
+                    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter);
+                }
+                if( 0 < wrapS ) {
+                    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
+                }
+                if( 0 < wrapT ) {
+                    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);            
+                }        
+                int glerr = gl.glGetError();
+                if(GL.GL_NO_ERROR != glerr) {
+                    gl.glDeleteTextures(1, name, 0);
+                    setName(0);
+                    throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+                }
+                resourceOwner = true;
+            }
+            if(DEBUG) {
+                System.err.println("Attachment.init: "+this);
+            }
+        }
+
+        @Override
+        public void free(GL gl) {
+            if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
+                final int[] name = new int[] { getName() };
+                gl.glDeleteTextures(1, name, 0);
+            }
+            super.free(gl);
+        }
+    }
+    
+    private boolean initialized;
+    private boolean basicFBOSupport;
+    private boolean fullFBOSupport;
+    private boolean rgba8Avail;
+    private boolean depth24Avail;
+    private boolean depth32Avail;
+    private boolean stencil01Avail;
+    private boolean stencil04Avail;
+    private boolean stencil08Avail;
+    private boolean stencil16Avail;
+    private boolean packedDepthStencilAvail;            
+    private int maxColorAttachments, maxSamples, maxTextureSize, maxRenderbufferSize;
+
+    private int width, height, samples;
+    private int vStatus;
+    private int fbName;
+    private boolean bound;
+
+    private int colorAttachmentCount;
+    private Colorbuffer[] colorAttachmentPoints; // colorbuffer attachment points 
+    private RenderAttachment depth, stencil; // depth and stencil maybe equal in case of packed-depth-stencil
+
+    private final FBObject samplesSink; // MSAA sink
+    private TextureAttachment samplesSinkTexture; 
+    private boolean samplesSinkDirty;
+
+    //
+    // ColorAttachment helper ..
+    //
+    
+    private final void validateColorAttachmentPointRange(int point) {
+        if(maxColorAttachments != colorAttachmentPoints.length) {
+            throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
+        }
+        if(0 > point || point >= maxColorAttachments) {
+            throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+        }
+    }
+    
+    private final void validateAddColorAttachment(int point, Colorbuffer ca) {
+        validateColorAttachmentPointRange(point);
+        if( null != colorAttachmentPoints[point] ) {
+            throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]);
+        }        
+    }
+    
+    private final void addColorAttachment(int point, Colorbuffer ca) {
+        validateColorAttachmentPointRange(point);
+        final Colorbuffer c = colorAttachmentPoints[point];
+        if( null != c && c != ca ) {
+            throw new IllegalArgumentException("Add failed: requested to add "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+        }
+        colorAttachmentPoints[point] = ca;
+        colorAttachmentCount++;
+    }
+    
+    private final void removeColorAttachment(int point, Colorbuffer ca) {
+        validateColorAttachmentPointRange(point);
+        final Colorbuffer c = colorAttachmentPoints[point];
+        if( null != c && c != ca ) {
+            throw new IllegalArgumentException("Remove failed: requested to removed "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+        }
+        colorAttachmentPoints[point] = null;
+        colorAttachmentCount--;
+    }
+    
+    /**
+     * Return the {@link Colorbuffer} attachment at <code>attachmentPoint</code> if it is attached to this FBO, otherwise null.
+     * 
+     * @see #attachColorbuffer(GL, boolean)
+     * @see #attachColorbuffer(GL, boolean)
+     * @see #attachTexture2D(GL, int, boolean, int, int, int, int)
+     * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int) 
+     */
+    public final Colorbuffer getColorbuffer(int attachmentPoint) {
+        validateColorAttachmentPointRange(attachmentPoint);        
+        return colorAttachmentPoints[attachmentPoint];
+    }
+    
+    /**
+     * Finds the passed {@link Colorbuffer} within the valid range of attachment points
+     * using <i>reference</i> comparison only.
+     * <p>
+     * Note: Slow. Implementation uses a logN array search to save resources, i.e. not using a HashMap.
+     * </p>
+     * @param ca the {@link Colorbuffer} to look for.
+     * @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1] 
+     */
+    public final int getColorbufferAttachmentPoint(Colorbuffer ca) {
+        for(int i=0; i<colorAttachmentPoints.length; i++) {
+            if( colorAttachmentPoints[i] == ca ) {
+                return i; 
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * Returns the passed {@link Colorbuffer} if it is attached to this FBO, otherwise null.
+     * Implementation compares the <i>reference</i> only.
+     * 
+     * <p>
+     * Note: Slow. Uses {@link #getColorbufferAttachmentPoint(Colorbuffer)} to determine it's attachment point
+     *       to be used for {@link #getColorbuffer(int)}
+     * </p>
+     * 
+     * @see #attachColorbuffer(GL, boolean)
+     * @see #attachColorbuffer(GL, boolean)
+     * @see #attachTexture2D(GL, int, boolean, int, int, int, int)
+     * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int) 
+     */
+    public final Colorbuffer getColorbuffer(Colorbuffer ca) {
+        final int p = getColorbufferAttachmentPoint(ca);
+        return p>=0 ? getColorbuffer(p) : null;
+    }
+        
+    /**
+     * Creates an uninitialized FBObject instance.
+     * <p>
+     * Call {@link #init(GL, int, int, int)} .. etc to use it.
+     * </p>
+     */
+    public FBObject() {
+        this(false);
+    }
+    /* pp */ FBObject(boolean isSampleSink) {
+        this.initialized = false;
+        
+        // TBD @ init
+        this.basicFBOSupport = false;
+        this.fullFBOSupport = false;
+        this.rgba8Avail = false;
+        this.depth24Avail = false;
+        this.depth32Avail = false;
+        this.stencil01Avail = false;
+        this.stencil04Avail = false;
+        this.stencil08Avail = false;
+        this.stencil16Avail = false;
+        this.packedDepthStencilAvail = false;
+        this.maxColorAttachments=-1;
+        this.maxSamples=-1;
+        this.maxTextureSize = 0;
+        this.maxRenderbufferSize = 0;
+        
+        this.width = 0;
+        this.height = 0;
+        this.samples = 0;
+        this.vStatus = -1;        
+        this.fbName = 0;
+        this.bound = false;
+        
+        this.colorAttachmentPoints = null; // at init ..
+        this.colorAttachmentCount = 0;
+        this.depth = null;
+        this.stencil = null;                
+        
+        this.samplesSink = isSampleSink ? null : new FBObject(true);
+        this.samplesSinkTexture = null;
+        this.samplesSinkDirty = true;
+    }
+    
+    private void init(GL gl, int width, int height, int samples) throws GLException {
+        if(initialized) {
+            throw new GLException("FBO already initialized");
+        }        
+        fullFBOSupport = supportsFullFBO(gl);
+        
+        if( !fullFBOSupport && !supportsBasicFBO(gl) ) {
+            throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
+        }
+        
+        basicFBOSupport = true;
+        
+        rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
+        depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
+        depth32Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth32);
+        stencil01Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil1);
+        stencil04Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil4);
+        stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8);
+        stencil16Avail = fullFBOSupport;
+        
+        packedDepthStencilAvail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil);
+        
+        final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments);
+                                
+        int val[] = new int[1];
+        
+        int glerr = gl.glGetError();
+        if(DEBUG && GL.GL_NO_ERROR != glerr) {
+            System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr));
+        }
+
+        int realMaxColorAttachments = 1;
+        maxColorAttachments = 1;
+        if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) {
+            try {
+                gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
+                glerr = gl.glGetError();
+                if(GL.GL_NO_ERROR == glerr) {
+                    realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
+                } else if(DEBUG) {
+                    System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr));
+                }
+            } catch (GLException gle) {}
+        }
+        maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
+        
+        colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
+        colorAttachmentCount = 0;
+        
+        maxSamples = 0;
+        if(fullFBOSupport) {
+            gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+            glerr = gl.glGetError();
+            if(GL.GL_NO_ERROR == glerr) {
+                maxSamples = val[0];
+            } else if(DEBUG) {
+                System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+            }
+        }
+        gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
+        maxTextureSize = val[0];
+        gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
+        this.maxRenderbufferSize = val[0];
+        
+        glerr = gl.glGetError();
+        if(DEBUG && GL.GL_NO_ERROR != glerr) {
+            System.err.println("FBObject.init-preexisting.1 GL Error 0x"+Integer.toHexString(glerr));
+        }
+        
+        this.width = width;
+        this.height = height;
+        this.samples = samples <= maxSamples ? samples : maxSamples;
+        
+        if(DEBUG) {
+            System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples");
+            System.err.println("basicFBOSupport:          "+basicFBOSupport);
+            System.err.println("fullFBOSupport:           "+fullFBOSupport);
+            System.err.println("maxColorAttachments:      "+maxColorAttachments+"/"+realMaxColorAttachments);
+            System.err.println("maxSamples:               "+maxSamples);
+            System.err.println("maxTextureSize:           "+maxTextureSize);
+            System.err.println("maxRenderbufferSize:      "+maxRenderbufferSize);
+            System.err.println("rgba8:                    "+rgba8Avail);
+            System.err.println("depth24:                  "+depth24Avail);
+            System.err.println("depth32:                  "+depth32Avail);
+            System.err.println("stencil01:                "+stencil01Avail);
+            System.err.println("stencil04:                "+stencil04Avail);
+            System.err.println("stencil08:                "+stencil08Avail);
+            System.err.println("stencil16:                "+stencil16Avail);
+            System.err.println("packedDepthStencil:       "+packedDepthStencilAvail);
+            System.err.println("NV_fbo_color_attachments: "+NV_fbo_color_attachments);
+            System.err.println(gl.getContext().getGLVersion());
+            System.err.println(JoglVersion.getGLStrings(gl, null).toString());
+            System.err.println(gl.getContext());
+        }
+        
+        checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
+        
+        if(width > 2 + maxTextureSize  || height> 2 + maxTextureSize ||
+           width > maxRenderbufferSize || height> maxRenderbufferSize  ) {
+            throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
+        }
+
+        if(null != samplesSink) {        
+            // init sampling sink
+            samplesSink.reset(gl, width, height);
+            resetMSAATexture2DSink(gl);
+        }
+
+        // generate fbo ..
+        gl.glGenFramebuffers(1, val, 0);
+        fbName = val[0];
+        if(0 == fbName) {
+            throw new GLException("null framebuffer");
+        }
+
+        // bind fbo ..
+        gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbName);        
+        checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB");  // throws GLException if error        
+        if(!gl.glIsFramebuffer(fbName)) {
+            checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
+        }
+        bound = true;        
+        initialized = true;
+        
+        updateStatus(gl);
+        if(DEBUG) {
+            System.err.println("FBObject.init(): "+this);
+        }
+    }
+
+    /**
+     * Initializes or resets this FBO's instance.
+     * <p>
+     * In case the new parameters are compatible with the current ones
+     * no action will be performed. Otherwise all attachments will be recreated
+     * to match the new given parameters.
+     * </p>
+     * <p>
+     * Currently incompatibility and hence recreation is given if
+     * the size or sample count doesn't match for subsequent calls.
+     * </p>
+     * 
+     * <p>Leaves the FBO bound state untouched</p>
+     * 
+     * @param gl the current GL context
+     * @param newWidth
+     * @param newHeight
+     * @throws GLException in case of an error
+     */
+    public final void reset(GL gl, int newWidth, int newHeight) {
+        reset(gl, newWidth, newHeight, 0);
+    }
+    
+    /**
+     * Initializes or resets this FBO's instance.
+     * <p>
+     * In case the new parameters are compatible with the current ones
+     * no action will be performed. Otherwise all attachments will be recreated
+     * to match the new given parameters.
+     * </p>
+     * <p>
+     * Currently incompatibility and hence recreation is given if
+     * the size or sample count doesn't match for subsequent calls.
+     * </p>
+     * 
+     * <p>Leaves the FBO bound state untouched</p>
+     * 
+     * @param gl the current GL context
+     * @param newWidth
+     * @param newHeight
+     * @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
+     * @throws GLException in case of an error
+     */
+    public final void reset(GL gl, int newWidth, int newHeight, int newSamples) {
+        if(!initialized) {
+            init(gl, newWidth, newHeight, newSamples);
+            return;
+        }
+        newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
+        
+        if( newWidth !=  width || newHeight !=  height || newSamples != samples ) {
+            if(DEBUG) {
+                System.err.println("FBObject.reset - START - "+this);
+            }        
+            
+            final boolean wasBound = isBound();
+            
+            width = newWidth;
+            height = newHeight;
+            samples = newSamples;
+            detachAllImpl(gl, true , true);
+            resetMSAATexture2DSink(gl);
+            
+            if(wasBound) {
+                bind(gl);
+            } else {
+                unbind(gl);
+            }
+            
+            if(DEBUG) {
+                System.err.println("FBObject.reset - END - "+this);
+            }
+        }        
+    }
+            
+    /** 
+     * Note that the status may reflect an incomplete state during transition of attachments.
+     * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
+     * @see #validateStatus() 
+     */
+    public final int getStatus() {
+        return vStatus;
+    }
+
+    /** return the {@link #getStatus()} as a string. */
+    public final String getStatusString() {
+        return getStatusString(vStatus);
+    }
+    
+    public static final String getStatusString(int fbStatus) {
+        switch(fbStatus) {
+            case -1:
+                return "NOT A FBO";
+                
+            case GL.GL_FRAMEBUFFER_COMPLETE:
+                return "OK";
+                
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+                return("GL FBO: incomplete, incomplete attachment\n");
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+                return("GL FBO: incomplete, missing attachment");
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+                return("GL FBO: incomplete, attached images must have same dimensions");
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+                 return("GL FBO: incomplete, attached images must have same format");
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+                return("GL FBO: incomplete, missing draw buffer");
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+                return("GL FBO: incomplete, missing read buffer");
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+                return("GL FBO: incomplete, missing multisample buffer");
+            case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:                
+                return("GL FBO: incomplete, layer targets");
+                
+            case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+                return("GL FBO: Unsupported framebuffer format");
+            case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+                 return("GL FBO: framebuffer undefined");
+                 
+            case 0:
+                return("GL FBO: incomplete, implementation fault");
+            default:
+                return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus));
+        }
+    }
+    
+    /**
+     * The status may even be valid if incomplete during transition of attachments.
+     * @see #getStatus()
+     */
+    public final boolean isStatusValid() {
+        switch(vStatus) {
+            case GL.GL_FRAMEBUFFER_COMPLETE:
+                return true;
+                
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+            case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+            case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+            case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+                if(0 == colorAttachmentCount || null == depth) {
+                    // we are in transition
+                    return true;
+                }
+         
+            case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+            case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+                
+            case 0:                
+            default:
+                System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) + 
+                        " : " + getStatusString(vStatus));
+                return false;
+        }
+    }
+        
+    private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
+        if(GL.GL_NO_ERROR != err) {
+            if(null != gl) {
+                destroy(gl);
+            }
+            if(null != exceptionMessage) {
+                throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private final void checkInitialized() throws GLException {
+        if(!initialized) {
+            throw new GLException("FBO not initialized, call init(GL) first.");
+        }                
+    }
+    
+    /**
+     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+     * selecting the texture data type and format automatically.
+     * 
+     * <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
+     * 
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     */
+    public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+        return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+    }
+    
+    /**
+     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+     * selecting the texture data type and format automatically.
+     * 
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
+     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+     * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     */
+    public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
+        final int textureInternalFormat, textureDataFormat, textureDataType;
+        if(gl.isGLES()) { 
+            textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+            textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+            textureDataType = GL.GL_UNSIGNED_BYTE;
+        } else { 
+            textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+            textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+            textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+        }
+        return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+    }
+    
+    /**
+     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+     * 
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
+     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+     * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     */
+    public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint,
+                                                   int internalFormat, int dataFormat, int dataType,
+                                                   int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
+        return attachTexture2D(gl, attachmentPoint, 
+                               new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType, 
+                                                     magFilter, minFilter, wrapS, wrapT, 0 /* name */));
+    }
+    
+    /**
+     * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+     *  
+     * <p>
+     * In case the passed TextureAttachment <code>texA</code> is uninitialized, i.e. it's texture name is <code>zero</code>,
+     * a new texture name is generated and setup w/ the texture parameter.<br/>
+     * Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
+     * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue. 
+     * </p>
+     *    
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above. 
+     * @return the passed TextureAttachment <code>texA</code> instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+     */
+    public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
+        validateAddColorAttachment(attachmentPoint, texA);
+        
+        if(samples>0) {
+            removeColorAttachment(attachmentPoint, texA);
+            throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+        }
+        
+        texA.initialize(gl);
+        addColorAttachment(attachmentPoint, texA);
+                
+        bind(gl);
+
+        // Set up the color buffer for use as a renderable texture:
+        gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+                                  GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+                                  GL.GL_TEXTURE_2D, texA.getName(), 0);
+        updateStatus(gl);
+        
+        if(!isStatusValid()) {
+            detachColorbuffer(gl, attachmentPoint);
+            throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+        }
+        if(DEBUG) {
+            System.err.println("FBObject.attachTexture2D: "+this);
+        }
+        return texA;
+    }
+    
+    /**
+     * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+     * selecting the format automatically.
+     *  
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
+     * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the colorbuffer couldn't be allocated
+     */
+    public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+        final int internalFormat;
+        if( rgba8Avail ) {
+            internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+        } else {
+            internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
+        }
+        return attachColorbuffer(gl, attachmentPoint, internalFormat);
+    }
+    
+    /**
+     * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+     *  
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param internalFormat usually {@link GL#GL_RGBA4}, {@link GL#GL_RGB5_A1}, {@link GL#GL_RGB565}, {@link GL#GL_RGB8} or {@link GL#GL_RGBA8}  
+     * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the colorbuffer couldn't be allocated
+     * @throws IllegalArgumentException if <code>internalFormat</code> doesn't reflect a colorbuffer
+     */
+    public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
+        final Attachment.Type atype = Attachment.Type.determine(internalFormat);
+        if( Attachment.Type.COLOR != atype ) {
+            throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+        }
+        
+        return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+    }
+    
+    /**
+     * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+     *  
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl
+     * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+     * @param colA the template for the new {@link ColorAttachment}   
+     * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+     * @throws GLException in case the colorbuffer couldn't be allocated
+     */
+    public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException {
+        validateAddColorAttachment(attachmentPoint, colA);
+        
+        colA.initialize(gl);        
+        addColorAttachment(attachmentPoint, colA);
+        
+        bind(gl);
+                
+        // Attach the color buffer
+        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
+                                     GL.GL_COLOR_ATTACHMENT0 + attachmentPoint, 
+                                     GL.GL_RENDERBUFFER, colA.getName());
+
+        updateStatus(gl);                
+        if(!isStatusValid()) {
+            detachColorbuffer(gl, attachmentPoint);
+            throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+        }
+        if(DEBUG) {
+            System.err.println("FBObject.attachColorbuffer: "+this);
+        }
+        return colA;
+    }
+
+    
+    /**
+     * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
+     * selecting the internalFormat automatically.
+     * <p>
+     * Stencil and depth buffer can be attached only once.
+     * </p>
+     * <p>
+     * In case the desired type or bit-number is not supported, the next available one is chosen.
+     * </p>  
+     * <p>
+     * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details
+     * about the attached buffer. The details cannot be returned, since it's possible 2 buffers
+     * are being created, depth and stencil.
+     * </p>
+     * 
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl
+     * @param atype either {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#DEPTH_STENCIL}  
+     * @param reqBits desired bits for depth or -1 for default (24 bits)
+     * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached.
+     * @throws IllegalArgumentException
+     * @see #getDepthAttachment()
+     * @see #getStencilAttachment()
+     */
+    public final void attachRenderbuffer(GL gl, Attachment.Type atype, int reqBits) throws GLException, IllegalArgumentException {        
+        if( 0 > reqBits ) {
+            reqBits = 24;
+        }        
+        final int internalFormat;
+        int internalStencilFormat = -1;
+        
+        switch ( atype ) {
+            case DEPTH:
+                if( 32 <= reqBits && depth32Avail ) {
+                    internalFormat = GL.GL_DEPTH_COMPONENT32;
+                } else if( 24 <= reqBits && depth24Avail ) {
+                    internalFormat = GL.GL_DEPTH_COMPONENT24;
+                } else {
+                    internalFormat = GL.GL_DEPTH_COMPONENT16;                    
+                }
+                break;
+                
+            case STENCIL:
+                if( 16 <= reqBits && stencil16Avail ) {
+                    internalFormat = GL2GL3.GL_STENCIL_INDEX16;
+                } else if( 8 <= reqBits && stencil08Avail ) {
+                    internalFormat = GL.GL_STENCIL_INDEX8;
+                } else if( 4 <= reqBits && stencil04Avail ) {
+                    internalFormat = GL.GL_STENCIL_INDEX4;
+                } else if( 1 <= reqBits && stencil01Avail ) {
+                    internalFormat = GL.GL_STENCIL_INDEX1;
+                } else {
+                    throw new GLException("stencil buffer n/a");        
+                }
+                break;
+                
+            case DEPTH_STENCIL:
+                if( packedDepthStencilAvail ) {
+                    internalFormat = GL.GL_DEPTH24_STENCIL8;
+                } else {
+                    if( 24 <= reqBits && depth24Avail ) {
+                        internalFormat = GL.GL_DEPTH_COMPONENT24;
+                    } else {
+                        internalFormat = GL.GL_DEPTH_COMPONENT16;                    
+                    }
+                    if( stencil08Avail ) {
+                        internalStencilFormat = GL.GL_STENCIL_INDEX8;
+                    } else if( stencil04Avail ) {
+                        internalStencilFormat = GL.GL_STENCIL_INDEX4;
+                    } else if( stencil01Avail ) {
+                        internalStencilFormat = GL.GL_STENCIL_INDEX1;
+                    } else {
+                        throw new GLException("stencil buffer n/a");
+                    }
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
+        }
+        
+        attachRenderbufferImpl(gl, atype, internalFormat);
+        
+        if(0<=internalStencilFormat) {
+            attachRenderbufferImpl(gl, Attachment.Type.STENCIL, internalStencilFormat);
+        }
+    }
+    
+    /**
+     * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
+     * depending on the <code>internalFormat</code>. 
+     * <p>
+     * Stencil and depth buffer can be attached only once.
+     * </p>
+     * <p>
+     * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details
+     * about the attached buffer. The details cannot be returned, since it's possible 2 buffers
+     * are being created, depth and stencil.
+     * </p>
+     * 
+     * <p>Leaves the FBO bound.</p>
+     * 
+     * @param gl the current GL context
+     * @param internalFormat {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24}, {@link GL#GL_DEPTH_COMPONENT32},
+     *                       {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8}
+     *                       or {@link GL#GL_DEPTH24_STENCIL8}
+     * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached.
+     * @throws IllegalArgumentException
+     * @see #getDepthAttachment()
+     * @see #getStencilAttachment()
+     */
+    public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException {
+        final Attachment.Type atype = Attachment.Type.determine(internalFormat);
+        if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) {
+            throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+        }
+        attachRenderbufferImpl(gl, atype, internalFormat);
+    }
+    
+    protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
+        if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
+            throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+        }        
+        if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
+            throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+        }
+        attachRenderbufferImpl2(gl, atype, internalFormat);
+    }
+        
+    private final void attachRenderbufferImpl2(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
+        if( Attachment.Type.DEPTH == atype ) {
+            if(null == depth) {
+                depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+            } else {
+                depth.setSize(width, height);
+                depth.setSamples(samples);
+            }
+            depth.initialize(gl);
+        } else if( Attachment.Type.STENCIL == atype ) {
+            if(null == stencil) {
+                stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, 0);
+            } else {
+                stencil.setSize(width, height);
+                stencil.setSamples(samples);
+            }
+            stencil.initialize(gl);
+        } else if( Attachment.Type.DEPTH_STENCIL == atype ) {
+            if(null == depth) {
+                depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+            } else {
+                depth.setSize(width, height);
+                depth.setSamples(samples);
+            }
+            depth.initialize(gl);
+            if(null == stencil) {
+                stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, depth.getName());
+            } else {
+                stencil.setName(depth.getName());
+                stencil.setSize(width, height);
+                stencil.setSamples(samples);
+            }
+            stencil.initialize(gl);
+        }
+
+        bind(gl);
+        
+        // Attach the buffer
+        if( Attachment.Type.DEPTH == atype ) {
+            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
+        } else if( Attachment.Type.STENCIL == atype ) {
+            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
+        } else if( Attachment.Type.DEPTH_STENCIL == atype ) {
+            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());            
+            gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
+        }
+        
+        updateStatus(gl);
+        if( !isStatusValid() ) {
+            detachRenderbuffer(gl, atype);
+            throw new GLException("renderbuffer attachment failed: "+this.getStatusString());
+        }
+
+        if(DEBUG) {
+            System.err.println("FBObject.attachRenderbuffer: "+this);
+        }
+    }
+    
+    /**
+     * <p>Leaves the FBO bound!</p>
+     * @param gl
+     * @param ca
+     * @throws IllegalArgumentException
+     */
+    public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException {
+        if(null == detachColorbufferImpl(gl, attachmentPoint, false)) {
+            throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);            
+        }
+        if(DEBUG) {
+            System.err.println("FBObject.detachAll: "+this);
+        }
+    }
+    
+    private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) {
+        final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+        
+        if(null == colbuf) {
+            return null;
+        }
+        
+        bind(gl);
+        
+        if(colbuf instanceof TextureAttachment) {
+            final TextureAttachment texA = (TextureAttachment) colbuf;
+            if( 0 != texA.getName() ) {
+                gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+                              GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+                              GL.GL_TEXTURE_2D, 0, 0);
+                gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+            }
+            texA.free(gl);
+            removeColorAttachment(attachmentPoint, texA);                
+            if(recreate) {
+                texA.setSize(width, height);
+                attachTexture2D(gl, attachmentPoint, texA);
+            }
+        } else if(colbuf instanceof ColorAttachment) {
+            final ColorAttachment colA = (ColorAttachment) colbuf;
+            if( 0 != colA.getName() ) {
+                gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, 
+                                             GL.GL_COLOR_ATTACHMENT0+attachmentPoint, 
+                                             GL.GL_RENDERBUFFER, 0);
+            }
+            colA.free(gl);
+            removeColorAttachment(attachmentPoint, colbuf);
+            if(recreate) {
+                colA.setSize(width, height);
+                colA.setSamples(samples);
+                attachColorbuffer(gl, attachmentPoint, colA);
+            }
+        }
+        return colbuf;
+    }
+    
+    /**
+     * 
+     * @param gl
+     * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL} 
+     */
+    public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException {
+        detachRenderbufferImpl(gl, atype, false);
+    }
+    
+    public final boolean isDepthStencilPackedFormat() {
+        final boolean res = null != depth && null != stencil &&
+                            depth.format == stencil.format ;
+        if(res && depth.getName() != stencil.getName() ) {
+            throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+        }
+        return res;
+    }
+        
+    private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException {
+        switch ( atype ) {
+            case DEPTH:
+            case STENCIL:
+            case DEPTH_STENCIL:             
+             break;
+             default:
+                 throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
+        }        
+        if( null == depth && null == stencil ) {
+            return ; // nop
+        } 
+        // reduction of possible combinations, create unique atype command(s)
+        final ArrayList<Attachment.Type> actions = new ArrayList<Attachment.Type>(2);  
+        if( isDepthStencilPackedFormat() ) {
+            // packed
+            actions.add(Attachment.Type.DEPTH_STENCIL);
+        } else {
+            // individual
+            switch ( atype ) {
+                case DEPTH:
+                    if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
+                    break;
+                case STENCIL:
+                    if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
+                    break;
+                case DEPTH_STENCIL:
+                    if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
+                    if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
+                    break;
+                 default: // handled
+            }
+        }
+        
+        bind(gl);        
+        
+        for(int i = 0; i < actions.size(); i++) {
+            final int format;
+            
+            Attachment.Type action = actions.get(i);
+            switch ( action ) {
+                case DEPTH:
+                    format = depth.format;
+                    if( 0 != depth.getName() ) {
+                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                    }
+                    depth.free(gl);
+                    if(!recreate) {
+                        depth = null;
+                    }
+                    break;
+                case STENCIL:
+                    format = stencil.format;
+                    if(0 != stencil.getName()) {
+                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                    }
+                    stencil.free(gl);
+                    if(!recreate) {
+                        stencil = null;
+                    }
+                    break;
+                case DEPTH_STENCIL:
+                    format = depth.format;
+                    if(0 != depth.getName()) {
+                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+                    }
+                    depth.free(gl);
+                    stencil.free(gl);
+                    if(!recreate) {
+                        depth = null;
+                        stencil = null;
+                    }
+                    break;
+                 default:
+                    throw new InternalError("XXX");
+            }
+            if(recreate) {
+                attachRenderbufferImpl2(gl, action, format);
+            }
+        }        
+    }
+        
+    /** 
+     * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s.
+     * <p>Leaves the FBO bound!</p>
+     * <p>
+     * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+     * </p> 
+     * @param gl the current GL context
+     */
+    public final void detachAll(GL gl) {
+        if(null != samplesSink) {
+            samplesSink.detachAll(gl);
+        }        
+        detachAllImpl(gl, true/* detachNonColorbuffer */, false /* recreate */);
+    }
+    
+    /** 
+     * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s.
+     * <p>Leaves the FBO bound!</p>
+     * <p>
+     * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+     * </p> 
+     * @param gl the current GL context
+     */
+    public final void detachAllColorbuffer(GL gl) {
+        if(null != samplesSink) {
+            samplesSink.detachAllColorbuffer(gl);
+        }        
+        detachAllImpl(gl, false/* detachNonColorbuffer */, false /* recreate */);
+    }
+    
+    /** 
+     * Detaches all {@link TextureAttachment}s 
+     * <p>Leaves the FBO bound!</p>
+     * <p>
+     * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+     * </p> 
+     * @param gl the current GL context
+     */
+    public final void detachAllTexturebuffer(GL gl) {
+        if(null != samplesSink) {
+            samplesSink.detachAllTexturebuffer(gl);
+        }
+        for(int i=0; i<maxColorAttachments; i++) {
+            if(colorAttachmentPoints[i] instanceof TextureAttachment) {
+                detachColorbufferImpl(gl, i, false);
+            }
+        }
+    }
+    
+    public final void detachAllRenderbuffer(GL gl) {
+        if(null != samplesSink) {
+            samplesSink.detachAllRenderbuffer(gl);
+        }
+        detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, false);
+    }
+    
+    private final void detachAllImpl(GL gl, boolean detachNonColorbuffer, boolean recreate) {
+        for(int i=0; i<maxColorAttachments; i++) {
+            detachColorbufferImpl(gl, i, recreate);
+        }
+        if( !recreate && colorAttachmentCount>0 ) {
+            throw new InternalError("Non zero ColorAttachments "+this);
+        }
+        
+        if(detachNonColorbuffer) {
+            detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate);
+        }
+        
+        if(DEBUG) {
+            System.err.println("FBObject.detachAll: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
+        }
+    }
+        
+    /**
+     * @param gl the current GL context
+     */
+    public final void destroy(GL gl) {
+        if(null != samplesSink) {
+            samplesSink.destroy(gl);
+        }
+        
+        detachAllImpl(gl, true /* detachNonColorbuffer */, false /* recreate */);
+        
+        // cache FB names, preset exposed to zero,
+        // braking ties w/ GL/GLContext link to getReadFramebuffer()/getWriteFramebuffer()
+        final int fb_cache = fbName;
+        fbName = 0;
+
+        int name[] = new int[1];
+        if(0!=fb_cache) {
+            name[0] = fb_cache;
+            gl.glDeleteFramebuffers(1, name, 0);
+        }        
+        initialized = false;
+        bound = false;
+        if(DEBUG) {
+            System.err.println("FBObject.destroy: "+this);
+        }
+    }
+
+    private final boolean sampleSinkSizeMismatch() {
+        return samplesSink.getWidth() != width || samplesSink.getHeight() != height ;
+    }
+    private final boolean sampleSinkTexMismatch() {
+        return null == samplesSinkTexture || 0 == samplesSinkTexture.getName() ;
+    }
+    private final boolean sampleSinkDepthStencilMismatch() {
+        final boolean depthMismatch   = ( null != depth && null == samplesSink.depth ) ||
+                                        ( null != depth && null != samplesSink.depth &&
+                                          depth.format != samplesSink.depth.format );
+        
+        final boolean stencilMismatch = ( null != stencil && null == samplesSink.stencil ) ||
+                                        ( null != stencil && null != samplesSink.stencil &&
+                                          stencil.format != samplesSink.stencil.format );        
+        
+        return depthMismatch || stencilMismatch;                
+    }
+        
+    private final void resetMSAATexture2DSink(GL gl) throws GLException {
+        if(0 == samples) {
+            // MSAA off
+            if(null != samplesSink) {
+                samplesSink.detachAll(gl);
+            }
+            return;
+        }
+        
+        boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
+        boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
+        boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
+        
+        /** if(DEBUG) {
+            System.err.println("FBObject.resetMSAATexture2DSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
+                               "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+        } */
+        
+        if(!sampleSinkSizeMismatch && !sampleSinkTexMismatch && !sampleSinkDepthStencilMismatch) {
+            // all properties match .. 
+            return;            
+        }
+        
+        unbind(gl);
+        
+        if(DEBUG) {
+            System.err.println("FBObject.resetMSAATexture2DSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+                               "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+        }
+                
+        if( sampleSinkDepthStencilMismatch ) {
+            samplesSink.detachAllRenderbuffer(gl);
+        }
+        
+        if( sampleSinkSizeMismatch ) {
+            samplesSink.reset(gl, width, height);
+        }
+        
+        if(null == samplesSinkTexture) {
+            samplesSinkTexture = samplesSink.attachTexture2D(gl, 0, true);
+        } else if( 0 == samplesSinkTexture.getName() ) {
+            samplesSinkTexture.setSize(width, height);
+            samplesSink.attachTexture2D(gl, 0, samplesSinkTexture);
+        }
+        
+        if( sampleSinkDepthStencilMismatch ) {
+            samplesSink.attachRenderbuffer(gl, depth.format);
+            if( null != stencil && !isDepthStencilPackedFormat() ) {
+                samplesSink.attachRenderbuffer(gl, stencil.format);
+            }
+        }        
+        
+        sampleSinkSizeMismatch = sampleSinkSizeMismatch();
+        sampleSinkTexMismatch = sampleSinkTexMismatch();
+        sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
+        if(sampleSinkSizeMismatch || sampleSinkTexMismatch || sampleSinkDepthStencilMismatch) {
+            throw new InternalError("Samples sink mismatch after reset: \n\tTHIS "+this+",\n\t SINK "+samplesSink+
+                                    "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+        }
+        
+        if(DEBUG) {
+            System.err.println("FBObject.resetMSAATexture2DSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+                               "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+        }
+    }
+    
+    /** 
+     * Bind this FBO, i.e. bind write framebuffer to {@link #getWriteFramebuffer()}.
+     * 
+     * <p>If multisampling is used, it sets the read framebuffer to the sampling sink {@link #getWriteFramebuffer()}, 
+     * if full FBO is supported.</p>
+     *  
+     * <p> 
+     * In case you have attached more than one color buffer,
+     * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
+     * </p>
+     * @param gl the current GL context
+     * @throws GLException
+     */
+    public final void bind(GL gl) throws GLException {
+        if(!bound || fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER)) {
+            checkInitialized();
+            if(samples > 0 && fullFBOSupport) {
+                // draw to multisampling - read from samplesSink
+                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer());
+                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getReadFramebuffer());
+            } else {
+                // one for all
+                gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());                
+            }
+
+            checkNoError(null, gl.glGetError(), "FBObject post-bind"); // throws GLException if error
+            bound = true;
+            samplesSinkDirty = true;
+        }
+    }
+
+    /** 
+     * Unbind this FBO, i.e. bind read and write framebuffer to default, see {@link GLBase#getDefaultDrawFramebuffer()}.
+     * 
+     * <p>If full FBO is supported, sets the read and write framebuffer individually to default, hence not disturbing 
+     * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}</p>
+     *  
+     * @param gl the current GL context
+     * @throws GLException
+     */
+    public final void unbind(GL gl) throws GLException {
+        if(bound) {
+            if(fullFBOSupport) {
+                // default read/draw buffers, may utilize GLContext/GLDrawable override of 
+                // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+            } else {
+                gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer                
+            }
+            checkNoError(null, gl.glGetError(), "FBObject post-unbind"); // throws GLException if error
+            bound = false;
+        }
+    }
+
+    /** 
+     * Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>.
+     * <p>
+     * Method verifies the bound state via {@link GL#getBoundFramebuffer(int)}.
+     * </p>
+     * @param gl the current GL context
+     */
+    public final boolean isBound(GL gl) { 
+        bound = bound &&  fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER) ;
+        return bound;
+    }
+    
+    /** Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>. */
+    public final boolean isBound() { return bound; }
+    
+    /** 
+     * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
+     *
+     * <p>The operation is skipped, if no multisampling is used or 
+     * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)},
+     * see {@link #isSamplingBufferDirty()} </p>
+     * 
+     * <p>If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing 
+     * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}</p>
+     * 
+     * <p>In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
+     * you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
+     * </p>
+     * 
+     * <p>Leaves the FBO unbound.</p>
+     * 
+     * @param gl the current GL context
+     * @param ta {@link TextureAttachment} to use, prev. attached w/  {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
+     * @throws IllegalArgumentException  
+     */
+    public final void syncSamplingBuffer(GL gl) {
+        unbind(gl);
+        if(samples>0 && samplesSinkDirty) {
+            samplesSinkDirty = false;
+            resetMSAATexture2DSink(gl);
+            gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
+            gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer());
+            ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK
+                                           GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
+            if(fullFBOSupport) {
+                // default read/draw buffers, may utilize GLContext/GLDrawable override of 
+                // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+                gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+            } else {
+                gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer                
+            }
+        }
+    }
+    
+    /** 
+     * Bind the given texture colorbuffer.
+     * 
+     * <p>If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.</p>
+     *  
+     * <p>Leaves the FBO unbound!</p>
+     * 
+     * @param gl the current GL context
+     * @param ta {@link TextureAttachment} to use, prev. attached w/  {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
+     * @throws IllegalArgumentException  
+     */
+    public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
+        if(null == ta) { throw new IllegalArgumentException("null TextureAttachment"); }
+        if(samples > 0 && samplesSinkTexture == ta) {
+            syncSamplingBuffer(gl);
+        } else {
+            unbind(gl);            
+        }
+        gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
+    }
+
+    /** 
+     * Unbind texture, ie bind 'non' texture 0
+     *  
+     * <p>Leaves the FBO unbound.</p>
+     */    
+    public final void unuse(GL gl) {
+        unbind(gl);
+        gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
+    }
+
+    /** 
+     * Returns <code>true</code> if <i>basic</i> or <i>full</i> FBO is supported, otherwise <code>false</code>.
+     * @param full <code>true</code> for <i>full</i> FBO supported query, otherwise <code>false</code> for <i>basic</i> FBO support query.
+     * @see #supportsFullFBO(GL)
+     * @see #supportsBasicFBO(GL)
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+    
+    /** 
+     * Returns <code>true</code> if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise <code>false</code>.
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final boolean supportsRGBA8() throws GLException { checkInitialized(); return rgba8Avail; }
+    
+    /** 
+     * Returns <code>true</code> if {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32} is supported, otherwise <code>false</code>.
+     * @param bits 16, 24 or 32 bits
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final boolean supportsDepth(int bits) throws GLException {
+        checkInitialized();
+        switch(bits) {
+            case 16: return basicFBOSupport; 
+            case 24: return depth24Avail;
+            case 32: return depth32Avail;
+            default: return false;            
+        }
+    }
+    
+    /** 
+     * Returns <code>true</code> if {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8} or {@link GL2GL3#GL_STENCIL_INDEX16} is supported, otherwise <code>false</code>.
+     * @param bits 1, 4, 8 or 16 bits
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final boolean supportsStencil(int bits) throws GLException {
+        checkInitialized();
+        switch(bits) {
+            case  1: return stencil01Avail; 
+            case  4: return stencil04Avail;
+            case  8: return stencil08Avail;
+            case 16: return stencil16Avail;
+            default: return false;            
+        }
+    }
+    
+    /** 
+     * Returns <code>true</code> if {@link GL#GL_DEPTH24_STENCIL8} is supported, otherwise <code>false</code>.
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final boolean supportsPackedDepthStencil() throws GLException { checkInitialized(); return packedDepthStencilAvail; }
+    
+    /**
+     * Returns the maximum number of colorbuffer attachments.
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
+    
+    /**
+     * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported. 
+     * @throws GLException if {@link #init(GL)} hasn't been called.
+     */
+    public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+    
+    /**
+     * Returns <code>true</code> if this instance has been initialized with {@link #reset(GL, int, int)} 
+     * or {@link #reset(GL, int, int, int)}, otherwise <code>false</code>
+     */
+    public final boolean isInitialized() { return initialized; }
+    /** Returns the width */
+    public final int getWidth() { return width; }
+    /** Returns the height */
+    public final int getHeight() { return height; }
+    /** Returns the number of samples for multisampling (MSAA). zero if no multisampling is used. */
+    public final int getNumSamples() { return samples; }
+    /** Returns the framebuffer name to render to. */
+    public final int getWriteFramebuffer() { return fbName; }
+    /** Returns the framebuffer name to read from. Depending on multisampling, this may be a different framebuffer. */
+    public final int getReadFramebuffer() { return ( samples > 0 ) ? samplesSink.getReadFramebuffer() : fbName; }
+    /** Return the number of color/texture attachments */
+    public final int getColorAttachmentCount() { return colorAttachmentCount; }
+    /** Return the stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */ 
+    public final RenderAttachment getStencilAttachment() { return stencil; }
+    /** Return the depth {@link RenderAttachment} attachment. Maybe share the same {@link Attachment#getName()} as {@link #getStencilAttachment()}, if packed depth-stencil is being used. */ 
+    public final RenderAttachment getDepthAttachment() { return depth; }
+    
+    /** Return the complete multisampling {@link FBObject} sink, if using multisampling. */ 
+    public final FBObject getSamplingSinkFBO() { return samplesSink; }
+    
+    /** Return the multisampling {@link TextureAttachment} sink, if using multisampling. */ 
+    public final TextureAttachment getSamplingSink() { return samplesSinkTexture; }
+    /** 
+     * Returns <code>true</code> if the multisampling colorbuffer (msaa-buffer) 
+     * has been flagged dirty by a previous call of {@link #bind(GL)},
+     * otherwise <code>false</code>.
+     */
+    public final boolean isSamplingBufferDirty() { return samplesSinkDirty; }
+    
+    int objectHashCode() { return super.hashCode(); }
+    
+    public final String toString() {
+        final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ; 
+        return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+", samples "+samples+"/"+maxSamples+
+               ", depth "+depth+", stencil "+stencil+", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
+               ": "+caps+", msaa-sink "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
+               ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+    }
+    
+    private final void updateStatus(GL gl) {
+        if( 0 == fbName ) {
+            vStatus = -1;
+        } else {
+            vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+        }
+    }       
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
new file mode 100644
index 000000000..f7e25fa01
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -0,0 +1,81 @@
+/**
+ * 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 com.jogamp.opengl;
+
+/**
+ * Class holding OpenGL extension strings, commonly used by JOGL's implementation. 
+ */
+public class GLExtensions {
+  public static final String VERSION_1_2                     = "GL_VERSION_1_2";
+  public static final String VERSION_1_4                     = "GL_VERSION_1_4";
+  public static final String VERSION_1_5                     = "GL_VERSION_1_5";
+  public static final String VERSION_2_0                     = "GL_VERSION_2_0";
+  
+  public static final String ARB_debug_output                = "GL_ARB_debug_output";
+  public static final String AMD_debug_output                = "GL_AMD_debug_output";
+    
+  public static final String ARB_framebuffer_object          = "GL_ARB_framebuffer_object";
+  public static final String OES_framebuffer_object          = "GL_OES_framebuffer_object";
+  public static final String EXT_framebuffer_object          = "GL_EXT_framebuffer_object";
+  public static final String EXT_framebuffer_blit            = "GL_EXT_framebuffer_blit";
+  public static final String EXT_framebuffer_multisample     = "GL_EXT_framebuffer_multisample";
+  public static final String EXT_packed_depth_stencil        = "GL_EXT_packed_depth_stencil";
+  public static final String OES_depth24                     = "GL_OES_depth24";
+  public static final String OES_depth32                     = "GL_OES_depth32";
+  public static final String OES_packed_depth_stencil        = "GL_OES_packed_depth_stencil";
+  public static final String NV_fbo_color_attachments        = "GL_NV_fbo_color_attachments";
+  
+  public static final String ARB_ES2_compatibility           = "GL_ARB_ES2_compatibility";
+  
+  public static final String EXT_abgr                        = "GL_EXT_abgr";
+  public static final String OES_rgb8_rgba8                  = "GL_OES_rgb8_rgba8";
+  public static final String OES_stencil1                    = "GL_OES_stencil1";
+  public static final String OES_stencil4                    = "GL_OES_stencil4";
+  public static final String OES_stencil8                    = "GL_OES_stencil8";
+  public static final String APPLE_float_pixels              = "GL_APPLE_float_pixels";
+  
+  public static final String ARB_texture_non_power_of_two    = "GL_ARB_texture_non_power_of_two";
+  public static final String ARB_texture_rectangle           = "GL_ARB_texture_rectangle";
+  public static final String EXT_texture_rectangle           = "GL_EXT_texture_rectangle";
+  public static final String NV_texture_rectangle            = "GL_NV_texture_rectangle";
+  public static final String EXT_texture_format_BGRA8888     = "GL_EXT_texture_format_BGRA8888";
+  public static final String IMG_texture_format_BGRA8888     = "GL_IMG_texture_format_BGRA8888";
+  public static final String EXT_texture_compression_s3tc    = "GL_EXT_texture_compression_s3tc";
+  public static final String NV_texture_compression_vtc      = "GL_NV_texture_compression_vtc";
+  public static final String SGIS_generate_mipmap            = "GL_SGIS_generate_mipmap";
+  public static final String OES_read_format                 = "GL_OES_read_format";
+  
+  public static final String OES_EGL_image_external          = "GL_OES_EGL_image_external";
+  
+  //
+  // Aliased GLX/WGL/.. extensions
+  //
+  
+  public static final String ARB_pixel_format                = "GL_ARB_pixel_format"; 
+  public static final String ARB_pbuffer                     = "GL_ARB_pbuffer";
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 75785fd86..cdb4b82bb 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -93,11 +93,13 @@ public class JoglVersion extends JogampVersion {
         return sb;        
     }
     
-    public static StringBuilder getDefaultOpenGLInfo(StringBuilder sb, boolean withCapabilitiesInfo) {
+    public static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, boolean withCapabilitiesInfo) {
         if(null==sb) {
             sb = new StringBuilder();
         }
-        final AbstractGraphicsDevice device = GLProfile.getDefaultDevice();
+        if(null == device) {
+            device = GLProfile.getDefaultDevice();
+        }
         sb.append("Default Profiles on device ").append(device).append(Platform.getNewline());
         if(null!=device) {
             GLProfile.glAvailabilityToString(device, sb, "\t", 1);
@@ -120,13 +122,21 @@ public class JoglVersion extends JogampVersion {
         if(null==sb) {
             sb = new StringBuilder();
         }
-        GLContext ctx = gl.getContext();
-
+        
         sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
         sb.append(device.getClass().getSimpleName()).append("[type ")
                 .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
         GLProfile.glAvailabilityToString(device, sb, "\t", 1);        
         sb.append(Platform.getNewline());
+
+        return getGLStrings(gl, sb);
+    }
+    
+    public static StringBuilder getGLStrings(GL gl, StringBuilder sb) {        
+        if(null==sb) {
+            sb = new StringBuilder();
+        }
+        final GLContext ctx = gl.getContext();
         sb.append("Swap Interval  ").append(gl.getSwapInterval());
         sb.append(Platform.getNewline());
         sb.append("GL Profile     ").append(gl.getGLProfile());
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
new file mode 100644
index 000000000..1ea8595c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
@@ -0,0 +1,89 @@
+/**
+ * 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 com.jogamp.opengl;
+
+import javax.media.opengl.GLAutoDrawableDelegate;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+/** 
+ * Platform-independent class exposing FBO offscreen functionality to
+ * applications.
+ * <p>
+ * This class distinguishes itself from {@link GLAutoDrawableDelegate}
+ * with it's {@link #setSize(int, int)} functionality.
+ * </p>
+ */
+public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
+  
+    public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, Object upstreamWidget) {
+        super(drawable, context, upstreamWidget);
+    }
+
+    /**
+     * Attempts to resize this offscreen auto drawable, if supported
+     * by the underlying {@link GLDrawable).
+     * @param newWidth
+     * @param newHeight
+     * @return <code>true</code> if resize was executed, otherwise <code>false</code>.
+     * @throws GLException in case of an error during the resize operation
+     */
+    public boolean setSize(int newWidth, int newHeight) throws GLException {
+        boolean done = false;
+        if(drawable instanceof GLFBODrawableImpl) {
+            context.makeCurrent();
+            try {                        
+                ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
+                done = true;
+            } finally {
+                context.release();
+            }
+        }
+        if(done) {
+            this.defaultWindowResizedOp();
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * If the underlying {@link GLDrawable} is an FBO implementation
+     * and contains an {#link FBObject}, the same is returned.
+     * Otherwise returns <code>null</code>.
+     */
+    public FBObject getFBObject() { 
+        if(drawable instanceof GLFBODrawableImpl) {
+            return ((GLFBODrawableImpl)drawable).getFBObject();
+        }
+        return null;
+    }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 5ee58b78d..0d9d3ddf5 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -231,6 +231,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
 
       /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite) */
       device = SWTAccessor.getDevice(this);
+      /* Since we have no means of querying the screen index yet, assume 0. Good choice due to Xinerama alike settings anyways. */
+      final int screenIdx = 0;
       /* Native handle for the control, used to associate with GLContext */
       nativeWindowHandle = SWTAccessor.getWindowHandle(this);
 
@@ -243,7 +245,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
       final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
 
       /* Create a NativeWindow proxy for the SWT canvas */
-      proxySurface = glFactory.createProxySurface(device, nativeWindowHandle, caps, chooser);
+      proxySurface = glFactory.createProxySurface(device, screenIdx, nativeWindowHandle, caps, chooser, swtCanvasUpStreamHook);
 
       /* Associate a GL surface with the proxy */
       drawable = glFactory.createGLDrawable(proxySurface);
@@ -265,12 +267,58 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
       addControlListener(new ControlAdapter() {
          @Override
          public void controlResized(final ControlEvent arg0) {
-            clientArea = GLCanvas.this.getClientArea();
-            /* Mark for OpenGL reshape next time the control is painted */
-            sendReshape = true;
+            updateSizeCheck();
          }
       });
    }
+   private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+    @Override
+    public final void create(ProxySurface s) { /* nop */ }
+
+    @Override
+    public final void destroy(ProxySurface s) { /* nop */ }
+
+    @Override
+    public final int getWidth(ProxySurface s) {
+        return clientArea.width;
+    }
+
+    @Override
+    public final int getHeight(ProxySurface s) {
+        return clientArea.height;
+    }
+    
+    @Override
+    public String toString() {
+        return "SETUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+"]";
+    }
+
+   };
+
+   protected final void updateSizeCheck() {
+      clientArea = GLCanvas.this.getClientArea();
+      if (clientArea != null && 
+          proxySurface.getWidth() != clientArea.width && 
+          proxySurface.getHeight() != clientArea.height) {
+          sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+      }
+      sendReshape = false;
+   }
+
+   @Override
+   public final Object getUpstreamWidget() {
+       return this;
+   }
+   
+   @Override
+   public int getWidth() {
+      return clientArea.width;
+   }
+
+   @Override
+   public int getHeight() {
+      return clientArea.height;
+   }
 
    @Override
    public void addGLEventListener(final GLEventListener arg0) {
@@ -417,25 +465,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
       return (drawable != null) ? drawable.getHandle() : 0;
    }
 
-   @Override
-   public int getHeight() {
-      final Rectangle clientArea = this.clientArea;
-      if (clientArea == null) return 0;
-      return clientArea.height;
-   }
-
    @Override
    public NativeSurface getNativeSurface() {
       return (drawable != null) ? drawable.getNativeSurface() : null;
    }
 
-   @Override
-   public int getWidth() {
-      final Rectangle clientArea = this.clientArea;
-      if (clientArea == null) return 0;
-      return clientArea.width;
-   }
-
    @Override
    public boolean isRealized() {
       return (drawable != null) ? drawable.isRealized() : false;
@@ -515,7 +549,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
        // System.err.println(NativeWindowVersion.getInstance());
        System.err.println(JoglVersion.getInstance());
 
-       System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+       System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
 
        final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
        final Display display = new Display();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
deleted file mode 100644
index 3e049a334..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2011 JogAmp Community. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- * - Redistribution in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * 
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * 
- */
-
-package com.jogamp.opengl.util;
-
-import javax.media.opengl.*;
-
-public class FBObject {
-    static final int MAX_FBO_TEXTURES = 32; // just for our impl .. not the real 'max' FBO color attachments
-    private int[] fbo_tex_names;
-    private int[] fbo_tex_units;
-    private int fbo_tex_num;
-    private int colorattachment_num;
-
-    private boolean initialized;
-    private int width, height;
-    private int fb, depth_rb, stencil_rb, vStatus;
-    private boolean bound;
-    
-    public FBObject(int width, int height) {
-        this.fbo_tex_names = new int[MAX_FBO_TEXTURES];
-        this.fbo_tex_units = new int[MAX_FBO_TEXTURES];
-        this.fbo_tex_num = 0;
-        this.colorattachment_num = 0;
-        this.initialized = false;
-        this.width = width;
-        this.height = height;
-        this.fb = 0;
-        this.depth_rb = 0;
-        this.stencil_rb = 0;
-        this.bound = false;
-    }        
-    
-    /**
-     * @return true if the FB status is valid, otherwise false
-     * @see #getStatus()
-     */
-    public boolean isStatusValid() {
-        switch(vStatus) {
-            case GL.GL_FRAMEBUFFER_COMPLETE:
-                return true;
-            case GL.GL_FRAMEBUFFER_UNSUPPORTED:
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
-            //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-            //case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-            //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
-            case 0:
-            default:
-                System.out.println("Framebuffer " + fb + " is incomplete: status = 0x" + Integer.toHexString(vStatus) + 
-                        " : " + getStatusString(vStatus));
-                return false;
-        }
-    }
-        
-    /** 
-     * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
-     * @see #validateStatus() 
-     */
-    public int getStatus() {
-        return vStatus;
-    }
-
-    public String getStatusString() {
-        return getStatusString(vStatus);
-    }
-    
-    public static final String getStatusString(int fbStatus) {
-        switch(fbStatus) {
-            case -1:
-                return "NOT A FBO";
-            case GL.GL_FRAMEBUFFER_COMPLETE:
-                return "OK";
-            case GL.GL_FRAMEBUFFER_UNSUPPORTED:
-                return("GL FBO: Unsupported framebuffer format");
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-                return("GL FBO: incomplete, incomplete attachment\n");
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-                return("GL FBO: incomplete, missing attachment");
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-                return("GL FBO: incomplete, attached images must have same dimensions");
-            case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
-                 return("GL FBO: incomplete, attached images must have same format");
-            case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
-                return("GL FBO: incomplete, missing draw buffer");
-            case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
-                return("GL FBO: incomplete, missing read buffer");
-            case GL2.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
-                return("GL FBO: incomplete, missing multisample buffer");
-            case 0:
-                return("GL FBO: incomplete, implementation fault");
-            default:
-                return("GL FBO: incomplete, implementation ERROR");
-        }
-    }
-    
-    private boolean checkNoError(GL gl, int err, String exceptionMessage) {
-        if(GL.GL_NO_ERROR != err) {
-            if(null != gl) {
-                destroy(gl);
-            }
-            if(null != exceptionMessage) {
-                throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
-            }
-            return false;
-        }
-        return true;
-    }
-
-    private final void checkInitialized() {
-        if(!initialized) {
-            throw new GLException("FBO not initialized, call init(GL) first.");
-        }                
-    }
-    
-    private final void checkBound(GL gl, boolean shallBeBound) {
-        checkInitialized();
-        if(bound != shallBeBound) {
-            final String s0 = shallBeBound ? "not" : "already" ; 
-            throw new GLException("FBO "+s0+" bound "+toString());
-        }
-        checkNoError(null, gl.glGetError(), "FBObject pre"); // throws GLException if error
-    }
-
-    /**
-     * Initializes this FBO's instance with it's texture.
-     * 
-     * <p>Leaves the FBO bound!</p>
-     * 
-     * @param gl the current GL context
-     * @throws GLException in case of an error
-     */
-    public void init(GL gl) throws GLException {
-        if(initialized) {
-            throw new GLException("FBO already initialized");
-        }        
-        checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
-                
-        // generate fbo ..
-        int name[] = new int[1];
-
-        gl.glGenFramebuffers(1, name, 0);
-        fb = name[0];
-        if(fb==0) {
-            throw new GLException("null generated framebuffer");
-        }
-
-        // bind fbo ..
-        gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);        
-        checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB");  // throws GLException if error        
-        if(!gl.glIsFramebuffer(fb)) {
-            checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
-        }
-        bound = true;        
-        initialized = true;
-        
-        updateStatus(gl);        
-    }
-
-    /**
-     * Attaches a[nother] Texture2D Color Buffer to this FBO's instance,
-     * selecting the texture data type and format automatically.
-     * <p>This may be done as many times as many color attachments are supported,
-     * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.</p> 
-     * 
-     * <p>Assumes a bound FBO</p>
-     * <p>Leaves the FBO bound!</p>
-     * 
-     * @param gl the current GL context
-     * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)}
-     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
-     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
-     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
-     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
-     * @return idx of the new attached texture, otherwise -1
-     * @throws GLException in case of an error
-     */
-    public int attachTexture2D(GL gl, int texUnit, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
-        final int textureInternalFormat, textureDataFormat, textureDataType;
-        if(gl.isGLES()) { 
-            textureInternalFormat=GL.GL_RGBA;
-            textureDataFormat=GL.GL_RGBA;
-            textureDataType=GL.GL_UNSIGNED_BYTE;
-        } else { 
-            textureInternalFormat=GL.GL_RGBA8;
-            textureDataFormat=GL.GL_BGRA;
-            textureDataType=GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV;
-        }
-        return attachTexture2D(gl, texUnit, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
-    }
-    
-    /**
-     * Attaches a[nother] Texture2D Color Buffer to this FBO's instance,
-     * selecting the texture data type and format automatically.
-     * <p>This may be done as many times as many color attachments are supported,
-     * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.</p> 
-     * 
-     * <p>Assumes a bound FBO</p>
-     * <p>Leaves the FBO bound!</p>
-     * 
-     * @param gl the current GL context
-     * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)}
-     * @param textureInternalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
-     * @param textureDataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
-     * @param textureDataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
-     * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
-     * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER} 
-     * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
-     * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
-     * @return index of the texture colorbuffer if bound and configured successfully, otherwise -1
-     * @throws GLException in case the texture colorbuffer couldn't be allocated
-     */
-    public int attachTexture2D(GL gl, int texUnit,
-                               int textureInternalFormat, int textureDataFormat, int textureDataType,
-                               int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
-        checkBound(gl, true);
-        final int fbo_tex_idx = fbo_tex_num;
-        gl.glGenTextures(1, fbo_tex_names, fbo_tex_num);
-        if(fbo_tex_names[fbo_tex_idx]==0) {
-            throw new GLException("null generated texture");
-        }
-        fbo_tex_units[fbo_tex_idx] = texUnit;
-        fbo_tex_num++;
-        if(0<=texUnit) {
-            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
-        }
-        gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx]);
-        checkNoError(gl, gl.glGetError(), "FBObject Init.bindTex");  // throws GLException if error        
-        gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, textureInternalFormat, width, height, 0,
-                        textureDataFormat, textureDataType, null);
-        int glerr = gl.glGetError();
-        if(GL.GL_NO_ERROR != glerr) {
-            int[] sz = new int[1];
-            gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, sz, 0);
-            // throws GLException if error
-            checkNoError(gl, glerr, "FBObject Init.texImage2D: "+
-                                    " int-fmt 0x"+Integer.toHexString(textureInternalFormat)+
-                                    ", "+width+"x"+height+
-                                    ", data-fmt 0x"+Integer.toHexString(textureDataFormat)+
-                                    ", data-type 0x"+Integer.toHexString(textureDataType)+
-                                    ", max tex-sz "+sz[0]);
-        }
-        if( 0 < magFilter ) {
-            gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
-        }
-        if( 0 < minFilter ) {
-            gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter);
-        }
-        if( 0 < wrapS ) {
-            gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
-        }
-        if( 0 < wrapT ) {
-            gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);            
-        }
-
-        // Set up the color buffer for use as a renderable texture:
-        gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
-                                  GL.GL_COLOR_ATTACHMENT0 + colorattachment_num++,
-                                  GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx], 0); 
-
-        updateStatus(gl);                
-        return isStatusValid() ? fbo_tex_idx : -1;
-    }
-    
-    /**
-     * Attaches one Depth Buffer to this FBO's instance.
-     * <p>This may be done only one time.</p>
-     * 
-     * <p>Assumes a bound FBO</p>
-     * <p>Leaves the FBO bound!</p>
-     * @param gl the current GL context
-     * @param depthComponentType {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32}
-     * @return true if the depth renderbuffer could be bound and configured, otherwise false
-     * @throws GLException in case the depth renderbuffer couldn't be allocated or one is already attached.
-     */
-    public boolean attachDepthBuffer(GL gl, int depthComponentType) throws GLException {
-        checkBound(gl, true);
-        if(depth_rb != 0) {
-            throw new GLException("FBO depth buffer already attached (rb "+depth_rb+")");
-        }        
-        int name[] = new int[1];
-        gl.glGenRenderbuffers(1, name, 0);
-        depth_rb = name[0];        
-        if(depth_rb==0) {
-            throw new GLException("null generated renderbuffer");
-        }
-        // Initialize the depth buffer:
-        gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, depth_rb);
-        if(!gl.glIsRenderbuffer(depth_rb)) {
-            System.err.println("not a depthbuffer: "+ depth_rb);
-            name[0] = depth_rb;
-            gl.glDeleteRenderbuffers(1, name, 0);
-            depth_rb=0;
-            return false;            
-        }
-        
-        gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, depthComponentType, width, height);
-        // Set up the depth buffer attachment:
-        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
-                                     GL.GL_DEPTH_ATTACHMENT,
-                                     GL.GL_RENDERBUFFER, depth_rb);
-        updateStatus(gl);
-        return isStatusValid();                
-    }
-    
-    /**
-     * Attaches one Stencil Buffer to this FBO's instance.
-     * <p>This may be done only one time.</p>
-     * 
-     * <p>Assumes a bound FBO</p>
-     * <p>Leaves the FBO bound!</p>
-     * @param gl the current GL context
-     * @param stencilComponentType {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4} or {@link GL#GL_STENCIL_INDEX8}
-     * @return true if the stencil renderbuffer could be bound and configured, otherwise false
-     * @throws GLException in case the stencil renderbuffer couldn't be allocated  or one is already attached.
-     */
-    public boolean attachStencilBuffer(GL gl, int stencilComponentType) throws GLException {
-        checkBound(gl, true);
-        if(stencil_rb != 0) {
-            throw new GLException("FBO stencil buffer already attached (rb "+stencil_rb+")");
-        }
-        int name[] = new int[1];
-        gl.glGenRenderbuffers(1, name, 0);
-        stencil_rb = name[0];
-        if(stencil_rb==0) {
-            throw new GLException("null generated stencilbuffer");
-        }
-        // Initialize the stencil buffer:
-        gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, stencil_rb);
-        if(!gl.glIsRenderbuffer(stencil_rb)) {
-            System.err.println("not a stencilbuffer: "+ stencil_rb);
-            name[0] = stencil_rb;
-            gl.glDeleteRenderbuffers(1, name, 0);
-            stencil_rb=0;
-            return false;
-        }
-        gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, stencilComponentType, width, height);
-        gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
-                                     GL.GL_STENCIL_ATTACHMENT,
-                                     GL.GL_RENDERBUFFER, stencil_rb);
-        updateStatus(gl);        
-        return isStatusValid();                
-    }
-
-    /**
-     * @param gl the current GL context
-     */
-    public void destroy(GL gl) {
-        if(bound) {
-            unbind(gl);
-        }
-
-        int name[] = new int[1];
-
-        if(0!=stencil_rb) {
-            name[0] = stencil_rb;
-            gl.glDeleteRenderbuffers(1, name, 0);
-            stencil_rb = 0;
-        }
-        if(0!=depth_rb) {
-            name[0] = depth_rb;
-            gl.glDeleteRenderbuffers(1, name, 0);
-            depth_rb=0;
-        }
-        if(null!=fbo_tex_names && fbo_tex_num>0) {
-            gl.glDeleteTextures(1, fbo_tex_names, fbo_tex_num);
-            fbo_tex_names = new int[MAX_FBO_TEXTURES];
-            fbo_tex_units = new int[MAX_FBO_TEXTURES];
-            fbo_tex_num = 0;
-        }
-        colorattachment_num = 0;
-        if(0!=fb) {
-            name[0] = fb;
-            gl.glDeleteFramebuffers(1, name, 0);
-            fb = 0;
-        }
-        initialized = false;
-    }
-
-    /** 
-     * Bind this FBO 
-     * <p>In case you have attached more than one color buffer,
-     * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.</p>
-     * @param gl the current GL context
-     */
-    public void bind(GL gl) {
-        checkBound(gl, false);
-        gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
-        bound = true;
-    }
-
-    /** 
-     * Unbind FBO, ie bind 'non' FBO 0 
-     * @param gl the current GL context
-     */
-    public void unbind(GL gl) {
-        checkBound(gl, true);
-        gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
-        bound = false;
-    }
-
-    /** 
-     * Bind the texture with given index.
-     * 
-     * <p>If a valid texture unit was named via {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)},
-     * the unit is activated via {@link GL#glActiveTexture(int) glActiveTexture(GL.GL_TEXTURE0 + unit)}.</p>
-     * @param gl the current GL context
-     * @param texIdx index of the texture to use, prev. attached w/  {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)}  
-     */
-    public void use(GL gl, int texIdx) {
-        checkBound(gl, false);
-        if(texIdx >= fbo_tex_num) {
-            throw new GLException("Invalid texId, only "+fbo_tex_num+" textures are attached");
-        }
-        if(0<=fbo_tex_units[texIdx]) {
-            gl.glActiveTexture(GL.GL_TEXTURE0 + fbo_tex_units[texIdx]);
-        }
-        gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[texIdx]); // use it ..
-    }
-
-    /** Unbind texture, ie bind 'non' texture 0 */    
-    public void unuse(GL gl) {
-        checkBound(gl, false);
-        gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
-    }
-    
-    public final boolean isBound() { return bound; }
-    public final int getWidth() { return width; }
-    public final int getHeight() { return height; }       
-    public final int getFBName() { return fb; }
-    public final int getTextureNumber() { return fbo_tex_num; }
-    public final int getTextureName(int idx) { return fbo_tex_names[idx]; }
-    
-    /** @return the named texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit was desired. */
-    public final int getTextureUnit(int idx) { return fbo_tex_units[idx]; }
-    public final int getColorAttachmentNumber() { return colorattachment_num; }
-    public final int getStencilBuffer() { return stencil_rb; }
-    public final int getDepthBuffer() { return depth_rb; }
-    public final String toString() {
-        return "FBO[name "+fb+", size "+width+"x"+height+", color num "+colorattachment_num+", tex num "+fbo_tex_num+", depth "+depth_rb+", stencil "+stencil_rb+"]";
-    }
-    
-    private void updateStatus(GL gl) {
-        if(!gl.glIsFramebuffer(fb)) {
-            vStatus = -1;
-        } else {
-            vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
-        }
-    }       
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index 8401b9cd2..331d6fa4e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -39,6 +39,7 @@
 package com.jogamp.opengl.util;
 
 import com.jogamp.common.nio.Buffers;
+
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2;
 import javax.media.opengl.GL2ES2;
@@ -56,22 +57,32 @@ import java.nio.*;
 public class GLBuffers extends Buffers {
 
     /**
-     * @param glType shall be one of 
-     *              GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
-     *              GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, 
-     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
-     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, 
-     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, 
-     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
-     *              GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, 
-     *              GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
-     *              GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
-     *              GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,         
-     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)         
+     * @param glType shall be one of (29) <br/>
+     *              GL_BYTE, GL_UNSIGNED_BYTE, <br/>
+     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
+     *              <br/>
+     *              GL_SHORT, GL_UNSIGNED_SHORT, <br/>
+     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, <br/> 
+     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, <br/>
+     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, <br/>
+     *              GL.GL_HALF_FLOAT, GLES2.GL_HALF_FLOAT_OES: <br/>
+     *              <br/>
+     *              GL_FIXED, GL_INT <br/>
+     *              GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8, <br/>
+     *              GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, <br/> 
+     *              GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, <br/>
+     *              GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV <br/> 
+     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV <br/>
+     *              <br/>
+     *              GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV <br/>
+     *              <br/>
+     *              GL_FLOAT, GL_DOUBLE <br/> 
+     *              
      * @return -1 if glType is unhandled, otherwise the actual value > 0 
      */
     public static final int sizeOfGLType(int glType) {
-        switch (glType) { // 25
+        switch (glType) { // 29
+            // case GL2.GL_BITMAP:
             case GL.GL_BYTE:
             case GL.GL_UNSIGNED_BYTE:
             case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -86,6 +97,8 @@ public class GLBuffers extends Buffers {
             case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
             case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
             case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+            case GL.GL_HALF_FLOAT:
+            case GLES2.GL_HALF_FLOAT_OES:
                 return SIZEOF_SHORT;
                                 
             case GL.GL_FIXED:
@@ -108,29 +121,38 @@ public class GLBuffers extends Buffers {
             case GL.GL_FLOAT:
                 return SIZEOF_FLOAT;
                 
-            case GL2.GL_DOUBLE:
+            case GL2GL3.GL_DOUBLE:
                 return SIZEOF_DOUBLE;
         }
         return -1;
     }
     
     /**
-     * @param glType shall be one of 
-     *              GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
-     *              GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, 
-     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
-     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, 
-     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, 
-     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
-     *              GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, 
-     *              GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
-     *              GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
-     *              GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,         
-     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)         
+     * @param glType shall be one of (29) <br/>
+     *              GL_BYTE, GL_UNSIGNED_BYTE, <br/>
+     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
+     *              <br/>
+     *              GL_SHORT, GL_UNSIGNED_SHORT, <br/>
+     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, <br/> 
+     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, <br/>
+     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, <br/>
+     *              GL_HALF_FLOAT, GL_HALF_FLOAT_OES <br/>
+     *              <br/>
+     *              GL_FIXED, GL_INT <br/>
+     *              GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8, <br/>
+     *              GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, <br/> 
+     *              GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, <br/>
+     *              GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV <br/> 
+     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV <br/>
+     *              <br/>
+     *              GL_FLOAT_32_UNSIGNED_INT_24_8_REV <br/>
+     *              <br/>
+     *              GL_FLOAT, GL_DOUBLE <br/> 
+     *              
      * @return null if glType is unhandled, otherwise the new Buffer object 
      */
     public static final Buffer newDirectGLBuffer(int glType, int numElements) {
-        switch (glType) {
+        switch (glType) { // 29
             case GL.GL_BYTE:
             case GL.GL_UNSIGNED_BYTE:
             case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -145,6 +167,8 @@ public class GLBuffers extends Buffers {
             case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
             case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
             case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+            case GL.GL_HALF_FLOAT:
+            case GLES2.GL_HALF_FLOAT_OES:
                 return newDirectShortBuffer(numElements);
                 
             case GL.GL_FIXED:
@@ -174,18 +198,26 @@ public class GLBuffers extends Buffers {
     }
 
     /**
-     * @param glType shall be one of 
-     *              GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
-     *              GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, 
-     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
-     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, 
-     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, 
-     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
-     *              GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, 
-     *              GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
-     *              GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
-     *              GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,      
-     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)         
+     * @param glType shall be one of (29) <br/>
+     *              GL_BYTE, GL_UNSIGNED_BYTE, <br/>
+     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
+     *              <br/>
+     *              GL_SHORT, GL_UNSIGNED_SHORT, <br/>
+     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, <br/> 
+     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, <br/>
+     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, <br/>
+     *              GL_HALF_FLOAT, GL_HALF_FLOAT_OES <br/>
+     *              <br/>
+     *              GL_FIXED, GL_INT <br/>
+     *              GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8, <br/>
+     *              GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, <br/> 
+     *              GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, <br/>
+     *              GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV <br/> 
+     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV <br/>
+     *              <br/>
+     *              GL_FLOAT_32_UNSIGNED_INT_24_8_REV <br/>
+     *              <br/>
+     *              GL_FLOAT, GL_DOUBLE <br/> 
      * @return null if glType is unhandled or parent is null or bufLen is 0, otherwise the new Buffer object 
      */
     public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
@@ -195,7 +227,7 @@ public class GLBuffers extends Buffers {
         parent.position(bytePos);
         parent.limit(bytePos + byteLen);
 
-        switch (glType) {
+        switch (glType) { // 29
             case GL.GL_BYTE:
             case GL.GL_UNSIGNED_BYTE:
             case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -210,6 +242,8 @@ public class GLBuffers extends Buffers {
             case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
             case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
             case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+            case GL.GL_HALF_FLOAT:
+            case GLES2.GL_HALF_FLOAT_OES:
                 return parent.asShortBuffer();
                 
             case GL.GL_FIXED:
@@ -362,28 +396,46 @@ public class GLBuffers extends Buffers {
      * 
      * @param tmp a pass through integer array of size >= 1 used to store temp data (performance)
      * 
-     * @param format must be one of 
-     *              GL_COLOR_INDEX, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL,
-     *              GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_LUMINANCE,
-     *              GL_RG, GL_LUMINANCE_ALPHA,
-     *              GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_ABGR_EXT,
-     *              GL_RED_INTEGER, GL_GREEN_INTEGER, GL_BLUE_INTEGER,
-     *              GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, 
-     *              GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_HILO_NV, GL_SIGNED_HILO_NV (26)
+     * @param format must be one of (26) <br/> 
+     *              GL_COLOR_INDEX GL_STENCIL_INDEX <br/> 
+     *              GL_DEPTH_COMPONENT GL_DEPTH_STENCIL <br/> 
+     *              GL_RED GL_RED_INTEGER <br/> 
+     *              GL_GREEN GL_GREEN_INTEGER <br/> 
+     *              GL_BLUE GL_BLUE_INTEGER <br/> 
+     *              GL_ALPHA GL_LUMINANCE (12) <br/> 
+     *              <br/> 
+     *              GL_LUMINANCE_ALPHA GL_RG <br/>
+     *              GL_RG_INTEGER GL_HILO_NV <br/> 
+     *              GL_SIGNED_HILO_NV (5) <br/> 
+     *              <br/> 
+     *              GL_RGB GL_RGB_INTEGER <br/> 
+     *              GL_BGR GL_BGR_INTEGER (4)<br/>  
+     *              <br/> 
+     *              GL_RGBA GL_RGBA_INTEGER <br/> 
+     *              GL_BGRA GL_BGRA_INTEGER <br/>
+     *              GL_ABGR_EXT (5)<br/> 
      *           
-     * @param type must be one of 
-     *              GL_BITMAP, 
-     *              GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
-     *              GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, 
-     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
-     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, 
-     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, 
-     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
-     *              GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV, 
-     *              GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
-     *              GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
-     *              GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
-     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV (28)         
+     * @param type must be one of (30) <br/>  
+     *              GL_BITMAP, <br/> 
+     *              GL_BYTE, GL_UNSIGNED_BYTE, <br/>
+     *              GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV, <br/>
+     *              <br/>
+     *              GL_SHORT, GL_UNSIGNED_SHORT, <br/>
+     *              GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV, <br/> 
+     *              GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV, <br/>
+     *              GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV, <br/>
+     *              GL_HALF_FLOAT, GL_HALF_FLOAT_OES <br/>
+     *              <br/>
+     *              GL_FIXED, GL_INT <br/>
+     *              GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8, <br/>
+     *              GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2, <br/> 
+     *              GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8, <br/>
+     *              GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV <br/> 
+     *              GL_HILO16_NV, GL_SIGNED_HILO16_NV <br/>
+     *              <br/>
+     *              GL_FLOAT_32_UNSIGNED_INT_24_8_REV <br/>
+     *              <br/>
+     *              GL_FLOAT, GL_DOUBLE <br/> 
      * 
      * @param width in pixels
      * @param height in pixels
@@ -402,7 +454,7 @@ public class GLBuffers extends Buffers {
         if (height < 0) return 0;
         if (depth < 0) return 0;
         
-        switch (format) /* 24 */ {
+        switch (format) /* 26 */ {
             case GL2.GL_COLOR_INDEX:
             case GL2GL3.GL_STENCIL_INDEX:
             case GL2GL3.GL_DEPTH_COMPONENT:
@@ -445,7 +497,7 @@ public class GLBuffers extends Buffers {
               throw new GLException("format 0x"+Integer.toHexString(format)+" not supported [yet], pls notify the maintainer in case this is our bug.");
         }
                 
-        switch (type) /* 26 */ {
+        switch (type) /* 30 */ {
             case GL2.GL_BITMAP:
               if (GL2.GL_COLOR_INDEX == format || GL2GL3.GL_STENCIL_INDEX == format) {
                 return (depth * (height * ((width+7)/8)));
@@ -460,6 +512,7 @@ public class GLBuffers extends Buffers {
             case GLES2.GL_HALF_FLOAT_OES:
               esize = 2;
               break;
+            case GL.GL_FIXED:
             case GL2ES2.GL_INT:
             case GL.GL_UNSIGNED_INT:
             case GL.GL_FLOAT:
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index 368cbc0a2..b0fae8a6d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -35,6 +35,7 @@ import java.io.IOException;
 import java.nio.*;
 import javax.media.opengl.*;
 
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.texture.Texture;
 import com.jogamp.opengl.util.texture.TextureData;
 import com.jogamp.opengl.util.texture.TextureIO;
@@ -67,6 +68,10 @@ public class GLReadBufferUtil {
       return null!=readTextureData && null!=readPixelBuffer ;
     }
     
+    public boolean hasAlpha() { return 4 == components ? true : false ; }
+    
+    public GLPixelStorageModes getGLPixelStorageModes() { return psm; }
+    
     /**
      * @return the raw pixel ByteBuffer, filled by {@link #readPixels(GLAutoDrawable, boolean)}
      */
@@ -104,13 +109,14 @@ public class GLReadBufferUtil {
     /**
      * Read the drawable's pixels to TextureData and Texture, if requested at construction
      * 
-     * @param gl the current GL object
+     * @param gl the current GL context object. It's read drawable is being used as the pixel source.
      * @param drawable the drawable to read from
      * @param flip weather to flip the data vertically or not
      * 
      * @see #GLReadBufferUtil(boolean, boolean)
      */
-    public boolean readPixels(GL gl, GLDrawable drawable, boolean flip) {
+    public boolean readPixels(GL gl, boolean flip) {
+        final GLDrawable drawable = gl.getContext().getGLReadDrawable();
         final int textureInternalFormat, textureDataFormat, textureDataType;
         final int[] glImplColorReadVals = new int[] { 0, 0 };
         
@@ -118,7 +124,7 @@ public class GLReadBufferUtil {
             textureInternalFormat=GL.GL_RGB;
             textureDataFormat=GL.GL_RGB;
             textureDataType = GL.GL_UNSIGNED_BYTE;            
-        } else if(gl.isGLES2Compatible() || gl.isExtensionAvailable("GL_OES_read_format")) {
+        } else if(gl.isGLES2Compatible() || gl.isExtensionAvailable(GLExtensions.OES_read_format)) {
             gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_FORMAT, glImplColorReadVals, 0);
             gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_TYPE, glImplColorReadVals, 1);            
             textureInternalFormat = (4 == components) ? GL.GL_RGBA : GL.GL_RGB;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index 3b817afcf..cf0373044 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -1,15 +1,20 @@
 
 package com.jogamp.opengl.util;
 
-import com.jogamp.common.util.*;
-import com.jogamp.opengl.util.glsl.ShaderState;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
 
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
 
-import java.nio.*;
-import java.util.Iterator;
-import java.util.ArrayList;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.util.glsl.ShaderState;
 
 public class ImmModeSink {
 
@@ -337,10 +342,8 @@ public class ImmModeSink {
         enableBuffer(gl, true);
 
         if (buffer!=null) {
-            GL2ES1 glf = gl.getGL2ES1();
-
             if(null==indices) {
-                glf.glDrawArrays(mode, 0, count);
+                gl.glDrawArrays(mode, 0, count);
             } else {
                 Class<?> clazz = indices.getClass();
                 int type=-1;
@@ -352,7 +355,7 @@ public class ImmModeSink {
                 if(0>type) {
                     throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
                 }
-                glf.glDrawElements(mode, indices.remaining(), type, indices);
+                gl.glDrawElements(mode, indices.remaining(), type, indices);
                 // GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
             }
         }
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
index fa66673fd..0022d5c2d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
@@ -48,6 +48,7 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.glu.gl2.GLUgl2;
 
 import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.GLPixelStorageModes;
 import com.jogamp.opengl.util.TGAWriter;
 
@@ -392,7 +393,7 @@ public class Screenshot {
 
   private static void checkExtABGR() {
     GL2 gl = GLUgl2.getCurrentGL2();
-    if (!gl.isExtensionAvailable("GL_EXT_abgr")) {
+    if (!gl.isExtensionAvailable(GLExtensions.EXT_abgr)) {
       throw new IllegalArgumentException("Saving alpha channel requires GL_EXT_abgr");
     }
   } 
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index 622ee1b79..1735fcddd 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -41,6 +41,7 @@ package com.jogamp.opengl.util.awt;
 
 import com.jogamp.common.nio.Buffers;
 
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.*;
 import com.jogamp.opengl.util.packrect.*;
 import com.jogamp.opengl.util.texture.*;
@@ -1976,7 +1977,7 @@ public class TextRenderer {
 
     private final boolean is15Available(GL gl) {
         if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) {
-            isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5");
+            isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable(GLExtensions.VERSION_1_5);
             checkFor_isExtensionAvailable_GL_VERSION_1_5 = true;
         }
         return isExtensionAvailable_GL_VERSION_1_5;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index 49d4add5f..e7bf87a36 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -44,6 +44,7 @@ import javax.media.nativewindow.NativeWindowFactory;
 
 import jogamp.opengl.*;
 
+import com.jogamp.opengl.GLExtensions;
 import com.jogamp.opengl.util.texture.spi.*;
 
 /**
@@ -262,8 +263,8 @@ public class Texture {
      *
      * See the <a href="#perftips">performance tips</a> above for hints
      * on how to maximize performance when using many Texture objects.
-     * @param gl TODO
-     *
+     * 
+     * @param gl the current GL context
      * @throws GLException if no OpenGL context was current or if any
      * OpenGL-related errors occurred
      */
@@ -448,12 +449,12 @@ public class Texture {
 
         // See whether we have automatic mipmap generation support
         boolean haveAutoMipmapGeneration =
-            (gl.isExtensionAvailable("GL_VERSION_1_4") ||
-             gl.isExtensionAvailable("GL_SGIS_generate_mipmap"));
+            (gl.isExtensionAvailable(GLExtensions.VERSION_1_4) ||
+             gl.isExtensionAvailable(GLExtensions.SGIS_generate_mipmap));
 
         // Indicate to the TextureData what functionality is available
-        data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
-        data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+        data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+        data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
 
         // Indicates whether both width and height are power of two
         boolean isPOT = isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight);
@@ -646,7 +647,7 @@ public class Texture {
 
         int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR);
         int magFilter = GL.GL_LINEAR;
-        int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
+        int wrapMode = (gl.isExtensionAvailable(GLExtensions.VERSION_1_2) || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
 
         // REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB
         if (texTarget != GL2.GL_TEXTURE_RECTANGLE_ARB) {
@@ -925,8 +926,8 @@ public class Texture {
     private void updateSubImageImpl(GL gl, TextureData data, int newTarget, int mipmapLevel,
                                     int dstx, int dsty,
                                     int srcx, int srcy, int width, int height) throws GLException {
-        data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
-        data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+        data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+        data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
 
         Buffer buffer = data.getBuffer();
         if (buffer == null && data.getMipmapData() == null) {
@@ -1044,8 +1045,8 @@ public class Texture {
             case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
             case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
             case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-                if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc") &&
-                    !gl.isExtensionAvailable("GL_NV_texture_compression_vtc")) {
+                if (!gl.isExtensionAvailable(GLExtensions.EXT_texture_compression_s3tc) &&
+                    !gl.isExtensionAvailable(GLExtensions.NV_texture_compression_vtc)) {
                     throw new GLException("DXTn compressed textures not supported by this graphics card");
                 }
                 break;
@@ -1081,7 +1082,7 @@ public class Texture {
     private static boolean haveTexRect(GL gl) {
         return (!disableTexRect &&
                 TextureIO.isTexRectEnabled() &&
-                gl.isExtensionAvailable("GL_ARB_texture_rectangle"));
+                gl.isExtensionAvailable(GLExtensions.ARB_texture_rectangle));
     }
 
     private static boolean preferTexRect(GL gl) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index ca97cdc4b..b878c6002 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -155,6 +155,14 @@ public class TextureIO {
         file. */
     public static final String TIFF    = "tiff";
 
+    /** Constant which can be used as a file suffix to indicate a PAM
+        file, NetPbm magic 7 - binary RGB and RGBA. Write support only. */
+    public static final String PAM     = "pam";
+    
+    /** Constant which can be used as a file suffix to indicate a PAM
+        file, NetPbm magic 6 - binary RGB. Write support only. */
+    public static final String PPM     = "ppm";
+    
     private static final boolean DEBUG = Debug.debug("TextureIO");
 
     // For manually disabling the use of the texture rectangle
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 5ee2104a3..6b41c0bc8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -102,7 +102,6 @@ import javax.media.opengl.GL;
  */
 public interface TextureSequence {
     public static final String GL_OES_EGL_image_external_Required_Prelude = "#extension GL_OES_EGL_image_external : enable\n";
-    public static final String GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
     public static final String samplerExternalOES = "samplerExternalOES";
     public static final String sampler2D = "sampler2D";
     
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
index c2b131b97..cd42a1157 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
@@ -77,8 +77,10 @@ public class NetPbmTextureWriter implements TextureWriter {
 
     public int getMagic() { return magic; }
 
-    public static final String PPM     = "ppm";
-    public static final String PAM     = "pam";
+    /** @see TextureIO#PPM */
+    public static final String PPM     = TextureIO.PPM;
+    /** @see TextureIO#PAM */
+    public static final String PAM     = TextureIO.PAM;
 
     public String getSuffix() { return (magic==6)?PPM:PAM; }
 
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index b57b85e5c..1b84bd9bd 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -141,7 +141,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
     for (int i = 0; i < scores.length; i++) {
       scores[i] = NO_SCORE;
     }
-    final int gldes_samples = gldes.getSampleBuffers() ? gldes.getNumSamples() : 0;
+    final int gldes_samples = gldes.getNumSamples();
     
     // Compute score for each
     for (int i = 0; i < availnum; i++) {
@@ -158,8 +158,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
       if (gldes.getStereo() != cur.getStereo()) {
         continue;
       }
-      final int cur_samples = 
-              cur.getSampleBuffers() ? cur.getNumSamples() : 0;
+      final int cur_samples = cur.getNumSamples() ;
       int score = 0;
               
       // Compute difference in color depth
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 80d4f796c..0b2c664fe 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -51,8 +51,8 @@ import jogamp.opengl.Debug;
     calls to {@link GLContext#makeCurrent makeCurrent} will block if
     the context is current on another thread. This allows the internal
     GLContext for the GLAutoDrawable to be used both by the event
-    based rendering mechanism as well by end users directly.<P>
-
+    based rendering mechanism as well by end users directly.
+    <p>
     The implementation shall initialize itself as soon as possible,
     ie if the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible/realized.
     The following protocol shall be satisfied:
@@ -64,18 +64,18 @@ import jogamp.opengl.Debug;
              registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.</li>
         <li> Send a reshape event by calling {@link GLEventListener#reshape reshape(..)} for all
              registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.</li>
-    </ul><P>
-
+    </ul></P>
+    <p>
     Another implementation detail is the drawable reconfiguration. One use case is where a window is being
     dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
-    shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.<br>
+    shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.<br/>
     For example, AWT's {@link java.awt.Canvas} 's {@link java.awt.Canvas#getGraphicsConfiguration getGraphicsConfiguration()}
     is capable to determine a display device change. This is demonstrated within {@link javax.media.opengl.awt.GLCanvas}'s
     and NEWT's <code>AWTCanvas</code> {@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
     specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
-    implementation on the Windows platform, which utilizes the native platform's <i>MonitorFromWindow(HWND)</i> function.<br>
+    implementation on the Windows platform, which utilizes the native platform's <i>MonitorFromWindow(HWND)</i> function.<br/>
     All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
-    to be choosen again. The following protocol shall be satisfied.
+    to be chosen again. The following protocol shall be satisfied.
     <ul>
         <li> Controlled disposal:</li>
         <ul>
@@ -97,16 +97,16 @@ import jogamp.opengl.Debug;
     </ul>
     Note: Current graphics driver keep the surface configuration for a given window, even if the window is moved to
     a monitor with a different pixel configuration, ie 32bpp to 16bpp. However, it is best to not assume such behavior
-    and make your application comply with the above protocol.<P>
-
-    However, to not introduce to much breakage with older applications and because of the situation
+    and make your application comply with the above protocol.
+    <p>
+    Avoiding breakage with older applications and because of the situation
     mentioned above, the <code>boolean</code> system property <code>jogl.screenchange.action</code> will control the
-    screen change action as follows:<br>
-
+    screen change action as follows:<br/>
     <PRE>
     -Djogl.screenchange.action=false Disable the drawable reconfiguration (the default)
     -Djogl.screenchange.action=true  Enable  the drawable reconfiguration
     </PRE>
+    </p>
   */
 public interface GLAutoDrawable extends GLDrawable {
   /** Flag reflecting wheather the drawable reconfiguration will be issued in
@@ -362,5 +362,29 @@ public interface GLAutoDrawable extends GLDrawable {
       demos for examples.
       @return the set GL pipeline or null if not successful */
   public GL setGL(GL gl);
+  
+  /**
+   * Method <i>may</i> return the upstream UI toolkit object
+   * holding this {@link GLAutoDrawable} instance, if exist.
+   * <p>
+   * Currently known Java UI toolkits and it's known return types are:
+   * 
+   * <table border="1">
+   *     <tr><td>Toolkit</td>  <td>GLAutoDrawable Implementation</td>            <td>~</td>      <td>Return Type of getUpstreamWidget()</td</tr>
+   *     <tr><td>NEWT</td>     <td>{@link com.jogamp.newt.opengl.GLWindow}</td>  <td>has a</td>  <td>{@link com.jogamp.newt.Window}</td</tr>
+   *     <tr><td>SWT</td>      <td>{@link com.jogamp.opengl.swt.GLCanvas}</td>   <td>is a</td>   <td>{@link org.eclipse.swt.widgets.Canvas}</td</tr>
+   *     <tr><td>AWT</td>      <td>{@link javax.media.opengl.awt.GLCanvas}</td>  <td>is a</td>   <td>{@link java.awt.Canvas}</td</tr>
+   *     <tr><td>AWT</td>      <td>{@link javax.media.opengl.awt.GLJPanel}</td>  <td>is a</td>   <td>{@link javax.swing.JPanel}</td</tr>
+   * </table>
+   * However, the result may be other object types than the listed above 
+   * due to new supported toolkits.
+   * </p>
+   * <p>
+   * This method may also return <code>null</code> if no UI toolkit is being used,
+   * as common for offscreen rendering.
+   * </p>
+   * @return
+   */
+  public Object getUpstreamWidget();
 
 }
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
index 89d5cc4cb..1f6166719 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
@@ -56,8 +56,14 @@ import jogamp.opengl.GLDrawableImpl;
 public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
     
-    public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context) {
+    /**
+     * @param drawable
+     * @param context
+     * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+     */
+    public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget) {
         super((GLDrawableImpl)drawable, (GLContextImpl)context);
+        this.upstreamWidget = null;
     }
     
     //
@@ -80,8 +86,14 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
     // Complete GLAutoDrawable
     //
     
-    private RecursiveLock lock = LockFactory.createRecursiveLock();  // instance wide lock
-
+    private final RecursiveLock lock = LockFactory.createRecursiveLock();  // instance wide lock
+    private final Object upstreamWidget;
+    
+    @Override
+    public final Object getUpstreamWidget() {
+        return upstreamWidget;
+    }
+    
     /**
      * {@inheritDoc}
      * <p>
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index bd24b15bc..f5831a72d 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -340,5 +340,60 @@ public interface GLBase {
     * completeness.
     */
    public Object getExtension(String extensionName);
+
+   /** Aliased entrypoint of <code> void {@native glClearDepth}(GLclampd depth); </code> and <code> void {@native glClearDepthf}(GLclampf depth); </code>. */  
+   public void glClearDepth( double depth );
+
+   /** Aliased entrypoint of <code> void {@native glDepthRange}(GLclampd depth); </code> and <code> void {@native glDepthRangef}(GLclampf depth); </code>. */  
+   public void glDepthRange(double zNear, double zFar);
+
+   /**
+    * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
+    * @return the GL buffer (VBO) name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+    */
+   public int glGetBoundBuffer(int target);
+
+   /**
+    * @param buffer a GL buffer name, generated with {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} for example.
+    * @return the size of the given GL buffer
+    */
+   public long glGetBufferSize(int buffer);
+
+   /**
+    * @return true if a VBO is bound to {@link GL.GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    */
+   public boolean glIsVBOArrayEnabled();
+
+   /**
+    * @return true if a VBO is bound to {@link GL.GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+    */
+   public boolean glIsVBOElementArrayEnabled();
+
+   /** 
+    * Return the framebuffer name bound to this context, 
+    * see {@link GL#glBindFramebuffer(int, int)}.
+    */
+   public int getBoundFramebuffer(int target);
+
+   /** 
+    * Return the default draw framebuffer name.
+    * <p> 
+    * May differ from it's default <code>zero</code>
+    * in case an framebuffer object ({@link FBObject}) based drawable
+    * is being used.
+    * </p> 
+    */
+   public int getDefaultDrawFramebuffer();
+
+   /** 
+    * Return the default read framebuffer name.
+    * <p> 
+    * May differ from it's default <code>zero</code>
+    * in case an framebuffer object ({@link FBObject}) based drawable
+    * is being used.
+    * </p> 
+    */
+   public int getDefaultReadFramebuffer();
+
 }
 
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index e5258bcfd..8845ec665 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -183,8 +183,8 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
         return -1;
     }
 
-    final int ms = sampleBuffers ? numSamples : 0;
-    final int xms = caps.getSampleBuffers() ? caps.getNumSamples() : 0;
+    final int ms = getNumSamples();
+    final int xms = caps.getNumSamples() ;
 
     if(ms > xms) {
         return 1;
@@ -231,15 +231,13 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
   /**
    * Enables or disables pbuffer usage.
    * <p>
-   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
-   * and {@link #setFBO(int) setFBO(false)}<br>
+   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
    * </p>
    * Defaults to false.
    */
   public void setPBuffer(boolean enable) {
     if(enable) {
       setOnscreen(false);
-      setFBO(false);
     }
     isPBuffer = enable;
   }
@@ -252,28 +250,28 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
   /**
    * Enables or disables FBO usage.
    * <p>
-   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
-   * and {@link #setPBuffer(int) setPBuffer(false)}<br>
+   * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
    * </p>
    * Defaults to false.
    */
   public void setFBO(boolean enable) {
     if(enable) {
       setOnscreen(false);
-      setPBuffer(false);
     }
     isFBO = enable;
   }
 
   /**
    * Sets whether the drawable surface supports onscreen.<br>
-   * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}<br>
+   * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
+   * and {@link #setFBO(int) setFBO(false)}<br>
    * Defaults to true.
   */
   @Override
   public void setOnscreen(boolean onscreen) {
     if(onscreen) {
         setPBuffer(false);
+        setFBO(false);
     }
     super.setOnscreen(onscreen);
   }
@@ -413,15 +411,18 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
     return sampleBuffers;
   }
 
-  /** If sample buffers are enabled, indicates the number of buffers
-      to be allocated. Defaults to 2. */
+  /** 
+   * If sample buffers are enabled, indicates the number of buffers
+   * to be allocated. Defaults to 2.
+   * @see #getNumSamples()
+   */
   public void setNumSamples(int numSamples) {
     this.numSamples = numSamples;
   }
 
   @Override
   public final int getNumSamples() {
-    return numSamples;
+    return sampleBuffers ? numSamples : 0;
   }
 
   /** For pbuffers only, indicates whether floating-point buffers
@@ -492,12 +493,14 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
     if(!isOnscreen()) {
         if(isFBO) {
             sink.append(", fbo");
-        } else if(isPBuffer) {
+        } 
+        if(isPBuffer) {
             sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
                 .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
                 .append(", float ").append(pbufferFloatingPointBuffers?1:0)
                 .append("]");
-        } else {
+        } 
+        if(!isFBO && !isPBuffer) {
             sink.append(", pixmap");
         }
     }
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
index 883f3912e..7e0459b2d 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -111,7 +111,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
 
     /**
      * Returns the number of sample buffers to be allocated if sample
-     * buffers are enabled. Defaults to 2.
+     * buffers are enabled, otherwise returns 0. Defaults to 2.
      */
     int getNumSamples();
 
@@ -144,12 +144,12 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
     boolean getStereo();
 
     /**
-     * Indicates whether pbuffer is used/requested.
+     * Indicates whether pbuffer offscreen is used/requested.
      */
     boolean isPBuffer();
 
     /**
-     * Indicates whether FBO is used/requested.
+     * Indicates whether FBO offscreen is used/requested.
      */
     boolean isFBO();
 
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 351f90027..63a02ad9c 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -55,6 +55,7 @@ import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.IntObjectHashMap;
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLExtensions;
 
 /** Abstraction for an OpenGL rendering context. In order to perform
     OpenGL rendering, a context must be "made current" on the current
@@ -69,6 +70,7 @@ import com.jogamp.common.util.locks.RecursiveLock;
     abstraction provides a stable object which clients can use to
     refer to a given context. */
 public abstract class GLContext {
+  
   /** 
    * If <code>true</code> (default), bootstrapping the available GL profiles 
    * will use the highest compatible GL context for each profile, 
@@ -120,13 +122,13 @@ public abstract class GLContext {
   protected static final int CTX_PROFILE_ES      = 1 <<  3;
   /** <code>ARB_create_context</code> related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
   protected static final int CTX_OPTION_FORWARD  = 1 <<  4;
-  /** <code>ARB_create_context</code> related: flag debug. Not a cache key. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+  /** <code>ARB_create_context</code> related: flag debug. Cache key value. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
   public static final int CTX_OPTION_DEBUG       = 1 <<  5;
 
   /** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
   protected static final int CTX_IMPL_ES2_COMPAT = 1 <<  8;
 
-  /** Context supports FBO, details see {@link #hasFBO()}.
+  /** Context supports basic FBO, details see {@link #hasFBO()}.
    * Not a cache key.
    * @see #hasFBO()
    * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
@@ -136,16 +138,6 @@ public abstract class GLContext {
   /** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. See {@link #isHardwareRasterizer()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
   protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 15;
 
-  protected static final String GL_ARB_ES2_compatibility           = "GL_ARB_ES2_compatibility";
-  protected static final String GL_ARB_framebuffer_object          = "GL_ARB_framebuffer_object";
-  protected static final String GL_EXT_framebuffer_object          = "GL_EXT_framebuffer_object";
-  protected static final String GL_EXT_framebuffer_blit            = "GL_EXT_framebuffer_blit";
-  protected static final String GL_EXT_framebuffer_multisample     = "GL_EXT_framebuffer_multisample";
-  protected static final String GL_EXT_packed_depth_stencil        = "GL_EXT_packed_depth_stencil";
-  protected static final String GL_ARB_texture_non_power_of_two    = "GL_ARB_texture_non_power_of_two";
-  protected static final String GL_EXT_texture_format_BGRA8888     = "GL_EXT_texture_format_BGRA8888";
-  protected static final String GL_IMG_texture_format_BGRA8888     = "GL_IMG_texture_format_BGRA8888";
-  
   private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
 
   private final HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
@@ -639,11 +631,19 @@ public abstract class GLContext {
       return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
   }
   
-  /** Returns whether the context supports FBO, hence is either GL-ES >= 2.0, >= core GL 3.0 or implements the extensions
-   * <code>GL_ARB_ES2_compatibility</code>, <code>ARB_framebuffer_object</code> or all of
-   * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>, 
-   * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>.
+  /** 
+   * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>.
+   * <p>
+   * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+   * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>.
+   * </p>
+   * <p>
+   * Basic FBO support may only include one color attachment and no multisampling,
+   * as well as limited internal formats for renderbuffer.
+   * </p>
    * @see #CTX_IMPL_FBO
+   * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
+   * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
    */
   public final boolean hasFBO() {
       return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
@@ -659,13 +659,13 @@ public abstract class GLContext {
 
   /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns <code>true</code>. */
   public boolean isNPOTTextureAvailable() {
-      return isGL3() || isGLES2Compatible() || isExtensionAvailable(GL_ARB_texture_non_power_of_two);
+      return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
   }
 
   public boolean isTextureFormatBGRA8888Available() {
       return isGL2GL3() ||
-             isExtensionAvailable(GL_EXT_texture_format_BGRA8888) ||
-             isExtensionAvailable(GL_IMG_texture_format_BGRA8888) ;
+             isExtensionAvailable(GLExtensions.EXT_texture_format_BGRA8888) ||
+             isExtensionAvailable(GLExtensions.IMG_texture_format_BGRA8888) ;
   }
 
   /** @see GLProfile#isGL4bc() */
@@ -798,7 +798,32 @@ public abstract class GLContext {
   }
   protected boolean bindSwapBarrierImpl(int group, int barrier) { /** nop per default .. **/  return false; }
 
-
+  /** 
+   * Return the framebuffer name bound to this context, 
+   * see {@link GL#glBindFramebuffer(int, int)}.
+   */
+  public abstract int getBoundFramebuffer(int target);
+  
+  /** 
+   * Return the default draw framebuffer name.
+   * <p> 
+   * May differ from it's default <code>zero</code>
+   * in case an framebuffer object ({@link FBObject}) based drawable
+   * is being used.
+   * </p> 
+   */
+  public abstract int getDefaultDrawFramebuffer();
+  
+  /** 
+   * Return the default read framebuffer name.
+   * <p> 
+   * May differ from it's default <code>zero</code>
+   * in case an framebuffer object ({@link FBObject}) based drawable
+   * is being used.
+   * </p> 
+   */
+  public abstract int getDefaultReadFramebuffer();
+  
   /**
    * @return The extension implementing the GLDebugOutput feature,
    *         either <i>GL_ARB_debug_output</i> or <i>GL_AMD_debug_output</i>.
@@ -984,6 +1009,7 @@ public abstract class GLContext {
           deviceVersionsAvailableSet.add(devKey);
           if (DEBUG) {
             System.err.println(getThreadName() + ": createContextARB: SET mappedVersionsAvailableSet "+devKey);
+            System.err.println(GLContext.dumpAvailableGLVersions(null).toString());            
           }
       }
   }
@@ -1010,6 +1036,10 @@ public abstract class GLContext {
     validateProfileBits(profile, "profile");
     validateProfileBits(resCtp, "resCtp");
 
+    if(DEBUG) {
+        System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
+        // Thread.dumpStack();
+    }
     final String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
     final Integer val = new Integer(composeBits(resMajor, resMinor, resCtp));
     synchronized(deviceVersionAvailable) {
@@ -1122,7 +1152,9 @@ public abstract class GLContext {
     } else /* if (glpImpl.isGL2()) */ {
         reqMajorCTP[0]=2;
     }
-    if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc
+    if( glpImpl.isGLES() ) {
+        reqMajorCTP[1]=CTX_PROFILE_ES;
+    } else if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc
         reqMajorCTP[1]=CTX_PROFILE_COMPAT;
     } else {
         reqMajorCTP[1]=CTX_PROFILE_CORE;
@@ -1141,8 +1173,7 @@ public abstract class GLContext {
     int _major[] = { 0 };
     int _minor[] = { 0 };
     int _ctp[] = { 0 };
-    if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1],
-                                        _major, _minor, _ctp)) {
+    if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], _major, _minor, _ctp)) {
       return _ctp[0];
     }
     return 0; // n/a
@@ -1180,6 +1211,23 @@ public abstract class GLContext {
     return null;
   }
 
+  /**
+   * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
+   * <p>
+   * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+   * </p> 
+   * <p>
+   * FBO support is queried as described in {@link #hasFBO()}.
+   * </p>
+   *
+   * @param device the device to request whether FBO is available for
+   * @param glp {@link GLProfile} to check for FBO capabilities
+   * @see GLContext#hasFBO()
+   */
+  public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
+      return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
+  }
+  
   /**
    * @param device the device to request whether the profile is available for
    * @param reqMajor Key Value either 1, 2, 3 or 4
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index d6480e7aa..612a02f14 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -50,9 +50,11 @@ import com.jogamp.common.JogampRuntimeException;
 import com.jogamp.common.util.ReflectionUtil;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
+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.opengl.GLProfile.ShutdownType;
 
 import jogamp.opengl.Debug;
@@ -398,9 +400,18 @@ public abstract class GLDrawableFactory {
   /**
    * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
    * <p>
-   * A Pbuffer drawable/surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
-   * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.<br>
-   * Otherwise a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.<br>
+   * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+   * </p>
+   * <p>
+   * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+   * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+   * </p>
+   * <p>
+   * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
+   * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+   * </p>
+   * <p>
+   * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
    * </p>
    *
    * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
@@ -421,42 +432,31 @@ public abstract class GLDrawableFactory {
     throws GLException;
 
   /**
-   * Creates an offscreen NativeSurface.<br>
-   * A Pbuffer surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
-   * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.<br>
-   * Otherwise a simple pixmap/bitmap surface is created. The latter is unlikely to be hardware accelerated.<br>
-   *
-   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
-   * @param caps the requested GLCapabilties
-   * @param chooser the custom chooser, may be null for default
-   * @param width the requested offscreen width
-   * @param height the requested offscreen height
-   * @return the created offscreen native surface
-   *
-   * @throws GLException if any window system-specific errors caused
-   *         the creation of the GLDrawable to fail.
-   */
-  public abstract NativeSurface createOffscreenSurface(AbstractGraphicsDevice device,
-                                                       GLCapabilitiesImmutable caps,
-                                                       GLCapabilitiesChooser chooser,
-                                                       int width, int height);
-
-  /**
-   * Highly experimental API entry, allowing developer of new windowing system bindings 
-   * to leverage the native window handle to produce a NativeSurface implementation (ProxySurface), having the required GLCapabilities.<br>
-   * Such surface can be used to instantiate a GLDrawable and hence test your new binding w/o the 
-   * costs of providing a full set of abstraction like the AWT GLCanvas or even the native NEWT bindings.
+   * Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance. 
+   * <p>
+   * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}.
+   * </p>
+   * <p>
+   * Lifecycle (destruction) of the given surface handle shall be handled by the caller.
+   * </p>
+   * <p>
+   * Such surface can be used to instantiate a GLDrawable. With the help of {@link GLAutoDrawableDelegate}
+   * you will be able to implement a new native windowing system  binding almost on-the-fly, see {@link com.jogamp.opengl.swt.GLCanvas}. 
+   * </p>
    * 
-   * @param device the platform's target device, shall not be <code>null</code>
+   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+   *        Caller has to ensure it is compatible w/ the given <code>windowHandle</code> 
+   * @param screenIdx matching screen index of given <code>windowHandle</code>
    * @param windowHandle the native window handle
    * @param caps the requested GLCapabilties
    * @param chooser the custom chooser, may be null for default
-   * @return The proxy surface wrapping the windowHandle on the device
+   * @param upstream optional {@link ProxySurface.UpstreamSurfaceHook} allowing control of the {@link ProxySurface}'s lifecycle and data it presents.
+   * @return the created {@link ProxySurface} instance w/ defined surface handle.
    */
-  public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device, 
+  public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+                                                  int screenIdx, 
                                                   long windowHandle, 
-                                                  GLCapabilitiesImmutable caps, 
-                                                  GLCapabilitiesChooser chooser);
+                                                  GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
 
   /**
    * Returns true if it is possible to create a GLPbuffer. Some older
@@ -492,23 +492,7 @@ public abstract class GLDrawableFactory {
                                             GLContext shareWith)
     throws GLException;
 
-  /**
-   * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
-   * <p>
-   * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
-   * </p> 
-   * <p>
-   * FBO support is queried as described in {@link GLContext#hasFBO()}.
-   * </p>
-   *
-   * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
-   * @param glp {@link GLProfile} to check for FBO capabilities
-   * @see GLContext#hasFBO()
-   */
-  public final boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp) {
-      return 0 != ( GLContext.CTX_IMPL_FBO & GLContext.getAvailableContextProperties(device, glp) );
-  }
-
+  
   //----------------------------------------------------------------------
   // Methods for interacting with third-party OpenGL libraries
 
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index a7200b560..73d13a387 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -117,10 +117,12 @@ public class GLProfile {
      * @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL. 
      */
     public static void initSingleton(final boolean firstUIActionOnProcess) {
+        final boolean justInitialized; 
         initLock.lock();
         try {
             if(!initialized) { // volatile: ok
                 initialized = true;
+                justInitialized = true;
                 if(DEBUG) {
                     System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
                     Thread.dumpStack();
@@ -166,10 +168,17 @@ public class GLProfile {
                         return null;
                     }
                 });
+            } else {
+                justInitialized = false;
             }
         } finally {
             initLock.unlock();
         }
+        if(DEBUG) {
+            if( justInitialized && ( hasGL234Impl || hasGLES1Impl || hasGLES2Impl ) ) {
+                System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
+            }
+        }        
     }
     
     /**
@@ -1532,18 +1541,17 @@ public class GLProfile {
 
         if(DEBUG) {
             // System.err.println("GLProfile.init addedAnyProfile      "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
-            System.err.println("GLProfile.init addedAnyProfile      "+addedAnyProfile);
-            System.err.println("GLProfile.init isAWTAvailable       "+isAWTAvailable);
-            System.err.println("GLProfile.init hasDesktopGLFactory  "+hasDesktopGLFactory);
-            System.err.println("GLProfile.init hasGL234Impl         "+hasGL234Impl);
-            System.err.println("GLProfile.init hasEGLFactory        "+hasEGLFactory);
-            System.err.println("GLProfile.init hasGLES1Impl         "+hasGLES1Impl);
-            System.err.println("GLProfile.init hasGLES2Impl         "+hasGLES2Impl);
-            System.err.println("GLProfile.init defaultDevice        "+defaultDevice);
-            System.err.println("GLProfile.init profile order        "+array2String(GL_PROFILE_LIST_ALL));
-            if(hasGL234Impl || hasGLES1Impl || hasGLES2Impl) { // avoid deadlock
-                System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true));
-            }
+            System.err.println("GLProfile.init addedAnyProfile       "+addedAnyProfile);
+            System.err.println("GLProfile.init isAWTAvailable        "+isAWTAvailable);
+            System.err.println("GLProfile.init hasDesktopGLFactory   "+hasDesktopGLFactory);
+            System.err.println("GLProfile.init hasGL234Impl          "+hasGL234Impl);
+            System.err.println("GLProfile.init hasEGLFactory         "+hasEGLFactory);
+            System.err.println("GLProfile.init hasGLES1Impl          "+hasGLES1Impl);
+            System.err.println("GLProfile.init hasGLES2Impl          "+hasGLES2Impl);
+            System.err.println("GLProfile.init defaultDevice         "+defaultDevice);
+            System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
+            System.err.println("GLProfile.init defaultDevice EGL     "+defaultEGLDevice);
+            System.err.println("GLProfile.init profile order         "+array2String(GL_PROFILE_LIST_ALL));
         }
     }
 
@@ -1642,24 +1650,6 @@ public class GLProfile {
             if (DEBUG) {
                 System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
             }
-            if( hasGLES2Impl ) {
-                // The native ES2 impl. overwrites a previous mapping using 'ES2 compatibility' by a desktop profile 
-                GLContext.mapAvailableGLVersion(device,
-                                                2, GLContext.CTX_PROFILE_ES,
-                                                2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_IMPL_ES2_COMPAT);
-                if (DEBUG) {
-                  System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES2 -> ES 2.0");
-                }
-            }
-            if( hasGLES1Impl ) {
-                // Always favor the native ES1 impl.
-                GLContext.mapAvailableGLVersion(device,
-                                                1, GLContext.CTX_PROFILE_ES,
-                                                1, 0, GLContext.CTX_PROFILE_ES);
-                if (DEBUG) {
-                  System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES1 -> ES 1.0");
-                }
-            }
             addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
         }
 
@@ -1767,7 +1757,7 @@ public class GLProfile {
                 }
                 _mappedProfiles.put(profile, glProfile);
                 if (DEBUG) {
-                    System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
+                    System.err.println("GLProfile.init map "+glProfile+" on device "+device.getConnection());
                 }
                 if(null==defaultGLProfileHW && isHardwareRasterizer[0]) {
                     defaultGLProfileHW=glProfile;
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 48f7ea24a..c2e36ef9b 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -261,6 +261,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     this.device = device;
   }
 
+  @Override
+  public final Object getUpstreamWidget() {
+    return this;
+  }
+     
   @Override
   public void setShallUseOffscreenLayer(boolean v) {
       shallUseOffscreenLayer = v;
@@ -1070,7 +1075,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
     // System.err.println(NativeWindowVersion.getInstance());
     System.err.println(JoglVersion.getInstance());
 
-    System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+    System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
 
     final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
     final Frame frame = new Frame("JOGL AWT Test");
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index cd18c5098..acb8f2183 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -87,7 +87,7 @@ import jogamp.opengl.awt.Java2D;
 import jogamp.opengl.awt.Java2DGLContext;
 
 import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
 import com.jogamp.opengl.util.GLBuffers;
 
 // FIXME: Subclasses need to call resetGLFunctionAvailability() on their
@@ -250,6 +250,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
     this.shareWith = shareWith;
   }
 
+  @Override
+  public final Object getUpstreamWidget() {
+    return this;
+  }
+  
   @Override
   public void display() {
     if (EventQueue.isDispatchThread()) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index 804e9ee14..aabef29b0 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -32,7 +32,6 @@ import java.nio.FloatBuffer;
 import javax.media.opengl.GL2ES2;
 // FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER ! 
 import javax.media.opengl.GL;
-import javax.media.opengl.GLException;
 import javax.media.opengl.GLUniformData;
 import javax.media.opengl.fixedfunc.GLMatrixFunc;
 
@@ -45,7 +44,9 @@ import com.jogamp.graph.geom.Vertex;
 
 import com.jogamp.graph.curve.opengl.GLRegion;
 import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.TextureAttachment;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -60,6 +61,7 @@ public class VBORegion2PES2  extends GLRegion {
     
     
     private FBObject fbo;
+    private TextureAttachment texA;
     private PMVMatrix fboPMVMatrix;
     GLUniformData mgl_fboPMVMatrix;
     
@@ -72,7 +74,7 @@ public class VBORegion2PES2  extends GLRegion {
         super(renderModes);
         fboPMVMatrix = new PMVMatrix();
         mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf());        
-        mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);        
+        mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);    
     }
     
     public void update(GL2ES2 gl, RenderState rs) {
@@ -214,8 +216,9 @@ public class VBORegion2PES2  extends GLRegion {
         final ShaderState st = rs.getShaderState();
         
         gl.glViewport(0, 0, width, hight);        
-        st.uniform(gl, mgl_ActiveTexture);        
-        fbo.use(gl, 0);                        
+        st.uniform(gl, mgl_ActiveTexture);    
+        gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
+        fbo.use(gl, texA);                        
         verticeFboAttr.enableBuffer(gl, true);       
         texCoordFboAttr.enableBuffer(gl, true);
         indicesFbo.enableBuffer(gl, true);
@@ -244,20 +247,16 @@ public class VBORegion2PES2  extends GLRegion {
         // System.out.println("FBO Scale: " + m.glGetMatrixf().get(0) +" " + m.glGetMatrixf().get(5));
         
         if(null != fbo && fbo.getWidth() != tex_width_c && fbo.getHeight() != tex_height_c ) {
-            fbo.destroy(gl);
-            fbo = null;
+            fbo.reset(gl, tex_width_c, tex_height_c);
         }
         
-        if(null == fbo) {        
-            fbo = new FBObject(tex_width_c, tex_height_c);
-            fbo.init(gl); 
+        if(null == fbo) {  
+            fbo = new FBObject();
+            fbo.reset(gl, tex_width_c, tex_height_c); 
             // FIXME: shall not use bilinear, due to own AA ? However, w/o bilinear result is not smooth
-            fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
-            // fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
-            fbo.attachDepthBuffer(gl, GL.GL_DEPTH_COMPONENT16); // FIXME: or shall we use 24 or 32 bit depth ?
-            if(!fbo.isStatusValid()) {
-                throw new GLException("FBO invalid: "+fbo);
-            }
+            texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+            // texA = fbo.attachTexture2D(gl, 0, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+            fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
         } else {
             fbo.bind(gl);
         }
@@ -305,6 +304,7 @@ public class VBORegion2PES2  extends GLRegion {
         if(null != fbo) {
             fbo.destroy(gl);
             fbo = null;
+            texA = null;
         }        
         if(null != verticeTxtAttr) {
             st.ownAttribute(verticeTxtAttr, false);
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 4dd8806fa..e730bc62e 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -49,8 +49,9 @@ import com.jogamp.common.os.DynamicLookupHelper;
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.gluegen.runtime.FunctionAddressResolver;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -88,13 +89,14 @@ public abstract class GLContextImpl extends GLContext {
   // Tracks creation and initialization of buffer objects to avoid
   // repeated glGet calls upon glMapBuffer operations
   private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
-  private GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
-  private GLStateTracker glStateTracker = new GLStateTracker();
+  private final GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+  private final GLStateTracker glStateTracker = new GLStateTracker();
   private GLDebugMessageHandler glDebugHandler = null;
+  private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
 
   protected GLDrawableImpl drawable;
   protected GLDrawableImpl drawableRead;
-
+  
   protected GL gl;
 
   protected static final Object mappedContextTypeObjectLock;
@@ -140,11 +142,11 @@ public abstract class GLContextImpl extends GLContext {
           bufferSizeTracker.clearCachedBufferSizes();
       }
 
-      if (bufferStateTracker != null) {
+      if (bufferStateTracker != null) { // <init>
           bufferStateTracker.clearBufferObjectState();
       }
 
-      if (glStateTracker != null) {
+      if (glStateTracker != null) { // <init>
           glStateTracker.clearStates(false);
       }
 
@@ -156,6 +158,11 @@ public abstract class GLContextImpl extends GLContext {
 
       glRenderer = "";
       glRendererLowerCase = glRenderer;
+      
+      if (boundFBOTarget != null) { // <init>
+          boundFBOTarget[0] = 0; // draw
+          boundFBOTarget[1] = 0; // read
+      }
 
       super.resetStates();
   }
@@ -199,7 +206,7 @@ public abstract class GLContextImpl extends GLContext {
         drawableRead = (GLDrawableImpl) readWrite;
     }
     final GLDrawable old = drawable;
-    drawable = ( null != readWrite ) ? (GLDrawableImpl) readWrite : null;
+    drawable = (GLDrawableImpl) readWrite ;
     if(lockHeld) {
         makeCurrent();
     }
@@ -252,16 +259,19 @@ public abstract class GLContextImpl extends GLContext {
   public void release() throws GLException {
     release(false);
   }
-  private void release(boolean force) throws GLException {
+  private void release(boolean inDestruction) throws GLException {
     if(TRACE_SWITCH) {
-        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+force+", "+lock);
+        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+inDestruction+", "+lock);
     }
     if ( !lock.isOwner(Thread.currentThread()) ) {
         throw new GLException("Context not current on current thread "+Thread.currentThread().getName()+": "+this);
     }
-    final boolean actualRelease = ( force || lock.getHoldCount() == 1 ) && 0 != contextHandle;
+    final boolean actualRelease = ( inDestruction || lock.getHoldCount() == 1 ) && 0 != contextHandle;
     try {
         if( actualRelease ) {
+            if( !inDestruction ) {
+                drawable.contextMadeCurrent(this, false);
+            }
             releaseImpl();
         }
     } finally {
@@ -306,13 +316,12 @@ public abstract class GLContextImpl extends GLContext {
               }
               try {
                   // release current context
-                  if(null != glDebugHandler) {
-                      if(lock.getHoldCount() == 1) {
-                          // needs current context to disable debug handler
-                          makeCurrent();
-                      }
-                      glDebugHandler.enable(false);
+                  if(lock.getHoldCount() == 1) {
+                      // needs current context to disable debug handler
+                      makeCurrent();
                   }
+                  drawable.contextRealized(this, false);
+                  glDebugHandler.enable(false);
                   if(lock.getHoldCount() > 1) {
                       // pending release() after makeCurrent()
                       release(true);
@@ -488,11 +497,18 @@ public abstract class GLContextImpl extends GLContext {
         if(TRACE_GL) {
             gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
         }
+        
+        drawable.contextRealized(this, true);
+        
         if(DEBUG || TRACE_SWITCH) {
             System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
         }
-      } else if(TRACE_SWITCH) {
-        System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+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);
+        }
       }
 
       /* FIXME: refactor dependence on Java 2D / JOGL bridge
@@ -543,14 +559,11 @@ public abstract class GLContextImpl extends GLContext {
             final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
             final AbstractGraphicsDevice device = config.getScreen().getDevice();
 
-            if( !GLContext.getAvailableGLVersionsSet(device) ) {
-                final int reqMajor;
-                final int reqProfile;
-                if( 0 != ( ctxOptions & GLContext.CTX_PROFILE_ES) ) {
-                    // ES1 or ES2
-                    reqMajor = ctxMajorVersion;
-                    reqProfile = GLContext.CTX_PROFILE_ES;
-                } else {
+            // Non ARB desktop profiles may not have been registered 
+            if( !GLContext.getAvailableGLVersionsSet(device) ) {        // not yet set
+                if( 0 == ( ctxOptions & GLContext.CTX_PROFILE_ES) ) {   // not ES profile
+                    final int reqMajor;
+                    final int reqProfile;
                     if(ctxMajorVersion<3 || ctxMajorVersion==3 && ctxMinorVersion==0) {
                         reqMajor = 2;
                     } else {
@@ -561,12 +574,13 @@ public abstract class GLContextImpl extends GLContext {
                     } else {
                         reqProfile = GLContext.CTX_PROFILE_COMPAT;
                     }
-                }
-                GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
-                                                ctxMajorVersion, ctxMinorVersion, ctxOptions);
-                GLContext.setAvailableGLVersionsSet(device);
-                if (DEBUG) {
-                  System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+                    GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
+                                                    ctxMajorVersion, ctxMinorVersion, ctxOptions);
+                    GLContext.setAvailableGLVersionsSet(device);
+                    
+                    if (DEBUG) {
+                      System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+                    }                    
                 }
             }
         }
@@ -776,7 +790,7 @@ public abstract class GLContextImpl extends GLContext {
   }
 
   /** 
-   * Note: Since context creation is temproary, caller need to issue {@link #resetStates()}, if creation was successful, i.e. returns true.
+   * Note: Since context creation is temporary, caller need to issue {@link #resetStates()}, if creation was successful, i.e. returns true.
    * This method does not reset the states, allowing the caller to utilize the state variables. 
    **/
   private final boolean createContextARBMapVersionsAvailable(int reqMajor, int reqProfile) {
@@ -1034,22 +1048,29 @@ public abstract class GLContextImpl extends GLContext {
     table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
   }
 
-  private final void initGLRendererStrings()  {
+  private final boolean initGLRendererStrings()  {
     final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
     final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
     if(0 == _glGetString) {
         // FIXME
         System.err.println("Warning: Entry point to 'glGetString' is NULL.");
-        Thread.dumpStack();
+        if(DEBUG) {
+            Thread.dumpStack();
+        }
+        return false;
     } else {
         final String _glRenderer = glGetStringInt(GL.GL_RENDERER, _glGetString);
         if(null == _glRenderer) {
             // FIXME
-            System.err.println("Warning: GL_RENDERER is NULL.");
-            Thread.dumpStack();
+            if(DEBUG) {
+                System.err.println("Warning: GL_RENDERER is NULL.");
+                Thread.dumpStack();
+            }
+            return false;
         } else {
             glRenderer = _glRenderer;
             glRendererLowerCase = glRenderer.toLowerCase();
+            return true;
         }
     }
   }
@@ -1088,17 +1109,20 @@ public abstract class GLContextImpl extends GLContext {
     }
     updateGLXProcAddressTable();
 
-    initGLRendererStrings();
+    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));
+    }
 
     if(!isCurrentContextHardwareRasterizer()) {
         ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
     }
-    final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
-    final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
 
     contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
     if (DEBUG) {
-      System.err.println(getThreadName() + ": Context FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+      System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
     }
 
     //
@@ -1154,11 +1178,10 @@ public abstract class GLContextImpl extends GLContext {
         }
     }
     
-    if( 0 != ( CTX_PROFILE_ES & ctxProfileBits ) && ctxMajorVersion >= 2 ||
-        isExtensionAvailable(GL_ARB_ES2_compatibility) ) {
+    if( ( 0 != ( CTX_PROFILE_ES & ctxProfileBits ) && major >= 2 ) || isExtensionAvailable(GLExtensions.ARB_ES2_compatibility) ) {
         ctxProfileBits |= CTX_IMPL_ES2_COMPAT;
         ctxProfileBits |= CTX_IMPL_FBO;
-    } else if( hasFBOImpl(ctxMajorVersion, ctxProfileBits, extensionAvailability) ) {
+    } else if( hasFBOImpl(major, ctxProfileBits, extensionAvailability) ) {
         ctxProfileBits |= CTX_IMPL_FBO;
     }
     
@@ -1168,23 +1191,26 @@ public abstract class GLContextImpl extends GLContext {
     setContextVersion(major, minor, ctxProfileBits, true);
 
     setDefaultSwapInterval();
+    
+    if(DEBUG) {
+        System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: "+contextFQN+" - "+GLContext.getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, null));
+    }
   }
   
-  protected static final boolean hasFBOImpl(int ctxMajorVersion, int ctxProfileBits, ExtensionAvailabilityCache extCache) {
-    return ( ctxMajorVersion >= 3 ) ||                                               // any >= 3.0 GL ctx
+  protected static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
+    return ( 0 != (ctp & CTX_PROFILE_ES) && major >= 2 ) ||   // ES >= 2.0
             
-           ( 0 != (ctxProfileBits & CTX_PROFILE_ES) && ctxMajorVersion >= 2 ) ||     // ES >= 2.0
+           major >= 3 ||                                                 // any >= 3.0 GL ctx                       
            
            ( null != extCache &&
            
-               ( extCache.isExtensionAvailable(GL_ARB_ES2_compatibility) ) ||        // ES 2.0 compatible
+               extCache.isExtensionAvailable(GLExtensions.ARB_ES2_compatibility)  ||         // ES 2.0 compatible
                
-               ( extCache.isExtensionAvailable(GL_ARB_framebuffer_object) ) ||       // ARB_framebuffer_object
+               extCache.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) ||         // ARB_framebuffer_object
                
-               ( extCache.isExtensionAvailable(GL_EXT_framebuffer_object) &&         // EXT_framebuffer_object*
-                 extCache.isExtensionAvailable(GL_EXT_framebuffer_multisample) &&
-                 extCache.isExtensionAvailable(GL_EXT_framebuffer_blit) &&
-                 extCache.isExtensionAvailable(GL_EXT_packed_depth_stencil) ) );           
+               extCache.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) ||         // EXT_framebuffer_object
+               
+               extCache.isExtensionAvailable(GLExtensions.OES_framebuffer_object) ) ;        // OES_framebuffer_object excluded               
   }
   
   protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
@@ -1259,11 +1285,11 @@ public abstract class GLContextImpl extends GLContext {
 
     // dynamic function lookup at last incl name aliasing (not cached)
     DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
-    String tmpBase = GLExtensionNames.normalizeVEN(GLExtensionNames.normalizeARB(glFunctionName, true), true);
+    String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
     long addr = 0;
-    int  variants = GLExtensionNames.getFuncNamePermutationNumber(tmpBase);
+    int  variants = GLNameResolver.getFuncNamePermutationNumber(tmpBase);
     for(int i = 0; 0==addr && i < variants; i++) {
-        String tmp = GLExtensionNames.getFuncNamePermutation(tmpBase, i);
+        String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i);
         try {
             addr = dynLookup.dynamicLookupFunction(tmp);
         } catch (Exception e) { }
@@ -1317,7 +1343,7 @@ public abstract class GLContextImpl extends GLContext {
 
   protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctxProfileBits) {
       // remove non-key values
-      ctxProfileBits &= ~( GLContext.CTX_OPTION_DEBUG | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) ;
+      ctxProfileBits &= ~( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) ;
 
       return device.getUniqueID() + "-" + toHexString(composeBits(major, minor, ctxProfileBits));
   }
@@ -1371,6 +1397,56 @@ public abstract class GLContextImpl extends GLContext {
     return lock.getQueueLength()>0;
   }
 
+  //---------------------------------------------------------------------------
+  // Special FBO hook
+  //
+  
+  /**
+   * Tracks {@link GL#GL_FRAMEBUFFER}, {@link GL2GL3#GL_DRAW_FRAMEBUFFER} and {@link GL2GL3#GL_READ_FRAMEBUFFER}
+   * to be returned via {@link #getBoundFramebuffer(int)}.
+   * 
+   * <p>Invoked by {@link GL#glBindFramebuffer(int, int)}. </p>
+   * 
+   * <p>Assumes valid <code>framebufferName</code> range of [0..{@link Integer#MAX_VALUE}]</p> 
+   * 
+   * <p>Does not throw an exception if <code>target</code> is unknown or <code>framebufferName</code> invalid.</p>
+   */
+  public final void setBoundFramebuffer(int target, int framebufferName) {
+      if(0 > framebufferName) {
+          return; // ignore invalid name
+      }
+      switch(target) {
+          case GL.GL_FRAMEBUFFER:
+              boundFBOTarget[0] = framebufferName; // draw
+              boundFBOTarget[1] = framebufferName; // read
+              break;
+          case GL2GL3.GL_DRAW_FRAMEBUFFER:
+              boundFBOTarget[0] = framebufferName; // draw
+              break;
+          case GL2GL3.GL_READ_FRAMEBUFFER:
+              boundFBOTarget[1] = framebufferName; // read
+              break;
+          default: // ignore untracked target
+      }
+  }
+  @Override
+  public final int getBoundFramebuffer(int target) {
+      switch(target) {
+          case GL.GL_FRAMEBUFFER:
+          case GL2GL3.GL_DRAW_FRAMEBUFFER:
+              return boundFBOTarget[0]; // draw
+          case GL2GL3.GL_READ_FRAMEBUFFER:
+              return boundFBOTarget[1]; // read
+          default:
+              throw new InternalError("Invalid FBO target name: "+toHexString(target));
+      }
+  }
+  
+  @Override
+  public final int getDefaultDrawFramebuffer() { return drawable.getDefaultDrawFramebuffer(); }  
+  @Override
+  public final int getDefaultReadFramebuffer() { return drawable.getDefaultReadFramebuffer(); }
+  
   //---------------------------------------------------------------------------
   // GL_ARB_debug_output, GL_AMD_debug_output helpers
   //
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index b950c2fdf..0000e6199 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -37,6 +37,8 @@ import javax.media.opengl.GLException;
 
 import com.jogamp.common.os.Platform;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.opengl.GLExtensions;
+
 import jogamp.opengl.gl4.GL4bcProcAddressTable;
 
 /**
@@ -54,12 +56,6 @@ import jogamp.opengl.gl4.GL4bcProcAddressTable;
  * the messages are translated to <i>ARB</i> {@link GLDebugMessage}, using {@link GLDebugMessage#translateAMDEvent(javax.media.opengl.GLContext, long, int, int, int, String)}.</p>
  */
 public class GLDebugMessageHandler {
-    /** Extension <i>GL_ARB_debug_output</i> implementing GLDebugMessage */
-    public static final String GL_ARB_debug_output = "GL_ARB_debug_output".intern();
-    
-    /** Extension <i>GL_AMD_debug_output</i> implementing GLDebugMessage */
-    public static final String GL_AMD_debug_output = "GL_AMD_debug_output".intern();
-    
     private static final boolean DEBUG = Debug.debug("GLDebugMessageHandler");
     
     private static final int EXT_ARB = 1;
@@ -131,11 +127,11 @@ public class GLDebugMessageHandler {
             }
             return;
         }
-        if( ctx.isExtensionAvailable(GL_ARB_debug_output) ) {
-            extName = GL_ARB_debug_output;
+        if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
+            extName = GLExtensions.ARB_debug_output;
             extType = EXT_ARB;
-        } else if( ctx.isExtensionAvailable(GL_AMD_debug_output) ) {
-            extName = GL_AMD_debug_output;
+        } else if( ctx.isExtensionAvailable(GLExtensions.AMD_debug_output) ) {
+            extName = GLExtensions.AMD_debug_output;
             extType = EXT_AMD;
         }
         if(DEBUG) {
@@ -145,6 +141,8 @@ public class GLDebugMessageHandler {
         if(0 == extType) {
             if(DEBUG) {
                 System.err.println("GLDebugMessageHandler: No extension available! "+ctx.getGLVersion());
+                System.err.println("GL_EXTENSIONS  "+ctx.getGLExtensionCount());
+                System.err.println(ctx.getGLExtensionsString());                
             }
             return;
         }
@@ -190,11 +188,11 @@ public class GLDebugMessageHandler {
     }
     
     public final boolean isExtensionARB() {
-        return extName == GL_ARB_debug_output;
+        return extName == GLExtensions.ARB_debug_output;
     }
     
     public final boolean isExtensionAMD() {
-        return extName == GL_AMD_debug_output;
+        return extName == GLExtensions.AMD_debug_output;
     }
     
     /**
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index e5c44a8d4..897d3fcaf 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -1,22 +1,22 @@
 /*
  * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
  * Copyright (c) 2010 JogAmp Community. All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  * - Redistribution of source code must retain the above copyright
  *   notice, this list of conditions and the following disclaimer.
- * 
+ *
  * - Redistribution in binary form must reproduce the above copyright
  *   notice, this list of conditions and the following disclaimer in the
  *   documentation and/or other materials provided with the distribution.
- * 
+ *
  * Neither the name of Sun Microsystems, Inc. or the names of
  * contributors may be used to endorse or promote products derived from
  * this software without specific prior written permission.
- * 
+ *
  * This software is provided "AS IS," without a warranty of any kind. ALL
  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,11 +29,11 @@
  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * 
+ *
  * You acknowledge that this software is not designed or intended for use
  * in the design, construction, operation or maintenance of any nuclear
  * facility.
- * 
+ *
  * Sun gratefully acknowledges that this software was originally authored
  * and developed by Kenneth Bradley Russell and Christopher John Kline.
  */
@@ -47,7 +47,8 @@ import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.OffscreenLayerSurface;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
@@ -88,7 +89,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
       return null;
   }
   protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
-  
+
   /**
    * Returns the shared device mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
    * either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
@@ -115,7 +116,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
   }
   protected abstract AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device);
 
-  /** 
+  /**
    * Returns the GLDynamicLookupHelper
    * @param profile if EGL/ES, profile <code>1</code> refers to ES1 and <code>2</code> to ES2,
    *        otherwise the profile is ignored.
@@ -125,6 +126,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
   //---------------------------------------------------------------------------
   // Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
   //
+  @Override
   public GLDrawable createGLDrawable(NativeSurface target) {
     if (target == null) {
       throw new IllegalArgumentException("Null target");
@@ -132,23 +134,37 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
     final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
     final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
     final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+    final boolean isFBOAvailable = GLContext.isFBOAvailable(adevice, chosenCaps.getGLProfile());
     GLDrawable result = null;
     adevice.lock();
     try {
         final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
         if(null != ols) {
-            // layered surface -> Offscreen/PBuffer
+            // layered surface -> Offscreen/[FBO|PBuffer]
             final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
             chosenCapsMod.setOnscreen(false);
-            chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice));
+            if( isFBOAvailable ) {
+                chosenCapsMod.setFBO(true);
+            } else if(canCreateGLPbuffer(adevice)) {
+                chosenCapsMod.setPBuffer(true);
+            } else {
+                chosenCapsMod.setFBO(false);
+                chosenCapsMod.setPBuffer(false);
+            }
             config.setChosenCapabilities(chosenCapsMod);
             if(DEBUG) {
                 System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
             }
-            if( ! ( target instanceof SurfaceChangeable ) ) {
+            if( ! ( target instanceof MutableSurface ) ) {
                 throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
+            }            
+            if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+                // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+                final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);                
+                result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+            } else {            
+                result = createOffscreenDrawableImpl(target);
             }
-            result = createOffscreenDrawableImpl(target);            
         } else if(chosenCaps.isOnscreen()) {
             // onscreen
             if(DEBUG) {
@@ -158,12 +174,18 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
         } else {
             // offscreen
             if(DEBUG) {
-                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target);
+                System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target);
             }
-            if( ! ( target instanceof SurfaceChangeable ) ) {
+            if( ! ( target instanceof MutableSurface ) ) {
                 throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
             }
-            result = createOffscreenDrawableImpl(target);
+            if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+                // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+                final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);                
+                result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+            } else {
+                result = createOffscreenDrawableImpl(target);
+            }
         }
     } finally {
         adevice.unlock();
@@ -176,43 +198,42 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
 
   //---------------------------------------------------------------------------
   //
-  // Onscreen GLDrawable construction 
+  // Onscreen GLDrawable construction
   //
 
   protected abstract GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target);
 
   //---------------------------------------------------------------------------
   //
-  // PBuffer Offscreen GLDrawable construction 
+  // PBuffer Offscreen GLDrawable construction
   //
-
+  
+  @Override
   public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
 
+  @Override
   public GLPbuffer createGLPbuffer(AbstractGraphicsDevice deviceReq,
                                    GLCapabilitiesImmutable capsRequested,
                                    GLCapabilitiesChooser chooser,
                                    int width,
                                    int height,
                                    GLContext shareWith) {
-    if(height<=0 || height<=0) {
-        throw new GLException("Width and height of pbuffer must be positive (were (" +
-                        width + ", " + height + "))");
+    if(width<=0 || height<=0) {
+        throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
     }
-
     AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
     if(null == device) {
         throw new GLException("No shared device for requested: "+deviceReq);
     }
-
-    if (!canCreateGLPbuffer(device)) {
-        throw new GLException("Pbuffer support not available with device: "+device);
+    if ( !canCreateGLPbuffer(device) ) {
+        throw new GLException("Pbuffer not available with device: "+device);
     }
-    
-    GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
+
+    final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
     GLDrawableImpl drawable = null;
     device.lock();
     try {
-        drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+        drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
         if(null != drawable) {
             drawable.setRealized(true);
         }
@@ -228,75 +249,155 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
 
   //---------------------------------------------------------------------------
   //
-  // Offscreen GLDrawable construction 
+  // Offscreen GLDrawable construction
   //
 
-  protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
-
+  @Override
   public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
                                             GLCapabilitiesImmutable capsRequested,
                                             GLCapabilitiesChooser chooser,
-                                            int width,
-                                            int height) {
+                                            int width, int height) {
     if(width<=0 || height<=0) {
-        throw new GLException("Width and height of pbuffer must be positive (were (" +
-                        width + ", " + height + "))");
+        throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
     }
-    AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+    final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
     if(null == device) {
         throw new GLException("No shared device for requested: "+deviceReq);
     }
-    GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
+    
+    if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+        device.lock();
+        try {
+            return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+        } finally {
+            device.unlock();
+        }
+    }
+    
+    final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
     device.lock();
     try {
-        return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+        return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
     } finally {
         device.unlock();
     }
   }
 
-  public NativeSurface createOffscreenSurface(AbstractGraphicsDevice deviceReq,
-                                              GLCapabilitiesImmutable capsRequested,
-                                              GLCapabilitiesChooser chooser,
-                                              int width, int height) {
-    AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+  /** Creates a platform independent offscreen FBO GLDrawable implementation */  
+  protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, 
+                                            int initialWidth, int initialHeight) {    
+    final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+    final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+    final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+    
+    return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+  }
+  
+  /** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */  
+  protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
+
+  /**
+   * Creates a mutable {@link ProxySurface} w/o defined surface handle.
+   * <p>
+   * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}.
+   * </p>
+   * <p>
+   * Lifecycle (destruction) of the TBD surface handle shall be handled by the caller.
+   * </p>
+   * @param device a valid platform dependent target device.
+   * @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details,
+   *                        otherwise <code>device</code> instance is used as-is.
+   * @param capsChosen
+   * @param capsRequested
+   * @param chooser the custom chooser, may be null for default
+   * @param width the initial width
+   * @param height the initial height
+   * @param lifecycleHook optional control of the surface's lifecycle 
+   * @return the created {@link MutableSurface} instance w/o defined surface handle
+   */
+  protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, 
+                                                           GLCapabilitiesImmutable capsChosen,
+                                                           GLCapabilitiesImmutable capsRequested,
+                                                           GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+
+  /**
+   * A dummy surface is not visible on screen and will not be used to render directly to,
+   * it maybe on- or offscreen.
+   * <p>
+   * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information.
+   * It also allows creation of framebuffer objects which are used for rendering.
+   * </p>
+   * @param deviceReq which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
+   * @param requestedCaps
+   * @param chooser the custom chooser, may be null for default
+   * @param width the initial width
+   * @param height the initial height
+   *
+   * @return the created {@link MutableSurface} instance w/o defined surface handle
+   */
+  public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+                                          int width, int height) {
+    final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
     if(null == device) {
         throw new GLException("No shared device for requested: "+deviceReq);
     }
-    GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
     device.lock();
     try {
-        return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height);
+        return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height);
     } finally {
         device.unlock();
     }
   }
-
+  
   /**
-   * creates an offscreen NativeSurface, which must implement SurfaceChangeable as well,
-   * so the windowing system related implementation is able to set the surface handle.
+   * A dummy surface is not visible on screen and will not be used to render directly to,
+   * it maybe on- or offscreen.
+   * <p>
+   * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information.
+   * It also allows creation of framebuffer objects which are used for rendering.
+   * </p>
+   * @param device a valid platform dependent target device.
+   * @param createNewDevice if <code>true</code> a new device instance is created using <code>device</code> details,
+   *                        otherwise <code>device</code> instance is used as-is.
+   * @param requestedCaps
+   * @param chooser the custom chooser, may be null for default
+   * @param width the initial width
+   * @param height the initial height
+   * @return the created {@link MutableSurface} instance w/o defined surface handle
    */
-  protected abstract NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,
-                                                              GLCapabilitiesImmutable capabilities, GLCapabilitiesImmutable capsRequested,
-                                                              GLCapabilitiesChooser chooser,
-                                                              int width, int height);
+  public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, 
+                                                      GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
 
-  public ProxySurface createProxySurface(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
+  //---------------------------------------------------------------------------
+  //
+  // ProxySurface (Wrapped pre-existing native surface) construction
+  //
+  
+  @Override
+  public ProxySurface createProxySurface(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, 
+                                         GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+    final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
     if(null == device) {
-        throw new GLException("No shared device for requested: "+device);
+        throw new GLException("No shared device for requested: "+deviceReq);
     }
 
     device.lock();
     try {
-        return createProxySurfaceImpl(device, windowHandle, capsRequested, chooser);
+        return createProxySurfaceImpl(device, screenIdx, windowHandle, capsRequested, chooser, upstream);
     } finally {
         device.unlock();
     }
-  }  
-  
-  protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
+  }
+
+  /**
+   * Creates a {@link ProxySurface} with a set surface handle.
+   * <p>
+   * Implementation is also required to allocate it's own {@link AbstractGraphicsDevice} instance.
+   * </p>
+ * @param upstream TODO
+   */
+  protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, 
+                                                         GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
 
   //---------------------------------------------------------------------------
   //
@@ -304,7 +405,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
   //
 
   protected abstract GLContext createExternalGLContextImpl();
-  
+
+  @Override
   public GLContext createExternalGLContext() {
     NativeWindowFactory.getDefaultToolkitLock().lock();
     try {
@@ -316,6 +418,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
 
   protected abstract GLDrawable createExternalGLDrawableImpl();
 
+  @Override
   public GLDrawable createExternalGLDrawable() {
     NativeWindowFactory.getDefaultToolkitLock().lock();
     try {
@@ -398,7 +501,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
    * normal ahead of time, use resetDisplayGamma(). Throws
    * IllegalArgumentException if any of the parameters were
    * out-of-bounds.
-   * 
+   *
    * @param gamma The gamma value, typically > 1.0 (default value is
    *   1.0)
    * @param brightness The brightness value between -1.0 and 1.0,
@@ -484,7 +587,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
       return;
     if (gammaShutdownHook == null) {
       gammaShutdownHook = new Thread(new Runnable() {
-          public void run() {
+          @Override
+        public void run() {
             synchronized (GLDrawableFactoryImpl.this) {
               resetGammaRamp(originalGammaRamp);
             }
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 58a4ac6b4..abf2bf557 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -42,6 +42,7 @@ package jogamp.opengl;
 
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawable;
@@ -75,7 +76,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
     if( !realized ) {
         return; // destroyed already
     }
-    GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+    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]
@@ -149,6 +150,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
         realized = realizedArg;
         AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
         if(realizedArg) {
+            if(surface instanceof ProxySurface) {
+                ((ProxySurface)surface).createNotify();
+            }
             if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
                 throw new GLException("GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)");
             }
@@ -156,17 +160,21 @@ public abstract class GLDrawableImpl implements GLDrawable {
             aDevice.lock();
         }
         try {
-            setRealizedImpl();
             if(realizedArg) {
+                setRealizedImpl();
                 updateHandle();
             } else {
                 destroyHandle();
+                setRealizedImpl();
             }
         } finally {
             if(realizedArg) {
                 unlockSurface();
             } else {
                 aDevice.unlock();
+                if(surface instanceof ProxySurface) {
+                    ((ProxySurface)surface).destroyNotify();
+                }
             }
         }
     } else if(DEBUG) {
@@ -175,6 +183,39 @@ public abstract class GLDrawableImpl implements GLDrawable {
   }
   protected abstract void setRealizedImpl();
 
+  /** 
+   * Callback for special implementations, allowing GLContext to trigger GL related lifecycle: <code>construct</code>, <code>destroy</code>.
+   * <p>
+   * 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.
+   * </p>
+   * <p>
+   * @see #contextMadeCurrent(GLContext, boolean)
+   */
+  protected void contextRealized(GLContext glc, boolean realized) {}
+  
+  /** 
+   * 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>
+   * @see #contextRealized(GLContext, boolean)
+   */ 
+  protected void contextMadeCurrent(GLContext glc, boolean current) { }
+
+  /** 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. */
+  protected int getDefaultReadFramebuffer() { return 0; }
+  
   @Override
   public final synchronized boolean isRealized() {
     return realized;
@@ -190,10 +231,12 @@ public abstract class GLDrawableImpl implements GLDrawable {
     return surface.getHeight();
   }
 
+  /** @see NativeSurface#lockSurface() */
   public final int lockSurface() throws GLException {
     return surface.lockSurface();
   }
 
+  /** @see NativeSurface#unlockSurface() */
   public final void unlockSurface() {
     surface.unlockSurface();
   }
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
new file mode 100644
index 000000000..b7ea4f826
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -0,0 +1,138 @@
+package jogamp.opengl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/**
+ * Offscreen GLDrawable implementation using framebuffer object (FBO)
+ * as it's offscreen rendering mechanism.
+ * 
+ * @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) {
+        super(factory, surface, false);
+        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();
+    }
+    
+    @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
+            if(samples > 0) {
+                fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+            } else {
+                fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+            }
+            if( caps.getStencilBits() > 0 ) {
+                fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+            } else {
+                fbo.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);
+        } else {
+            fbo.unbind(gl);
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+            fbo.use(gl, samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) );
+            if( samples > 0) {
+                gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+            }
+        }
+    }
+    
+    @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 void setSamples(GL gl, int newSamples) throws GLException {
+        samples = newSamples;
+        fbo.reset(gl, width, height, samples);
+        samples = fbo.getNumSamples(); // update, maybe capped
+    }
+    
+    
+    @Override
+    public GLContext createContext(GLContext shareWith) {
+        final GLContext ctx = parent.createContext(shareWith);
+        ctx.setGLDrawable(this, false);
+        return ctx;
+    }
+
+    @Override
+    public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+        return parent.getGLDynamicLookupHelper();
+    }
+
+    @Override
+    protected void swapBuffersImpl() {
+    }
+
+    @Override
+    protected 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
+    public int getWidth() {
+        return width;
+    }
+
+    @Override
+    public int getHeight() {
+        return height;
+    }    
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index b7c15bfda..900d6a2a0 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -38,7 +38,8 @@ public class GLGraphicsConfigurationUtil {
     public static final int WINDOW_BIT  = 1 << 0;
     public static final int BITMAP_BIT  = 1 << 1;
     public static final int PBUFFER_BIT = 1 << 2;
-    public static final int ALL_BITS    = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ;
+    public static final int FBO_BIT     = 1 << 3;
+    public static final int ALL_BITS    = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
 
     public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
         if(null==sb) {
@@ -61,30 +62,43 @@ public class GLGraphicsConfigurationUtil {
                 sb.append(", ");
             }
             sb.append("PBUFFER");
+            seperator=true;
+        }
+        if( 0 != ( FBO_BIT & winattrbits )  )  {
+            if(seperator) {
+                sb.append(", ");
+            }
+            sb.append("FBO");
         }
         return sb;
     }
 
     /**
+     * @param isFBO TODO
      * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
      */
-    public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) {
+    public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer, boolean isFBO) {
         int winattrbits = 0;
         if(isOnscreen) {
             winattrbits |= WINDOW_BIT;
-        } else if (!isPBuffer) {
-            winattrbits |= BITMAP_BIT;
         } else {
-            winattrbits |= PBUFFER_BIT;
+            if(isFBO) {
+                winattrbits |= FBO_BIT;
+            }
+            if (!isPBuffer) {
+                winattrbits |= BITMAP_BIT;
+            } else {
+                winattrbits |= PBUFFER_BIT;
+            }
         }
         return winattrbits;
     }
 
     /**
-     * @see #getWinAttributeBits(boolean, boolean)
+     * @see #getWinAttributeBits(boolean, boolean, boolean)
      */
     public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
-        return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
+        return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer(), false);
     }
 
     public static final boolean addGLCapabilitiesPermutations(List<GLCapabilitiesImmutable> capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
@@ -92,43 +106,58 @@ public class GLGraphicsConfigurationUtil {
         if( 0 != ( WINDOW_BIT & winattrbits )  )  {
             GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
             cpy.setOnscreen(true);
+            cpy.setPBuffer(false);
+            cpy.setFBO(false);
             capsBucket.add(cpy);
         }
-        if( 0 != ( PBUFFER_BIT & winattrbits )  )  {
+        if( 0 != ( PBUFFER_BIT & winattrbits ) || 0 != ( FBO_BIT & winattrbits )  )  {
             GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
-            cpy.setPBuffer(true);
+            cpy.setFBO(0 != ( FBO_BIT & winattrbits ));
+            cpy.setPBuffer(0 != ( PBUFFER_BIT & winattrbits ));
             capsBucket.add(cpy);
         }
         if( 0 != ( BITMAP_BIT & winattrbits )  )  {
             GLCapabilities cpy  = (GLCapabilities) temp.cloneMutable();
             cpy.setOnscreen(false);
             cpy.setPBuffer(false);
+            cpy.setFBO(false);
             capsBucket.add(cpy);
         }
         return capsBucket.size() > preSize;
     }
 
-    public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+    public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
     {
         if( !capsRequested.isOnscreen() ) {
-            return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable);
+            return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
         }
-        return capsRequested;
+        return fixOnscreenGLCapabilities(capsRequested);
     }
 
-    public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+    public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
+    {
+        if( !capsRequested.isOnscreen() ) {
+            // fix caps ..
+            GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+            caps2.setOnscreen(true);
+            return caps2;
+        }
+        return capsRequested;
+    }
+    
+    public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
     {
         if( capsRequested.getDoubleBuffered() ||
             capsRequested.isOnscreen() ||
-            ( !pbufferAvailable && capsRequested.isPBuffer() ) )
+            ( fboAvailable != capsRequested.isFBO() ) || 
+            ( pbufferAvailable != capsRequested.isPBuffer() ) )
         {
             // fix caps ..
             GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
             caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
             caps2.setOnscreen(false);
-            if(caps2.isPBuffer() && !pbufferAvailable) {
-                caps2.setPBuffer(false);
-            }
+            caps2.setFBO( fboAvailable ); 
+            caps2.setPBuffer( pbufferAvailable );
             return caps2;
         }
         return capsRequested;
@@ -136,12 +165,13 @@ public class GLGraphicsConfigurationUtil {
 
     public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
     {
-        if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer()) {
+        if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer() || capsRequested.isFBO() ) {
             // fix caps ..
             GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
             caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
             caps2.setOnscreen(false);
             caps2.setPBuffer(true);
+            caps2.setFBO(false);
             return caps2;
         }
         return capsRequested;
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index a8277fd71..bbc28e283 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -54,8 +54,7 @@ import javax.media.opengl.GLPbuffer;
 public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
   private int floatMode;
 
-  public GLPbufferImpl(GLDrawableImpl pbufferDrawable,
-                       GLContext sharedContext) {
+  public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext) {
     super(pbufferDrawable, null); // drawable := pbufferDrawable 
     
     GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
@@ -111,6 +110,11 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
   // GLAutoDrawable completion
   //
   
+  @Override
+  public final Object getUpstreamWidget() {
+    return null;
+  }
+  
   @Override
   public void destroy() {
     defaultDestroyOp();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 65a4c3ece..c5d0df645 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -110,14 +110,8 @@ public abstract class EGLContext extends GLContextImpl {
 
     @Override
     protected void makeCurrentImpl() throws GLException {
-        if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
-            throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable);
-        }
         if (EGL.eglGetCurrentContext() != contextHandle) {
-            if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
-                                    drawable.getHandle(),
-                                    drawableRead.getHandle(),
-                                    contextHandle)) {
+            if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
                 throw new GLException("Error making context 0x" +
                                       Long.toHexString(contextHandle) + " current: error code 0x" + Integer.toHexString(EGL.eglGetError()));
             }
@@ -126,10 +120,7 @@ public abstract class EGLContext extends GLContextImpl {
 
     @Override
     protected void releaseImpl() throws GLException {
-      if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
-                              EGL.EGL_NO_SURFACE,
-                              EGL.EGL_NO_SURFACE,
-                              EGL.EGL_NO_CONTEXT)) {
+      if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT)) {
             throw new GLException("Error freeing OpenGL context 0x" +
                                   Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(EGL.eglGetError()));
       }
@@ -137,7 +128,7 @@ public abstract class EGLContext extends GLContextImpl {
 
     @Override
     protected void destroyImpl() throws GLException {
-      if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) {
+      if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle)) {
           final int eglError = EGL.eglGetError();
           if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
               throw new GLException("Error destroying OpenGL context 0x" +
@@ -158,16 +149,16 @@ public abstract class EGLContext extends GLContextImpl {
 
     @Override
     protected boolean createImpl(GLContextImpl shareWith) throws GLException {
-        long eglDisplay = ((EGLDrawable)drawable).getDisplay();
-        EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
-        GLProfile glProfile = drawable.getGLProfile();
-        long eglConfig = config.getNativeConfig();
+        final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+        final long eglDisplay = config.getScreen().getDevice().getHandle();
+        final GLProfile glProfile = drawable.getGLProfile();
+        final long eglConfig = config.getNativeConfig();
         long shareWithHandle = EGL.EGL_NO_CONTEXT;
 
-        if (eglDisplay == 0) {
+        if ( 0 == eglDisplay ) {
             throw new GLException("Error: attempted to create an OpenGL context without a display connection");
         }
-        if (eglConfig == 0) {
+        if ( 0 == eglConfig ) {
             throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
         }
 
@@ -217,10 +208,7 @@ public abstract class EGLContext extends GLContextImpl {
                                ",\n\t"+this+
                                ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
         }
-        if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
-                                drawable.getHandle(),
-                                drawableRead.getHandle(),
-                                contextHandle)) {
+        if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
             throw new GLException("Error making context 0x" +
                                   Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
         }
@@ -269,8 +257,7 @@ public abstract class EGLContext extends GLContextImpl {
           eglQueryStringInitialized = true;
         }
         if (eglQueryStringAvailable) {
-            final String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(),
-                                                  EGL.EGL_EXTENSIONS);
+            final String ret = EGL.eglQueryString(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_EXTENSIONS);
             if (DEBUG) {
               System.err.println("EGL extensions: " + ret);
             }
@@ -291,7 +278,7 @@ public abstract class EGLContext extends GLContextImpl {
             }
             return false;
         }
-        return EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval);
+        return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
     }
 
     @Override
@@ -300,6 +287,45 @@ public abstract class EGLContext extends GLContextImpl {
     @Override
     public abstract void releasePbufferFromTexture();
 
+    //
+    // Accessible ..
+    //
+    
+    /**
+     * If context is an ES profile, map it to the given device 
+     * via {@link GLContext#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, int, int, int)}.
+     * <p>
+     * We intentionally override a non native EGL device ES profile mapping,
+     * i.e. this will override/modify an already 'set' X11/WGL/.. mapping.
+     * </p> 
+     * 
+     * @param device
+     */
+    protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
+        mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
+    }
+        
+    protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
+        int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES );  
+        mapCurrentAvailableGLVersionImpl(device, major, 0, ctp);
+    }
+    private static void mapCurrentAvailableGLVersionImpl(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+        if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
+            // ES1 or ES2
+            final int reqMajor = major;
+            final int reqProfile = GLContext.CTX_PROFILE_ES;
+            GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
+                                            major, minor, ctp);
+        }
+    }
+    
+    protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+        return GLContext.getAvailableGLVersionsSet(device);
+    }
+    protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+        GLContext.setAvailableGLVersionsSet(device);
+    }
+    
     protected static String toHexString(int hex) {
         return GLContext.toHexString(hex);
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 7f10d3bd9..432010f49 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -136,7 +136,17 @@ public class EGLDisplayUtil {
         return res;
     }
     
-    public static final EGLGraphicsDevice.EGLTerminateCallback eglTerminateCallback = new EGLGraphicsDevice.EGLTerminateCallback() {
+    public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
+        public long eglGetAndInitDisplay(long nativeDisplayID) {
+            long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
+            if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+                throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+            }
+            if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
+                throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+            }
+            return eglDisplay;
+        }
         public void eglTerminate(long eglDisplayHandle) {
             EGLDisplayUtil.eglTerminate(eglDisplayHandle);
         }
@@ -148,17 +158,12 @@ public class EGLDisplayUtil {
      * @param unitID
      * @return an initialized EGLGraphicsDevice 
      * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails
-     * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLTerminateCallback) 
+     * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback) 
      */
     public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID)  {
-        long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
-        if (eglDisplay == EGL.EGL_NO_DISPLAY) {
-            throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-        }
-        if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
-            throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-        }
-        return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, connection, unitID, eglTerminateCallback);
+        final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback);
+        eglDisplay.open();
+        return eglDisplay;
     }
     
     /**
@@ -189,6 +194,6 @@ public class EGLDisplayUtil {
             throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
         }
         final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
-        return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglTerminateCallback);                                            
+        return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);                                            
     }
 }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index d777c4f04..383b61f88 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,82 +36,65 @@
 
 package jogamp.opengl.egl;
 
-import jogamp.opengl.GLDynamicLookupHelper;
-import jogamp.opengl.GLDrawableImpl;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
 
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
-import javax.media.opengl.*;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
 
-import com.jogamp.nativewindow.egl.*;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
 public abstract class EGLDrawable extends GLDrawableImpl {
-    private boolean ownEGLDisplay = false; // for destruction
     private boolean ownEGLSurface = false; // for destruction
-    private EGLGraphicsConfiguration eglConfig;
-    private EGLGraphicsDevice eglDevice;
-    private long eglSurface;
 
-    protected EGLDrawable(EGLDrawableFactory factory,
-                       NativeSurface component) throws GLException {
+    protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
         super(factory, component, false);
-        eglSurface=EGL.EGL_NO_SURFACE;
-        eglDevice=null;
-    }
-
-    public final long getDisplay() {
-        return null != eglDevice ? eglDevice.getHandle() : 0;
-    }
-
-    @Override
-    public final long getHandle() {
-        return eglSurface;
-    }
-
-    public final EGLGraphicsConfiguration getGraphicsConfiguration() {
-        return eglConfig;
-    }
-
-    @Override
-    public final GLCapabilitiesImmutable getChosenGLCapabilities() {
-        return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities();
     }
 
     @Override
     public abstract GLContext createContext(GLContext shareWith);
 
-    protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle);
+    protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
 
     private final void recreateSurface() {
-        // create a new EGLSurface ..
-        if(EGL.EGL_NO_SURFACE!=eglSurface) {
-            EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface);
-        }
-
+        final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
         if(DEBUG) {
-            System.err.println(getThreadName() + ": createSurface using "+eglDevice+", "+eglConfig);
+            System.err.println(getThreadName() + ": createSurface using "+eglConfig);
+        }        
+        if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
+            EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
         }
-
-        eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surface.getSurfaceHandle());
-        int eglError0 = EGL.EGL_SUCCESS;
+        
+        final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
+        final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
+        long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+        
+        int eglError0;
         if (EGL.EGL_NO_SURFACE == eglSurface) {
             eglError0 = EGL.eglGetError();
             if(EGL.EGL_BAD_NATIVE_WINDOW == eglError0) {
                 // Try window handle if available and differs (Windows HDC / HWND).
                 // ANGLE impl. required HWND on Windows.
-                if(surface instanceof NativeWindow) {
-                    final NativeWindow nw = (NativeWindow) surface;
+                if(upstreamSurface instanceof NativeWindow) {
+                    final NativeWindow nw = (NativeWindow) upstreamSurface;
                     if(nw.getWindowHandle() != nw.getSurfaceHandle()) {
                         if(DEBUG) {
                             System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
                         }
-                        eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), nw.getWindowHandle());
+                        eglSurface = createSurface(eglConfig, nw.getWindowHandle());
                         if (EGL.EGL_NO_SURFACE == eglSurface) {
                             eglError0 = EGL.eglGetError();
                         }
                     }
                 }
             }
+        } else {
+            eglError0 = EGL.EGL_SUCCESS;
         }
         if (EGL.EGL_NO_SURFACE == eglSurface) {
             throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
@@ -120,6 +103,8 @@ public abstract class EGLDrawable extends GLDrawableImpl {
         if(DEBUG) {
             System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
         }
+        
+        ((MutableSurface)surface).setSurfaceHandle(eglSurface);
     }
 
     @Override
@@ -131,123 +116,71 @@ 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) {
-            AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
-            AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
-            if(aDevice instanceof EGLGraphicsDevice) {
+            final long eglDisplayHandle = eglDevice.getHandle();
+            if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
+                throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+            }
+            int[] tmp = new int[1];
+            boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
+            if(eglSurfaceValid) {
+                eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
+                if(!eglSurfaceValid) {
+                    if(DEBUG) {
+                        System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
+                    }                    
+                }
+            }
+            if(eglSurfaceValid) {
+                // surface holds valid EGLSurface
                 if(DEBUG) {
-                    System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): using existing EGL config - START");
+                    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);
                 }
-                // just fetch the data .. trust but verify ..
-                ownEGLDisplay = false;
-                eglDevice = (EGLGraphicsDevice) aDevice;
-                if (eglDevice.getHandle() == EGL.EGL_NO_DISPLAY) {
-                    throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+                final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
+                if( null == upstreamHook ) {
+                    throw new InternalError("null upstreamHook of: "+surface);
                 }
-                if(aConfig instanceof EGLGraphicsConfiguration) {
-                    eglConfig = (EGLGraphicsConfiguration) aConfig; // done ..
-                    if (null == eglConfig) {
-                        throw new GLException("Null EGLGraphicsConfiguration from "+aConfig);
-                    }
-
-                    int[] tmp = new int[1];
-                    if ( 0 != surface.getSurfaceHandle() &&
-                         EGL.eglQuerySurface(eglDevice.getHandle(), surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) {
-                        // surface holds static EGLSurface
-                        eglSurface = surface.getSurfaceHandle();
-                        if(DEBUG) {
-                            System.err.println(getThreadName() + ": setSurface re-using component's EGLSurface: handle "+toHexString(eglSurface));
-                        }
-                        ownEGLSurface=false;
-                    } else {
-                        // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
-                        ownEGLSurface=true;
-                    }
-                } else {
-                    throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig);
+                if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
+                    throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
                 }
-            } else {
-                if(DEBUG) {
-                    System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): creating new EGL config - START");
+                if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
+                    throw new InternalError("null upstream surface");
                 }
-                // create a new EGL config ..
-                ownEGLDisplay=true;
-                // EGLSurface is ours ..
                 ownEGLSurface=true;
-
-                eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
-                AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
-                final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
-                if(aConfig instanceof EGLGraphicsConfiguration) {
-                    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: "+capsChosen+" of "+aConfig);
-                        }
-                    }
-                    eglConfig  = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
-                    if(DEBUG) {
-                        System.err.println(getThreadName() + ": 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() + ": Chosen eglConfig: "+eglConfig);
-                    }
+                if(DEBUG) {
+                    System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
                 }
-                // subsequent updateHandle() will issue recreateSurface();
-            }
-            if(DEBUG) {
-                System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): END: ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface);
             }
-        } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) {
+        } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
             if(DEBUG) {
-                System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(eglSurface));
+                System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
             }
             // Destroy the window surface
-            if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
+            if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
                 throw new GLException("Error destroying window surface (eglDestroySurface)");
             }
-            eglSurface = EGL.EGL_NO_SURFACE;
-            eglConfig=null;
-            eglDevice.close();
-            eglDevice=null;
+            ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_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(), eglSurface)) {
+        if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
             throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
         }
     }
 
-    /**
-     * Surface not realizes yet (onscreen) .. Quering EGL surface size only makes sense for external drawable.
-     * Leave it here for later impl. of an EGLExternalDrawable.
-    public int getWidth() {
-        int[] tmp = new int[1];
-        if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
-            throw new GLException("Error querying surface width, eglError "+toHexString(EGL.eglGetError()));
-        }
-        return tmp[0];
-    }
-
-    public int getHeight() {
-        int[] tmp = new int[1];
-        if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) {
-            throw new GLException("Error querying surface height, eglError "+toHexString(EGL.eglGetError()));
-        }
-        return tmp[0];
-    } */
-
     @Override
     public GLDynamicLookupHelper getGLDynamicLookupHelper() {
         if (getGLProfile().usesNativeGLES2()) {
@@ -263,10 +196,9 @@ public abstract class EGLDrawable extends GLDrawableImpl {
     public String toString() {
         return getClass().getName()+"[realized "+isRealized()+
                     ",\n\tfactory    "+getFactory()+
-                    ",\n\tdevice     "+eglDevice+
                     ",\n\tsurface    "+getNativeSurface()+
-                    ",\n\teglSurface "+toHexString(eglSurface)+
-                    ",\n\teglConfig  "+eglConfig+
+                    ",\n\teglSurface "+toHexString(surface.getSurfaceHandle())+
+                    ",\n\teglConfig  "+surface.getGraphicsConfiguration()+
                     ",\n\trequested  "+getRequestedGLCapabilities()+
                     ",\n\tchosen     "+getChosenGLCapabilities()+"]";
     }
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index f4fa1f13f..c848e3e5c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -46,21 +46,29 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.DefaultGraphicsScreen;
+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.VisualIDHolder;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
 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.GLProfile;
 import javax.media.opengl.GLProfile.ShutdownType;
 
+import jogamp.opengl.Debug;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
 
 import com.jogamp.common.JogampRuntimeException;
 import com.jogamp.common.os.Platform;
@@ -69,6 +77,9 @@ import com.jogamp.nativewindow.WrappedSurface;
 import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
 
 public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+    /* 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);
+    
     private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
     private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
     private static boolean isANGLE = false;
@@ -231,7 +242,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
       // final EGLContext getContextES1() { return contextES1; }
       // final EGLContext getContextES2() { return contextES2; }
       final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
-      final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+      final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }      
     }
 
     @Override
@@ -245,35 +256,98 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
       return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
     }
 
-    /**
-    private boolean isEGLContextAvailable(EGLGraphicsDevice sharedDevice, String profile) {
-        boolean madeCurrent = false;
-        final GLCapabilities caps = new GLCapabilities(GLProfile.get(profile));
-        caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
-        caps.setDoubleBuffered(false);
-        caps.setOnscreen(false);
-        caps.setPBuffer(true);
-        final EGLDrawable drawable = (EGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
-        if(null!=drawable) {
+    private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) {
+        if( !GLProfile.isAvailable(adevice, profileString) ) {
+            return false;
+        }
+        final GLProfile glp = GLProfile.get(adevice, profileString) ;
+        final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
+        EGLGraphicsDevice eglDevice = null;
+        NativeSurface surface = null;
+        ProxySurface upstreamSurface = null; // X11, GLX, ..
+        boolean success = false;
+        boolean deviceFromUpstreamSurface = false;
+        try {            
+            final GLCapabilities caps = new GLCapabilities(glp);
+            caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
+            if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) {
+                eglDevice = sharedEGLDevice; // reuse
+                surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen
+                upstreamSurface = (ProxySurface)surface;
+                upstreamSurface.createNotify();
+                deviceFromUpstreamSurface = false;
+            } else {
+                surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window
+                upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
+                if(null != upstreamSurface) {
+                    upstreamSurface.createNotify();
+                }                    
+                eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+                deviceFromUpstreamSurface = true;
+            }
+            
+            final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
+            drawable.setRealized(true);
             final EGLContext context = (EGLContext) drawable.createContext(null);
             if (null != context) {
-                context.setSynchronized(true);
                 try {
                     context.makeCurrent(); // could cause exception
-                    madeCurrent = context.isCurrent();
+                    success = context.isCurrent();
+                    if(success) {
+                        final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+                        if(null == glVersion) {
+                            // Oops .. something is wrong
+                            if(DEBUG) {
+                                System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");                                
+                            }
+                            success = false;
+                        }
+                    }
+                    if(success) {
+                        context.mapCurrentAvailableGLVersion(eglDevice);
+                        if(eglDevice != adevice) {
+                            context.mapCurrentAvailableGLVersion(adevice);
+                        }
+                    }
                 } catch (GLException gle) {
                     if (DEBUG) {
-                        System.err.println("EGLDrawableFactory.createShared: INFO: makeCurrent failed");
+                        System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
                         gle.printStackTrace();
                     }
                 } finally {
                     context.destroy();
                 }
             }
-            drawable.destroy();
+            drawable.setRealized(false);
+        } catch (Throwable t) {
+            if(DEBUG) {
+                System.err.println("Catched Exception:");
+                t.printStackTrace();
+            }
+            success = false;
+        } finally {
+            if(eglDevice == sharedEGLDevice) {
+                if(null != upstreamSurface) {
+                    upstreamSurface.destroyNotify();
+                }                
+            } else if( deviceFromUpstreamSurface ) {
+                if(null != eglDevice) {
+                    eglDevice.close();
+                }
+                if(null != upstreamSurface) {
+                    upstreamSurface.destroyNotify();
+                }
+            } else {
+                if(null != upstreamSurface) {
+                    upstreamSurface.destroyNotify();
+                }                
+                if(null != eglDevice) {
+                    eglDevice.close();
+                }
+            }
         }
-        return madeCurrent;
-    } */
+        return success;
+    }
 
     /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
         if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
@@ -285,18 +359,41 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
             sr = sharedMap.get(connection);
         }
         if(null==sr) {
-            final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, connection, adevice.getUnitID());
+            final boolean madeCurrentES1;            
+            final boolean madeCurrentES2;
+            final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
             
-            // final boolean madeCurrentES1 = isEGLContextAvailable(sharedDevice, GLProfile.GLES1);
-            // final boolean madeCurrentES2 = isEGLContextAvailable(sharedDevice, GLProfile.GLES2);
-            final boolean madeCurrentES1 = true; // FIXME
-            final boolean madeCurrentES2 = true; // FIXME
+            if(QUERY_EGL_ES) {
+                madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1);
+                madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2);                
+            } else {            
+                madeCurrentES1 = true;            
+                madeCurrentES2 = true;
+                EGLContext.mapStaticGLESVersion(sharedDevice, 1);
+                if(sharedDevice != adevice) {
+                    EGLContext.mapStaticGLESVersion(adevice, 1);
+                }
+                EGLContext.mapStaticGLESVersion(sharedDevice, 2);
+                if(sharedDevice != adevice) {
+                    EGLContext.mapStaticGLESVersion(adevice, 2);
+                }
+            }
+            
+            if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
+                // Even though we override the non EGL native mapping intentionally,
+                // avoid exception due to double 'set' - carefull exception of the rule. 
+                EGLContext.setAvailableGLVersionsSet(adevice);
+            }
             sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
+            
             synchronized(sharedMap) {
                 sharedMap.put(connection, sr);
+                if(adevice != sharedDevice) {
+                    sharedMap.put(sharedDevice.getConnection(), sr);
+                }
             }
             if (DEBUG) {
-                System.err.println("EGLDrawableFactory.createShared: device:  " + sharedDevice);
+                System.err.println("EGLDrawableFactory.createShared: devices:  queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice);
                 System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
                 System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
             }
@@ -367,8 +464,51 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
         if (target == null) {
           throw new IllegalArgumentException("Null target");
         }
-        return new EGLOnscreenDrawable(this, target);
+        return new EGLOnscreenDrawable(this, getEGLSurface(target));
+    }
+    
+    protected static NativeSurface getEGLSurface(NativeSurface surface) {
+        AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
+        AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+        if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
+            // already in native EGL format
+            if(DEBUG) {
+                System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig);
+            }
+            return surface;
+        }
+        // create EGL instance out of platform native types
+        final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+        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: "+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
     protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
@@ -390,22 +530,115 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
     }
 
     @Override
-    protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
-        final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
-        final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
-        WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser));
-        ns.surfaceSizeChanged(width, height);
-        return ns;
+    protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                    GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
+                                                    GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+        final EGLGraphicsDevice device;
+        if(createNewDevice) {
+            final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
+            device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+        } else {
+            device = (EGLGraphicsDevice) deviceReq;
+        }
+        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);
+    }
+    
+    @Override
+    public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                     GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+        final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq));        
+        return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+    }
+    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. 
+     *           It will also hold the resulting pbuffer surface handle. 
+     * @param useTexture
+     * @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();
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
+        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+        final int texFormat;
+
+        if(useTexture) {
+            texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+        } else {
+            texFormat = EGL.EGL_NO_TEXTURE;
+        }
+
+        if (DEBUG) {
+          System.out.println("Pbuffer config: " + config);
+        }
+
+        final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), 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()));
+        } else if(DEBUG) {
+            System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+        }
+        ms.setSurfaceHandle(surf);
+        return ms;
     }
 
     @Override
-    protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
-        // FIXME device/windowHandle -> screen ?!
-        EGLGraphicsDevice device = (EGLGraphicsDevice) adevice;
-        DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
-        EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
-        WrappedSurface ns = new WrappedSurface(cfg, windowHandle);
-        return ns;
+    protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+        final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
+        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);
     }
 
     @Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 56e7a4d22..214b36493 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -151,7 +151,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
     public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
                                                            boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
         List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
         if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
             return (EGLGLCapabilities) bucket.get(0);
         } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 809e2b688..6be9cb547 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -38,7 +38,6 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.CapabilitiesChooser;
 import javax.media.nativewindow.CapabilitiesImmutable;
-import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.nativewindow.VisualIDHolder;
 import javax.media.nativewindow.VisualIDHolder.VIDType;
@@ -47,6 +46,7 @@ import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.GLDrawableFactory;
@@ -180,6 +180,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         }
         EGLGraphicsDevice eglDevice = sharedResource.getDevice();
         long eglDisplay = eglDevice.getHandle();
+        if(0 == eglDisplay) {
+            throw new GLException("null eglDisplay");
+        }
 
         List<GLCapabilitiesImmutable> availableCaps = null;
         IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
@@ -236,11 +239,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             ownEGLDisplay = true;
         }
 
-        EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
-        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) );
-
-        GLProfile glp = capsChosen.getGLProfile();
-        GLCapabilities fixedCaps;
+        final GLProfile glp = capsChosen.getGLProfile();
+        final EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(absDevice, glp), factory.canCreateGLPbuffer(absDevice) );
 
         EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
         if(null==res) {
@@ -251,13 +252,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..]
             //
             // rgb888 - d16, s4
-            fixedCaps = new GLCapabilities(glp);
+            final GLCapabilities fixedCaps = new GLCapabilities(glp);
             fixedCaps.setRedBits(8);
             fixedCaps.setGreenBits(8);
             fixedCaps.setBlueBits(8);
             fixedCaps.setDepthBits(16);
             fixedCaps.setSampleBuffers(true);
             fixedCaps.setNumSamples(4);
+            if( !capsChosen.isOnscreen() ) {
+                fixedCaps.setOnscreen(false);
+                fixedCaps.setPBuffer(capsChosen.isPBuffer());
+                fixedCaps.setFBO(capsChosen.isFBO());
+            }            
             if(DEBUG) {
                 System.err.println("trying fixed caps (1): "+fixedCaps);
             }
@@ -266,11 +272,16 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         if(null==res) {
             //
             // rgb565 - d16, s0
-            fixedCaps = new GLCapabilities(glp);
+            final GLCapabilities fixedCaps = new GLCapabilities(glp);
             fixedCaps.setRedBits(5);
             fixedCaps.setGreenBits(6);
             fixedCaps.setBlueBits(5);
             fixedCaps.setDepthBits(16);
+            if( !capsChosen.isOnscreen() ) {
+                fixedCaps.setOnscreen(false);
+                fixedCaps.setPBuffer(capsChosen.isPBuffer());
+                fixedCaps.setFBO(capsChosen.isFBO());
+            }            
             if(DEBUG) {
                 System.err.println("trying fixed caps (2): "+fixedCaps);
             }
@@ -279,13 +290,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         if(null==res) {
             //
             // rgb565 - d16, s4
-            fixedCaps = new GLCapabilities(glp);
+            final GLCapabilities fixedCaps = new GLCapabilities(glp);
             fixedCaps.setRedBits(5);
             fixedCaps.setGreenBits(6);
             fixedCaps.setBlueBits(5);
             fixedCaps.setDepthBits(16);
             fixedCaps.setSampleBuffers(true);
             fixedCaps.setNumSamples(4);
+            if( !capsChosen.isOnscreen() ) {
+                fixedCaps.setOnscreen(false);
+                fixedCaps.setPBuffer(capsChosen.isPBuffer());
+                fixedCaps.setFBO(capsChosen.isFBO());
+            }            
             if(DEBUG) {
                 System.err.println("trying fixed caps (3): "+fixedCaps);
             }
@@ -309,7 +325,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
         final GLProfile glp = capsChosen.getGLProfile();
         final boolean onscreen = capsChosen.isOnscreen();
         final boolean usePBuffer = capsChosen.isPBuffer();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
         List<GLCapabilitiesImmutable> availableCaps = null;
         int recommendedIndex = -1;
         long recommendedEGLConfig = -1;
@@ -322,8 +338,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
         }
         if (DEBUG) {
-            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig maxConfigs: "+numConfigs.get(0));
-            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglDisplay "+toHexString(eglDisplay)+", "+capsChosen+", nativeVisualID "+toHexString(nativeVisualID));
+            System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", onscreen "+onscreen+", usePBuffer "+usePBuffer+", "+capsChosen+", numConfigs "+numConfigs.get(0));
         }
 
         final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
@@ -362,7 +377,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
                 throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
             }
             if (numConfigs.get(0) > 0) {
-                availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+                availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);                
             }
         }
 
@@ -370,6 +385,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             if(DEBUG) {
                 // FIXME: this happens on a ATI PC Emulation ..
                 System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
+                availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
+                printCaps("AllCaps", availableCaps, System.err);
             }
             return null;
         }
@@ -428,27 +445,5 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
             out.println(prefix+"["+i+"] "+caps.get(i));
         }
     }
-
-    static EGLGraphicsConfiguration createOffscreenGraphicsConfiguration(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser) {
-        if(capsChosen.isOnscreen()) {
-            throw new GLException("Error: Onscreen set: "+capsChosen);
-        }
-
-        if(capsChosen.getDoubleBuffered()) {
-            // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
-            GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
-            caps2.setDoubleBuffered(false);
-            capsChosen = caps2;
-        }
-
-        DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
-        EGLGraphicsConfiguration eglConfig = chooseGraphicsConfigurationStatic(capsChosen, capsReq, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
-        if (null == eglConfig) {
-            throw new GLException("Couldn't create EGLGraphicsConfiguration from "+screen);
-        } else if(DEBUG) {
-            System.err.println("Chosen eglConfig: "+eglConfig);
-        }
-        return eglConfig;
-    }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index 3768f1588..d54057775 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(long eglDpy, long eglNativeCfg, long surfaceHandle) {
-        return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
+    protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+        return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
     }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index b2217c095..4a36625bd 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -40,15 +40,11 @@
 
 package jogamp.opengl.egl;
 
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
-import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
 
 public class EGLPbufferDrawable extends EGLDrawable {
-    private int texFormat;
     protected static final boolean useTexture = false; // No yet ..
 
     protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeSurface target) {
@@ -56,30 +52,12 @@ public class EGLPbufferDrawable extends EGLDrawable {
     }
 
     @Override
-    protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
-        final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
-        final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-
-        if(useTexture) {
-            texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
-        } else {
-            texFormat = EGL.EGL_NO_TEXTURE;
-        }
-
-        if (DEBUG) {
-          System.out.println("Pbuffer config: " + config);
-        }
-
-        NativeSurface nw = getNativeSurface();
-        int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
-        long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
-        if (EGL.EGL_NO_SURFACE==surf) {
-            throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+nw.getWidth()+"x"+nw.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
-        } else if(DEBUG) {
-            System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+    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());
         }
-        ((SurfaceChangeable)nw).setSurfaceHandle(surf);
-        return surf;
+        return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
     }
 
     @Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
new file mode 100644
index 000000000..42c6e100e
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -0,0 +1,56 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+    private final NativeSurface upstreamSurface;
+    
+    public EGLUpstreamSurfaceHook(NativeSurface upstream) {
+        upstreamSurface = upstream;
+    }
+    
+    public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+    
+    @Override
+    public final void create(ProxySurface surface) {
+        if(upstreamSurface instanceof ProxySurface) {
+            ((ProxySurface)upstreamSurface).createNotify();
+            if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+                throw new GLException("Could not lock: "+upstreamSurface);
+            }
+        }
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+        eglDevice.open();
+    }
+
+    @Override
+    public final void destroy(ProxySurface surface) {
+        final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+        eglDevice.close();
+        if(upstreamSurface instanceof ProxySurface) {
+            upstreamSurface.unlockSurface();
+            ((ProxySurface)upstreamSurface).destroyNotify();
+        }
+    }
+
+    @Override
+    public final int getWidth(ProxySurface s) {
+        return upstreamSurface.getWidth();
+    }
+
+    @Override
+    public final int getHeight(ProxySurface s) {
+        return upstreamSurface.getHeight();
+    }
+    
+    @Override
+    public String toString() {
+        final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil"; 
+        return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+    }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index aa66aa9d1..4bf2a3c9d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ProxySurface;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLException;
@@ -63,6 +64,7 @@ import com.jogamp.common.os.Platform;
 import com.jogamp.common.util.VersionNumber;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
 
 public abstract class MacOSXCGLContext extends GLContextImpl
 {
@@ -252,9 +254,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
 
   @Override
   protected void makeCurrentImpl() throws GLException {
+    /** FIXME: won't work w/ special drawables (like FBO) - check for CGL mode regressions!
+     *  
     if (getOpenGLMode() != ((MacOSXCGLDrawable)drawable).getOpenGLMode()) {
       setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode());
-    }
+    } */
     if (!impl.makeCurrent(contextHandle)) {
       throw new GLException("Error making Context current: "+this);
     }
@@ -338,8 +342,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
 
   @Override
   public boolean isExtensionAvailable(String glExtensionName) {
-    if (glExtensionName.equals("GL_ARB_pbuffer") ||
-        glExtensionName.equals("GL_ARB_pixel_format")) {
+    if (glExtensionName.equals(GLExtensions.ARB_pbuffer) ||
+        glExtensionName.equals(GLExtensions.ARB_pixel_format)) {
       return true;
     }
     return super.isExtensionAvailable(glExtensionName);
@@ -426,10 +430,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl
     @Override
     public long create(long share, int ctp, int major, int minor) {
         long ctx = 0;
-        final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.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) {
@@ -443,13 +450,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl
         screenVSyncTimeout = 1000000f / sRefreshRate;
         if(DEBUG) {
             System.err.println("NS create OSX>=lion "+isLionOrLater);
-            System.err.println("NS create backendType: "+drawable.getOpenGLMode());
+            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(drawable.getNSViewHandle()));
             System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
             // Thread.dumpStack();
         }
@@ -457,7 +463,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
           int[] viewNotReady = new int[1];
           // Try to allocate a context with this
           ctx = CGL.createContext(share,
-                                  drawable.getNSViewHandle(), null!=backingLayerHost,
+                                  drawable.getHandle(), allowIncompleteView,
                                   pixelFormat,
                                   chosenCaps.isBackgroundOpaque(),
                                   viewNotReady, 0);
@@ -473,10 +479,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
               CGL.setContextOpacity(ctx, 0);
           }
 
-          if(DEBUG) {
-              GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat);
-              System.err.println("NS create pixelformat2GLCaps: "+caps0);
-          }
           GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
           fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
           config.setChosenCapabilities(fixedCaps);
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index 257635b8c..841edb2b0 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -106,10 +106,6 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
   protected void setRealizedImpl() {
   }
 
-  protected long getNSViewHandle() {
-      return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
-  }
-
   protected void registerContext(MacOSXCGLContext ctx) {
     // NOTE: we need to keep track of the created contexts in order to
     // implement swapBuffers() because of how Mac OS X implements its
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 4e9d18fed..9689d9f64 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -50,8 +50,8 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
@@ -62,15 +62,19 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.GLProfile.ShutdownType;
 
+import jogamp.nativewindow.macosx.OSXUtil;
 import jogamp.opengl.DesktopGLDynamicLookupHelper;
+import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
 
 import com.jogamp.common.JogampRuntimeException;
 import com.jogamp.common.util.ReflectionUtil;
 import com.jogamp.nativewindow.WrappedSurface;
 import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.opengl.GLExtensions;
 
 public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null;
@@ -214,44 +218,39 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
             if (null == glp) {
                 throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
             }
-            final GLCapabilities caps = new GLCapabilities(glp);
-            caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
-            caps.setDepthBits(5);
-            caps.setDoubleBuffered(false);
-            caps.setOnscreen(false);
-            caps.setPBuffer(true);
-            final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
-            if(null!=drawable) {
-                drawable.setRealized(true);
-                final GLContext context = drawable.createContext(null);
-                if (null != context) {
-                    try {
-                        context.makeCurrent(); // could cause exception
-                        madeCurrent = context.isCurrent();
-                        if(madeCurrent) {
-                            GL gl = context.getGL();
-                            hasNPOTTextures = gl.isNPOTTextureAvailable();
-                            hasRECTTextures = gl.isExtensionAvailable("GL_EXT_texture_rectangle");
-                            hasAppleFloatPixels = gl.isExtensionAvailable("GL_APPLE_float_pixels");
-                        }
-                    } catch (GLException gle) {
-                        if (DEBUG) {
-                            System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:");
-                            gle.printStackTrace();
-                        }
-                    } finally {
-                        try {
-                            context.destroy();
-                        } catch (GLException gle) {
-                            if (DEBUG) {
-                                System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:");
-                                gle.printStackTrace();
-                            }
-                        }
+            final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+            sharedDrawable.setRealized(true);
+            
+            final GLContextImpl sharedContext  = (GLContextImpl) sharedDrawable.createContext(null);
+            if (null == sharedContext) {
+                throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+            }
+            
+            try {
+                sharedContext.makeCurrent(); // could cause exception
+                madeCurrent = sharedContext.isCurrent();
+                if(madeCurrent) {
+                    GL gl = sharedContext.getGL();
+                    hasNPOTTextures = gl.isNPOTTextureAvailable();
+                    hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle);
+                    hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels);
+                }
+            } catch (GLException gle) {
+                if (DEBUG) {
+                    System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:");
+                    gle.printStackTrace();
+                }
+            } finally {
+                try {
+                    sharedContext.destroy();
+                } catch (GLException gle) {
+                    if (DEBUG) {
+                        System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:");
+                        gle.printStackTrace();
                     }
                 }
-                drawable.setRealized(false);
             }
+            sharedDrawable.setRealized(false);
         }
         sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels);
         synchronized(sharedMap) {
@@ -332,18 +331,82 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
-    AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
-    WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true));
-    ns.surfaceSizeChanged(width, height);
-    return ns;
+  protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                  GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
+                                                  GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+    final MacOSXGraphicsDevice device;
+    if(createNewDevice) {
+        device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
+    } else {
+        device = (MacOSXGraphicsDevice)deviceReq;
+    }
+    final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+    final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true);
+    if(null == config) {
+        throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
+    }    
+    return new WrappedSurface(config, 0, width, height, lifecycleHook);
   }
 
   @Override
-  protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
-    AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
-    WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true), windowHandle);
-    return ns;
+  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); 
+  }  
+  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);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 8393a688e..421e1ef96 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -154,7 +154,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
                 break;
 
               case CGL.NSOpenGLPFASamples:
-                ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0;
+                ivalues[idx] = caps.getNumSamples() ;
                 break;
 
               default:
@@ -233,7 +233,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
       return fmt.get(0);
     }
     
-    static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {
+    static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {        
         return PixelFormat2GLCapabilities(null, pixelFormat, false);
     }
 
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index ad4c06af2..6be9e386d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -114,8 +114,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
         // set a fake marker stating a valid drawable
         currentDrawable = 1;
     }
-    WrappedSurface ns = new WrappedSurface(cfg);
-    ns.setSurfaceHandle(currentDrawable);
+    WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, null);
     return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 242cea068..b144c020d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -42,7 +42,7 @@ package jogamp.opengl.macosx.cgl;
 
 import javax.media.nativewindow.DefaultGraphicsConfiguration;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2;
 import javax.media.opengl.GL2GL3;
@@ -95,12 +95,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
     return ctx;
   }
 
-  @Override
-  protected long getNSViewHandle() {
-      // pbuffer handle is NSOpenGLPixelBuffer
-      return 0;
-  }
-
   @Override
   public long getHandle() {
     return pBuffer;
@@ -115,7 +109,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
       NativeSurface ns = getNativeSurface();
       impl.destroy(pBuffer);
       this.pBuffer = 0;
-      ((SurfaceChangeable)ns).setSurfaceHandle(0);
+      ((MutableSurface)ns).setSurfaceHandle(0);
     }
   }
 
@@ -174,7 +168,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
       throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
     }
 
-    ((SurfaceChangeable)ns).setSurfaceHandle(pBuffer);
+    ((MutableSurface)ns).setSurfaceHandle(pBuffer);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
index 31f13297b..6bf8839af 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
@@ -113,7 +113,7 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
             // create EGLImage from texture
             clientBuffer = null; // FIXME
             nioTmp.put(0, EGL.EGL_NONE);
-            image =  eglExt.eglCreateImageKHR( eglDrawable.getDisplay(), eglCtx.getHandle(),
+            image =  eglExt.eglCreateImageKHR( eglDrawable.getNativeSurface().getDisplayHandle(), eglCtx.getHandle(),
                                                EGLExt.EGL_GL_TEXTURE_2D_KHR,
                                                clientBuffer, nioTmp);
             if (0==image) {
@@ -130,7 +130,7 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
             // rendering the EGLImage texture before we tell OpenMAX to fill
             // it with a new frame.
             tmp[0] = EGL.EGL_NONE;
-            sync = eglExt.eglCreateSyncKHR(eglDrawable.getDisplay(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
+            sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
             if (0==sync) {
                 throw new RuntimeException("EGLSync creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", err "+toHexString(EGL.eglGetError()));
             }
@@ -159,10 +159,10 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
         final EGLTextureFrame eglTex = (EGLTextureFrame) imgTex;
         
         if(0!=eglTex.getImage()) {
-            eglExt.eglDestroyImageKHR(eglDrawable.getDisplay(), eglTex.getImage());
+            eglExt.eglDestroyImageKHR(eglDrawable.getNativeSurface().getDisplayHandle(), eglTex.getImage());
         }
         if(0!=eglTex.getSync()) {
-            eglExt.eglDestroySyncKHR(eglDrawable.getDisplay(), eglTex.getSync());
+            eglExt.eglDestroySyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), eglTex.getSync());
         }
         super.destroyTexImage(gl, imgTex);
     }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index 296d53ce3..cf6f43b1c 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -41,7 +41,7 @@
 package jogamp.opengl.windows.wgl;
 
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
@@ -139,7 +139,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
         hbitmap = 0;
       throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr);
     }
-    ((SurfaceChangeable)ns).setSurfaceHandle(hdc);
+    ((MutableSurface)ns).setSurfaceHandle(hdc);
     if(DEBUG) {
         System.err.println("WindowsBitmapWGLDrawable (2): "+ns);
     }
@@ -164,7 +164,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
       GDI.DeleteDC(ns.getSurfaceHandle());
       origbitmap = 0;
       hbitmap = 0;
-      ((SurfaceChangeable)ns).setSurfaceHandle(0);
+      ((MutableSurface)ns).setSurfaceHandle(0);
     }
   }
 }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
deleted file mode 100644
index 05d6d9862..000000000
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package jogamp.opengl.windows.wgl;
-
-import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.NativeSurface;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import jogamp.nativewindow.windows.GDI;
-import jogamp.nativewindow.windows.GDISurface;
-import jogamp.nativewindow.windows.GDIUtil;
-
-public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
-  private long hwnd;
-  private boolean handleHwndLifecycle;
-
-  private WindowsDummyWGLDrawable(GLDrawableFactory factory, GDISurface ns, boolean handleHwndLifecycle) {
-    super(factory, ns, true);
-    this.handleHwndLifecycle = handleHwndLifecycle;
-
-    if(NativeSurface.LOCK_SURFACE_NOT_READY >= ns.lockSurface()) {
-        throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)");
-    }
-    try {
-        WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
-        config.updateGraphicsConfiguration(factory, ns, null);
-        if (DEBUG) {
-          System.err.println("WindowsDummyWGLDrawable: "+config);
-        }
-    } catch (Throwable t) {
-        setRealized(false);
-        throw new GLException(t);
-    } finally {
-        unlockSurface();
-    }
-  }
-
-  public static WindowsDummyWGLDrawable create(GLDrawableFactory factory, GLProfile glp, AbstractGraphicsScreen absScreen,
-                                               long windowHandle, int width, int height, boolean handleWindowLifecycle) {
-    if(0 == windowHandle) {
-        throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
-    }
-    GLCapabilities caps = new GLCapabilities(glp);
-    WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen);
-    GDISurface ns = new GDISurface(cfg, windowHandle);
-    ns.surfaceSizeChanged(width, height);
-    return new WindowsDummyWGLDrawable(factory, ns, handleWindowLifecycle);
-  }
-
-  @Override
-  public GLContext createContext(GLContext shareWith) {
-    // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
-    return new WindowsWGLContext(this, shareWith);
-  }
-
-  @Override
-  protected void setRealizedImpl() {
-    super.setRealizedImpl();
-    if(!realized) {
-        if (handleHwndLifecycle && hwnd != 0) {
-          GDI.ShowWindow(hwnd, GDI.SW_HIDE);
-          GDIUtil.DestroyDummyWindow(hwnd);
-          hwnd = 0;
-        }
-    }
-  }
-}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index 86441c688..96c1187d3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -55,7 +55,6 @@ import com.jogamp.nativewindow.WrappedSurface;
 import jogamp.nativewindow.windows.GDI;
 import jogamp.opengl.GLContextShareSet;
 
-
 public class WindowsExternalWGLContext extends WindowsWGLContext {
   private GLContext lastContext;
 
@@ -103,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)), ctx, cfg);
+    return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null)), 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 8f22aa60e..15bd005dc 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -50,6 +50,7 @@ import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
 
 import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
 
 import com.jogamp.nativewindow.WrappedSurface;
 
@@ -69,9 +70,9 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
       throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError());
     }
 
-    AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
-    WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
-    return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc));
+    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));
   }
 
 
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
index a11d6e78e..7dda6a1f1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
@@ -42,6 +42,8 @@ package jogamp.opengl.windows.wgl;
 
 import javax.media.opengl.*;
 
+import com.jogamp.opengl.GLExtensions;
+
 import jogamp.opengl.GLContextImpl;
 
 public class WindowsPbufferWGLContext extends WindowsWGLContext {
@@ -112,7 +114,7 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext {
         } else {
           hasRTT = true;
 
-          if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+          if (rect && !gl.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) {
             System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " +
                                "supported; skipping requested render_to_texture_rectangle support for pbuffer");
             rect = false;
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index b00c796ec..175622343 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -42,7 +42,7 @@ package jogamp.opengl.windows.wgl;
 
 import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
@@ -92,7 +92,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
           if (wglExt.wglReleasePbufferDCARB(buffer, ns.getSurfaceHandle()) == 0) {
             throw new GLException("Error releasing pbuffer device context: error code " + GDI.GetLastError());
           }
-          ((SurfaceChangeable)ns).setSurfaceHandle(0);
+          ((MutableSurface)ns).setSurfaceHandle(0);
         }
         if (!wglExt.wglDestroyPbufferARB(buffer)) {
             throw new GLException("Error destroying pbuffer: error code " + GDI.GetLastError());
@@ -121,7 +121,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
     }
     try {
         long sharedHdc = sharedSurface.getSurfaceHandle();
-        WGLExt wglExt = sharedResource.getContext().getWGLExt();
+        WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt();
 
         if (DEBUG) {
             System.out.println("Pbuffer config: " + config);
@@ -131,7 +131,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
         float[] fattributes = new float[1];
         int[]   floatModeTmp = new int[1];
         int     niattribs   = 0;
-        int     width, height;
 
         GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
         GLProfile glProfile = chosenCaps.getGLProfile();
@@ -206,7 +205,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
                 iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
                 iattributes[niattribs++] = GL.GL_FALSE;
 
-                iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+                iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; // exact
                 iattributes[niattribs++] = GL.GL_FALSE;
               }
 
@@ -235,7 +234,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
         NativeSurface ns = getNativeSurface();
         // Set up instance variables
         buffer = tmpBuffer;
-        ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc);
+        ((MutableSurface)ns).setSurfaceHandle(tmpHdc);
         cachedWGLExt = wglExt;
 
         // Re-query chosen pixel format
@@ -249,14 +248,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
           }
           config.setCapsPFD(newCaps);
         }
-
-        // Determine the actual width and height we were able to create.
-        int[] tmp = new int[1];
-        wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB,  tmp, 0 );
-        width = tmp[0];
-        wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
-        height = tmp[0];
-        ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
     } finally {
         sharedSurface.unlockSurface();
     }
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index f143c158b..8825bad0a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -53,6 +53,8 @@ import javax.media.opengl.GLCapabilitiesImmutable;
 
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
+
 import jogamp.nativewindow.windows.GDI;
 import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableImpl;
@@ -77,8 +79,8 @@ public class WindowsWGLContext extends GLContextImpl {
     functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
 
     extensionNameMap = new HashMap<String, String>();
-    extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
-    extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+    extensionNameMap.put(GLExtensions.ARB_pbuffer, WindowsWGLDrawableFactory.WGL_ARB_pbuffer);
+    extensionNameMap.put(GLExtensions.ARB_pixel_format, WindowsWGLDrawableFactory.WGL_ARB_pixel_format);
   }
 
   // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 176d27a71..09e97ff79 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -51,9 +51,10 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.DefaultGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
 import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
@@ -67,9 +68,11 @@ import jogamp.nativewindow.windows.GDISurface;
 import jogamp.nativewindow.windows.GDIUtil;
 import jogamp.nativewindow.windows.RegisteredClassFactory;
 import jogamp.opengl.DesktopGLDynamicLookupHelper;
+import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.SharedResourceRunner;
 
 import com.jogamp.common.JogampRuntimeException;
@@ -79,6 +82,7 @@ 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;
 
 public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   private static DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper = null;
@@ -203,8 +207,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   static class SharedResource implements SharedResourceRunner.Resource {
       private WindowsGraphicsDevice device;
       private AbstractGraphicsScreen screen;
-      private WindowsDummyWGLDrawable drawable;
-      private WindowsWGLContext context;
+      private GLDrawableImpl drawable;
+      private GLContextImpl context;
       private boolean hasARBPixelFormat;
       private boolean hasARBMultisample;
       private boolean hasARBPBuffer;
@@ -214,7 +218,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
       private boolean isVendorNVIDIA;
       private boolean needsCurrenContext4ARBPFDQueries;
 
-      SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
+      SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, GLDrawableImpl draw, GLContextImpl ctx,
                      boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable, String glVendor) {
           device = dev;
           screen = scrn;
@@ -250,9 +254,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
       @Override
       final public AbstractGraphicsScreen getScreen() { return screen; }
       @Override
-      final public WindowsWGLDrawable getDrawable() { return drawable; }
+      final public GLDrawableImpl getDrawable() { return drawable; }
       @Override
-      final public WindowsWGLContext getContext() { return context; }
+      final public GLContextImpl getContext() { return context; }
 
       final boolean hasARBPixelFormat() { return hasARBPixelFormat; }
       final boolean hasARBMultisample() { return hasARBMultisample; }
@@ -302,21 +306,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
 
         @Override
         public SharedResourceRunner.Resource createSharedResource(String connection) {
-            WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
+            final WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
             sharedDevice.lock();
             try {
-                AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
-                GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
+                final AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
+                final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
                 if (null == glp) {
                     throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
                 }
-                final int f_dim = 64;
-                long hwnd = GDIUtil.CreateDummyWindow(0, 0, f_dim, f_dim);
-                WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen, hwnd, f_dim, f_dim, true);
-                if (null == sharedDrawable) {
-                    throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
-                }
-                WindowsWGLContext sharedContext  = (WindowsWGLContext) sharedDrawable.createContext(null);
+                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+                sharedDrawable.setRealized(true);
+                                
+                final GLContextImpl sharedContext  = (GLContextImpl) sharedDrawable.createContext(null);
                 if (null == sharedContext) {
                     throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
                 }
@@ -329,7 +330,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
                 try {
                     hasARBPixelFormat = sharedContext.isExtensionAvailable(WGL_ARB_pixel_format);
                     hasARBMultisample = sharedContext.isExtensionAvailable(WGL_ARB_multisample);
-                    hasARBPBuffer = sharedContext.isExtensionAvailable(GL_ARB_pbuffer);
+                    hasARBPBuffer = sharedContext.isExtensionAvailable(GLExtensions.ARB_pbuffer);
                     hasARBReadDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) &&
                                             sharedContext.isFunctionAvailable(wglMakeContextCurrent);
                     vendor = sharedContext.getGL().glGetString(GL.GL_VENDOR);
@@ -401,7 +402,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
       return false;
   }
 
-  final static String GL_ARB_pbuffer = "GL_ARB_pbuffer";
+  final static String WGL_ARB_pbuffer      = "WGL_ARB_pbuffer";
   final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format";
   final static String WGL_ARB_multisample = "WGL_ARB_multisample";
   final static String WGL_NV_float_buffer = "WGL_NV_float_buffer";
@@ -534,22 +535,89 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
-    AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
-    WrappedSurface ns = new WrappedSurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
-                                     capsChosen, capsRequested, chooser, screen) );
-    ns.surfaceSizeChanged(width, height);
-    return ns;
+  protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                        GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, 
+                                                        GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+    final WindowsGraphicsDevice device;
+    if(createNewDevice) {
+        device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
+    } else {
+        device = (WindowsGraphicsDevice)deviceReq;
+    }
+    final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+    final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen);
+    if(null == config) {
+        throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
+    }    
+    return new WrappedSurface(config, 0, width, height, lifecycleHook);
   }
 
   @Override
-  protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
-    // FIXME device/windowHandle -> screen ?!
-    WindowsGraphicsDevice device = (WindowsGraphicsDevice) adevice;
-    AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
-    WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
-    GDISurface ns = new GDISurface(cfg, windowHandle);
-    return ns;
+  public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                   GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+    final WindowsGraphicsDevice device;
+    if(createNewDevice) {
+        device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
+    } else {
+        device = (WindowsGraphicsDevice)deviceReq;
+    }
+    final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+    final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+    final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen);
+    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[]";
+    }
+  };
+  
+  
+  @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);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 408d8b074..209589b29 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -48,11 +48,13 @@ import javax.media.opengl.GLPbuffer;
 import javax.media.opengl.GLProfile;
 
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.opengl.GLExtensions;
 
 import jogamp.nativewindow.windows.DWM_BLURBEHIND;
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.MARGINS;
 import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
+import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
 public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {    
@@ -160,7 +162,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         }
     
         if (!WGLUtil.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) {
-            throw new GLException("Unable to set pixel format " + caps +
+            throw new GLException("Unable to set pixel format " + caps.getPFDID() + " of " + caps +
                                   " for device context " + toHexString(hdc) +
                                   ": error code " + GDI.GetLastError());
         }
@@ -250,7 +252,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
         }
             
         if(sharedResource.hasARBPBuffer()) {
-            WindowsWGLContext sharedCtx = sharedResource.getContext();
+            GLContextImpl sharedCtx = sharedResource.getContext();
             if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) {
                 // pbo float buffer
                 iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
@@ -313,12 +315,12 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
 
         int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
 
-        if (!sharedResource.getContext().getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+        if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
             throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + 
                                   " of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
         }
         List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(1);
-        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
         if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
             return (WGLGLCapabilities) bucket.get(0);
         }
@@ -342,7 +344,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
 
         int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
         int[] numFormatsTmp = new int[1];
-        if ( !sharedResource.getContext().getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
+        if ( !((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
                                                                 fattributes, 0,
                                                                 WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
                                                                 pformatsTmp, 0, numFormatsTmp, 0))
@@ -374,7 +376,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
 
     static List<GLCapabilitiesImmutable> wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
                                                                     long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) {
-        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+        final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
         return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits);
     }
 
@@ -398,7 +400,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
 
         for(int i = 0; i<numFormats; i++) {
             if ( pfdIDs[i] >= 1 &&
-                 sharedResource.getContext().getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
+                 ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
                 AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
             } else if (DEBUG) {
                 System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
@@ -507,9 +509,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
             throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
           }
 
-          WindowsWGLContext sharedCtx = sharedResource.getContext();
+          GLContextImpl sharedCtx = sharedResource.getContext();
           if (rect) {
-            if (!sharedCtx.isExtensionAvailable("GL_NV_texture_rectangle")) {
+            if (!sharedCtx.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) {
               throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
             }
           }
@@ -658,7 +660,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
     }
 
     static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
         List<GLCapabilitiesImmutable> capsBucket = new ArrayList<GLCapabilitiesImmutable>(1);
         if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
             return (WGLGLCapabilities) capsBucket.get(0);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 850b64aa8..943c7fec4 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -52,6 +52,7 @@ import javax.media.opengl.GLProfile;
 
 import jogamp.nativewindow.windows.GDI;
 import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
+import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLGraphicsConfigurationFactory;
 import jogamp.opengl.GLGraphicsConfigurationUtil;
 
@@ -99,10 +100,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         if(null==absScreen) {
             absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
         }
-        AbstractGraphicsDevice absDevice = absScreen.getDevice();
-
+        final AbstractGraphicsDevice absDevice = absScreen.getDevice();
+        final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
         capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
-                capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) );
+                capsChosen, GLContext.isFBOAvailable(absDevice, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(absDevice) );
 
         return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
     }
@@ -112,9 +113,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         if(null == sharedResource) {
             throw new GLException("Shared resource for device n/a: "+device);
         }
-        WindowsWGLDrawable sharedDrawable = sharedResource.getDrawable();
+        GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
         GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
-        WindowsWGLContext sharedContext = sharedResource.getContext();
+        GLContext sharedContext = sharedResource.getContext();
         List<GLCapabilitiesImmutable> availableCaps = null;
         
         if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -150,7 +151,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
     }
 
     static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) {
-        int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc);
+        int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
         return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile);
     }
 
@@ -265,7 +266,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
         }
         AbstractGraphicsDevice device = config.getScreen().getDevice();
         WindowsWGLDrawableFactory.SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(device);
-        WindowsWGLContext sharedContext = null;
+        GLContext sharedContext = null;
         if (null != sharedResource && sharedResource.needsCurrentContext4ARBPFDQueries()) {
             sharedContext = sharedResource.getContext();
             if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) {
@@ -355,7 +356,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
                         System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
                     }
                     // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
-                    pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc);
+                    pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
                     if (DEBUG) {
                         final int len = ( null != pformats ) ? pformats.length : 0;
                         System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
@@ -451,7 +452,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
             if(null == pformats) {
                 pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
             }
-            final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+            final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
 
             for (int i = 0; i < pformats.length; i++) {
                 WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
deleted file mode 100644
index 8914e2db9..000000000
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- *    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.x11.glx;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLProfile;
-
-import jogamp.nativewindow.x11.X11Lib;
-
-import com.jogamp.nativewindow.WrappedSurface;
-import com.jogamp.nativewindow.x11.X11GraphicsDevice;
-import com.jogamp.nativewindow.x11.X11GraphicsScreen;
-
-public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
-  private static final int f_dim = 64;
-  private long dummyWindow = 0;
-
-  /**
-   * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
-   * we cannot switch the Display as we please,
-   * hence we reuse the target's screen configuration.
-   */
-  public X11DummyGLXDrawable(X11GraphicsScreen screen, GLDrawableFactory factory, GLCapabilitiesImmutable caps) {
-    super(factory,
-          new WrappedSurface(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
-            caps, caps, null, screen)));
-    this.realized = true;
-
-    WrappedSurface ns = (WrappedSurface) getNativeSurface();
-    X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)ns.getGraphicsConfiguration();
-
-    X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
-    long dpy = device.getHandle();
-    int scrn = screen.getIndex();
-    int visualID = config.getXVisualID();
-
-    dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim);
-    ns.setSurfaceHandle( dummyWindow );
-    ns.surfaceSizeChanged(f_dim, f_dim);
-
-    updateHandle();
-  }
-
-  public static X11DummyGLXDrawable create(X11GraphicsScreen screen, GLDrawableFactory factory, GLProfile glp) {
-      GLCapabilities caps = new GLCapabilities(glp);
-      return new X11DummyGLXDrawable(screen, factory, caps);
-  }
-
-  public void setSize(int width, int height) {
-  }
-
-  @Override
-  public int getWidth() {
-    return 1;
-  }
-
-  @Override
-  public int getHeight() {
-    return 1;
-  }
-  
-  
-  @Override
-  protected void setRealizedImpl() {
-    super.setRealizedImpl();
-    if(!realized) {
-        if(0!=dummyWindow) {
-            destroyHandle();
-            X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
-            X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
-        }
-    }
-  }
-}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index 53776386c..b847363e0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -76,8 +76,15 @@ public class X11ExternalGLXContext extends X11GLXContext {
     long drawable = GLX.glXGetCurrentDrawable();
     if (drawable == 0) {
       throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
-    }
+    }    
     int[] val = new int[1];
+    
+    int w, h;
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
+    w=val[0];
+    GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
+    h=val[0];
+    
     GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0);
     X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
 
@@ -97,8 +104,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
         cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
     }
 
-    WrappedSurface ns = new WrappedSurface(cfg);
-    ns.setSurfaceHandle(drawable);
+    final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, null);
     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 3fabe7a13..8652e2d4a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -87,10 +87,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])+")");
       }
     }
-    WrappedSurface ns = new WrappedSurface(cfg);
-    ns.setSurfaceHandle(drawable);
-    ns.surfaceSizeChanged(w, h);
-    return new X11ExternalGLXDrawable(factory, ns);
+    return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, null));
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 0afadc677..e6b74a769 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -61,6 +61,7 @@ import jogamp.opengl.GLDrawableImpl;
 import com.jogamp.common.nio.Buffers;
 import com.jogamp.gluegen.runtime.ProcAddressTable;
 import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
 
 public abstract class X11GLXContext extends GLContextImpl {
   private static final Map<String, String> functionNameMap;
@@ -83,8 +84,8 @@ public abstract class X11GLXContext extends GLContextImpl {
     functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
 
     extensionNameMap = new HashMap<String, String>();
-    extensionNameMap.put("GL_ARB_pbuffer",      "GLX_SGIX_pbuffer");
-    extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough
+    extensionNameMap.put(GLExtensions.ARB_pbuffer,      X11GLXDrawableFactory.GLX_SGIX_pbuffer);
+    extensionNameMap.put(GLExtensions.ARB_pixel_format, X11GLXDrawableFactory.GLX_SGIX_pbuffer); // good enough
   }
 
   X11GLXContext(GLDrawableImpl drawable,
@@ -508,8 +509,8 @@ public abstract class X11GLXContext extends GLContextImpl {
 
   @Override
   public boolean isExtensionAvailable(String glExtensionName) {
-    if (glExtensionName.equals("GL_ARB_pbuffer") ||
-        glExtensionName.equals("GL_ARB_pixel_format")) {
+    if (glExtensionName.equals(GLExtensions.ARB_pbuffer) ||
+        glExtensionName.equals(GLExtensions.ARB_pixel_format)) {
       return getGLDrawable().getFactory().canCreateGLPbuffer(
           drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice() );
     }
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 9a563bdb8..8ffbf3951 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -49,6 +49,8 @@ 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.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
@@ -64,6 +66,7 @@ import jogamp.opengl.GLContextImpl;
 import jogamp.opengl.GLDrawableFactoryImpl;
 import jogamp.opengl.GLDrawableImpl;
 import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
 import jogamp.opengl.SharedResourceRunner;
 
 import com.jogamp.common.util.VersionNumber;
@@ -79,6 +82,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   public static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0);
   public static final VersionNumber versionOneFour = new VersionNumber(1, 4, 0);
 
+  static final String GLX_SGIX_pbuffer = "GLX_SGIX_pbuffer";
+  
   private static DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper = null;
 
   public X11GLXDrawableFactory() {
@@ -153,8 +158,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   static class SharedResource implements SharedResourceRunner.Resource {
       X11GraphicsDevice device;
       X11GraphicsScreen screen;
-      X11DummyGLXDrawable drawable;
-      X11GLXContext context;
+      GLDrawableImpl drawable;
+      GLContextImpl context;
       String glXServerVendorName;
       boolean isGLXServerVendorATI;
       boolean isGLXServerVendorNVIDIA;
@@ -164,7 +169,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
       boolean glXMultisampleAvailable;
 
       SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
-                     X11DummyGLXDrawable draw, X11GLXContext ctx,
+                     GLDrawableImpl draw, GLContextImpl ctx,
                      VersionNumber glXServerVer, String glXServerVendor, boolean glXServerMultisampleAvail) {
           device = dev;
           screen = scrn;
@@ -224,13 +229,15 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
 
         @Override
         public SharedResourceRunner.Resource createSharedResource(String connection) {
-            X11GraphicsDevice sharedDevice =
+            final X11GraphicsDevice sharedDevice =
                     new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
-                                          true); // own non-shared display connection, no locking
+                                          true); // own non-shared display connection, w/ locking
                     // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
-                    //                       NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, no locking
+                    //                       NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking
             sharedDevice.lock();
             try {
+                final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+                
                 if(!GLXUtil.isGLXAvailableOnServer(sharedDevice)) {
                     throw new GLException("GLX not available on device/server: "+sharedDevice);
                 }
@@ -242,20 +249,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
                     X11Util.setMarkAllDisplaysUnclosable(true);
                     X11Util.markDisplayUncloseable(sharedDevice.getHandle());
                 }
-                X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
-
-                GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
+                
+                final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
                 if (null == glp) {
                     throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
                 }
-                X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp);
-                if (null == sharedDrawable) {
-                    throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp);
-                }
-                X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null);
+                
+                final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+                sharedDrawable.setRealized(true);
+                
+                final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
                 if (null == sharedContext) {
                     throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
                 }
+                
                 boolean madeCurrent = false;
                 sharedContext.makeCurrent();
                 try {
@@ -298,7 +305,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
 
             if (null != sr.context) {
                 // may cause JVM SIGSEGV:
-                sr.context.destroy();
+                sr.context.destroy(); // will also pull the dummy MutuableSurface
                 sr.context = null;
             }
 
@@ -394,7 +401,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
     if (target == null) {
       throw new IllegalArgumentException("Null target");
     }
-    return new X11OnscreenGLXDrawable(this, target);
+    return new X11OnscreenGLXDrawable(this, target, false);
   }
 
   @Override
@@ -495,40 +502,88 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
   }
 
   @Override
-  protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq,
-                                                           GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
-                                                           GLCapabilitiesChooser chooser,
-                                                           int width, int height) {
-    if(null == deviceReq) {
-        throw new InternalError("deviceReq is null");
-    }
-    final SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(deviceReq);
-    if(null==sr) {
-        throw new InternalError("No SharedResource for: "+deviceReq);
+  protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, 
+                                                        GLCapabilitiesImmutable capsChosen,
+                                                        GLCapabilitiesImmutable capsRequested,
+                                                        GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+    final X11GraphicsDevice device;
+    if(createNewDevice) {
+        // Null X11 locking, due to private non-shared Display handle
+        device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+    } else {
+        device = (X11GraphicsDevice)deviceReq;
     }
-    final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sr.getScreen();
-    final AbstractGraphicsDevice sharedDevice = sharedScreen.getDevice(); // should be same ..
-
-    // create screen/device pair - Null X11 locking, due to private non-shared Display handle
-    final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(sharedDevice.getConnection()), AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), true);
-    final X11GraphicsScreen screen = new X11GraphicsScreen(device, sharedScreen.getIndex());
-
-    WrappedSurface ns = new WrappedSurface(
-               X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen) );
-    if(ns != null) {
-        ns.surfaceSizeChanged(width, height);
+    final X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
+    final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen);
+    if(null == config) {
+        throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen); 
     }
-    return ns;
+    return new WrappedSurface( config, 0, width, height, lifecycleHook);
   }
 
   @Override
-  protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
-    // FIXME device/windowHandle -> screen ?!
-    X11GraphicsDevice device = (X11GraphicsDevice) adevice;
-    X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
-    X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
-    WrappedSurface ns = new WrappedSurface(cfg, windowHandle);
-    return ns;
+  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); 
+  }  
+  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) {
+    final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+    final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
+    final X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
+    return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b54b5150c..b5b80e0b3 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -36,12 +36,14 @@ package jogamp.opengl.x11.glx;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GL;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
@@ -67,7 +69,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     }
 
     static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
-      final long display = x11Screen.getDevice().getHandle();
+      final AbstractGraphicsDevice device = x11Screen.getDevice();
+      final long display = device.getHandle();
       if(0==display) {
           throw new GLException("Display null of "+x11Screen);
       }
@@ -80,7 +83,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
         glp = GLProfile.getDefault(x11Screen.getDevice());
       }
       final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
-      final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(x11Screen.getDevice()));
+      final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, device, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(device));
       if(null==caps) {
           throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
       }
@@ -233,11 +236,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     return true;
   }
 
-  static int FBCfgDrawableTypeBits(final long display, final long fbcfg) {
+  static int FBCfgDrawableTypeBits(final AbstractGraphicsDevice device, GLProfile glp, final long fbcfg) {
     int val = 0;
 
     int[] tmp = new int[1];
-    int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
+    int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
 
     if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
         val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
@@ -248,17 +251,20 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
     if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
         val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
     }
+    if ( GLContext.isFBOAvailable(device, glp) ) {
+        val |= GLGraphicsConfigurationUtil.FBO_BIT;
+    }
     return val;
   }
 
-  static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
+  static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
                                                             boolean relaxed, boolean onscreen, boolean usePBuffer,
                                                             boolean isMultisampleAvailable) {
     ArrayList<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>();
-    final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
-    if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) {
+    final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
+    if( GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, winattrmask, isMultisampleAvailable) ) {
         return (X11GLCapabilities) bucket.get(0);
-    } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+    } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
         return (X11GLCapabilities) bucket.get(0);
     }
     return null;
@@ -273,11 +279,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
   }
 
   static boolean GLXFBConfig2GLCapabilities(List<GLCapabilitiesImmutable> capsBucket,
-                                            GLProfile glp, long display, long fbcfg,
+                                            GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
                                             int winattrmask, boolean isMultisampleAvailable) {
-    final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg);
+    final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp,  fbcfg);
     int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
+    
+    final long display = device.getHandle(); 
     int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg);
     XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg);
     if(null == visualInfo) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 8377d2453..331401c06 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -44,6 +44,7 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
 import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
 import javax.media.opengl.GLProfile;
@@ -161,7 +162,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
             return null;
         }
         for (int i = 0; i < fbcfgsL.limit(); i++) {
-            if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+            if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
                 if(DEBUG) {
                     System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
                 }
@@ -209,7 +210,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();        
         X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
 
-        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) );
+        capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(x11Device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(x11Device) );
         boolean usePBuffer = capsChosen.isPBuffer();
     
         X11GLXGraphicsConfiguration res = null;
@@ -245,7 +246,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
         final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
                
-        final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
+        final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, absDevice, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
         return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
     }
 
@@ -258,6 +259,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         GLProfile glProfile = capsChosen.getGLProfile();
         boolean onscreen = capsChosen.isOnscreen();
         boolean usePBuffer = capsChosen.isPBuffer();
+        boolean useFBO = capsChosen.isFBO();
 
         // Utilizing FBConfig
         //
@@ -270,13 +272,12 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
         int[] count = { -1 };
         List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
-
+        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
         // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
         fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
         if (fbcfgsL != null && fbcfgsL.limit()>0) {
             for (int i = 0; i < fbcfgsL.limit(); i++) {
-                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
+                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
                     if(DEBUG) {
                         System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
                     }
@@ -309,7 +310,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
             }
 
             for (int i = 0; i < fbcfgsL.limit(); i++) {
-                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
+                if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
                     if(DEBUG) {
                         System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
                     }
@@ -338,7 +339,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
         }
 
         GLProfile glProfile = capsChosen.getGLProfile();
-        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */);
+        final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */, false);
         List<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
         int recommendedIndex = -1;
 
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 9e22afa6d..363299321 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -51,10 +51,13 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
   long glXWindow; // GLXWindow, a GLXDrawable representation
   boolean useGLXWindow;
 
-  protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeSurface component) {
-    super(factory, component, false);
+  protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeSurface component, boolean realized) {
+    super(factory, component, realized);
     glXWindow=0;
     useGLXWindow=false;
+    if(realized) {
+        updateHandle();
+    }
   }
 
   @Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index cdf81ebd3..e1fe2f27e 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -43,7 +43,7 @@ package jogamp.opengl.x11.glx;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
@@ -77,7 +77,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
     if (ns.getSurfaceHandle() != 0) {
       GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle());
     }
-    ((SurfaceChangeable)ns).setSurfaceHandle(0);
+    ((MutableSurface)ns).setSurfaceHandle(0);
   }
 
   private void createPbuffer() {
@@ -108,12 +108,14 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
 
       // Create the p-buffer.
       int niattribs = 0;
-      int[] iattributes = new int[5];
+      int[] iattributes = new int[7];
 
       iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
       iattributes[niattribs++] = ns.getWidth();
       iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
       iattributes[niattribs++] = ns.getHeight();
+      iattributes[niattribs++] = GLX.GLX_LARGEST_PBUFFER; // exact
+      iattributes[niattribs++] = 0;
       iattributes[niattribs++] = 0;
 
       long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
@@ -123,15 +125,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
       }
 
       // Set up instance variables
-      ((SurfaceChangeable)ns).setSurfaceHandle(pbuffer);
-
-      // Determine the actual width and height we were able to create.
-      int[] tmp = new int[1];
-      GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_WIDTH, tmp, 0);
-      int width = tmp[0];
-      GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
-      int height = tmp[0];
-      ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
+      ((MutableSurface)ns).setSurfaceHandle(pbuffer);
 
       if (DEBUG) {
         System.err.println("Created pbuffer " + this);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index 1e7b89828..04627724c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -43,7 +43,7 @@ package jogamp.opengl.x11.glx;
 import javax.media.nativewindow.AbstractGraphicsDevice;
 import javax.media.nativewindow.AbstractGraphicsScreen;
 import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.opengl.GLContext;
 import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLException;
@@ -93,7 +93,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
         pixmap = 0;
         throw new GLException("glXCreateGLXPixmap failed");
     }
-    ((SurfaceChangeable)ns).setSurfaceHandle(drawable);
+    ((MutableSurface)ns).setSurfaceHandle(drawable);
     if (DEBUG) {
         System.err.println("Created pixmap " + toHexString(pixmap) +
                            ", GLXPixmap " + toHexString(drawable) +
@@ -133,7 +133,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
     X11Lib.XFreePixmap(display, pixmap);
     drawable = 0;
     pixmap = 0;
-    ((SurfaceChangeable)ns).setSurfaceHandle(0);
+    ((MutableSurface)ns).setSurfaceHandle(0);
     display = 0;
   }
 }
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
index 776284cfc..b81b43e54 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
@@ -32,7 +32,6 @@
     int texWidth;
     int texHeight;
     GLuint textureID;
-    struct timespec lastWaitTime;
 #ifdef HAS_CADisplayLink
     CADisplayLink* displayLink;
 #else
@@ -41,6 +40,7 @@
     int tc;
     struct timespec t0;
 @public
+    struct timespec lastWaitTime;
     GLint swapInterval;
     GLint swapIntervalCounter;
     pthread_mutex_t renderLock;
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 8ac9f4700..d3f703142 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -503,7 +503,7 @@ NSView* getNSView(NSOpenGLContext* ctx) {
 
 NSOpenGLContext* createContext(NSOpenGLContext* share,
                     NSView* view,
-                    Bool isBackingLayerView,
+                    Bool allowIncompleteView,
                     NSOpenGLPixelFormat* fmt,
                     Bool opaque,
                     int* viewNotReady)
@@ -512,13 +512,13 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
 
     getRendererInfo();
     
-    DBG_PRINT("createContext.0: share %p, view %p, isBackingLayer %d, pixfmt %p, opaque %d\n",
-        share, view, (int)isBackingLayerView, fmt, opaque);
+    DBG_PRINT("createContext.0: share %p, view %p, allowIncompleteView %d, pixfmt %p, opaque %d\n",
+        share, view, (int)allowIncompleteView, fmt, opaque);
 
     if (view != NULL) {
         Bool viewReady = true;
 
-        if(!isBackingLayerView) {
+        if(!allowIncompleteView) {
             if ([view lockFocusIfCanDraw] == NO) {
                 DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n");
                 viewReady = false;
@@ -527,7 +527,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
         if(viewReady) {
             NSRect frame = [view frame];
             if ((frame.size.width == 0) || (frame.size.height == 0)) {
-                if(!isBackingLayerView) {
+                if(!allowIncompleteView) {
                     [view unlockFocus];
                 }
                 DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
@@ -558,7 +558,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
             [ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
         }
         [ctx setView:view];
-        if(!isBackingLayerView) {
+        if(!allowIncompleteView) {
             [view unlockFocus];        
         }
       }
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
index 04f616daf..b7f6ba45d 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
@@ -30,51 +30,49 @@ package com.jogamp.nativewindow;
 
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.SurfaceChangeable;
 
+public class WrappedSurface extends ProxySurface {
+  protected long surfaceHandle;  
 
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
-  protected long surfaceHandle;
-
-  public WrappedSurface(AbstractGraphicsConfiguration cfg) {
-      this(cfg, 0);
-  }
-
-  public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle) {
-    super(cfg);
+  public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+    super(cfg, initialWidth, initialHeight, upstream);
     surfaceHandle=handle;
   }
 
   @Override
-  protected final void invalidateImpl() {
+  protected void invalidateImpl() {    
     surfaceHandle = 0;
   }
 
   @Override
-  final public long getSurfaceHandle() {
+  public final long getSurfaceHandle() {
     return surfaceHandle;
   }
 
   @Override
-  final public void setSurfaceHandle(long surfaceHandle) {
+  public final void setSurfaceHandle(long surfaceHandle) {
     this.surfaceHandle=surfaceHandle;
   }
-
+  
   @Override
-  final protected int lockSurfaceImpl() {
-      return LOCK_SUCCESS;
+  protected final int lockSurfaceImpl() {
+    return LOCK_SUCCESS;
   }
 
   @Override
-  final protected void unlockSurfaceImpl() {
+  protected final void unlockSurfaceImpl() {
   }
 
   @Override
   public String toString() {
+    final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
+    final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil"; 
+    
     return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
            ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
            ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
            ", size " + getWidth() + "x" + getHeight() +
-           ", surfaceLock "+surfaceLock+"]";
+           ", surfaceLock "+surfaceLock+
+           ", upstreamSurfaceHook "+ush_s+"]";
   }
 }
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index d161f2f34..389949e90 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.*;
  */
 public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
     final long nativeDisplayID;
-    final EGLTerminateCallback eglTerminateCallback;
+    final EGLDisplayLifecycleCallback eglLifecycleCallback;
 
     /**
      * Hack to allow inject a EGL termination call.
@@ -47,7 +47,14 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
      * since then it can be utilized directly.
      * </p> 
      */
-    public interface EGLTerminateCallback {
+    public interface EGLDisplayLifecycleCallback {
+        /**
+         * Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
+         * inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
+         * @param eglDisplayHandle
+         */
+        public long eglGetAndInitDisplay(long nativeDisplayID);
+        
         /**
          * Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
          * @param eglDisplayHandle
@@ -61,28 +68,45 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
      */
     public EGLGraphicsDevice(String connection, int unitID) {
         super(NativeWindowFactory.TYPE_EGL, connection, unitID);
-        this.nativeDisplayID = 0;
-        this.eglTerminateCallback = null;
+        this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+        this.eglLifecycleCallback = null;
     }
 
-    public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLTerminateCallback eglTerminateCallback) {
+    public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
         super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
         this.nativeDisplayID = nativeDisplayID;
-        this.eglTerminateCallback = eglTerminateCallback;
+        this.eglLifecycleCallback = eglLifecycleCallback;
     }
     
     public long getNativeDisplayID() { return nativeDisplayID; }
     
+    @Override
     public Object clone() {
       return super.clone();
     }
+
+    @Override
+    public boolean open() {
+        if(null != eglLifecycleCallback && 0 == handle) {
+            if(DEBUG) {
+                System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.open(): "+this);
+            }
+            handle = eglLifecycleCallback.eglGetAndInitDisplay(nativeDisplayID);
+            if(0 == handle) {
+                throw new NativeWindowException("EGLGraphicsDevice.open() failed: "+this);
+            }
+            return true;
+        }
+        return false;
+    }
     
+    @Override
     public boolean close() {
-        if(null != eglTerminateCallback) {
+        if(null != eglLifecycleCallback && 0 != handle) {
             if(DEBUG) {
-                System.err.println(Thread.currentThread().getName() + " - eglTerminate: "+this);
+                System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.close(): "+this);
             }
-            eglTerminateCallback.eglTerminate(handle);
+            eglLifecycleCallback.eglTerminate(handle);
         }
         return super.close();
     }
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 735d85fb1..0494bb408 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -43,7 +43,6 @@ import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
 import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
 import com.jogamp.nativewindow.x11.X11GraphicsDevice;
 
-import jogamp.common.awt.AWTEDTExecutor;
 import jogamp.nativewindow.macosx.OSXUtil;
 
 public class SWTAccessor {
@@ -204,8 +203,6 @@ public class SWTAccessor {
         if( null != OS_gtk_class ) {
             long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
             long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
-            // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
-            //        to avoid locking problems !
             return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
         }
         if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index a02332413..7a98e3c25 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -33,7 +33,6 @@
 
 package com.jogamp.nativewindow.x11;
 
-import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.x11.X11Lib;
 import jogamp.nativewindow.x11.X11Util;
 
@@ -46,7 +45,7 @@ import javax.media.nativewindow.ToolkitLock;
  */
 
 public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
-    final boolean closeDisplay;
+    final boolean handleOwner;
 
     /** Constructs a new X11GraphicsDevice corresponding to the given connection and default
      *  {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
@@ -56,7 +55,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
      */
     public X11GraphicsDevice(String connection, int unitID) {
         super(NativeWindowFactory.TYPE_X11, connection, unitID);
-        closeDisplay = false;
+        handleOwner = false;
     }
 
     /** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
@@ -69,7 +68,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
         if(0==display) {
             throw new NativeWindowException("null display");
         }
-        closeDisplay = owner;
+        handleOwner = owner;
     }
 
     /**
@@ -82,16 +81,39 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
         if(0==display) {
             throw new NativeWindowException("null display");
         }
-        closeDisplay = owner;
+        handleOwner = owner;
     }
 
+    public int getDefaultVisualID() {
+        // It still could be an AWT hold handle ..
+        final long display = getHandle();
+        final int scrnIdx = X11Lib.DefaultScreen(display);
+        return (int) X11Lib.DefaultVisualID(display, scrnIdx);
+    }
+    
+    @Override
     public Object clone() {
       return super.clone();
     }
 
+    @Override
+    public boolean open() {
+        if(handleOwner && 0 == handle) {
+            if(DEBUG) {
+                System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.open(): "+this);
+            }
+            handle = X11Util.openDisplay(connection);
+            if(0 == handle) {
+                throw new NativeWindowException("X11GraphicsDevice.open() failed: "+this);
+            }
+            return true;
+        }
+        return false;
+    }
+        
+    @Override
     public boolean close() {
-        // FIXME: shall we respect the unitID ?
-        if(closeDisplay && 0 != handle) {
+        if(handleOwner && 0 != handle) {
             if(DEBUG) {
                 System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this);
             }
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 94013ec38..014f4f688 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -56,13 +56,11 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
         return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
     }
 
-    public long getDefaultVisualID() {
+    public int getVisualID() {
         // It still could be an AWT hold handle ..
-        long display = getDevice().getHandle();
-        int scrnIdx = X11Lib.DefaultScreen(display);
-        return X11Lib.DefaultVisualID(display, scrnIdx);
+        return (int) X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
     }
-
+    
     private static int fetchScreen(X11GraphicsDevice device, int screen) {
         // It still could be an AWT hold handle ..
         if(X11Util.XineramaIsEnabled(device.getHandle())) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 4979f1949..756e4451b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -113,16 +113,33 @@ public interface AbstractGraphicsDevice extends Cloneable {
      */
     public void unlock();
 
+    /** 
+     * Optionally [re]opening the device if handle is <code>null</code>.
+     * <p>
+     * The default implementation is a <code>NOP</code>.
+     * </p>
+     * <p>
+     * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice} 
+     * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice} 
+     * issue the native open operation in case handle is <code>null</code>.
+     * </p> 
+     *
+     * @return true if the handle was <code>null</code> and opening was successful, otherwise false.
+     */
+    public boolean open();
+
     /**
-     * Optionally closing the device.
+     * Optionally closing the device if handle is not <code>null</code>.
      * <p>
      * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
      * </p>
-     * The specific implementing, ie {@link com.jogamp.nativewindow.x11.X11GraphicsDevice},
-     * shall have a enable/disable like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},<br>
-     * which shall be invoked at creation time to determine ownership/role of freeing the resource.<br>
+     * <p>
+     * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice} 
+     * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice} 
+     * issue the native close operation or skip it depending on the handles's ownership.
+     * </p> 
      *
-     * @return true if the handle was not <code>null</code>, otherwise false.
+     * @return true if the handle was not <code>null</code> and closing was successful, otherwise false.
      */
     public boolean close();
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 187959a67..583fde07f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -97,22 +97,27 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
         }
     }
 
+    @Override
     public final String getType() {
         return type;
     }
 
+    @Override
     public final String getConnection() {
         return connection;
     }
 
+    @Override
     public final int getUnitID() {
         return unitID;
     }
 
+    @Override
     public final String getUniqueID() {
       return uniqueID;
     }
 
+    @Override
     public final long getHandle() {
         return handle;
     }
@@ -124,6 +129,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
      */
+    @Override
     public final void lock() {
         toolkitLock.lock();
     }
@@ -135,10 +141,17 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
      * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
      */
+    @Override
     public final void unlock() {
         toolkitLock.unlock();
     }
+    
+    @Override
+    public boolean open() {
+        return false;
+    }
 
+    @Override
     public boolean close() {
         if(0 != handle) {
             handle = 0;
diff --git a/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
new file mode 100644
index 000000000..ff53c8109
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow;
+
+/**
+ * Provides a {@link NativeSurface} with a mutable <code>surfaceHandle</code>
+ * via {@link #setSurfaceHandle(long)}.
+ * 
+ * @see NativeSurface
+ */
+public interface MutableSurface extends NativeSurface {
+
+    /** 
+     * Sets the surface handle which is created outside of this implementation.
+     */
+    public void setSurfaceHandle(long surfaceHandle);
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index 1dabc3dcd..7fc9789c2 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,38 +28,108 @@
 
 package javax.media.nativewindow;
 
-
 import jogamp.nativewindow.Debug;
 import jogamp.nativewindow.SurfaceUpdatedHelper;
 
 import com.jogamp.common.util.locks.LockFactory;
 import com.jogamp.common.util.locks.RecursiveLock;
 
-public abstract class ProxySurface implements NativeSurface {
+public abstract class ProxySurface implements NativeSurface, MutableSurface {
     public static final boolean DEBUG = Debug.debug("ProxySurface");
+    
+    /** 
+     * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
+     * @see #setImplBitfield(int)
+     * @see #getImplBitfield()
+     */ 
+    public static final int OWN_DEVICE = 1 << 7;
+    
+    /** 
+     * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
+     * @see #setImplBitfield(int)
+     * @see #getImplBitfield()
+     */ 
+    public static final int INVISIBLE_WINDOW = 1 << 8;
 
-    private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
-    private AbstractGraphicsConfiguration config; // control access due to delegation
-    protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+    /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */ 
+    public interface UpstreamSurfaceHook {
+        /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+        public void create(ProxySurface s);
+        /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+        public void destroy(ProxySurface s);
+
+        /** Returns the width of the upstream surface */ 
+        public int getWidth(ProxySurface s);
+        /** Returns the height of the upstream surface */ 
+        public int getHeight(ProxySurface s);
+    }
+    
+    private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+    private final AbstractGraphicsConfiguration config; // control access due to delegation
+    private final UpstreamSurfaceHook upstream;
+    public final int initialWidth;
+    public final int initialHeight;
     private long surfaceHandle_old;
+    protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
     protected long displayHandle;
-    protected int height;
     protected int scrnIndex;
-    protected int width;
+    protected int implBitfield;
 
-    public ProxySurface(AbstractGraphicsConfiguration cfg) {
-        invalidate();
-        config = cfg;
-        displayHandle=cfg.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
-        surfaceHandle_old = 0;
+    /**
+     * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+     * @param initialWidth the initial width
+     * @param initialHeight the initial height
+     */
+    protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+        if(null == cfg) {
+            throw new IllegalArgumentException("null config");
+        }
+        this.config = cfg;
+        this.upstream = upstream;
+        this.initialWidth = initialWidth;
+        this.initialHeight = initialHeight;
+        this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+        this.surfaceHandle_old = 0;
+        this.implBitfield = 0;
     }
 
-    void invalidate() {
-        displayHandle = 0;
-        invalidateImpl();
+    public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+    
+    /** 
+     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
+     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
+     * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
+     */ 
+    public void createNotify() {
+        if(null != upstream) {
+            upstream.create(this);
+        }
+        this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+        this.surfaceHandle_old = 0;
     }
-    protected abstract void invalidateImpl();
-
+    
+    /** 
+     * If a valid {@link UpstreamSurfaceHook} instance is passed in the 
+     * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor}, 
+     * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
+     */ 
+    public void destroyNotify() {
+        if(null != upstream) {
+            upstream.destroy(this);
+            invalidateImpl();
+        }
+        this.displayHandle = 0;
+        this.surfaceHandle_old = 0;
+    }
+    
+    /** 
+     * Must be overridden by implementations allowing having a {@link UpstreamSurfaceHook} being passed.
+     * @see #destroyNotify() 
+     */
+    protected void invalidateImpl() {
+        throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");        
+    }
+    
     @Override
     public final long getDisplayHandle() {
         return displayHandle;
@@ -82,19 +152,23 @@ public abstract class ProxySurface implements NativeSurface {
     @Override
     public abstract long getSurfaceHandle();
 
+    @Override
+    public abstract void setSurfaceHandle(long surfaceHandle);
+    
     @Override
     public final int getWidth() {
-        return width;
+        if(null != upstream) {
+            return upstream.getWidth(this);
+        }
+        return initialWidth;
     }
 
     @Override
     public final int getHeight() {
-        return height;
-    }
-
-    public void surfaceSizeChanged(int width, int height) {
-        this.width = width;
-        this.height = height;
+        if(null != upstream) {
+            return upstream.getHeight(this);
+        }
+        return initialHeight;
     }
 
     @Override
@@ -187,7 +261,10 @@ public abstract class ProxySurface implements NativeSurface {
     public final Thread getSurfaceLockOwner() {
         return surfaceLock.getOwner();
     }
-
+    
     @Override
     public abstract String toString();
+    
+    public int getImplBitfield() { return implBitfield; }    
+    public void setImplBitfield(int v) { implBitfield=v; }
 }
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
deleted file mode 100644
index 956e68e61..000000000
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- * - Redistribution in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * 
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * 
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- * 
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package javax.media.nativewindow;
-
-public interface SurfaceChangeable {
-
-  /** Sets the surface handle which is created outside of this implementation */
-  public void setSurfaceHandle(long surfaceHandle);
-  
-  /** 
-   * The surface's size has been determined or changed. 
-   * Implementation shall update the stored surface size with the given ones. 
-   */  
-  public void surfaceSizeChanged(int width, int height);
-
-}
-
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
index 4877d5c4f..4f68c6945 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -34,8 +34,8 @@ import javax.media.nativewindow.NativeSurface;
 import javax.media.nativewindow.SurfaceUpdatedListener;
 
 public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
-    private Object surfaceUpdatedListenersLock = new Object();
-    private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
+    private final Object surfaceUpdatedListenersLock = new Object();
+    private final ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
 
     //
     // Management Utils
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 42fd08df1..e81d61e0f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -48,7 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.Capabilities;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.nativewindow.util.Point;
 
 import com.jogamp.nativewindow.MutableGraphicsConfiguration;
@@ -62,7 +62,7 @@ import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
 import jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo;
 import jogamp.nativewindow.macosx.OSXUtil;
 
-public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
+public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
   public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
     super(comp, config);
     if(DEBUG) {
@@ -103,24 +103,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
       if(DEBUG) {
         System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
       }
-      sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
       this.surfaceHandle = surfaceHandle;
   }
 
-  public void surfaceSizeChanged(int width, int height) {
-      sscSet = true;
-      sscWidth = width;
-      sscHeight = height;
-  }
-
-  public int getWidth() {
-    return sscSet ? sscWidth : super.getWidth();
-  }
-
-  public int getHeight() {
-    return sscSet ? sscHeight: super.getHeight();
-  }
-
   protected JAWT fetchJAWTImpl() throws NativeWindowException {
        // use offscreen if supported and [ applet or requested ]
       return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
@@ -280,8 +265,6 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
   private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer
   
   private long surfaceHandle = 0;
-  private int sscWidth, sscHeight;
-  private boolean sscSet = false;
    
   // Workaround for instance of 4796548
   private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 4d472b01a..99fc9244e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -63,19 +63,15 @@ public class OSXUtil {
       return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
     }
     
-    public static long CreateNSView(int x, int y, int width, int height) {
-      return CreateNSView0(x, y, width, height);
-    }
-    public static void DestroyNSView(long nsView) {
-        DestroyNSView0(nsView);
-    }
-
     public static long CreateNSWindow(int x, int y, int width, int height) {
       return CreateNSWindow0(x, y, width, height);
     }
     public static void DestroyNSWindow(long nsWindow) {
         DestroyNSWindow0(nsWindow);
     }
+    public static long GetNSView(long nsWindow) {
+      return GetNSView0(nsWindow);
+    }
     
     public static long CreateCALayer(int x, int y, int width, int height) {
         return CreateCALayer0(x, y, width, height);
@@ -134,10 +130,9 @@ public class OSXUtil {
     
     private static native boolean initIDs0();
     private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
-    private static native long CreateNSView0(int x, int y, int width, int height);
-    private static native void DestroyNSView0(long nsView);
     private static native long CreateNSWindow0(int x, int y, int width, int height);
     private static native void DestroyNSWindow0(long nsWindow);
+    private static native long GetNSView0(long nsWindow);
     private static native long CreateCALayer0(int x, int y, int width, int height);
     private static native void AddCASublayer0(long rootCALayer, long subCALayer);
     private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index c24f64b32..e368aa6a1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -31,6 +31,7 @@ package jogamp.nativewindow.windows;
 import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.NativeWindowException;
 import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
 
 
 /**
@@ -43,22 +44,49 @@ public class GDISurface extends ProxySurface {
   protected long windowHandle;
   protected long surfaceHandle;
 
-  public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle) {
-    super(cfg);
-    if(0 == windowHandle) {
-        throw new NativeWindowException("Error hwnd 0, werr: "+GDI.GetLastError());
-    }
+  public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+    super(cfg, initialWidth, initialHeight, upstream);
     this.windowHandle=windowHandle;
+    this.surfaceHandle=0;
   }
 
   @Override
-  protected final void invalidateImpl() {
-    windowHandle=0;
-    surfaceHandle=0;
+  protected void invalidateImpl() {    
+    if(0 != surfaceHandle) {
+        throw new NativeWindowException("didn't release surface Handle: "+this);
+    }
+    windowHandle = 0;
+    // surfaceHandle = 0;
+  }
+  
+  /**
+   * {@inheritDoc}
+   * <p>
+   * Actually the window handle (HWND), since the surfaceHandle (HDC) is derived 
+   * from it at {@link #lockSurface()}.
+   * </p> 
+   */
+  @Override
+  public final void setSurfaceHandle(long surfaceHandle) {
+      this.windowHandle = surfaceHandle;
+  }
+
+  /**
+   * Sets the window handle (HWND). 
+   */
+  public final void setWindowHandle(long windowHandle) {
+      this.windowHandle = windowHandle;
+  }
+
+  public final long getWindowHandle() {
+      return windowHandle;
   }
 
   @Override
   final protected int lockSurfaceImpl() {
+    if (0 == windowHandle) {
+        throw new NativeWindowException("null window handle: "+this);
+    }
     if (0 != surfaceHandle) {
         throw new InternalError("surface not released");
     }
@@ -89,12 +117,15 @@ public class GDISurface extends ProxySurface {
 
   @Override
   final public String toString() {
-    return "GDISurface[config "+getPrivateGraphicsConfiguration()+
+    final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
+    final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";       
+    return getClass().getSimpleName()+"[config "+getPrivateGraphicsConfiguration()+
                 ", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
                 ", windowHandle 0x"+Long.toHexString(windowHandle)+
                 ", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
                 ", size "+getWidth()+"x"+getHeight()+
-                ", surfaceLock "+surfaceLock+"]";
+                ", surfaceLock "+surfaceLock+
+                ", upstreamSurfaceHook "+ush_s+"]";
   }
 
 }
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e010fc440..ebfefe345 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -148,37 +148,6 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
     return res;
 }
 
-/*
- * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
- * Method:    CreateNSView0
- * Signature: (IIIIZ)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0
-  (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
-{
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    NSRect rect = NSMakeRect(x, y, width, height);
-    NSView * view = [[NSView alloc] initWithFrame: rect] ;
-    [view setCanDrawConcurrently: YES];
-    [pool release];
-
-    return (jlong) (intptr_t) view;
-}
-
-/*
- * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
- * Method:    DestroyNSView0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0
-  (JNIEnv *env, jclass unused, jlong nsView)
-{
-    NSView* view = (NSView*) (intptr_t) nsView;
-    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-    [view release];
-    [pool release];
-}
-
 /*
  * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
  * Method:    CreateNSWindow0
@@ -222,6 +191,27 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
     [pool release];
 }
 
+/*
+ * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method:    GetNSView0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0
+  (JNIEnv *env, jclass unused, jlong window)
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    NSWindow* win = (NSWindow*) ((intptr_t) window);
+
+    DBG_PRINT( "contentView0 - window: %p (START)\n", win);
+
+    jlong res = (jlong) ((intptr_t) [win contentView]);
+
+    DBG_PRINT( "contentView0 - window: %p (END)\n", win);
+
+    [pool release];
+    return res;
+}
+
 /*
  * Class:     Java_jogamp_nativewindow_macosx_OSXUtil
  * Method:    CreateCALayer0
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 71e86d520..e8537fec5 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -40,8 +40,20 @@ import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.WindowClosingProtocol;
 
 /**
- * Specifying the public Window functionality for the
- * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
+ * Specifying NEWT's Window functionality:
+ * <ul>
+ *   <li>On- and offscreen windows</li>
+ *   <li>Keyboard and multi-pointer input</li>
+ *   <li>Native reparenting</li>
+ *   <li>Toggable fullscreen and decoration mode</li>
+ *   <li>Transparency</li>
+ *   <li>... and more</li>
+ * </ul>
+ * <p>
+ * One use case is {@link com.jogamp.newt.opengl.GLWindow}, which delegates 
+ * window operation to an instance of this interface while providing OpenGL 
+ * functionality.
+ * </p>
  */
 public interface Window extends NativeWindow, WindowClosingProtocol {
     public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 44fcea49c..4db661eeb 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -43,7 +43,7 @@ public class KeyEvent extends InputEvent
      this.keyChar=keyChar;
  }
 
- /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */
+ /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */
  public char getKeyChar() {
     return keyChar;
  }
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index f08fbc8fa..c50ab77c4 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -124,6 +124,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
         this.window.setLifecycleHook(new GLLifecycleHook());
     }
 
+    @Override
+    public final Object getUpstreamWidget() {
+        return window;
+    }
+    
     /**
      * Creates a new GLWindow attaching a new Window referencing a
      * new default Screen and default Display with the given GLCapabilities.
@@ -762,7 +767,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
         System.err.println(GlueGenVersion.getInstance());
         System.err.println(JoglVersion.getInstance());
 
-        System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+        System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
 
         final GLProfile glp = GLProfile.getDefault();
         final GLCapabilitiesImmutable caps = new GLCapabilities( glp );
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index 050e24b6c..be543aba9 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -34,15 +34,24 @@
 
 package jogamp.newt;
 
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+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.util.Insets;
 import javax.media.nativewindow.util.Point;
 
-public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
+public class OffscreenWindow extends WindowImpl implements MutableSurface {
 
     long surfaceHandle = 0;
-
+    ProxySurface.UpstreamSurfaceHook upstreamHook;
+    ProxySurface dummySurface;
+    
     public OffscreenWindow() {
+        upstreamHook = null;
+        dummySurface = null;
     }
 
     static long nextWindowHandle = 0x100; // start here - a marker
@@ -52,6 +61,17 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
             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()).chooseGraphicsConfiguration(
                                                          capsRequested, capsRequested, capabilitiesChooser, aScreen);
         if (null == cfg) {
@@ -68,13 +88,14 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
         // nop
     }
 
-    public void surfaceSizeChanged(int width, int height) {
-         sizeChanged(false, width, height, false);
-    }
-    
     @Override
     public synchronized void destroy() {
         super.destroy();
+        if(null != dummySurface) {
+            dummySurface.destroyNotify();
+            dummySurface = null;
+            upstreamHook = null;
+        }
         surfaceHandle = 0;
     }
 
@@ -84,8 +105,12 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
 
     @Override
     public long getSurfaceHandle() {
+        if(null != dummySurface) {
+            return dummySurface.getSurfaceHandle();
+            // return upstreamHook.getWidth();
+        }
         return surfaceHandle;
-    }
+    }        
 
     protected void requestFocusImpl(boolean reparented) {
     }
diff --git a/src/newt/classes/jogamp/newt/driver/android/MD.java b/src/newt/classes/jogamp/newt/driver/android/MD.java
index 403eae383..f2f30937b 100644
--- a/src/newt/classes/jogamp/newt/driver/android/MD.java
+++ b/src/newt/classes/jogamp/newt/driver/android/MD.java
@@ -43,7 +43,7 @@ public class MD {
               .append(JoglVersion.getInstance()).append(Platform.NEWLINE)
               .append(Platform.NEWLINE);
               
-        JoglVersion.getDefaultOpenGLInfo(sb, true);
+        JoglVersion.getDefaultOpenGLInfo(null, sb, true);
 
         return sb.toString();       
    }
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index 942994c13..fcca5c843 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
 import javax.media.nativewindow.GraphicsConfigurationFactory;
 import javax.media.nativewindow.NativeWindow;
 import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
 import javax.media.nativewindow.util.Insets;
 import javax.media.nativewindow.util.InsetsImmutable;
 import javax.media.nativewindow.util.Point;
@@ -50,7 +50,7 @@ import jogamp.newt.driver.DriverUpdatePosition;
 
 import com.jogamp.newt.event.KeyEvent;
 
-public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus, DriverUpdatePosition {
+public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
     
     static {
         MacDisplay.initSingleton();
@@ -131,10 +131,6 @@ public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverCl
         }        
     }
 
-    public void surfaceSizeChanged(int width, int height) {
-        sizeChanged(false, width, height, false);
-    }
-    
     @Override
     protected void setTitleImpl(final String title) {
         setTitle0(getWindowHandle(), title);
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index f914467af..b58b99e38 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -972,7 +972,7 @@ static jint mods2JavaMods(NSUInteger mods)
 
     NSView* nsview = [self contentView];
     if( ! [nsview isMemberOfClass:[NewtView class]] ) {
-        return;
+        return NO;
     }
     NewtView* view = (NewtView *) nsview;
 
@@ -981,14 +981,14 @@ static jint mods2JavaMods(NSUInteger mods)
         DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
         if (javaWindowObject == NULL) {
             DBG_PRINT("windowWillClose: null javaWindowObject\n");
-            return;
+            return NO;
         }
         int shallBeDetached = 0;
         JavaVM *jvmHandle = [view getJVMHandle];
         JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
         if(NULL==env) {
             DBG_PRINT("windowWillClose: null JNIEnv\n");
-            return;
+            return NO;
         }
 
         [view setDestroyNotifySent: true]; // earmark assumption of being closed
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index a09cc76ac..b22be0a93 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -194,7 +194,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
             pw.printf("%s-%03dx%03d-T%04d", objName, drawable.getWidth(), drawable.getHeight(), texSize[0]);
             
             final String filename = dir + sw +".png";
-            if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+            if(screenshot.readPixels(drawable.getGL(), false)) {
                 screenshot.write(new File(filename));
             }
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
index a3182a30f..6378c1ee3 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
@@ -194,7 +194,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
         pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), texSize[0], objName);
         
         final String filename = dir + tech + sw +".png";
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+        if(screenshot.readPixels(drawable.getGL(), false)) {
             screenshot.write(new File(filename));
         }
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
index d0093ad0c..15daf70cd 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
@@ -180,7 +180,7 @@ public abstract class UIListenerBase01 implements GLEventListener {
         pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), 0, objName);
         
         final String filename = dir + tech + sw +".png";
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+        if(screenshot.readPixels(drawable.getGL(), false)) {
             screenshot.write(new File(filename));
         }
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
new file mode 100644
index 000000000..1a33845b3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
@@ -0,0 +1,272 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+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.GLProfile;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.OffscreenAutoDrawable;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+public class TestFBODrawableNEWT extends UITestCase {
+    
+    static final int widthStep = 800/4;
+    static final int heightStep = 600/4;
+    volatile int szStep = 2;
+    
+    @Test
+    public void testGL2ES2_Demo1Normal() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        testGLFBODrawableImpl(caps, new GearsES2(0));
+    }
+    
+    @Test
+    public void testGL2ES2_Demo1MSAA4() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(4);
+        testGLFBODrawableImpl(caps, new GearsES2(0));
+    }
+    
+    @Test
+    public void testGL2ES2_Demo2Normal() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        testGLFBODrawableImpl(caps, new MultisampleDemoES2(false));
+    }
+    
+    @Test
+    public void testGL2ES2_Demo2MSAA4() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(4);
+        testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
+    }
+    
+    @Test
+    public void testGL2ES2_FBODemoNormal() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+        demo.setDoRotation(false);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        testGLFBODrawableImpl(caps, demo);
+    }
+    
+    @Test
+    public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {    
+        final GLProfile glp = GLProfile.getGL2ES2();
+        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+        demo.setDoRotation(false);
+        final GLCapabilities caps = new GLCapabilities(glp);
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(4);
+        testGLFBODrawableImpl(caps, demo);
+    }
+    
+    @Test
+    public void testEGLES2_Demo0Normal() throws InterruptedException {    
+        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
+            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+            final GLCapabilities caps = new GLCapabilities(glp);
+            testGLFBODrawableImpl(caps, new GearsES2(0));
+        } else {
+            System.err.println("EGL ES2 n/a");
+        }
+    }
+    
+    @Test
+    public void testEGLES2_Demo0MSAA4() throws InterruptedException {    
+        if( GLProfile.isAvailable(GLProfile.GLES2) )  {
+            final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+            final GLCapabilities caps = new GLCapabilities(glp);
+            caps.setSampleBuffers(true);
+            caps.setNumSamples(4);
+            testGLFBODrawableImpl(caps, new GearsES2(0));
+        } else {
+            System.err.println("EGL ES2 n/a");
+        }
+    }
+
+    boolean skipShot = false;
+    
+    void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
+        caps.setFBO(true);
+        final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+        final GLDrawable fboDrawable = factory.createOffscreenDrawable(null, caps, null, widthStep*szStep, heightStep*szStep);
+        Assert.assertNotNull(fboDrawable);
+        Assert.assertTrue("Not an FBO Drawable", fboDrawable instanceof GLFBODrawableImpl);
+        
+        fboDrawable.setRealized(true);
+        Assert.assertTrue(fboDrawable.isRealized());
+        
+        final FBObject fbo = ((GLFBODrawableImpl)fboDrawable).getFBObject();
+        
+        System.out.println("Realized: "+fboDrawable);
+        System.out.println("Realized: "+fboDrawable.getChosenGLCapabilities());
+        System.out.println("Realized: "+fbo);
+        
+        final GLContext context = fboDrawable.createContext(null);
+        Assert.assertNotNull(context);
+        
+        int res = context.makeCurrent();
+        Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+        context.release();
+        
+        System.out.println("Post Create-Ctx: "+fbo);        
+        final FBObject.Colorbuffer colorA = fbo.getColorbuffer(0);
+        Assert.assertNotNull(colorA);
+        final FBObject.RenderAttachment depthA = fbo.getDepthAttachment();
+        Assert.assertNotNull(depthA);
+        
+        final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, null);
+
+        glad.addGLEventListener(demo);
+        glad.addGLEventListener(new GLEventListener() {
+            volatile int displayCount=0;
+            volatile int reshapeCount=0;
+            public void init(GLAutoDrawable drawable) {}
+            public void dispose(GLAutoDrawable drawable) {}
+            public void display(GLAutoDrawable drawable) {
+                final GL gl = drawable.getGL();
+                // System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": step "+szStep+" "+drawable.getWidth()+"x"+drawable.getHeight());
+                // System.err.println(Thread.currentThread().getName()+": ** FBO-THIS: "+fbo);
+                // System.err.println(Thread.currentThread().getName()+": ** FBO-SINK: "+fbo.getSamplingSinkFBO());
+                // System.err.println(Thread.currentThread().getName()+": ** drawable-read: "+gl.getDefaultReadFramebuffer());
+                if(skipShot) {
+                    skipShot=false;
+                } else {
+                    snapshot(getSimpleTestName("."), displayCount, "msaa"+fbo.getNumSamples(), gl, screenshot, TextureIO.PNG, null);
+                }
+                Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
+                Assert.assertEquals(drawable.getHeight(), heightStep*szStep); 
+                displayCount++;
+            }
+            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+                System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": step "+szStep+" "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
+                Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
+                Assert.assertEquals(drawable.getHeight(), heightStep*szStep);                
+                reshapeCount++;
+            }
+        });
+
+        // 0 - szStep = 2
+        glad.display();
+        
+        // 1, 2 (resize + display)
+        szStep = 1;
+        skipShot=true;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        glad.display();
+        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+        {
+            // Check whether the attachment reference are still valid!
+            FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
+            Assert.assertNotNull(_colorA);
+            Assert.assertTrue(colorA == _colorA);
+            Assert.assertTrue(colorA.equals(_colorA));
+            FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
+            Assert.assertNotNull(_depthA);
+            Assert.assertTrue(depthA == _depthA);
+            Assert.assertTrue(depthA.equals(_depthA));
+            
+            _colorA = fbo.getColorbuffer(colorA);
+            Assert.assertNotNull(_colorA);
+            Assert.assertTrue(colorA == _colorA);
+            Assert.assertTrue(colorA.equals(_colorA));
+        }
+        
+        // 3, 4 (resize + display)
+        szStep = 4;
+        skipShot=true;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        glad.display();
+        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+        {
+            // Check whether the attachment reference are still valid!
+            FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
+            Assert.assertNotNull(_colorA);
+            Assert.assertTrue(colorA == _colorA);
+            final FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
+            Assert.assertNotNull(_depthA);
+            Assert.assertTrue(depthA == _depthA);
+            
+            _colorA = fbo.getColorbuffer(colorA);
+            Assert.assertNotNull(_colorA);
+            Assert.assertTrue(colorA == _colorA);
+        }
+        
+        // 5
+        glad.display();
+        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+        
+        // 6, 7 (resize + display)
+        szStep = 3;
+        skipShot=true;
+        glad.setSize(widthStep*szStep, heightStep*szStep);
+        glad.display();
+        Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+        Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+        
+        glad.destroy();
+        System.out.println("Fin: "+fboDrawable);
+        
+        // final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(fboDrawable, context);
+    }
+    
+    public static void main(String args[]) throws IOException {
+        org.junit.runner.JUnitCore.main(TestFBODrawableNEWT.class.getName());
+    }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
new file mode 100644
index 000000000..f7c83a03b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
@@ -0,0 +1,266 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.FBObject.Attachment.Type;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.NEWTGLContext;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLUniformData;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestFBOMRTNEWT01 extends UITestCase {
+    static long durationPerTest = 10*40*2; // ms
+
+    @Test
+    public void test01() throws InterruptedException {
+        final int step = 4;
+        final int width = 800;
+        final int height = 600;
+        // preset ..
+        if(!GLProfile.isAvailable(GLProfile.GL2GL3)) {
+            System.err.println("Test requires GL2/GL3 profile.");
+            return;
+        }
+        final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(
+                new GLCapabilities(GLProfile.getGL2GL3()), width/step, height/step, true);        
+        final GLDrawable drawable = winctx.context.getGLDrawable();
+        GL2GL3 gl = winctx.context.getGL().getGL2GL3();
+        gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
+        System.err.println(winctx.context);
+
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        // test code ..        
+        final ShaderState st = new ShaderState();
+        // st.setVerbose(true);
+        
+        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
+                "shader/bin", "fbo-mrt-1", false);
+        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+                "shader/bin", "fbo-mrt-1", false);
+        final ShaderProgram sp0 = new ShaderProgram();
+        sp0.add(gl, vp0, System.err);
+        sp0.add(gl, fp0, System.err);       
+        Assert.assertTrue(0<=sp0.program()); 
+        Assert.assertTrue(!sp0.inUse());
+        Assert.assertTrue(!sp0.linked());
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
+        st.attachShaderProgram(gl, sp0, false);
+        
+        final ShaderCode vp1 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
+                "shader/bin", "fbo-mrt-2", false);
+        final ShaderCode fp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+                "shader/bin", "fbo-mrt-2", false);
+        final ShaderProgram sp1 = new ShaderProgram();
+        sp1.add(gl, vp1, System.err);
+        sp1.add(gl, fp1, System.err);       
+        Assert.assertTrue(0<=sp1.program()); 
+        Assert.assertTrue(!sp1.inUse());
+        Assert.assertTrue(!sp1.linked());
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
+        st.attachShaderProgram(gl, sp1, true);
+                        
+        final PMVMatrix pmvMatrix = new PMVMatrix();
+        final GLUniformData pmvMatrixUniform = new GLUniformData("gcu_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        st.ownUniform(pmvMatrixUniform);       
+        st.uniform(gl, pmvMatrixUniform);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        
+        final GLArrayDataServer vertices0 = GLArrayDataServer.createGLSL("gca_Vertices", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+        // st.bindAttribLocation(gl, 0, vertices0);
+        vertices0.putf(0); vertices0.putf(1);  vertices0.putf(0);
+        vertices0.putf(1);  vertices0.putf(1);  vertices0.putf(0);
+        vertices0.putf(0); vertices0.putf(0); vertices0.putf(0);
+        vertices0.putf(1);  vertices0.putf(0); vertices0.putf(0);
+        vertices0.seal(gl, true);
+        st.ownAttribute(vertices0, true);
+        vertices0.enableBuffer(gl, false);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        
+        final GLArrayDataServer colors0 = GLArrayDataServer.createGLSL("gca_Colors", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+        // st.bindAttribLocation(gl, 1, colors0);
+        colors0.putf(1); colors0.putf(0);  colors0.putf(1); colors0.putf(1);
+        colors0.putf(0);  colors0.putf(0);  colors0.putf(1); colors0.putf(1);
+        colors0.putf(0); colors0.putf(0); colors0.putf(0); colors0.putf(1);
+        colors0.putf(0);  colors0.putf(1); colors0.putf(1); colors0.putf(1);
+        colors0.seal(gl, true);
+        st.ownAttribute(colors0, true);
+        colors0.enableBuffer(gl, false);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        
+        final GLUniformData texUnit0 = new GLUniformData("gcs_TexUnit0", 0);
+        st.ownUniform(texUnit0);       
+        st.uniform(gl, texUnit0);
+        final GLUniformData texUnit1 = new GLUniformData("gcs_TexUnit1", 1);
+        st.ownUniform(texUnit1);       
+        st.uniform(gl, texUnit1);
+                
+        final GLArrayDataServer texCoords0 = GLArrayDataServer.createGLSL("gca_TexCoords", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+        // st.bindAttribLocation(gl, 2, texCoords0);
+        texCoords0.putf(0f); texCoords0.putf(1f);
+        texCoords0.putf(1f);  texCoords0.putf(1f);
+        texCoords0.putf(0f); texCoords0.putf(0f);
+        texCoords0.putf(1f);  texCoords0.putf(0f);        
+        texCoords0.seal(gl, true);
+        st.ownAttribute(texCoords0, true);
+        texCoords0.enableBuffer(gl, false);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+        final int texA0Point = 0; // attachment point for texA0
+        final int texA1Point = 1; // attachment point for texA1
+        
+        // FBO w/ 2 texture2D color buffers
+        final FBObject fbo_mrt = new FBObject();
+        fbo_mrt.reset(gl, drawable.getWidth(), drawable.getHeight());
+        final TextureAttachment texA0 = fbo_mrt.attachTexture2D(gl, texA0Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+        final TextureAttachment texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+        fbo_mrt.attachRenderbuffer(gl, Type.DEPTH, 24);
+        Assert.assertTrue( fbo_mrt.isStatusValid() ) ;
+        fbo_mrt.unbind(gl);
+        
+        // misc GL setup
+        gl.glClearColor(1, 1, 1, 1);
+        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+        // reshape
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+        pmvMatrix.glLoadIdentity();
+        pmvMatrix.glOrthof(0f, 1f, 0f, 1f, -10f, 10f);
+        pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+        pmvMatrix.glLoadIdentity();
+        st.uniform(gl, pmvMatrixUniform);
+        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+        
+        final int[] two_buffers = new int[] { GL.GL_COLOR_ATTACHMENT0+texA0Point, GL.GL_COLOR_ATTACHMENT0+texA1Point };
+        final int[] bck_buffers = new int[] { GL2GL3.GL_BACK_LEFT };
+        
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+        int step_i = 0;
+        int[] last_snap_size = new int[] { 0, 0 };
+        
+        for(int i=0; i<durationPerTest; i+=50) {
+            // pass 1 - MRT: Red -> buffer0, Green -> buffer1
+            st.attachShaderProgram(gl, sp0, true);           
+            vertices0.enableBuffer(gl, true);
+            colors0.enableBuffer(gl, true);
+            
+            fbo_mrt.bind(gl);
+            gl.glDrawBuffers(2, two_buffers, 0);
+            gl.glViewport(0, 0, fbo_mrt.getWidth(), fbo_mrt.getHeight());        
+            
+            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+            gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+            fbo_mrt.unbind(gl);
+            vertices0.enableBuffer(gl, false);
+            colors0.enableBuffer(gl, false);
+            
+            // pass 2 - mix buffer0, buffer1 and blue
+            // rg = buffer0.rg + buffer1.rg, b = Blue - length(rg);
+            st.attachShaderProgram(gl, sp1, true);
+            vertices0.enableBuffer(gl, true);
+            colors0.enableBuffer(gl, true);
+            texCoords0.enableBuffer(gl, true);
+            gl.glDrawBuffers(1, bck_buffers, 0);
+            
+            gl.glViewport(0, 0, drawable.getWidth(), drawable.getHeight());
+            
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());            
+            fbo_mrt.use(gl, texA0);
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+            fbo_mrt.use(gl, texA1);
+            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+            gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+            fbo_mrt.unuse(gl);
+            vertices0.enableBuffer(gl, false);
+            colors0.enableBuffer(gl, false);
+            texCoords0.enableBuffer(gl, false);
+            
+            {
+                final NativeSurface ns = gl.getContext().getGLReadDrawable().getNativeSurface();
+                if(last_snap_size[0] != ns.getWidth() && last_snap_size[1] != ns.getHeight()) {
+                    gl.glFinish(); // sync .. no swap buffers yet!
+                    snapshot(getSimpleTestName("."), step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
+                    last_snap_size[0] = ns.getWidth();
+                    last_snap_size[1] = ns.getHeight();
+                }
+            }
+            
+            drawable.swapBuffers();
+            Thread.sleep(50);
+            int j = (int) ( (long)i / (durationPerTest/(long)step) ) + 1;
+            if(j>step_i) {
+                int w = width/step * j;
+                int h = height/step * j;
+                System.err.println("resize: "+step_i+" -> "+j+" - "+w+"x"+h);
+                fbo_mrt.reset(gl, w, h);
+                winctx.window.setSize(w, h);
+                step_i = j;
+            }
+        }
+        
+        NEWTGLContext.destroyWindow(winctx);
+    }
+    
+    public static void main(String args[]) throws IOException {
+        System.err.println("main - start");
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
+            }
+        }
+        String tstname = TestFBOMRTNEWT01.class.getName();
+        org.junit.runner.JUnitCore.main(tstname);
+        System.err.println("main - end");
+    }    
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
new file mode 100644
index 000000000..b384c9327
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java
@@ -0,0 +1,258 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestFBOMix2DemosES2NEWT extends UITestCase {    
+    static long duration = 500; // ms
+    static int swapInterval = 1;
+    static boolean showFPS = false;
+    static boolean forceES2 = false;
+    static boolean doRotate = true;
+    static boolean demo0Only = false;
+    static int globalNumSamples = 0;
+    static boolean mainRun = false;
+    
+    @AfterClass
+    public static void releaseClass() {
+    }
+
+    protected void runTestGL(GLCapabilitiesImmutable caps, int numSamples) throws InterruptedException {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+        System.err.println("requested: vsync "+swapInterval+", "+caps);
+        final GLWindow glWindow = GLWindow.create(caps);
+        Assert.assertNotNull(glWindow);
+        glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), swapInterval "+swapInterval);
+        if(mainRun) {
+            glWindow.setSize(512, 512);            
+        } else {
+            glWindow.setSize(128, 128);
+        }
+
+        final FBOMix2DemosES2 demo = new FBOMix2DemosES2(swapInterval);
+        demo.setMSAA(numSamples);
+        demo.setDoRotation(doRotate);
+        demo.setDemo0Only(demo0Only);
+        glWindow.addGLEventListener(demo);
+        glWindow.addGLEventListener(new GLEventListener() {
+            int i=0, c=0;
+            int origS;
+            public void init(GLAutoDrawable drawable) {
+                origS = demo.getMSAA();
+            }
+            public void dispose(GLAutoDrawable drawable) {}
+            public void display(GLAutoDrawable drawable) {
+                if(mainRun) return;
+                
+                final int dw = drawable.getWidth();
+                final int dh = drawable.getHeight();
+                c++;
+                
+                if(dw<800) {
+                    System.err.println("XXX: "+dw+"x"+dh+", c "+c);
+                    if(0 == c%3) {
+                        snapshot(getSimpleTestName("."), i++, "msaa"+demo.getMSAA(), drawable.getGL(), screenshot, TextureIO.PNG, null);                        
+                    }
+                    if( 3 == c ) {
+                        new Thread() { 
+                            @Override
+                            public void run() {
+                                demo.setMSAA(4);
+                            } }.start();
+                    } else if( 6 == c ) {
+                        new Thread() { 
+                            @Override
+                            public void run() {
+                                demo.setMSAA(8);
+                            } }.start();
+                    } else if(9 == c) {
+                        c=0;
+                        new Thread() { 
+                            @Override
+                            public void run() {
+                                glWindow.setSize(dw+256, dh+256);
+                                demo.setMSAA(origS);
+                            } }.start();                            
+                    }
+                }
+            }
+            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+        });
+        
+        Animator animator = new Animator(glWindow);
+        QuitAdapter quitAdapter = new QuitAdapter();
+
+        //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter));
+        //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter));
+        glWindow.addKeyListener(quitAdapter);
+        glWindow.addWindowListener(quitAdapter);
+
+        glWindow.addWindowListener(new WindowAdapter() {
+            public void windowResized(WindowEvent e) {
+                System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+            }
+            public void windowMoved(WindowEvent e) {
+                System.err.println("window moved:   "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+            }            
+        });
+        
+        glWindow.addKeyListener(new KeyAdapter() {
+            public void keyTyped(KeyEvent e) {
+                System.err.println("*** "+e);
+                if(e.getKeyChar()=='f') {
+                    new Thread() {
+                        public void run() {
+                            System.err.println("[set fullscreen  pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+                            glWindow.setFullscreen(!glWindow.isFullscreen());
+                            System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
+                    } }.start();
+                } else if(e.getKeyChar()=='d') {
+                    demo.setDemo0Only(!demo.getDemo0Only());
+                } else {
+                    int num = e.getKeyChar() - '0';
+                    System.err.println("*** "+num);
+                    if(0 <= num && num <= 8) {
+                        System.err.println("MSAA: "+demo.getMSAA()+" -> "+num);
+                        demo.setMSAA(num);                        
+                    }
+                }
+            }
+        });
+
+        animator.start();
+        // glWindow.setSkipContextReleaseThread(animator.getThread());
+
+        glWindow.setVisible(true);
+        
+        System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
+        System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
+        System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+        
+        animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+        
+        while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+            Thread.sleep(100);
+        }
+
+        animator.stop();
+        Assert.assertFalse(animator.isAnimating());
+        Assert.assertFalse(animator.isStarted());
+        glWindow.destroy();
+        Assert.assertEquals(true,  AWTRobotUtil.waitForRealized(glWindow, false));
+    }
+
+    @Test
+    public void test01_Main() throws InterruptedException {
+        if( mainRun ) {
+            GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+            caps.setAlphaBits(1);
+            runTestGL(caps, globalNumSamples);            
+        }
+    }
+    
+    @Test
+    public void test01() throws InterruptedException {
+        if( mainRun ) return ;
+        GLCapabilities caps = new GLCapabilities(forceES2 ? GLProfile.get(GLProfile.GLES2) : GLProfile.getGL2ES2());
+        caps.setAlphaBits(1);
+        runTestGL(caps, 0);
+    }
+
+    public static void main(String args[]) throws IOException {        
+        boolean waitForKey = false;
+        
+        mainRun = true;
+        
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                i++;
+                duration = MiscUtils.atol(args[i], duration);
+            } else if(args[i].equals("-vsync")) {
+                i++;
+                swapInterval = MiscUtils.atoi(args[i], swapInterval);
+            } else if(args[i].equals("-es2")) {
+                forceES2 = true;
+            } else if(args[i].equals("-showFPS")) {
+                showFPS = true;
+            } else if(args[i].equals("-samples")) {
+                i++;
+                globalNumSamples = MiscUtils.atoi(args[i], globalNumSamples);
+            } else if(args[i].equals("-norotate")) {
+                doRotate = false;
+            } else if(args[i].equals("-demo0Only")) {
+                demo0Only = true;
+            } else if(args[i].equals("-wait")) {
+                waitForKey = true;
+            } else if(args[i].equals("-nomain")) {
+                mainRun = false;
+            }
+        }
+        
+        System.err.println("swapInterval "+swapInterval);
+        System.err.println("forceES2 "+forceES2);
+
+        if(waitForKey) {
+            BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+            System.err.println("Press enter to continue");
+            try {
+                System.err.println(stdin.readLine());
+            } catch (IOException e) { }
+        }
+        org.junit.runner.JUnitCore.main(TestFBOMix2DemosES2NEWT.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
index a2d060a8c..eb716677d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
@@ -85,7 +85,7 @@ public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
         Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
         context.release();
         
-        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context) {
+        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window) {
             @Override
             public void destroy() {
                 super.destroy();  // destroys drawable/context
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
index 483a09735..06aa29b4f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
@@ -88,7 +88,7 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
         drawable.setRealized(true);
         Assert.assertTrue(drawable.isRealized());
         
-        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null) {
+        final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window) {
             @Override
             public void destroy() {
                 super.destroy();  // destroys drawable/context
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
index 9ca6670ad..d9429129b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
@@ -54,7 +54,7 @@ public class TestGLProfile01NEWT extends UITestCase {
         System.err.println(JoglVersion.getInstance());
         System.err.println(NewtVersion.getInstance());
 
-        System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());        
+        System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());        
     }
 
     @Test
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
index 5f374830d..b21ad5b5b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
@@ -86,7 +86,7 @@ public class TestShutdownCompleteNEWT extends UITestCase {
         }
         long t2 = System.nanoTime();
         if(glInfo) {
-            System.err.println(JoglVersion.getDefaultOpenGLInfo(null, false).toString());
+            System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, false).toString());
         }
         long t3 = System.nanoTime();        
         GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);        
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemoES1.java
deleted file mode 100644
index 0aaf4b020..000000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemoES1.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package com.jogamp.opengl.test.junit.jogl.caps;
-
-import jogamp.opengl.x11.glx.GLX;
-import jogamp.opengl.x11.glx.X11GLXGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.opengl.GL;
-import javax.media.opengl.GL2ES1;
-import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLPipelineFactory;
-
-import com.jogamp.opengl.util.ImmModeSink;
-
-class MultisampleDemoES1 implements GLEventListener {
-
-    static boolean glDebug = false;
-    static boolean glTrace = false;
-
-    boolean multisample;
-    ImmModeSink immModeSink;
-
-    public MultisampleDemoES1(boolean multisample) {
-        this.multisample = multisample;
-    }
-
-    public void init(GLAutoDrawable drawable) {
-        System.err.println();
-        System.err.println("Requested: " + drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
-        System.err.println();
-        System.err.println("Chosen   : " + drawable.getChosenGLCapabilities());
-        System.err.println();
-        if (!drawable.getGL().isGLES() && NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(false))) {
-            AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
-            X11GLXGraphicsConfiguration x11config = (X11GLXGraphicsConfiguration) config;
-            long display = drawable.getNativeSurface().getDisplayHandle();
-            int[] foo = new int[1];
-            GLX.glXGetFBConfigAttrib(display, x11config.getFBConfig(), GLX.GLX_SAMPLES, foo, 0);
-            System.out.println("GLX_SAMPLES " + foo[0]);
-            GLX.glXGetFBConfigAttrib(display, x11config.getFBConfig(), GLX.GLX_SAMPLE_BUFFERS, foo, 0);
-            System.out.println("GLX_SAMPLE_BUFFERS " + foo[0]);
-        }
-        GL _gl = drawable.getGL();
-        if (glDebug) {
-            try {
-                // Debug ..
-                _gl = _gl.getContext().setGL(GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES1.class, _gl, null));
-                if (glTrace) {
-                    // Trace ..
-                    _gl = _gl.getContext().setGL(GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES1.class, _gl, new Object[]{System.err}));
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-        GL2ES1 gl = _gl.getGL2ES1();
-        if (multisample) {
-            gl.glEnable(GL.GL_MULTISAMPLE);
-        }
-        gl.glClearColor(0, 0, 0, 0);
-        //      gl.glEnable(GL.GL_DEPTH_TEST);
-        //      gl.glDepthFunc(GL.GL_LESS);
-        gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
-        gl.glLoadIdentity();
-        gl.glMatrixMode(GL2ES1.GL_PROJECTION);
-        gl.glLoadIdentity();
-        gl.glOrtho(-1, 1, -1, 1, -1, 1);
-        if (multisample) {
-            gl.glDisable(GL.GL_MULTISAMPLE);
-        }
-        immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40, 
-                                              3, GL.GL_FLOAT,  // vertex
-                                              0, GL.GL_FLOAT,  // color
-                                              0, GL.GL_FLOAT,// normal
-                                              0, GL.GL_FLOAT); // texture
-        final int numSteps = 20;
-        final double increment = Math.PI / numSteps;
-        final double radius = 1;
-        immModeSink.glBegin(GL.GL_LINES);
-        for (int i = numSteps - 1; i >= 0; i--) {
-            immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)), 
-                                   (float) (radius * Math.sin(i * increment)), 
-                                   0f);
-            immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)), 
-                                   (float) (-1.0 * radius * Math.sin(i * increment)), 
-                                   0f);
-        }
-        immModeSink.glEnd(gl, false);
-    }
-
-    public void dispose(GLAutoDrawable drawable) {
-        immModeSink.destroy(drawable.getGL());
-        immModeSink = null;
-    }
-
-    public void display(GLAutoDrawable drawable) {
-        GL2ES1 gl = drawable.getGL().getGL2ES1();
-        if (multisample) {
-            gl.glEnable(GL.GL_MULTISAMPLE);
-        }
-        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-        immModeSink.draw(gl, true);
-        if (multisample) {
-            gl.glDisable(GL.GL_MULTISAMPLE);
-        }
-    }
-
-    // Unused routines
-    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
-    }
-
-    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
-    }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
index 4b0caf898..478bd4543 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
@@ -40,7 +40,6 @@
 
 package com.jogamp.opengl.test.junit.jogl.caps;
 
-import java.io.File;
 import java.lang.reflect.InvocationTargetException;
 import java.awt.BorderLayout;
 import java.awt.Frame;
@@ -48,14 +47,15 @@ import java.awt.Frame;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
-import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.awt.GLCanvas;
 
+import com.jogamp.opengl.test.junit.jogl.demos.es1.MultisampleDemoES1;
 import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import org.junit.Test;
 
@@ -75,13 +75,6 @@ public class TestMultisampleES1AWT extends UITestCase {
      org.junit.runner.JUnitCore.main(tstname);
   }
 
-  protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
-    GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
-    if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
-        screenshot.write(new File(filename));
-    }                
-  }
-    
   @Test
   public void testOnscreenMultiSampleAA0() throws InterruptedException, InvocationTargetException {
     testMultiSampleAAImpl(0);
@@ -98,6 +91,7 @@ public class TestMultisampleES1AWT extends UITestCase {
   }
 
   private void testMultiSampleAAImpl(int reqSamples) throws InterruptedException, InvocationTargetException {
+    final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
     GLProfile glp = GLProfile.getMaxFixedFunc(true);
     GLCapabilities caps = new GLCapabilities(glp);
     GLCapabilitiesChooser chooser = new MultisampleChooser01();
@@ -110,14 +104,11 @@ public class TestMultisampleES1AWT extends UITestCase {
     canvas = new GLCanvas(caps, chooser, null, null);
     canvas.addGLEventListener(new MultisampleDemoES1(reqSamples>0?true:false));
     canvas.addGLEventListener(new GLEventListener() {
+        int displayCount = 0;
         public void init(GLAutoDrawable drawable) {}
         public void dispose(GLAutoDrawable drawable) {}
         public void display(GLAutoDrawable drawable) {
-            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
-            final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
-            final String aaext = caps.getSampleExtension();
-            final int samples = caps.getSampleBuffers() ? caps.getNumSamples() : 0 ;
-            snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-S"+samples+"-"+aaext+"-"+drawable.getGLProfile().getName()+".png");
+            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
         }
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
index 2e47b6841..ed8e2bd85 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
@@ -40,21 +40,20 @@
 
 package com.jogamp.opengl.test.junit.jogl.caps;
 
-import java.io.File;
-
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLCapabilitiesChooser;
-import javax.media.opengl.GLCapabilitiesImmutable;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 
 import org.junit.Test;
 
 import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.MultisampleDemoES1;
 import com.jogamp.opengl.test.junit.util.MiscUtils;
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 public class TestMultisampleES1NEWT extends UITestCase {
   static long durationPerTest = 60; // ms
@@ -71,13 +70,6 @@ public class TestMultisampleES1NEWT extends UITestCase {
      org.junit.runner.JUnitCore.main(tstname);
   }
 
-  protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
-    GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
-    if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
-        screenshot.write(new File(filename));
-    }                
-  }
-    
   @Test
   public void testOnscreenMultiSampleAA0() throws InterruptedException {
     testMultiSampleAAImpl(true, 0);
@@ -119,6 +111,7 @@ public class TestMultisampleES1NEWT extends UITestCase {
   }
 
   private void testMultiSampleAAImpl(boolean onscreen, int reqSamples) throws InterruptedException {
+    final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
     GLProfile glp = GLProfile.getMaxFixedFunc(true);
     GLCapabilities caps = new GLCapabilities(glp);
     GLCapabilitiesChooser chooser = new MultisampleChooser01();
@@ -136,14 +129,11 @@ public class TestMultisampleES1NEWT extends UITestCase {
     window.setCapabilitiesChooser(chooser);
     window.addGLEventListener(new MultisampleDemoES1(reqSamples>0?true:false));
     window.addGLEventListener(new GLEventListener() {
+        int displayCount = 0;
         public void init(GLAutoDrawable drawable) {}
         public void dispose(GLAutoDrawable drawable) {}
         public void display(GLAutoDrawable drawable) {
-            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
-            final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
-            final String aaext = caps.getSampleExtension();
-            final int samples = caps.getSampleBuffers() ? caps.getNumSamples() : 0 ;
-            snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-S"+samples+"-"+aaext+"-"+drawable.getGLProfile().getName()+".png");
+            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
         }
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
     });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
new file mode 100644
index 000000000..b2dad1f39
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ * 
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.caps;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+public class TestMultisampleES2NEWT extends UITestCase {
+  static long durationPerTest = 60; // ms
+  private GLWindow window;
+
+  public static void main(String[] args) {
+     for(int i=0; i<args.length; i++) {
+        if(args[i].equals("-time")) {
+            durationPerTest = MiscUtils.atoi(args[++i], 500);
+        }
+     }
+     System.out.println("durationPerTest: "+durationPerTest);
+     String tstname = TestMultisampleES2NEWT.class.getName();
+     org.junit.runner.JUnitCore.main(tstname);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOnscreenMultiSampleAA0() throws InterruptedException {
+    testMultiSampleAAImpl(false, false, 0);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOnscreenMultiSampleAA8() throws InterruptedException {
+    testMultiSampleAAImpl(false, false, 8);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOffscreenPBufferMultiSampleAA0() throws InterruptedException {
+    testMultiSampleAAImpl(false, true, 0);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOffsreenPBufferMultiSampleAA8() throws InterruptedException {
+    testMultiSampleAAImpl(false, true, 8);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOffscreenFBOMultiSampleAA0() throws InterruptedException {
+    testMultiSampleAAImpl(true, false, 0);
+  }
+
+  @Test(timeout = 3000) // 3s timeout
+  public void testOffsreenFBOMultiSampleAA8() throws InterruptedException {
+    testMultiSampleAAImpl(true, false, 8);
+  }
+
+  private void testMultiSampleAAImpl(boolean useFBO, boolean usePBuffer, int reqSamples) throws InterruptedException {
+    if(useFBO) {
+        System.err.println("NEWT offscreen FBO Window n/a yet");
+        return;
+    }
+    final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+    GLProfile glp = GLProfile.getGL2ES2();
+    GLCapabilities caps = new GLCapabilities(glp);
+    GLCapabilitiesChooser chooser = new MultisampleChooser01();
+
+    caps.setAlphaBits(1);
+    caps.setFBO(useFBO);
+    caps.setPBuffer(usePBuffer);
+    
+    if(reqSamples>0) {
+        caps.setSampleBuffers(true);
+        caps.setNumSamples(reqSamples);
+    }
+
+    window = GLWindow.create(caps);
+    window.setCapabilitiesChooser(chooser);
+    window.addGLEventListener(new MultisampleDemoES2(reqSamples>0?true:false));
+    window.addGLEventListener(new GLEventListener() {
+        int displayCount = 0;
+        public void init(GLAutoDrawable drawable) {}
+        public void dispose(GLAutoDrawable drawable) {}
+        public void display(GLAutoDrawable drawable) {
+            snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+        }
+        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+    });
+    window.setSize(512, 512);
+    window.setVisible(true);
+    window.requestFocus();
+
+    Thread.sleep(durationPerTest);
+
+    window.destroy();
+  }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 5c82a43c6..e81d1b4af 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -129,12 +129,13 @@ public class GearsES1 implements GLEventListener {
             
     gl.glEnable(GL2ES1.GL_NORMALIZE);
                 
-    if (drawable.getNativeSurface() instanceof Window) {
-        Window window = (Window) drawable.getNativeSurface();
+    final Object upstreamWidget = drawable.getUpstreamWidget();
+    if (upstreamWidget instanceof Window) {            
+        final Window window = (Window) upstreamWidget;
         window.addMouseListener(gearsMouse);
         window.addKeyListener(gearsKeys);
-    } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
-        java.awt.Component comp = (java.awt.Component) drawable;
+    } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+        final java.awt.Component comp = (java.awt.Component) upstreamWidget;
         new com.jogamp.newt.event.awt.AWTMouseAdapter(gearsMouse).addTo(comp);
         new com.jogamp.newt.event.awt.AWTKeyAdapter(gearsKeys).addTo(comp);
     }
@@ -165,8 +166,9 @@ public class GearsES1 implements GLEventListener {
 
   public void dispose(GLAutoDrawable drawable) {
     System.err.println(Thread.currentThread()+" GearsES1.dispose ... ");
-    if (drawable.getNativeSurface() instanceof Window) {
-        Window window = (Window) drawable.getNativeSurface();
+    final Object upstreamWidget = drawable.getUpstreamWidget();
+    if (upstreamWidget instanceof Window) {            
+        final Window window = (Window) upstreamWidget;
         window.removeMouseListener(gearsMouse);
         window.removeKeyListener(gearsKeys);
     }
@@ -188,8 +190,9 @@ public class GearsES1 implements GLEventListener {
     GL2ES1 gl = drawable.getGL().getGL2ES1();
 
     final boolean hasFocus;
-    if(drawable.getNativeSurface() instanceof NativeWindow) {
-      hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+    final Object upstreamWidget = drawable.getUpstreamWidget();
+    if(upstreamWidget instanceof NativeWindow) {
+      hasFocus = ((NativeWindow)upstreamWidget).hasFocus();
     } else {
       hasFocus = true;
     }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
new file mode 100644
index 000000000..aad56581b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.demos.es1;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+
+import com.jogamp.opengl.util.ImmModeSink;
+
+public class MultisampleDemoES1 implements GLEventListener {
+
+    boolean multisample;
+    ImmModeSink immModeSink;
+
+    public MultisampleDemoES1(boolean multisample) {
+        this.multisample = multisample;
+    }
+
+    public void init(GLAutoDrawable drawable) {
+        System.err.println();
+        System.err.println("Requested: " + drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
+        System.err.println();
+        System.err.println("Chosen   : " + drawable.getChosenGLCapabilities());
+        System.err.println();
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        if (multisample) {
+            gl.glEnable(GL.GL_MULTISAMPLE);
+        }
+        gl.glClearColor(0, 0, 0, 0);
+        //      gl.glEnable(GL.GL_DEPTH_TEST);
+        //      gl.glDepthFunc(GL.GL_LESS);
+        gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glMatrixMode(GL2ES1.GL_PROJECTION);
+        gl.glLoadIdentity();
+        gl.glOrtho(-1, 1, -1, 1, -1, 1);
+        if (multisample) {
+            gl.glDisable(GL.GL_MULTISAMPLE);
+        }
+        immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40, 
+                                              3, GL.GL_FLOAT,  // vertex
+                                              0, GL.GL_FLOAT,  // color
+                                              0, GL.GL_FLOAT,// normal
+                                              0, GL.GL_FLOAT); // texture
+        final int numSteps = 20;
+        final double increment = Math.PI / numSteps;
+        final double radius = 1;
+        immModeSink.glBegin(GL.GL_LINES);
+        for (int i = numSteps - 1; i >= 0; i--) {
+            immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)), 
+                                   (float) (radius * Math.sin(i * increment)), 
+                                   0f);
+            immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)), 
+                                   (float) (-1.0 * radius * Math.sin(i * increment)), 
+                                   0f);
+        }
+        immModeSink.glEnd(gl, false);
+    }
+
+    public void dispose(GLAutoDrawable drawable) {
+        immModeSink.destroy(drawable.getGL());
+        immModeSink = null;
+    }
+
+    public void display(GLAutoDrawable drawable) {
+        GL2ES1 gl = drawable.getGL().getGL2ES1();
+        if (multisample) {
+            gl.glEnable(GL.GL_MULTISAMPLE);
+        }
+        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+        immModeSink.draw(gl, true);
+        if (multisample) {
+            gl.glDisable(GL.GL_MULTISAMPLE);
+        }
+    }
+
+    // Unused routines
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+    }
+
+    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
new file mode 100644
index 000000000..3dfbb4893
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
@@ -0,0 +1,309 @@
+/**
+ * Copyright (C) 2011 JogAmp Community. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.FBObject.Attachment.Type;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class FBOMix2DemosES2 implements GLEventListener {
+    private final GearsES2 demo0;
+    private final RedSquareES2 demo1;
+    private final int swapInterval;
+    private int numSamples;
+    private boolean demo0Only;
+    
+    
+    private final ShaderState st;
+    private final PMVMatrix pmvMatrix;
+    
+    private final FBObject fbo0;    
+    private final FBObject fbo1;
+    
+    private TextureAttachment fbo0Tex;
+    private TextureAttachment fbo1Tex;
+        
+    private ShaderProgram sp0;
+    private GLUniformData pmvMatrixUniform;
+    private GLArrayDataServer interleavedVBO;
+    private GLUniformData texUnit0;
+    private GLUniformData texUnit1;
+    
+    public FBOMix2DemosES2(int swapInterval) {
+        demo0 = new GearsES2(-1);
+        demo0.setIsFBOSlave(true);
+        demo1 = new RedSquareES2(-1);
+        demo1.setIsFBOSlave(true);
+        this.swapInterval = swapInterval;
+        
+        st = new ShaderState();
+        // st.setVerbose(true);        
+        pmvMatrix = new PMVMatrix();
+        
+        fbo0 = new FBObject();        
+        fbo1 = new FBObject();
+        
+        numSamples = 0;
+        demo0Only = false;
+    }
+    
+    public void setDemo0Only(boolean v) { 
+        this.demo0Only = v; 
+    }
+    public boolean getDemo0Only() { return demo0Only; }
+    
+    public void setMSAA(int numSamples) { 
+        this.numSamples=numSamples; 
+    }
+    public int getMSAA() { return numSamples; }
+    
+    public void setDoRotation(boolean rotate) { demo1.setDoRotation(rotate); }
+    
+    static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
+    static final String gl2_prelude = "#version 110\n";
+    
+    @Override
+    public void init(GLAutoDrawable drawable) {
+        final GL2ES2 gl = drawable.getGL().getGL2ES2();
+        
+        demo0.init(drawable);
+        demo1.init(drawable);
+        
+        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, FBOMix2DemosES2.class, "shader",
+                "shader/bin", "texture01_xxx", true);
+        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, FBOMix2DemosES2.class, "shader",
+                "shader/bin", "texture02_xxx", true);
+        
+        // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
+        int fp0Pos;
+        if(gl.isGLES2()) {
+            vp0.insertShaderSource(0, 0, es2_prelude[0]);
+            fp0Pos = fp0.insertShaderSource(0, 0, es2_prelude[0]);
+        } else {
+            vp0.insertShaderSource(0, 0, gl2_prelude);
+            fp0Pos = fp0.insertShaderSource(0, 0, gl2_prelude);
+        }
+        if(gl.isGLES2()) {
+            fp0Pos = fp0.insertShaderSource(0, fp0Pos, es2_prelude[1]);
+        }        
+        
+        sp0 = new ShaderProgram();
+        sp0.add(gl, vp0, System.err);
+        sp0.add(gl, fp0, System.err);       
+        st.attachShaderProgram(gl, sp0, true);
+        
+        pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+        st.ownUniform(pmvMatrixUniform);       
+        st.uniform(gl, pmvMatrixUniform);
+        
+        interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
+        {        
+            interleavedVBO.addGLSLSubArray("mgl_Vertex",        3, GL.GL_ARRAY_BUFFER);            
+            interleavedVBO.addGLSLSubArray("mgl_Color",         4, GL.GL_ARRAY_BUFFER);            
+            //interleavedVBO.addGLSLSubArray("mgl_Normal",        3, GL.GL_ARRAY_BUFFER);
+            interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+
+            FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
+            
+            for(int i=0; i<4; i++) {
+                ib.put(s_quadVertices,  i*3, 3);
+                ib.put(s_quadColors,    i*4, 4);  
+                //ib.put(s_cubeNormals,   i*3, 3);
+                ib.put(s_quadTexCoords, i*2, 2);
+            }                        
+        }
+        interleavedVBO.seal(gl, true);
+        interleavedVBO.enableBuffer(gl, false);
+        st.ownAttribute(interleavedVBO, true);
+                
+        texUnit0 = new GLUniformData("mgl_Texture0", 0);
+        st.ownUniform(texUnit0);       
+        st.uniform(gl, texUnit0);
+        texUnit1 = new GLUniformData("mgl_Texture1", 1);
+        st.ownUniform(texUnit1);       
+        st.uniform(gl, texUnit1);
+        
+        st.useProgram(gl, false);
+        
+        System.err.println("**** Init");
+        resetFBOs(gl, drawable);
+        
+        fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
+        fbo0.unbind(gl);
+        fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
+        fbo1.unbind(gl);
+        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+        
+        numSamples=fbo0.getNumSamples();
+    }
+    
+    /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
+    private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+        // remove all texture attachments, since MSAA uses just color-render-buffer
+        // and non-MSAA uses texture2d-buffer
+        fbo0.detachAllColorbuffer(gl);
+        fbo1.detachAllColorbuffer(gl);
+            
+        fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+        fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+        if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
+            throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
+        }        
+        numSamples = fbo0.getNumSamples();
+        
+        if(numSamples>0) {
+            fbo0.attachColorbuffer(gl, 0, true);
+            fbo1.attachColorbuffer(gl, 0, true);
+            fbo0Tex = fbo0.getSamplingSink();
+            fbo1Tex = fbo1.getSamplingSink();
+        } else {
+            fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
+            fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
+        }        
+    }
+
+    @Override
+    public void dispose(GLAutoDrawable drawable) {
+        final GL2ES2 gl = drawable.getGL().getGL2ES2();
+        demo0.dispose(drawable);
+        demo1.dispose(drawable);
+        fbo0.destroy(gl);
+        fbo1.destroy(gl);
+        st.destroy(gl);
+        
+        fbo0Tex = null;
+        fbo1Tex = null;
+        sp0 = null;
+        pmvMatrixUniform = null;
+        interleavedVBO = null;
+    }
+
+    @Override
+    public void display(GLAutoDrawable drawable) {
+        final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+        if( fbo0.getNumSamples() != numSamples ) {
+            System.err.println("**** NumSamples: "+fbo0.getNumSamples()+" -> "+numSamples);
+            resetFBOs(gl, drawable);
+        }
+        
+        if(0 < numSamples) {
+            gl.glEnable(GL.GL_MULTISAMPLE);
+        }
+        
+        fbo0.bind(gl);
+        demo0.display(drawable);
+        fbo0.unbind(gl);
+        
+        if(!demo0Only) {
+            fbo1.bind(gl);
+            demo1.display(drawable);
+            fbo1.unbind(gl);
+        }
+        
+        st.useProgram(gl, true);
+        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+        
+        gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+        fbo0.use(gl, fbo0Tex);
+        if(!demo0Only) {
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+            fbo1.use(gl, fbo1Tex);
+        }
+        interleavedVBO.enableBuffer(gl, true);
+        
+        gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+        
+        interleavedVBO.enableBuffer(gl, false);
+        fbo0.unuse(gl);
+        if(!demo0Only) {
+            fbo1.unuse(gl);
+        }
+        
+        st.useProgram(gl, false);        
+    }
+
+    @Override
+    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+        final GL2ES2 gl = drawable.getGL().getGL2ES2();
+        
+        if(-1 != swapInterval) {        
+            gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        }
+        
+        // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
+            System.err.println("**** Reshape: "+width+"x"+height);
+            resetFBOs(gl, drawable);            
+        //}        
+        
+        fbo0.bind(gl);
+        demo0.reshape(drawable, x, y, width, height);
+        fbo0.unbind(gl);
+        fbo1.bind(gl);
+        demo1.reshape(drawable, x, y, width, height);
+        fbo1.unbind(gl);
+        
+        pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+        pmvMatrix.glLoadIdentity();
+        pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+
+        pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+        pmvMatrix.glLoadIdentity();
+        
+        st.useProgram(gl, true);
+        st.uniform(gl, pmvMatrixUniform);
+        st.useProgram(gl, false);
+        
+    }
+
+    private static final float[] s_quadVertices = { 
+      -1f, -1f, 0f, // LB
+       1f, -1f, 0f, // RB
+      -1f,  1f, 0f, // LT
+       1f,  1f, 0f  // RT 
+    };
+    private static final float[] s_quadColors = { 
+      1f, 1f, 1f, 1f,
+      1f, 1f, 1f, 1f,
+      1f, 1f, 1f, 1f,
+      1f, 1f, 1f, 1f };
+    private static final float[] s_quadTexCoords = { 
+            0f, 0f, // LB
+            1f, 0f, // RB
+            0f, 1f, // LT   
+            1f, 1f  // RT
+    };
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 6aea5bb9c..38e8a15ce 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -65,6 +65,7 @@ public class GearsES2 implements GLEventListener {
 
     private int prevMouseX, prevMouseY;
     private boolean isInitialized = false;
+    boolean isFBOSlave = false;
 
     public GearsES2(int swapInterval) {
         this.swapInterval = swapInterval;
@@ -74,6 +75,8 @@ public class GearsES2 implements GLEventListener {
         this.swapInterval = 1;
     }
 
+    public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
+    
     public void setPMVUseBackingArray(boolean pmvUseBackingArray) {
         this.pmvUseBackingArray = pmvUseBackingArray;
     }
@@ -115,7 +118,6 @@ public class GearsES2 implements GLEventListener {
         System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
         System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
 
-        gl.glEnable(GL.GL_CULL_FACE);
         gl.glEnable(GL.GL_DEPTH_TEST);
         
         st = new ShaderState();
@@ -168,13 +170,14 @@ public class GearsES2 implements GLEventListener {
             gear3 = new GearsObjectES2(gear3, pmvMatrix, pmvMatrixUniform, colorU);
             System.err.println("gear3 reused: "+gear3);
         }                
-        
-        if (drawable.getNativeSurface() instanceof Window) {
-            Window window = (Window) drawable.getNativeSurface();
+    
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {
+            final Window window = (Window) upstreamWidget;
             window.addMouseListener(gearsMouse);
             window.addKeyListener(gearsKeys);
-        } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
-            java.awt.Component comp = (java.awt.Component) drawable;
+        } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+            final java.awt.Component comp = (java.awt.Component) upstreamWidget;
             new com.jogamp.newt.event.awt.AWTMouseAdapter(gearsMouse).addTo(comp);
             new com.jogamp.newt.event.awt.AWTKeyAdapter(gearsKeys).addTo(comp);
         }
@@ -187,7 +190,9 @@ public class GearsES2 implements GLEventListener {
         System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
         GL2ES2 gl = drawable.getGL().getGL2ES2();
 
-        gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        if(-1 != swapInterval) {
+            gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        }
         
         st.useProgram(gl, true);
         pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
@@ -218,8 +223,9 @@ public class GearsES2 implements GLEventListener {
         }
         isInitialized = false;
         System.err.println(Thread.currentThread()+" GearsES2.dispose ... ");
-        if (drawable.getNativeSurface() instanceof Window) {
-            Window window = (Window) drawable.getNativeSurface();
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {            
+            final Window window = (Window) upstreamWidget;
             window.removeMouseListener(gearsMouse);
             window.removeKeyListener(gearsKeys);
         }
@@ -235,6 +241,7 @@ public class GearsES2 implements GLEventListener {
         colorU = null;        
         st.destroy(gl);
         st = null;
+
         System.err.println(Thread.currentThread()+" GearsES2.dispose FIN");
     }
 
@@ -246,12 +253,16 @@ public class GearsES2 implements GLEventListener {
         GL2ES2 gl = drawable.getGL().getGL2ES2();
 
         final boolean hasFocus;
-        if(drawable.getNativeSurface() instanceof NativeWindow) {
-          hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if(upstreamWidget instanceof NativeWindow) {
+          hasFocus = ((NativeWindow)upstreamWidget).hasFocus();
         } else {
           hasFocus = true;
         }
-        if(hasFocus) {
+        
+        gl.glEnable(GL.GL_CULL_FACE);
+        
+        if( isFBOSlave || hasFocus ) {
           gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         } else {
           gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
@@ -278,7 +289,9 @@ public class GearsES2 implements GLEventListener {
         gear2.draw(gl,  3.1f, -2.0f, -2f * angle -  9.0f, GearsObject.green);
         gear3.draw(gl, -3.1f,  4.2f, -2f * angle - 25.0f, GearsObject.blue);    
         pmvMatrix.glPopMatrix();
-        st.useProgram(gl, false);        
+        st.useProgram(gl, false);
+        
+        gl.glDisable(GL.GL_CULL_FACE);
     }
     
     boolean confinedFixedCenter = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
new file mode 100644
index 000000000..5facc1a49
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class MultisampleDemoES2 implements GLEventListener {
+
+    private boolean multisample;
+    private final ShaderState st;
+    private final PMVMatrix pmvMatrix;
+    private ShaderProgram sp0;
+    private GLUniformData pmvMatrixUniform;
+    private ImmModeSink immModeSink;
+
+    public MultisampleDemoES2(boolean multisample) {
+        this.multisample = multisample;
+        st = new ShaderState();
+        st.setVerbose(true);        
+        pmvMatrix = new PMVMatrix();        
+    }
+
+    static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
+    static final String gl2_prelude = "#version 110\n";
+    
+    public void init(GLAutoDrawable glad) {
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        System.err.println();
+        System.err.println("Requested: " + glad.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
+        System.err.println();
+        System.err.println("Chosen   : " + glad.getChosenGLCapabilities());
+        System.err.println();
+        
+        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MultisampleDemoES2.class, "shader",
+                "shader/bin", "mgl_default_xxx", true);
+        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MultisampleDemoES2.class, "shader",
+                "shader/bin", "mgl_default_xxx", true);
+        
+        // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
+        int fp0Pos;
+        if(gl.isGLES2()) {
+            vp0.insertShaderSource(0, 0, es2_prelude[0]);
+            fp0Pos = fp0.insertShaderSource(0, 0, es2_prelude[0]);
+        } else {
+            vp0.insertShaderSource(0, 0, gl2_prelude);
+            fp0Pos = fp0.insertShaderSource(0, 0, gl2_prelude);
+        }
+        if(gl.isGLES2()) {
+            fp0Pos = fp0.insertShaderSource(0, fp0Pos, es2_prelude[1]);
+        }        
+        
+        sp0 = new ShaderProgram();
+        sp0.add(gl, vp0, System.err);
+        sp0.add(gl, fp0, System.err);       
+        st.attachShaderProgram(gl, sp0, true);
+        
+        pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+        st.ownUniform(pmvMatrixUniform);       
+        st.uniform(gl, pmvMatrixUniform);
+        
+        // Using predef array names, see 
+        //    GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
+        immModeSink = ImmModeSink.createGLSL(gl, GL.GL_STATIC_DRAW, 40, 
+                                              3, GL.GL_FLOAT,  // vertex
+                                              4, GL.GL_FLOAT,  // color
+                                              0, GL.GL_FLOAT,// normal
+                                              0, GL.GL_FLOAT); // texture
+        final int numSteps = 20;
+        final double increment = Math.PI / numSteps;
+        final double radius = 1;
+        immModeSink.glBegin(GL.GL_LINES);
+        for (int i = numSteps - 1; i >= 0; i--) {
+            immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)), 
+                                   (float) (radius * Math.sin(i * increment)), 
+                                   0f);
+            immModeSink.glColor4f( 1f, 1f, 1f, 1f ); 
+            immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)), 
+                                   (float) (-1.0 * radius * Math.sin(i * increment)), 
+                                   0f);
+            immModeSink.glColor4f( 1f, 1f, 1f, 1f ); 
+        }
+        immModeSink.glEnd(gl, false);
+        
+        st.useProgram(gl, false);
+    }
+
+    public void dispose(GLAutoDrawable glad) {
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        immModeSink.destroy(gl);
+        immModeSink = null;
+        st.destroy(gl);
+    }
+
+    public void display(GLAutoDrawable glad) {
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        if (multisample) {
+            gl.glEnable(GL.GL_MULTISAMPLE);
+        }
+        gl.glClearColor(0, 0, 0, 0);
+        //      gl.glEnable(GL.GL_DEPTH_TEST);
+        //      gl.glDepthFunc(GL.GL_LESS);
+        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+        
+        st.useProgram(gl, true);
+        
+        immModeSink.draw(gl, true);
+        
+        st.useProgram(gl, false);
+    }
+
+    // Unused routines
+    public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
+        System.err.println("reshape ..");
+        final GL2ES2 gl = glad.getGL().getGL2ES2();
+        pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+        pmvMatrix.glLoadIdentity();
+        // pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
+        pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+        pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+        pmvMatrix.glLoadIdentity();
+        
+        st.useProgram(gl, true);
+        st.uniform(gl, pmvMatrixUniform);
+        st.useProgram(gl, false);
+    }
+
+    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index 6982d61b7..436c44759 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -27,9 +27,9 @@
  */
 package com.jogamp.opengl.test.junit.jogl.demos.es2;
 
+import com.jogamp.newt.Window;
 import com.jogamp.newt.event.MouseAdapter;
 import com.jogamp.newt.event.MouseEvent;
-import com.jogamp.newt.opengl.GLWindow;
 import com.jogamp.opengl.util.GLArrayDataServer;
 import com.jogamp.opengl.util.PMVMatrix;
 import com.jogamp.opengl.util.glsl.ShaderCode;
@@ -37,10 +37,8 @@ import com.jogamp.opengl.util.glsl.ShaderProgram;
 import com.jogamp.opengl.util.glsl.ShaderState;
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAnimatorControl;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLRunnable;
 import javax.media.opengl.GLUniformData;
 
 public class RedSquareES2 implements GLEventListener {
@@ -52,10 +50,11 @@ public class RedSquareES2 implements GLEventListener {
     long t0;
     private int swapInterval = 0;
     MyMouseAdapter myMouse = new MyMouseAdapter();
-    GLWindow glWindow = null;
+    Window window = null;
     float aspect = 1.0f;
     boolean doRotate = true;
     boolean isInitialized = false;
+    boolean isFBOSlave = false;
 
     public RedSquareES2(int swapInterval) {
         this.swapInterval = swapInterval;
@@ -65,6 +64,7 @@ public class RedSquareES2 implements GLEventListener {
         this.swapInterval = 1;
     }
         
+    public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
     public void setAspect(float aspect) { this.aspect = aspect; }
     public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
     
@@ -129,13 +129,13 @@ public class RedSquareES2 implements GLEventListener {
         colors.enableBuffer(gl, false);
         
         // OpenGL Render Settings
-        gl.glClearColor(0, 0, 0, 0);
         gl.glEnable(GL2ES2.GL_DEPTH_TEST);
         st.useProgram(gl, false);        
 
-        if (glad instanceof GLWindow) {
-            glWindow = (GLWindow) glad;
-            glWindow.addMouseListener(myMouse);
+        final Object upstreamWidget = glad.getUpstreamWidget();
+        if (!isFBOSlave && upstreamWidget instanceof Window) {
+            window = (Window) upstreamWidget;
+            window.addMouseListener(myMouse);
         }
         t0 = System.currentTimeMillis();
         System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
@@ -145,6 +145,7 @@ public class RedSquareES2 implements GLEventListener {
         long t1 = System.currentTimeMillis();
 
         GL2ES2 gl = glad.getGL().getGL2ES2();
+        gl.glClearColor(0, 0, 0, 0);
         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
         st.useProgram(gl, true);
         // One rotation every four seconds
@@ -171,7 +172,9 @@ public class RedSquareES2 implements GLEventListener {
         System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);        
         GL2ES2 gl = glad.getGL().getGL2ES2();
         
-        gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        if(-1 != swapInterval) {        
+            gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+        }
         
         st.useProgram(gl, true);
         // Set location in front of camera
@@ -192,9 +195,9 @@ public class RedSquareES2 implements GLEventListener {
         }
         isInitialized = false;
         System.err.println(Thread.currentThread()+" RedSquareES2.dispose ... ");
-        if (null != glWindow) {
-            glWindow.removeMouseListener(myMouse);
-            glWindow = null;            
+        if (null != window) {
+            window.removeMouseListener(myMouse);
+            window = null;            
         }
         GL2ES2 gl = glad.getGL().getGL2ES2();
         st.destroy(gl);
@@ -207,24 +210,9 @@ public class RedSquareES2 implements GLEventListener {
     class MyMouseAdapter extends MouseAdapter {
         public void mouseClicked(MouseEvent e) {
             System.err.println(e);
-            if(null != glWindow && e.getSource() == glWindow.getDelegatedWindow()) {
-                if(e.getX() < glWindow.getWidth()/2) {
-                    glWindow.setFullscreen(!glWindow.isFullscreen());
-                    System.err.println("setFullscreen: "+glWindow.isFullscreen());
-                } else { 
-                    glWindow.invoke(false, new GLRunnable() {
-                        public boolean run(GLAutoDrawable drawable) {
-                            GL gl = drawable.getGL();
-                            gl.setSwapInterval(gl.getSwapInterval()<=0?1:0);
-                            System.err.println("setSwapInterval: "+gl.getSwapInterval());
-                            final GLAnimatorControl a = drawable.getAnimator();
-                            if( null != a ) {
-                                a.resetFPSCounter();
-                            }
-                            return true;
-                        }
-                    });
-                }                
+            if(null != window && e.getSource() == window) {
+                window.setFullscreen(!window.isFullscreen());
+                System.err.println("setFullscreen: "+window.isFullscreen());
             }
         }
      }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
index b04bd07c1..9217e2b53 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
@@ -265,11 +265,12 @@ public class TextureSequenceCubeES2 implements GLEventListener {
 
         st.useProgram(gl, false);
 
-        if (drawable instanceof Window) {
-            Window window = (Window) drawable;
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {            
+            final Window window = (Window) upstreamWidget;
             window.addMouseListener(mouseAction);
-        } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
-            java.awt.Component comp = (java.awt.Component) drawable;
+        } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+            final java.awt.Component comp = (java.awt.Component) upstreamWidget;
             new com.jogamp.newt.event.awt.AWTMouseAdapter(mouseAction).addTo(comp);
         }
         
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index 0b83aacd8..7f2713354 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -163,8 +163,9 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
         mPlayer.start();
 
         boolean added;
-        if (drawable instanceof Window) {
-            Window window = (Window) drawable;
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {            
+            final Window window = (Window) upstreamWidget;
             window.addKeyListener(keyAction);
             added = true;
         } else { added = false; }       
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index 8210065ab..e17c9e88b 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -400,8 +400,9 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
         
         startTime = System.currentTimeMillis();
         
-        if (drawable instanceof Window) {
-            Window window = (Window) drawable;
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {            
+            final Window window = (Window) upstreamWidget;
             window.addMouseListener(mouseAction);
             winWidth = window.getWidth();
             winHeight = window.getHeight();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index 04563d62e..797a16485 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -258,7 +258,6 @@ public class TestGearsES2NEWT extends UITestCase {
 
     public static void main(String args[]) throws IOException {        
         int x=0, y=0, w=640, h=480;
-        boolean useSize = false;
         boolean usePos = false;
         
         for(int i=0; i<args.length; i++) {
@@ -291,11 +290,9 @@ public class TestGearsES2NEWT extends UITestCase {
             } else if(args[i].equals("-width")) {
                 i++;
                 w = MiscUtils.atoi(args[i], w);
-                useSize = true;
             } else if(args[i].equals("-height")) {
                 i++;
                 h = MiscUtils.atoi(args[i], h);
-                useSize = true;
             } else if(args[i].equals("-x")) {
                 i++;
                 x = MiscUtils.atoi(args[i], x);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
index 74d52c352..ff231ef91 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java
@@ -54,6 +54,7 @@ public class TestRedSquareES2NEWT extends UITestCase {
     static GLProfile.ShutdownType loop_shutdown = null;
     static boolean vsync = false;
     static boolean forceES2 = false;
+    static boolean doRotate = true;
 
     @BeforeClass
     public static void initClass() {
@@ -72,7 +73,9 @@ public class TestRedSquareES2NEWT extends UITestCase {
         glWindow.setTitle("Gears NEWT Test");
         glWindow.setSize(width, height);
 
-        glWindow.addGLEventListener(new RedSquareES2(vsync ? 1 : -1));
+        final RedSquareES2 demo = new RedSquareES2(vsync ? 1 : -1);
+        demo.setDoRotation(doRotate);
+        glWindow.addGLEventListener(demo);
 
         Animator animator = new Animator(glWindow);
         QuitAdapter quitAdapter = new QuitAdapter();
@@ -143,6 +146,8 @@ public class TestRedSquareES2NEWT extends UITestCase {
                 } catch (Exception ex) { ex.printStackTrace(); }
             } else if(args[i].equals("-es2")) {
                 forceES2 = true;
+            } else if(args[i].equals("-norotate")) {
+                doRotate = false;
             } else if(args[i].equals("-loops")) {
                 i++;
                 loops = MiscUtils.atoi(args[i], 1);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
new file mode 100644
index 000000000..a26dc9737
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.fp
@@ -0,0 +1,10 @@
+// Copyright 2012 JogAmp Community. All rights reserved.
+
+varying  vec4          frontColor;
+
+void main (void)
+{
+  gl_FragColor = frontColor;
+  // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
new file mode 100644
index 000000000..097a73e4c
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/mgl_default_xxx.vp
@@ -0,0 +1,14 @@
+//Copyright 2012 JogAmp Community. All rights reserved.
+
+
+uniform mat4    mgl_PMVMatrix[2]; // P, Mv
+attribute vec4  mgl_Vertex;
+attribute vec4  mgl_Color;
+
+varying   vec4  frontColor;
+
+void main(void)
+{
+  frontColor = mgl_Color;
+  gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
new file mode 100644
index 000000000..d222606cd
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/texture02_xxx.fp
@@ -0,0 +1,20 @@
+// Copyright 2012 JogAmp Community. All rights reserved.
+
+varying  vec2          mgl_texCoord;
+varying  vec4          frontColor;
+
+uniform sampler2D      mgl_Texture0;
+uniform sampler2D      mgl_Texture1;
+
+const vec4 One = vec4(1.0, 1.0, 1.0, 1.0);
+
+void main (void)
+{
+  vec4 texColor0 = texture2D(mgl_Texture0, mgl_texCoord);
+  vec4 texColor1 = texture2D(mgl_Texture1, mgl_texCoord);
+
+  // gl_FragColor = ( ( texColor0 + texColor1 ) / 2.0 ) * frontColor;
+  // gl_FragColor = mix(texColor0, texColor1, One/2.0) * frontColor;
+  gl_FragColor = min(One, mix(texColor0, texColor1, One/2.0) * 1.6) * frontColor;
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
index c09119a32..b3166b03b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/Gears.java
@@ -124,14 +124,15 @@ public class Gears implements GLEventListener {
             
     gl.glEnable(GL2.GL_NORMALIZE);
                 
-    if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
-        java.awt.Component comp = (java.awt.Component) drawable;
-        new AWTMouseAdapter(gearsMouse).addTo(comp);
-        new AWTKeyAdapter(gearsKeys).addTo(comp);    
-    } else if (drawable.getNativeSurface() instanceof Window) {
-        Window window = (Window) drawable.getNativeSurface();
+    final Object upstreamWidget = drawable.getUpstreamWidget();
+    if (upstreamWidget instanceof Window) {            
+        final Window window = (Window) upstreamWidget;
         window.addMouseListener(gearsMouse);
         window.addKeyListener(gearsKeys);
+    } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+        final java.awt.Component comp = (java.awt.Component) upstreamWidget;
+        new AWTMouseAdapter(gearsMouse).addTo(comp);
+        new AWTKeyAdapter(gearsKeys).addTo(comp);    
     }
   }
     
@@ -159,8 +160,9 @@ public class Gears implements GLEventListener {
   public void dispose(GLAutoDrawable drawable) {
     System.err.println("Gears: Dispose");
     try {
-        if (drawable.getNativeSurface() instanceof Window) {
-            Window window = (Window) drawable.getNativeSurface();
+        final Object upstreamWidget = drawable.getUpstreamWidget();
+        if (upstreamWidget instanceof Window) {            
+            final Window window = (Window) upstreamWidget;
             window.removeMouseListener(gearsMouse);
             window.removeKeyListener(gearsKeys);
         }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
new file mode 100644
index 000000000..4f97feb4f
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ * 
+ *    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 com.jogamp.opengl.test.junit.jogl.demos.gl2.awt;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.FPSAnimator;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+import javax.media.opengl.awt.GLJPanel;
+import javax.media.opengl.glu.gl2.GLUgl2;
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+/**
+ * Test for bug 450, which causes the right part of the frame to be black
+ * for all x >= height.
+ * 
+ * Draws the Gears demo in a window that's twice as wide than it is tall,
+ * and checks to see if a particular pixel in the right half of the frame
+ * is colored.
+ *
+ * @author Wade Walker (adapted from TestGearsGLJPanelAWT)
+ */
+public class TestGLJPanelAWTBug450 extends UITestCase {
+    static GLProfile glp;
+    static int width, height;
+    static int r_x, r_y;
+    /** Set this if test fails. Needed because we can't throw an exception
+     * all the way up the stack from where we test the pixel. */
+    static boolean failed;
+
+    @BeforeClass
+    public static void initClass() {
+        glp = GLProfile.getGL2ES2();
+        Assert.assertNotNull(glp);
+        height = 256;
+        width  = 2*height;
+        r_x    = 5*height/4; // 5/8 * width
+        r_y    =   height/2;
+    }
+
+    @AfterClass
+    public static void releaseClass() {
+    }
+
+    protected void runTestGL(GLCapabilities caps)
+            throws AWTException, InterruptedException, InvocationTargetException
+    {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+        JFrame frame = new JFrame("Swing GLJPanel");
+        Assert.assertNotNull(frame);
+
+        GLJPanel glJPanel = new GLJPanel(caps);
+        Assert.assertNotNull(glJPanel);
+        RedSquareES2 demo = new RedSquareES2();
+        demo.setAspect((float)width/(float)height);
+        demo.setDoRotation(false);
+        glJPanel.addGLEventListener(demo);
+        glJPanel.addGLEventListener(new GLEventListener() {
+            int f = 0;
+            @Override
+            public void init(GLAutoDrawable drawable) {
+                // drawable.getGL().glClearColor(0, 0, 1, 1);                
+            }
+            @Override
+            public void display(GLAutoDrawable drawable) {
+                // look at one pixel at the bottom of the frame, just right of
+                // the center line, and make sure it's not black
+                GL2 gl = GLUgl2.getCurrentGL2();
+                ByteBuffer bytebuffer = ByteBuffer.allocateDirect( 3 );
+                gl.glReadPixels( r_x, r_y, 1, 1, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, bytebuffer );
+                byte byte0 = bytebuffer.get( 0 );
+                byte byte1 = bytebuffer.get( 1 );
+                byte byte2 = bytebuffer.get( 2 );
+                if( (byte0 == 0) && (byte1 == 0) && (byte2 == 0) ) {
+                    failed = true;
+                }
+                if(0 == f) {
+                    System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
+                    snapshot(getSimpleTestName("."), f, null, gl, screenshot, TextureIO.PNG, null);
+                }
+                f++;
+            }
+            @Override
+            public void dispose(GLAutoDrawable drawable) {}
+            @Override
+            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+        });
+
+        FPSAnimator animator = new FPSAnimator(glJPanel, 60);
+
+        final JFrame _frame = frame;
+        final GLJPanel _glJPanel = glJPanel;
+        SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    _frame.getContentPane().add(_glJPanel, BorderLayout.CENTER);
+                    _frame.setSize(width, height);
+                    _frame.setVisible(true);
+                } } ) ;
+
+        animator.setUpdateFPSFrames(1, null);        
+        animator.start();
+        Assert.assertEquals(true, animator.isAnimating());
+
+        while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+            Thread.sleep(100);
+        }
+
+        Assert.assertNotNull(frame);
+        Assert.assertNotNull(glJPanel);
+        Assert.assertNotNull(animator);
+
+        animator.stop();
+        Assert.assertEquals(false, animator.isAnimating());
+        SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    _frame.setVisible(false);
+                    _frame.getContentPane().remove(_glJPanel);
+                    _frame.remove(_glJPanel);
+                    _glJPanel.destroy();
+                    _frame.dispose();
+                } } );
+
+        Assert.assertFalse( failed );
+    }
+
+    @Test
+    public void test01()
+            throws AWTException, InterruptedException, InvocationTargetException
+    {
+        GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
+        runTestGL(caps);
+    }
+
+    static long duration = 500; // ms
+
+    public static void main(String args[]) {
+        for(int i=0; i<args.length; i++) {
+            if(args[i].equals("-time")) {
+                i++;
+                try {
+                    duration = Integer.parseInt(args[i]);
+                } catch (Exception ex) { ex.printStackTrace(); }
+            }
+        }
+        org.junit.runner.JUnitCore.main(TestGLJPanelAWTBug450.class.getName());
+    }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsGLJPanelAWTBug450.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsGLJPanelAWTBug450.java
deleted file mode 100644
index e3f33e301..000000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsGLJPanelAWTBug450.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- * 
- *    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 com.jogamp.opengl.test.junit.jogl.demos.gl2.awt;
-
-import javax.media.opengl.*;
-
-import com.jogamp.opengl.util.FPSAnimator;
-import com.jogamp.opengl.util.GLReadBufferUtil;
-
-import javax.media.opengl.awt.GLJPanel;
-import javax.media.opengl.glu.gl2.GLUgl2;
-
-import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-import java.awt.AWTException;
-import java.awt.BorderLayout;
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.ByteBuffer;
-
-import javax.swing.JFrame;
-import javax.swing.SwingUtilities;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.AfterClass;
-import org.junit.Test;
-
-/**
- * Test for bug 450, which causes the right part of the frame to be black
- * for all x >= height.
- * 
- * Draws the Gears demo in a window that's twice as wide than it is tall,
- * and checks to see if a particular pixel in the right half of the frame
- * is colored.
- *
- * @author Wade Walker (adapted from TestGearsGLJPanelAWT)
- */
-public class TestGearsGLJPanelAWTBug450 extends UITestCase {
-    static GLProfile glp;
-    static int width, height;
-    static int r_x, r_y;
-    /** Set this if test fails. Needed because we can't throw an exception
-     * all the way up the stack from where we test the pixel. */
-    static boolean failed;
-
-    @BeforeClass
-    public static void initClass() {
-        glp = GLProfile.getGL2ES2();
-        Assert.assertNotNull(glp);
-        height = 256;
-        width  = 2*height;
-        r_x    = 5*height/4; // 5/8 * width
-        r_y    =   height/2;
-    }
-
-    @AfterClass
-    public static void releaseClass() {
-    }
-
-    protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
-        GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
-        if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
-            screenshot.write(new File(filename));
-        }                
-    }
-    
-    protected void runTestGL(GLCapabilities caps)
-            throws AWTException, InterruptedException, InvocationTargetException
-    {
-        JFrame frame = new JFrame("Swing GLJPanel");
-        Assert.assertNotNull(frame);
-
-        GLJPanel glJPanel = new GLJPanel(caps);
-        Assert.assertNotNull(glJPanel);
-        RedSquareES2 demo = new RedSquareES2();
-        demo.setAspect((float)width/(float)height);
-        demo.setDoRotation(false);
-        glJPanel.addGLEventListener(demo);
-        glJPanel.addGLEventListener(new GLEventListener() {
-            int f = 0;
-            @Override
-            public void init(GLAutoDrawable drawable) {
-                // drawable.getGL().glClearColor(0, 0, 1, 1);                
-            }
-            @Override
-            public void display(GLAutoDrawable drawable) {
-                // look at one pixel at the bottom of the frame, just right of
-                // the center line, and make sure it's not black
-                GL2 gl = GLUgl2.getCurrentGL2();
-                ByteBuffer bytebuffer = ByteBuffer.allocateDirect( 3 );
-                gl.glReadPixels( r_x, r_y, 1, 1, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, bytebuffer );
-                byte byte0 = bytebuffer.get( 0 );
-                byte byte1 = bytebuffer.get( 1 );
-                byte byte2 = bytebuffer.get( 2 );
-                if( (byte0 == 0) && (byte1 == 0) && (byte2 == 0) ) {
-                    failed = true;
-                }
-                if(0 == f) {
-                    System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
-                    snapshot(drawable, true,  false, getSimpleTestName(".")+".png");
-                }
-                f++;
-            }
-            @Override
-            public void dispose(GLAutoDrawable drawable) {}
-            @Override
-            public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
-        });
-
-        FPSAnimator animator = new FPSAnimator(glJPanel, 60);
-
-        final JFrame _frame = frame;
-        final GLJPanel _glJPanel = glJPanel;
-        SwingUtilities.invokeAndWait(new Runnable() {
-                public void run() {
-                    _frame.getContentPane().add(_glJPanel, BorderLayout.CENTER);
-                    _frame.setSize(width, height);
-                    _frame.setVisible(true);
-                } } ) ;
-
-        animator.setUpdateFPSFrames(1, null);        
-        animator.start();
-        Assert.assertEquals(true, animator.isAnimating());
-
-        while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
-            Thread.sleep(100);
-        }
-
-        Assert.assertNotNull(frame);
-        Assert.assertNotNull(glJPanel);
-        Assert.assertNotNull(animator);
-
-        animator.stop();
-        Assert.assertEquals(false, animator.isAnimating());
-        SwingUtilities.invokeAndWait(new Runnable() {
-                public void run() {
-                    _frame.setVisible(false);
-                    _frame.getContentPane().remove(_glJPanel);
-                    _frame.remove(_glJPanel);
-                    _glJPanel.destroy();
-                    _frame.dispose();
-                } } );
-
-        Assert.assertFalse( failed );
-    }
-
-    @Test
-    public void test01()
-            throws AWTException, InterruptedException, InvocationTargetException
-    {
-        GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
-        runTestGL(caps);
-    }
-
-    static long duration = 500; // ms
-
-    public static void main(String args[]) {
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-time")) {
-                i++;
-                try {
-                    duration = Integer.parseInt(args[i]);
-                } catch (Exception ex) { ex.printStackTrace(); }
-            }
-        }
-        org.junit.runner.JUnitCore.main(TestGearsGLJPanelAWTBug450.class.getName());
-    }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java
deleted file mode 100644
index 1b33866d7..000000000
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * Copyright 2010 JogAmp Community. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- *    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 com.jogamp.opengl.test.junit.jogl.glsl;
-
-import com.jogamp.opengl.util.FBObject;
-import com.jogamp.opengl.util.GLArrayDataServer;
-import com.jogamp.opengl.util.PMVMatrix;
-import com.jogamp.opengl.util.glsl.ShaderCode;
-import com.jogamp.opengl.util.glsl.ShaderProgram;
-import com.jogamp.opengl.util.glsl.ShaderState;
-import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
-import com.jogamp.opengl.test.junit.util.MiscUtils;
-import com.jogamp.opengl.test.junit.util.NEWTGLContext;
-import com.jogamp.opengl.test.junit.util.UITestCase;
-
-import java.io.IOException;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GL2GL3;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLPipelineFactory;
-import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLUniformData;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestFBOMRTNEWT01 extends UITestCase {
-    static long durationPerTest = 10; // ms
-
-    @Test
-    public void test01() throws InterruptedException {
-        // preset ..
-        if(!GLProfile.isAvailable(GLProfile.GL2GL3)) {
-            System.err.println("Test requires GL2/GL3 profile.");
-            return;
-        }
-        final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(
-                new GLCapabilities(GLProfile.getGL2GL3()), 640, 480, true);        
-        final GLDrawable drawable = winctx.context.getGLDrawable();
-        GL2GL3 gl = winctx.context.getGL().getGL2GL3();
-        gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
-        System.err.println(winctx.context);
-
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        // test code ..        
-        final ShaderState st = new ShaderState();
-        // st.setVerbose(true);
-        
-        final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "fbo-mrt-1", false);
-        final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "fbo-mrt-1", false);
-        final ShaderProgram sp0 = new ShaderProgram();
-        sp0.add(gl, vp0, System.err);
-        sp0.add(gl, fp0, System.err);       
-        Assert.assertTrue(0<=sp0.program()); 
-        Assert.assertTrue(!sp0.inUse());
-        Assert.assertTrue(!sp0.linked());
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
-        st.attachShaderProgram(gl, sp0, false);
-        
-        final ShaderCode vp1 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "fbo-mrt-2", false);
-        final ShaderCode fp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
-                "shader/bin", "fbo-mrt-2", false);
-        final ShaderProgram sp1 = new ShaderProgram();
-        sp1.add(gl, vp1, System.err);
-        sp1.add(gl, fp1, System.err);       
-        Assert.assertTrue(0<=sp1.program()); 
-        Assert.assertTrue(!sp1.inUse());
-        Assert.assertTrue(!sp1.linked());
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());        
-        st.attachShaderProgram(gl, sp1, true);
-                        
-        final PMVMatrix pmvMatrix = new PMVMatrix();
-        final GLUniformData pmvMatrixUniform = new GLUniformData("gcu_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        st.ownUniform(pmvMatrixUniform);       
-        st.uniform(gl, pmvMatrixUniform);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        
-        final GLArrayDataServer vertices0 = GLArrayDataServer.createGLSL("gca_Vertices", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
-        // st.bindAttribLocation(gl, 0, vertices0);
-        vertices0.putf(0); vertices0.putf(1);  vertices0.putf(0);
-        vertices0.putf(1);  vertices0.putf(1);  vertices0.putf(0);
-        vertices0.putf(0); vertices0.putf(0); vertices0.putf(0);
-        vertices0.putf(1);  vertices0.putf(0); vertices0.putf(0);
-        vertices0.seal(gl, true);
-        st.ownAttribute(vertices0, true);
-        vertices0.enableBuffer(gl, false);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        
-        final GLArrayDataServer colors0 = GLArrayDataServer.createGLSL("gca_Colors", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
-        // st.bindAttribLocation(gl, 1, colors0);
-        colors0.putf(1); colors0.putf(0);  colors0.putf(1); colors0.putf(1);
-        colors0.putf(0);  colors0.putf(0);  colors0.putf(1); colors0.putf(1);
-        colors0.putf(0); colors0.putf(0); colors0.putf(0); colors0.putf(1);
-        colors0.putf(0);  colors0.putf(1); colors0.putf(1); colors0.putf(1);
-        colors0.seal(gl, true);
-        st.ownAttribute(colors0, true);
-        colors0.enableBuffer(gl, false);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        
-        final GLUniformData texUnit0 = new GLUniformData("gcs_TexUnit0", 0);
-        st.ownUniform(texUnit0);       
-        st.uniform(gl, texUnit0);
-        final GLUniformData texUnit1 = new GLUniformData("gcs_TexUnit1", 1);
-        st.ownUniform(texUnit1);       
-        st.uniform(gl, texUnit1);
-                
-        final GLArrayDataServer texCoords0 = GLArrayDataServer.createGLSL("gca_TexCoords", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
-        // st.bindAttribLocation(gl, 2, texCoords0);
-        texCoords0.putf(0f); texCoords0.putf(1f);
-        texCoords0.putf(1f);  texCoords0.putf(1f);
-        texCoords0.putf(0f); texCoords0.putf(0f);
-        texCoords0.putf(1f);  texCoords0.putf(0f);        
-        texCoords0.seal(gl, true);
-        st.ownAttribute(texCoords0, true);
-        texCoords0.enableBuffer(gl, false);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-
-        // FBO w/ 2 texture2D color buffers
-        final FBObject fbo_mrt = new FBObject(drawable.getWidth(), drawable.getHeight());
-        fbo_mrt.init(gl);
-        Assert.assertTrue( 0 == fbo_mrt.attachTexture2D(gl, texUnit0.intValue(), GL.GL_NEAREST, GL.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE) );
-        Assert.assertTrue( 1 == fbo_mrt.attachTexture2D(gl, texUnit1.intValue(), GL.GL_NEAREST, GL.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE) );
-        Assert.assertTrue( fbo_mrt.attachDepthBuffer(gl, GL.GL_DEPTH_COMPONENT16) );
-        Assert.assertTrue( fbo_mrt.isStatusValid() ) ;
-        fbo_mrt.unbind(gl);
-        
-        // misc GL setup
-        gl.glClearColor(1, 1, 1, 1);
-        gl.glEnable(GL2ES2.GL_DEPTH_TEST);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-
-        // reshape
-        pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
-        pmvMatrix.glLoadIdentity();
-        pmvMatrix.glOrthof(0f, 1f, 0f, 1f, -10f, 10f);
-        pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
-        pmvMatrix.glLoadIdentity();
-        st.uniform(gl, pmvMatrixUniform);
-        Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
-        
-        final int[] two_buffers = new int[] { GL.GL_COLOR_ATTACHMENT0, GL.GL_COLOR_ATTACHMENT0+1 };
-        final int[] bck_buffers = new int[] { GL2GL3.GL_BACK_LEFT };
-        
-        for(int i=0; i<durationPerTest; i+=50) {
-            // pass 1 - MRT: Red -> buffer0, Green -> buffer1
-            st.attachShaderProgram(gl, sp0, true);           
-            vertices0.enableBuffer(gl, true);
-            colors0.enableBuffer(gl, true);
-            
-            fbo_mrt.bind(gl);
-            gl.glDrawBuffers(2, two_buffers, 0);
-            gl.glViewport(0, 0, fbo_mrt.getWidth(), fbo_mrt.getHeight());        
-            
-            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-            gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
-            fbo_mrt.unbind(gl);
-            vertices0.enableBuffer(gl, false);
-            colors0.enableBuffer(gl, false);
-            
-            // pass 2 - mix buffer0, buffer1 and blue
-            // rg = buffer0.rg + buffer1.rg, b = Blue - length(rg);
-            st.attachShaderProgram(gl, sp1, true);
-            vertices0.enableBuffer(gl, true);
-            colors0.enableBuffer(gl, true);
-            texCoords0.enableBuffer(gl, true);
-            gl.glDrawBuffers(1, bck_buffers, 0);
-            
-            gl.glViewport(0, 0, drawable.getWidth(), drawable.getHeight());
-            fbo_mrt.use(gl, 0);
-            fbo_mrt.use(gl, 1);
-            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-            gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
-            fbo_mrt.unuse(gl);
-            vertices0.enableBuffer(gl, false);
-            colors0.enableBuffer(gl, false);
-            texCoords0.enableBuffer(gl, false);
-            
-            drawable.swapBuffers();
-            Thread.sleep(50);
-        }
-        
-        NEWTGLContext.destroyWindow(winctx);
-    }
-    
-    public static void main(String args[]) throws IOException {
-        System.err.println("main - start");
-        for(int i=0; i<args.length; i++) {
-            if(args[i].equals("-time")) {
-                durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
-            }
-        }
-        String tstname = TestFBOMRTNEWT01.class.getName();
-        org.junit.runner.JUnitCore.main(tstname);
-        System.err.println("main - end");
-    }    
-}
-
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
index 881399ddb..987dedc65 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
@@ -47,7 +47,6 @@ import javax.media.opengl.GLUniformData;
 
 import org.junit.Assert;
 import org.junit.Test;
-import org.junit.BeforeClass;
 
 /**
  * Testing different vertex attribute (VA) data sets on one shader
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
index 6421c2405..91dcfc3c3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
@@ -47,7 +47,6 @@ import javax.media.opengl.GLUniformData;
 
 import org.junit.Assert;
 import org.junit.Test;
-import org.junit.BeforeClass;
 
 /**
  * Testing different vertex attribute (VA) data sets on one shader
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
index e3ca25ae6..4ef7b2719 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java
@@ -85,9 +85,7 @@ public class ReadBufferBase implements GLEventListener {
     }
 
     public void display(GLAutoDrawable drawable) {
-        GL gl = drawable.getGL();
-
-        readBufferUtil.readPixels(gl, drawable, false);
+        readBufferUtil.readPixels(drawable.getGL(), false);
     }
 
 }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java
index b046df6af..974e32289 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java
@@ -64,7 +64,7 @@ public class Surface2File implements SurfaceUpdatedListener {
                 GL gl = ctx.getGL();
                 // FIXME glFinish() is an expensive paranoia sync, should not be necessary due to spec
                 gl.glFinish();
-                if(readBufferUtil.readPixels(gl, drawable, false)) {
+                if(readBufferUtil.readPixels(gl, false)) {
                     gl.glFinish();
                     try {
                         surface2File();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor02GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor02GLn.java
index 2121205e2..6100ff377 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor02GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAccessor02GLn.java
@@ -34,6 +34,8 @@ import javax.media.opengl.GLDrawableFactory;
 import javax.media.opengl.GLProfile;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.graphics.Rectangle;
@@ -146,9 +148,9 @@ public class TestSWTAccessor02GLn extends UITestCase {
         System.err.println("*** device: " + device);
         System.err.println("*** window handle: 0x" + Long.toHexString(nativeWindowHandle));
         
-        ProxySurface proxySurface = factory.createProxySurface(device, nativeWindowHandle, caps, null);
+        final SWTUpstreamHook swtUpstreamHook = new SWTUpstreamHook(canvas);
+        final ProxySurface proxySurface = factory.createProxySurface(device, 0, nativeWindowHandle, caps, null, swtUpstreamHook);
         Assert.assertNotNull( proxySurface );        
-        proxySurface.surfaceSizeChanged( 640, 480 );
         System.err.println("*** ProxySurface: " + proxySurface);
         final GLDrawable drawable = factory.createGLDrawable(proxySurface);
         Assert.assertNotNull( drawable );
@@ -221,6 +223,41 @@ public class TestSWTAccessor02GLn extends UITestCase {
         drawable.setRealized(false);
         canvas.dispose();
     }
+    private static class SWTUpstreamHook implements ProxySurface.UpstreamSurfaceHook, ControlListener {
+        private Canvas c;
+        Rectangle clientArea;
+        public SWTUpstreamHook(Canvas c) {
+            this.c = c ;
+            this.clientArea = c.getClientArea();
+        }
+        @Override
+        public final void create(ProxySurface s) { /* nop */ }
+    
+        @Override
+        public final void destroy(ProxySurface s) { /* nop */ }
+    
+        @Override
+        public final int getWidth(ProxySurface s) {
+            return clientArea.width;
+        }    
+        @Override
+        public final int getHeight(ProxySurface s) {
+            return clientArea.width;
+        }
+        
+        @Override
+        public void controlResized(final ControlEvent arg0) {
+            clientArea = c.getClientArea();
+        }
+        @Override
+        public void controlMoved(ControlEvent e) {
+        }
+        @Override
+        public String toString() {
+            final String us_s = null != c ? c.toString() : "nil"; 
+            return "SETUpstreamSurfaceHook[upstream: "+us_s+"]";
+    }
+    };
 
     @Test
     public void test() throws InterruptedException {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
index f79a73040..6cee319ba 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01AWT.java
@@ -30,7 +30,6 @@ package com.jogamp.opengl.test.junit.jogl.util.texture;
 
 import java.awt.Dimension;
 import java.awt.Frame;
-import java.io.File;
 
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
@@ -42,6 +41,7 @@ import jogamp.nativewindow.jawt.JAWTUtil;
 
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -68,14 +68,10 @@ public class TestGLReadBufferUtilTextureIOWrite01AWT extends UITestCase {
         height = 256;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
-        GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
-        if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
-            screenshot.write(new File(filename));
-        }                
-    }
-    
     protected void testWritePNG_Impl(boolean offscreenLayer) throws InterruptedException {
+        final GLReadBufferUtil screenshotRGB = new GLReadBufferUtil(false, false);
+        final GLReadBufferUtil screenshotRGBA = new GLReadBufferUtil(true, false);
+        
         if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
             System.err.println("onscreen layer n/a");
             return;
@@ -96,12 +92,13 @@ public class TestGLReadBufferUtilTextureIOWrite01AWT extends UITestCase {
         glc.setSize(width, height);
         glc.addGLEventListener(new GearsES2(1));
         glc.addGLEventListener(new GLEventListener() {
+            int f = 0;
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
-                snapshot(drawable, true,  false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
-                snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
+                snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(getSimpleTestName("."), f, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+                f++;
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
         });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
index b5b12035d..5681df0ad 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
@@ -28,8 +28,6 @@
  
 package com.jogamp.opengl.test.junit.jogl.util.texture;
 
-import java.io.File;
-
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.opengl.GLAutoDrawable;
@@ -37,6 +35,7 @@ import javax.media.opengl.GLCapabilities;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLProfile;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -62,32 +61,26 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
         height = 256;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
-        GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
-        if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
-            screenshot.write(new File(filename));
-        }                
-    }
-    
     @Test
     public void testOnscreenWritePNG_TGA_PAM() throws InterruptedException {
+        final GLReadBufferUtil screenshotRGB = new GLReadBufferUtil(false, false);
+        final GLReadBufferUtil screenshotRGBA = new GLReadBufferUtil(true, false);
         GLWindow glWindow = GLWindow.create(caps);
         Assert.assertNotNull(glWindow);
         glWindow.setTitle("Shared Gears NEWT Test");
         glWindow.setSize(width, height);
         glWindow.addGLEventListener(new GearsES2(1));
         glWindow.addGLEventListener(new GLEventListener() {
+            int f = 0;
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
-                // snapshot(drawable, false, true,  getSimpleTestName(".")+"-rgb_-"+drawable.getGLProfile().getName()+".ppm");
-                snapshot(drawable, true,  false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
-                snapshot(drawable, true,  false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".tga");
-                snapshot(drawable, true,  true,  getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".pam");
-                snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
-                snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".tga");
-                snapshot(drawable, false, true,  getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".pam");
+                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);                
+                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
+                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.TGA, null);                
+                snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
+                snapshot(getSimpleTestName("."), f++, null,  drawable.getGL(), screenshotRGB, TextureIO.PAM, null);                
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
         });
@@ -98,18 +91,21 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
 
     @Test
     public void testOffscreenWritePNG() throws InterruptedException {
+        final GLReadBufferUtil screenshotRGB = new GLReadBufferUtil(false, false);
+        final GLReadBufferUtil screenshotRGBA = new GLReadBufferUtil(true, false);
         final GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);        
         GLWindow glWindow = GLWindow.create(caps2);
         Assert.assertNotNull(glWindow);
         glWindow.setSize(width, height);
         glWindow.addGLEventListener(new GearsES2(1));
         glWindow.addGLEventListener(new GLEventListener() {
+            int f = 0;
             public void init(GLAutoDrawable drawable) {}
             public void dispose(GLAutoDrawable drawable) {}
             public void display(GLAutoDrawable drawable) {
-                final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
-                snapshot(drawable, true,  false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
-                snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
+                snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+                snapshot(getSimpleTestName("."), f, null,  drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+                f++;
             }
             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
         });
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
index 10dd4ea70..43641fe6d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
@@ -30,9 +30,6 @@ package com.jogamp.opengl.test.junit.jogl.util.texture;
 
 import java.awt.Dimension;
 import java.awt.Frame;
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.GLCapabilities;
@@ -45,6 +42,7 @@ import jogamp.nativewindow.jawt.JAWTUtil;
 
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
 import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -71,20 +69,6 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
         height = 64;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, GLReadBufferUtil screenshot, int i) {
-        final StringWriter filename = new StringWriter();
-        {
-            final PrintWriter pw = new PrintWriter(filename);
-            final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
-            pw.printf("%s-F_rgba-I_%s-%s-n%03d-%04dx%04d.png", 
-                    getSimpleTestName("."), pfmt, drawable.getGLProfile().getName(), i, drawable.getWidth(), drawable.getHeight());
-        }
-        drawable.getGL().glFinish(); // poor mans sync ..
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
-            screenshot.write(new File(filename.toString()));
-        }                
-    }
-    
     protected void testWritePNGWithResizeImpl(boolean offscreenLayer) throws InterruptedException {
         if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
             System.err.println("onscreen layer n/a");
@@ -127,7 +111,7 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
                 if(snap) {
                     System.err.println("XXX: ["+fw_old+", "+dw_old+"], "+fw+"x"+fh+", "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
                     c=0;
-                    snapshot(drawable, screenshot, i++);
+                    snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                     dw_old = dw;
                     fw_old = fw;
                     Threading.invoke(true, new Runnable() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
index ed0791f7c..d1ffa84cf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
@@ -28,10 +28,6 @@
  
 package com.jogamp.opengl.test.junit.jogl.util.texture;
 
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
 import com.jogamp.newt.opengl.GLWindow;
 
 import javax.media.opengl.GLAutoDrawable;
@@ -41,6 +37,7 @@ import javax.media.opengl.GLProfile;
 
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import com.jogamp.opengl.test.junit.util.UITestCase;
 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -66,19 +63,6 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
         height = 64;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, GLReadBufferUtil screenshot, int i) {
-        final StringWriter filename = new StringWriter();
-        {
-            final PrintWriter pw = new PrintWriter(filename);
-            final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
-            pw.printf("%s-F_rgba-I_%s-%s-n%03d-%04dx%04d.png", 
-                    getSimpleTestName("."), pfmt, drawable.getGLProfile().getName(), i, drawable.getWidth(), drawable.getHeight());
-        }
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
-            screenshot.write(new File(filename.toString()));
-        }                
-    }
-    
     private void testWritePNGWithResizeImpl(boolean offscreen) throws InterruptedException {
         final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
         final GLCapabilities caps2 = offscreen ? WindowUtilNEWT.fixCaps(caps, false, true, false) : caps;
@@ -110,7 +94,7 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
                 if(snap) {
                     System.err.println("XXX: ["+dw_old+"], "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
                     c=0;
-                    snapshot(drawable, screenshot, i++);
+                    snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                     dw_old = dw;
                     new Thread() { 
                         @Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
index 068732696..0d4f2b01e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
@@ -52,7 +52,6 @@ import com.jogamp.opengl.util.GLReadBufferUtil;
 import java.awt.Dimension;
 import java.awt.Frame;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLConnection;
@@ -96,16 +95,10 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
         testTextureStream = null;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, String filename) {
-        GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
-            screenshot.write(new File(filename));
-        }                
-    }
-    
     public void testImpl(boolean useFFP, final InputStream istream, final boolean useAWTIIOP) 
             throws InterruptedException, IOException 
     {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
         GLProfile glp;
         if(useFFP && GLProfile.isAvailable(GLProfile.GL2GL3)) {
             glp = GLProfile.getGL2GL3();
@@ -137,7 +130,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
         // the bug submitter was doing it
         final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
         glc.addGLEventListener(gle);
-        glc.addGLEventListener(new GLEventListener() {
+        glc.addGLEventListener(new GLEventListener() {            
             boolean shot = false;
             
             @Override public void init(GLAutoDrawable drawable) {}
@@ -147,7 +140,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
                 // 1 snapshot
                 if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
                     shot = true;
-                    snapshot(drawable, getSimpleTestName(".")+".png");                            
+                    snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                 }
             }
 
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index d973dea2d..b4faafbe7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -48,7 +48,6 @@ import com.jogamp.opengl.util.texture.TextureIO;
 import com.jogamp.opengl.util.Animator;
 import com.jogamp.opengl.util.GLReadBufferUtil;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLConnection;
@@ -80,14 +79,8 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
         testTextureStream = null;
     }
 
-    protected void snapshot(GLAutoDrawable drawable, String filename) {
-        GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
-        if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
-            screenshot.write(new File(filename));
-        }                
-    }
-    
     public void testImpl(boolean useFFP, final InputStream istream) throws InterruptedException, IOException {
+        final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
         GLProfile glp;
         if(useFFP && GLProfile.isAvailable(GLProfile.GL2GL3)) {
             glp = GLProfile.getGL2GL3();
@@ -119,7 +112,7 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
                 // 1 snapshot
                 if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
                     shot = true;
-                    snapshot(drawable, getSimpleTestName(".")+".png");                            
+                    snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
                 }
             }
             
diff --git a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
index 672675fab..c07d5b741 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
@@ -28,7 +28,17 @@
  
 package com.jogamp.opengl.test.junit.util;
 
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawable;
+
 import com.jogamp.common.util.locks.SingletonInstance;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
 
 import org.junit.Assume;
 import org.junit.Before;
@@ -108,6 +118,49 @@ public abstract class UITestCase {
     }
     
     static final String unsupportedTestMsg = "Test not supported on this platform.";
-
+    
+    /**
+     * Takes a snapshot of the drawable's current framebuffer. Example filenames: 
+     * <pre>
+     * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png
+     * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png
+     * </pre>
+     * 
+     * @param simpleTestName will be used as the filename prefix
+     * @param sn sequential number 
+     * @param postSNDetail optional detail to be added to the filename after <code>sn</code>
+     * @param gl the current GL context object. It's read drawable is being used as the pixel source and to gather some details which will end up in the filename.
+     * @param readBufferUtil the {@link GLReadBufferUtil} to be used to read the pixels for the screenshot.
+     * @param fileSuffix Optional file suffix without a <i>dot</i> defining the file type, i.e. <code>"png"</code>.
+     *                   If <code>null</code> the <code>"png"</code> as defined in {@link TextureIO#PNG} is being used.
+     * @param destPath Optional platform dependent file path. It shall use {@link File#separatorChar} as is directory separator.
+     *                 It shall not end with a directory separator, {@link File#separatorChar}.
+     *                 If <code>null</code> the current working directory is being used.  
+     */
+    public static void snapshot(String simpleTestName, int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
+        if(null == fileSuffix) {
+            fileSuffix = TextureIO.PNG;
+        }
+        final StringWriter filenameSW = new StringWriter();
+        {
+            final GLDrawable drawable = gl.getContext().getGLReadDrawable();
+            final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+            final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_";
+            final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
+            final String aaext = caps.getSampleExtension();
+            final int samples = caps.getNumSamples() ;
+            postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
+            final PrintWriter pw = new PrintWriter(filenameSW);
+            pw.printf("%s-n%04d%s-F_%s-I_%s-S%d_%s-%s-%04dx%04d.%s", 
+                    simpleTestName, sn, postSNDetail, F_pfmt, pfmt, samples, aaext, drawable.getGLProfile().getName(), 
+                    drawable.getWidth(), drawable.getHeight(), fileSuffix);
+        }
+        final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
+        System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
+        gl.glFinish(); // just make sure rendering finished ..
+        if(readBufferUtil.readPixels(gl, false)) {
+            readBufferUtil.write(new File(filename));
+        }                
+    }    
 }
 
-- 
cgit v1.2.3