aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/egl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-07-19 21:15:10 +0200
committerSven Gothel <[email protected]>2012-07-19 21:15:10 +0200
commit20bf031db719f7baa4c6e74734fc999061e08fe2 (patch)
treea5957e2bb4a75ac28513f430bf458a65bf866fe0 /src/jogl/classes/jogamp/opengl/egl
parent3988e3d7df9b80e9b7058f64758b34a5389f38b0 (diff)
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
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/egl')
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java76
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java27
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java214
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java307
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java65
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java34
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java56
9 files changed, 505 insertions, 280 deletions
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+"]";
+ }
+
+}