diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/egl')
14 files changed, 2107 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java new file mode 100644 index 000000000..107d7fbbb --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.gluegen.runtime.ProcAddressTable; +import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; +import java.nio.*; +import java.util.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; + +public abstract class EGLContext extends GLContextImpl { + private boolean eglQueryStringInitialized; + private boolean eglQueryStringAvailable; + private EGLExt eglExt; + // Table that holds the addresses of the native C-language entry points for + // EGL extension functions. + private EGLExtProcAddressTable eglExtProcAddressTable; + + EGLContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + public Object getPlatformGLExtensions() { + return getEGLExt(); + } + + public EGLExt getEGLExt() { + if (eglExt == null) { + eglExt = new EGLExtImpl(this); + } + return eglExt; + } + + public final ProcAddressTable getPlatformExtProcAddressTable() { + return eglExtProcAddressTable; + } + + public final EGLExtProcAddressTable getEGLExtProcAddressTable() { + return eglExtProcAddressTable; + } + + protected Map/*<String, String>*/ getFunctionNameMap() { return null; } + + protected Map/*<String, String>*/ getExtensionNameMap() { return null; } + + public final boolean isGLReadDrawableAvailable() { + return true; + } + + protected void makeCurrentImpl(boolean newCreated) 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)) { + throw new GLException("Error making context 0x" + + Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); + } + } + } + + protected void releaseImpl() throws GLException { + if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), + 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 " + EGL.eglGetError()); + } + } + + protected void destroyImpl() throws GLException { + if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) { + throw new GLException("Error destroying OpenGL context 0x" + + Long.toHexString(contextHandle) + ": error code " + EGL.eglGetError()); + } + } + + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + return 0; // FIXME + } + + protected void destroyContextARBImpl(long _context) { + // FIXME + } + + protected boolean createImpl() throws GLException { + long eglDisplay = ((EGLDrawable)drawable).getDisplay(); + EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration(); + GLProfile glProfile = drawable.getGLProfile(); + long eglConfig = config.getNativeConfig(); + long shareWith = EGL.EGL_NO_CONTEXT; + + if (eglDisplay == 0) { + throw new GLException("Error: attempted to create an OpenGL context without a display connection"); + } + if (eglConfig == 0) { + throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration"); + } + + try { + // might be unavailable on EGL < 1.2 + if(!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) { + throw new GLException("eglBindAPI to ES failed , error 0x"+Integer.toHexString(EGL.eglGetError())); + } + } catch (GLException glex) { + if (DEBUG) { + glex.printStackTrace(); + } + } + + EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this); + if (other != null) { + shareWith = other.getHandle(); + if (shareWith == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + + int[] contextAttrs = new int[] { + EGL.EGL_CONTEXT_CLIENT_VERSION, -1, + EGL.EGL_NONE + }; + if (glProfile.usesNativeGLES2()) { + contextAttrs[1] = 2; + } else if (glProfile.usesNativeGLES1()) { + contextAttrs[1] = 1; + } else { + throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile); + } + contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0); + if (contextHandle == 0) { + throw new GLException("Error creating OpenGL context: eglDisplay 0x"+Long.toHexString(eglDisplay)+ + ", "+glProfile+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + GLContextShareSet.contextCreated(this); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" + + Long.toHexString(contextHandle) + + ",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) + + ",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+ + ",\n\t"+this+ + ",\n\tsharing with 0x" + Long.toHexString(shareWith)); + } + if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(), + drawable.getHandle(), + drawableRead.getHandle(), + contextHandle)) { + throw new GLException("Error making context 0x" + + Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); + } + setGLFunctionAvailability(true, glProfile.usesNativeGLES2()?2:1, 0, CTX_PROFILE_ES|CTX_OPTION_ANY); + return true; + } + + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Initializing EGLextension address table: "+key); + } + eglQueryStringInitialized = false; + eglQueryStringAvailable = false; + + EGLExtProcAddressTable table = null; + synchronized(mappedContextTypeObjectLock) { + table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( key ); + } + if(null != table) { + eglExtProcAddressTable = table; + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); + } + } else { + if (eglExtProcAddressTable == null) { + // FIXME: cache ProcAddressTables by capability bits so we can + // share them among contexts with the same capabilities + eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver()); + } + resetProcAddressTable(getEGLExtProcAddressTable()); + synchronized(mappedContextTypeObjectLock) { + mappedGLXProcAddress.put(key, getEGLExtProcAddressTable()); + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+key+") -> "+getEGLExtProcAddressTable().hashCode()); + } + } + } + } + + public synchronized String getPlatformExtensionsString() { + if (!eglQueryStringInitialized) { + eglQueryStringAvailable = + getDrawableImpl().getGLDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0; + eglQueryStringInitialized = true; + } + if (eglQueryStringAvailable) { + String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(), + EGL.EGL_EXTENSIONS); + if (DEBUG) { + System.err.println("!!! EGL extensions: " + ret); + } + return ret; + } else { + return ""; + } + } + + protected void setSwapIntervalImpl(int interval) { + if (EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval)) { + currentSwapInterval = interval ; + } + } + + public abstract void bindPbufferToTexture(); + + public abstract void releasePbufferFromTexture(); + + //---------------------------------------------------------------------- + // Currently unimplemented stuff + // + + protected void copyImpl(GLContext source, int mask) throws GLException { + throw new GLException("Not yet implemented"); + } + + + public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { + throw new GLException("Should not call this"); + } + + public boolean offscreenImageNeedsVerticalFlip() { + throw new GLException("Should not call this"); + } + + public int getOffscreenContextPixelDataType() { + throw new GLException("Should not call this"); + } +} diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java new file mode 100644 index 000000000..4120b0167 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import com.jogamp.opengl.impl.GLDynamicLookupHelper; +import com.jogamp.opengl.impl.GLDrawableImpl; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.*; +import javax.media.opengl.*; + +public abstract class EGLDrawable extends GLDrawableImpl { + protected boolean ownEGLDisplay = false; // for destruction + protected boolean ownEGLSurface = false; // for destruction + private EGLGraphicsConfiguration eglConfig; + protected long eglDisplay; + protected long eglSurface; + + protected EGLDrawable(EGLDrawableFactory factory, + NativeSurface component) throws GLException { + super(factory, component, false); + eglSurface=EGL.EGL_NO_SURFACE; + eglDisplay=0; + } + + public long getDisplay() { + return eglDisplay; + } + + public long getHandle() { + return eglSurface; + } + + public EGLGraphicsConfiguration getGraphicsConfiguration() { + return eglConfig; + } + + public GLCapabilitiesImmutable getChosenGLCapabilities() { + return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities(); + } + + public abstract GLContext createContext(GLContext shareWith); + + protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle); + + private void recreateSurface() { + // create a new EGLSurface .. + if(EGL.EGL_NO_SURFACE!=eglSurface) { + EGL.eglDestroySurface(eglDisplay, eglSurface); + } + + if(DEBUG) { + System.err.println("createSurface using eglDisplay 0x"+Long.toHexString(eglDisplay)+", "+eglConfig); + } + + eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), surface.getSurfaceHandle()); + if (EGL.EGL_NO_SURFACE==eglSurface) { + throw new GLException("Creation of window surface failed: "+eglConfig+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + + if(DEBUG) { + System.err.println("setSurface using component: handle 0x"+Long.toHexString(surface.getSurfaceHandle())+" -> 0x"+Long.toHexString(eglSurface)); + } + } + + protected void setRealizedImpl() { + if (realized) { + AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); + if(aDevice instanceof EGLGraphicsDevice) { + if(DEBUG) { + System.err.println("EGLDrawable.setRealized: using existing EGL config: "+this); + } + // just fetch the data .. trust but verify .. + eglDisplay = aDevice.getHandle(); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice); + } + 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(eglDisplay, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { + // surface holds static EGLSurface + eglSurface = surface.getSurfaceHandle(); + if(DEBUG) { + System.err.println("setSurface re-using component's EGLSurface: handle 0x"+Long.toHexString(eglSurface)); + } + } else { + // EGLSurface is ours .. + ownEGLSurface=true; + + eglConfig.updateGraphicsConfiguration(); + + recreateSurface(); + } + } else { + throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig); + } + } else { + if(DEBUG) { + System.err.println("EGLDrawable.setRealized: creating new EGL config: "+this); + } + // create a new EGL config .. + ownEGLDisplay=true; + // EGLSurface is ours .. + ownEGLSurface=true; + + long nDisplay=0; + if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) { + nDisplay = surface.getSurfaceHandle(); // don't even ask .. + } else { + nDisplay = aDevice.getHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY + } + eglDisplay = EGL.eglGetDisplay(nDisplay); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + if(DEBUG) { + System.err.println("eglDisplay("+Long.toHexString(nDisplay)+" <surfaceHandle>): failed, using EGL_DEFAULT_DISPLAY"); + } + nDisplay = EGL.EGL_DEFAULT_DISPLAY; + eglDisplay = EGL.eglGetDisplay(nDisplay); + } + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display: nhandle 0x"+Long.toHexString(nDisplay)+", "+aDevice+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } else if(DEBUG) { + System.err.println("eglDisplay("+Long.toHexString(nDisplay)+"): 0x"+Long.toHexString(eglDisplay)); + } + if (!EGL.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex()); + // yes, use the already choosen/requested Capabilities (x11,win32,..) + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) aConfig.getChosenCapabilities(); + GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities(); + eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration( + capsChosen, capsRequested, null, s); + if (null == eglConfig) { + throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s); + } else if(DEBUG) { + System.err.println("Chosen eglConfig: "+eglConfig); + } + recreateSurface(); + } + } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) { + // Destroy the window surface + if (!EGL.eglDestroySurface(eglDisplay, eglSurface)) { + throw new GLException("Error destroying window surface (eglDestroySurface)"); + } + eglSurface = EGL.EGL_NO_SURFACE; + if (ownEGLDisplay && EGL.EGL_NO_DISPLAY!=eglDisplay) { + EGL.eglTerminate(eglDisplay); + } + eglDisplay=EGL.EGL_NO_DISPLAY; + eglConfig=null; + } + } + + 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"); + } + 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"); + } + return tmp[0]; + } + + public GLDynamicLookupHelper getGLDynamicLookupHelper() { + if (getGLProfile().usesNativeGLES2()) { + return getFactoryImpl().getGLDynamicLookupHelper(2); + } else if (getGLProfile().usesNativeGLES1()) { + return getFactoryImpl().getGLDynamicLookupHelper(1); + } else { + throw new GLException("Unsupported: "+getGLProfile()); + } + } + + public String toString() { + return getClass().getName()+"[realized "+isRealized()+ + ",\n\tfactory "+getFactory()+ + ",\n\tsurface "+getNativeSurface()+ + ",\n\teglSurface 0x"+Long.toHexString(eglSurface)+ + ",\n\teglConfig "+eglConfig+ + ",\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 new file mode 100644 index 000000000..c32f2f22c --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.EGLGraphicsDevice; +import javax.media.opengl.*; + +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.util.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.ProxySurface; + +import java.util.HashMap; +import java.util.List; + +public class EGLDrawableFactory extends GLDrawableFactoryImpl { + + private static final GLDynamicLookupHelper eglES1DynamicLookupHelper; + private static final GLDynamicLookupHelper eglES2DynamicLookupHelper; + + static { + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new EGLGraphicsConfigurationFactory(); + + // Check for other underlying stuff .. + if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) { + try { + ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader()); + } catch (JogampRuntimeException jre) { /* n/a .. */ } + } + + // FIXME: Probably need to move EGL from a static model + // to a dynamic one, where there can be 2 instances + // for each ES profile with their own ProcAddressTable. + + GLDynamicLookupHelper tmp=null; + try { + tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + eglES1DynamicLookupHelper = tmp; + if(null!=eglES1DynamicLookupHelper && eglES1DynamicLookupHelper.isLibComplete()) { + EGL.resetProcAddressTable(eglES1DynamicLookupHelper); + } + + tmp=null; + try { + tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + eglES2DynamicLookupHelper = tmp; + if(null!=eglES2DynamicLookupHelper && eglES2DynamicLookupHelper.isLibComplete()) { + EGL.resetProcAddressTable(eglES2DynamicLookupHelper); + } + } + + public EGLDrawableFactory() { + super(); + defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + + static class SharedResource { + private EGLGraphicsDevice device; + //private EGLDrawable drawable; + //private EGLContext context; + + SharedResource(EGLGraphicsDevice dev /*, EGLDrawable draw, EGLContext ctx */) { + device = dev; + // drawable = draw; + // context = ctx; + } + EGLGraphicsDevice getDevice() { return device; } + } + HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); + EGLGraphicsDevice defaultDevice; + + public final AbstractGraphicsDevice getDefaultDevice() { + return defaultDevice; + } + + public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { + if(device instanceof EGLGraphicsDevice) { + return true; + } + return false; + } + + private SharedResource getOrCreateShared(AbstractGraphicsDevice device) { + String connection = device.getConnection(); + SharedResource sr; + synchronized(sharedMap) { + sr = (SharedResource) sharedMap.get(connection); + } + if(null==sr) { + long eglDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError())); + } else if(DEBUG) { + System.err.println("eglDisplay(EGL_DEFAULT_DISPLAY): 0x"+Long.toHexString(eglDisplay)); + } + if (!EGL.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + EGLGraphicsDevice sharedDevice = new EGLGraphicsDevice(eglDisplay, connection, device.getUnitID()); + sr = new SharedResource(sharedDevice); + synchronized(sharedMap) { + sharedMap.put(connection, sr); + } + if (DEBUG) { + System.err.println("!!! SharedDevice: "+sharedDevice); + } + } + return sr; + } + + + protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { + // FIXME: not implemented .. needs a dummy EGL surface - NEEDED ? + return null; + } + + protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { + SharedResource sr = getOrCreateShared(device); + if(null!=sr) { + return sr.getDevice(); + } + return null; + } + + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) getOrCreateShared(device); + } + + public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) { + if (2==esProfile) { + if(null==eglES2DynamicLookupHelper) { + throw new GLException("GLDynamicLookupHelper for ES2 not available"); + } + return eglES2DynamicLookupHelper; + } else if (1==esProfile) { + if(null==eglES1DynamicLookupHelper) { + throw new GLException("GLDynamicLookupHelper for ES1 not available"); + } + return eglES1DynamicLookupHelper; + } else { + throw new GLException("Unsupported: ES"+esProfile); + } + } + + protected final void shutdownInstance() {} + + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + return new EGLOnscreenDrawable(this, target); + } + + protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(!caps.isPBuffer()) { + throw new GLException("Not yet implemented"); + } + // PBuffer GLDrawable Creation + return new EGLPbufferDrawable(this, target); + } + + public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { + return true; + } + + protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { + ProxySurface ns = new ProxySurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser)); + ns.setSize(width, height); + return ns; + } + + protected GLContext createExternalGLContextImpl() { + AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_EGL); + return new EGLExternalContext(absScreen); + } + + public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { + return false; + } + + protected GLDrawable createExternalGLDrawableImpl() { + throw new GLException("Not yet implemented"); + } + + public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { + return false; + } + + public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) + throws GLException { + throw new GLException("Unimplemented on this platform"); + } +} diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java new file mode 100644 index 000000000..5b4a59cd0 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java @@ -0,0 +1,73 @@ +/** + * 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.impl.egl; + +import com.jogamp.common.os.DynamicLookupHelper; +import com.jogamp.common.os.NativeLibrary; +import java.util.*; +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import java.security.*; + +/** + * Abstract implementation of the DynamicLookupHelper for EGL, + * which decouples it's dependencies to EGLDrawable. + * + * Currently two implementations exist, one for ES1 and one for ES2. + */ +public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo { + + protected EGLDynamicLibraryBundleInfo() { + super(); + } + + /** Might be a desktop GL library, and might need to allow symbol access to subsequent libs */ + public boolean shallLinkGlobal() { return true; } + + public final List getToolGetProcAddressFuncNameList() { + List res = new ArrayList(); + res.add("eglGetProcAddress"); + return res; + } + + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return EGL.eglGetProcAddress(toolGetProcAddressHandle, funcName); + } + + protected List/*<String>*/ getEGLLibNamesList() { + List/*<String>*/ eglLibNames = new ArrayList(); + // EGL + eglLibNames.add("EGL"); + // for windows distributions using the 'unlike' lib prefix, + // where our tool does not add it. + eglLibNames.add("libEGL"); + return eglLibNames; + } +} diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java new file mode 100644 index 000000000..1507dc8c6 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java @@ -0,0 +1,73 @@ +/** + * 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.impl.egl; + +import java.util.*; +import com.jogamp.opengl.impl.*; + +public class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo { + static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + glueLibNames.addAll(GLDynamicLibraryBundleInfo.getGlueLibNamesPreload()); + glueLibNames.add("jogl_es1"); + } + + protected EGLES1DynamicLibraryBundleInfo() { + super(); + } + + public List getToolLibNames() { + List/*<List>*/ libNames = new ArrayList(); + + List/*<String>*/ glesLibNames = new ArrayList(); + glesLibNames.add("GLES_CM"); + glesLibNames.add("GLES_CL"); + glesLibNames.add("GLESv1_CM"); + // for windows distributions using the 'unlike' lib prefix, + // where our tool does not add it. + glesLibNames.add("libGLES_CM"); + glesLibNames.add("libGLES_CL"); + glesLibNames.add("libGLESv1_CM"); + // last but not least, we may even use the desktop GL library, + // which would be eg Mesa + Gallium EGL .. + glesLibNames.add("libGL.so.1"); + glesLibNames.add("libGL.so"); + glesLibNames.add("GL"); + + libNames.add(glesLibNames); + libNames.add(getEGLLibNamesList()); + return libNames; + } + + public List/*<String>*/ getGlueLibNames() { + return glueLibNames; + } +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java new file mode 100644 index 000000000..3c02aec88 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java @@ -0,0 +1,73 @@ +/** + * 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.impl.egl; + +import java.util.*; +import com.jogamp.opengl.impl.*; + +public class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo { + static List/*<String>*/ glueLibNames; + static { + glueLibNames = new ArrayList(); + glueLibNames.addAll(GLDynamicLibraryBundleInfo.getGlueLibNamesPreload()); + glueLibNames.add("jogl_es2"); + } + + protected EGLES2DynamicLibraryBundleInfo() { + super(); + } + + public List getToolLibNames() { + List/*<List>*/ libNames = new ArrayList(); + + List/*<String>*/ glesLibNames = new ArrayList(); + glesLibNames.add("GLES20"); + glesLibNames.add("GLESv2"); + glesLibNames.add("GLESv2_CM"); + // for windows distributions using the 'unlike' lib prefix + // where our tool does not add it. + glesLibNames.add("libGLES20"); + glesLibNames.add("libGLESv2"); + glesLibNames.add("libGLESv2_CM"); + // last but not least, we may even use the desktop GL library, + // which would be eg Mesa + Gallium EGL .. + glesLibNames.add("libGL.so.1"); + glesLibNames.add("libGL.so"); + glesLibNames.add("GL"); + + libNames.add(glesLibNames); + libNames.add(getEGLLibNamesList()); + return libNames; + } + + public List/*<String>*/ getGlueLibNames() { + return glueLibNames; + } +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java new file mode 100644 index 000000000..ae8b5bf70 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import javax.media.nativewindow.*; + +public class EGLExternalContext extends EGLContext { + private boolean firstMakeCurrent = true; + private GLContext lastContext; + + public EGLExternalContext(AbstractGraphicsScreen screen) { + super(null, null); + GLContextShareSet.contextCreated(this); + setGLFunctionAvailability(false, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES|CTX_OPTION_ANY); + getGLStateTracker().setEnabled(false); // external context usage can't track state in Java + } + + public int makeCurrent() throws GLException { + // Save last context if necessary to allow external GLContexts to + // talk to other GLContexts created by this library + GLContext cur = getCurrent(); + if (cur != null && cur != this) { + lastContext = cur; + setCurrent(null); + } + return super.makeCurrent(); + } + + public void release() throws GLException { + super.release(); + setCurrent(lastContext); + lastContext = null; + } + + protected void makeCurrentImpl(boolean newCreated) throws GLException { + if (firstMakeCurrent) { + firstMakeCurrent = false; + } + } + + protected void releaseImpl() throws GLException { + } + + protected void destroyImpl() throws GLException { + } + + public void bindPbufferToTexture() { + throw new GLException("Should not call this"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Should not call this"); + } + +} diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java new file mode 100644 index 000000000..db6d485e3 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java @@ -0,0 +1,96 @@ +/** + * 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.impl.egl; + +import java.util.Comparator; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class EGLGLCapabilities extends GLCapabilities { + long eglcfg; + int eglcfgid; + + /** Comparing EGLConfig ID only */ + public static class EglCfgIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof EGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a EGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof EGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a EGLGLCapabilities object: " + c); + } + + final EGLGLCapabilities caps1 = (EGLGLCapabilities) o1; + final long id1 = caps1.getEGLConfigID(); + + final EGLGLCapabilities caps2 = (EGLGLCapabilities) o2; + final long id2 = caps2.getEGLConfigID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public EGLGLCapabilities(long eglcfg, int eglcfgid, GLProfile glp) { + super(glp); + this.eglcfg = eglcfg; + this.eglcfgid = eglcfgid; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public long getEGLConfig() { return eglcfg; } + final public int getEGLConfigID() { return eglcfgid; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(eglcfgid)).append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java new file mode 100644 index 000000000..eca324046 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import java.util.ArrayList; +import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.*; +import javax.media.opengl.*; +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.opengl.impl.*; + +public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public final long getNativeConfig() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig(); + } + + public final int getNativeConfigID() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID(); + } + + EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen, + EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + super(absScreen, capsChosen, capsRequested); + this.chooser = chooser; + } + + public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) { + AbstractGraphicsDevice absDevice = absScreen.getDevice(); + if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) { + throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice"); + } + long dpy = absDevice.getHandle(); + if (dpy == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display: "+absDevice); + } + GLProfile glp = capsRequested.getGLProfile(); + long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID); + EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); + return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser()); + } + + public Object clone() { + return super.clone(); + } + + void updateGraphicsConfiguration() { + EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration( + getChosenCapabilities(), getRequestedCapabilities(), chooser, getScreen()); + if(null!=newConfig) { + // FIXME: setScreen( ... ); + setChosenCapabilities(newConfig.getChosenCapabilities()); + if(DEBUG) { + System.err.println("!!! updateGraphicsConfiguration: "+this); + } + } + } + + public static long EGLConfigId2EGLConfig(GLProfile glp, long display, int configID) { + int[] attrs = new int[] { + EGL.EGL_CONFIG_ID, configID, + EGL.EGL_NONE + }; + PointerBuffer configs = PointerBuffer.allocateDirect(1); + int[] numConfigs = new int[1]; + if (!EGL.eglChooseConfig(display, + attrs, 0, + configs, 1, + numConfigs, 0)) { + return 0; + } + if (numConfigs[0] == 0) { + return 0; + } + return configs.get(0); + } + + static int EGLConfigDrawableTypeBits(final long display, final long config) { + int val = 0; + + int[] stype = new int[1]; + if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) { + throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); + } + + if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + + return val; + } + + public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config, + boolean relaxed, boolean onscreen, boolean usePBuffer) { + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask) ) { + return (EGLGLCapabilities) bucket.get(0); + } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS) ) { + return (EGLGLCapabilities) bucket.get(0); + } + return null; + } + + public static boolean EGLConfig2Capabilities(ArrayList capsBucket, + GLProfile glp, long display, long config, + int winattrmask) { + final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + + int[] val = new int[1]; + + // get the configID + if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val, 0)) { + if(DEBUG) { + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError())); + } + return false; + } + GLCapabilities caps = new EGLGLCapabilities(config, val[0], glp); + + // Read the actual configuration into the choosen caps + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) { + caps.setRedBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_GREEN_SIZE, val, 0)) { + caps.setGreenBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_BLUE_SIZE, val, 0)) { + caps.setBlueBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_ALPHA_SIZE, val, 0)) { + caps.setAlphaBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_STENCIL_SIZE, val, 0)) { + caps.setStencilBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val, 0)) { + caps.setDepthBits(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val, 0)) { + caps.setSampleBuffers(val[0]>0?true:false); + caps.setNumSamples(val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_TYPE, val, 0)) { + caps.setBackgroundOpaque(val[0] != EGL.EGL_TRANSPARENT_RGB); + } + if(!caps.isBackgroundOpaque()) { + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_RED_VALUE, val, 0)) { + caps.setTransparentRedValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_GREEN_VALUE, val, 0)) { + caps.setTransparentGreenValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); + } + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_BLUE_VALUE, val, 0)) { + caps.setTransparentBlueValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); + } + /** Not defined in EGL + if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_ALPHA_VALUE, val, 0)) { + caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); + } */ + } + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits ); + } + + public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { + int[] attrs = new int[32]; + int idx=0; + + attrs[idx++] = EGL.EGL_SURFACE_TYPE; + attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ; + + attrs[idx++] = EGL.EGL_RED_SIZE; + attrs[idx++] = caps.getRedBits(); + + attrs[idx++] = EGL.EGL_GREEN_SIZE; + attrs[idx++] = caps.getGreenBits(); + + attrs[idx++] = EGL.EGL_BLUE_SIZE; + attrs[idx++] = caps.getBlueBits(); + + attrs[idx++] = EGL.EGL_ALPHA_SIZE; + attrs[idx++] = caps.getAlphaBits() > 0 ? caps.getAlphaBits() : EGL.EGL_DONT_CARE; + + attrs[idx++] = EGL.EGL_STENCIL_SIZE; + attrs[idx++] = caps.getStencilBits() > 0 ? caps.getStencilBits() : EGL.EGL_DONT_CARE; + + attrs[idx++] = EGL.EGL_DEPTH_SIZE; + attrs[idx++] = caps.getDepthBits(); + + attrs[idx++] = EGL.EGL_SAMPLES; + attrs[idx++] = caps.getSampleBuffers() ? caps.getNumSamples() : 1; + + attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE; + attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE; + + // 20 + + if(!caps.isBackgroundOpaque()) { + attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE; + attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE; + + attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE; + attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE; + + attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE; + attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE; + + /** Not define in EGL + attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE; + attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */ + } + + // 26 + + attrs[idx++] = EGL.EGL_RENDERABLE_TYPE; + if(caps.getGLProfile().usesNativeGLES1()) { + attrs[idx++] = EGL.EGL_OPENGL_ES_BIT; + } + else if(caps.getGLProfile().usesNativeGLES2()) { + attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT; + } else { + attrs[idx++] = EGL.EGL_OPENGL_BIT; + } + + // 28 + + attrs[idx++] = EGL.EGL_NONE; + + return attrs; + } + + public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) { + int[] attrs = new int[16]; + int idx=0; + + attrs[idx++] = EGL.EGL_WIDTH; + attrs[idx++] = width; + + attrs[idx++] = EGL.EGL_HEIGHT; + attrs[idx++] = height; + + attrs[idx++] = EGL.EGL_TEXTURE_FORMAT; + attrs[idx++] = texFormat; + + attrs[idx++] = EGL.EGL_TEXTURE_TARGET; + attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D; + + attrs[idx++] = EGL.EGL_NONE; + + return attrs; + } + + public String toString() { + return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID "+toHexString(getNativeConfigID())+ + ",\n\trequested " + getRequestedCapabilities()+ + ",\n\tchosen " + getChosenCapabilities()+ + "]"; + + } + + private GLCapabilitiesChooser chooser; +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java new file mode 100644 index 000000000..3e3d4f964 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2008 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. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +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.egl.EGLGraphicsDevice; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLDrawableFactory; + +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.io.PrintStream; + + +/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits + are used on X11 platforms. Toolkits will likely need to delegate + to this one to change the accepted and returned types of the + GraphicsDevice and GraphicsConfiguration abstractions. */ + +public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { + protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL"); + static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator(); + + EGLGraphicsConfigurationFactory() { + // become the selector for KD/EGL .. + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this); + } + + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl ( + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { + if (absScreen == null) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects"); + } + + if (! (capsChosen instanceof GLCapabilitiesImmutable) ) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen"); + } + + if (! (capsRequested instanceof GLCapabilitiesImmutable) ) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable) capsChosen, + (GLCapabilitiesImmutable) capsRequested, + (GLCapabilitiesChooser) chooser, + absScreen); + } + + protected static List/*<EGLGLCapabilities>*/ getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) { + EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + EGLGraphicsDevice eglDevice = sharedResource.getDevice(); + long eglDisplay = eglDevice.getHandle(); + + List/*<EGLGLCapabilities>*/ availableCaps = null; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); + int[] numConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + GLProfile glp = GLProfile.getDefault(device); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], GLGraphicsConfigurationUtil.ALL_BITS); + if( null != availableCaps ) { + Collections.sort(availableCaps, EglCfgIDComparator); + } + } + + return availableCaps; + } + + private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsReq, + GLCapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + if (capsChosen == null) { + capsChosen = new GLCapabilities(null); + } + + if(null==absScreen) { + throw new GLException("Null AbstractGraphicsScreen"); + } + AbstractGraphicsDevice absDevice = absScreen.getDevice(); + + if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) { + throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice"); + } + long eglDisplay = absDevice.getHandle(); + + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display: "+absDevice); + } + + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) ); + + GLProfile glp = capsChosen.getGLProfile(); + + EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen); + if(null!=res) { + return res; + } + if(DEBUG) { + System.err.println("eglChooseConfig failed with given capabilities "+capsChosen); + } + + // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..] + // + // rgb888 - d16, s4 + GLCapabilities fixedCaps = new GLCapabilities(glp); + fixedCaps.setRedBits(8); + fixedCaps.setGreenBits(8); + fixedCaps.setBlueBits(8); + fixedCaps.setDepthBits(16); + fixedCaps.setSampleBuffers(true); + fixedCaps.setNumSamples(4); + if(DEBUG) { + System.err.println("trying fixed caps (1): "+fixedCaps); + } + res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen); + if(null!=res) { + return res; + } + + // + // rgb565 - d16, s0 + fixedCaps = new GLCapabilities(glp); + fixedCaps.setRedBits(5); + fixedCaps.setGreenBits(6); + fixedCaps.setBlueBits(5); + fixedCaps.setDepthBits(16); + if(DEBUG) { + System.err.println("trying fixed caps (2): "+fixedCaps); + } + res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen); + if(null!=res) { + return res; + } + + // + // rgb565 - d16, s4 + fixedCaps = new GLCapabilities(glp); + fixedCaps.setRedBits(5); + fixedCaps.setGreenBits(6); + fixedCaps.setBlueBits(5); + fixedCaps.setDepthBits(16); + fixedCaps.setSampleBuffers(true); + fixedCaps.setNumSamples(4); + if(DEBUG) { + System.err.println("trying fixed caps (3): "+fixedCaps); + } + res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen); + if(null!=res) { + return res; + } + throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]"); + } + + static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + GLProfile glp = capsChosen.getGLProfile(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + List/*<EGLGLCapabilities>*/ availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + int recommendedIndex = -1; + long recommendedEGLConfig = -1; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + if (DEBUG) { + System.err.println("!!! eglChooseConfig maxConfigs: "+maxConfigs[0]); + } + + int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen); + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); + int[] numConfigs = new int[1]; + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + if (!EGL.eglChooseConfig(eglDisplay, + attrs, 0, + configs, configs.capacity(), + numConfigs, 0)) { + throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen+", error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); + if(availableCaps.size() > 0) { + recommendedEGLConfig = configs.get(0); + recommendedIndex = 0; + if (DEBUG) { + System.err.println("!!! eglChooseConfig recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); + } + } else if (DEBUG) { + System.err.println("!!! eglChooseConfig no caps for recommended fbcfg " + toHexString(configs.get(0))); + System.err.println("!!! user caps " + capsChosen); + } + } + + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if( null == availableCaps || 0 == availableCaps.size() ) { + // reset .. + recommendedEGLConfig = -1; + recommendedIndex = -1; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); + } + } + + if( null == availableCaps || 0 == availableCaps.size() ) { + if(DEBUG) { + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("Graphics configuration 1st choice and 2nd choice failed - no configs"); + } + return null; + } + + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex); + + return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser); + } + + static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask) { + ArrayList caps = new ArrayList(num); + for(int i=0; i<num; i++) { + EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask); + } + return caps; + } + + static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) { + for(int i=0; i<caps.size(); i++) { + 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); + 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/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java new file mode 100644 index 000000000..cb8b01d8d --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.gluegen.runtime.ProcAddressTable; +import java.nio.*; +import java.util.*; + +public class EGLOnscreenContext extends EGLContext { + public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } + + public void bindPbufferToTexture() { + throw new GLException("Should not call this"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Should not call this"); + } + +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java new file mode 100644 index 000000000..820ac04e9 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java @@ -0,0 +1,64 @@ +/* + * 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.impl.egl; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; + +public class EGLOnscreenDrawable extends EGLDrawable { + protected EGLOnscreenDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException { + super(factory, component); + } + + public GLContext createContext(GLContext shareWith) { + return new EGLOnscreenContext(this, shareWith); + } + + protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) { + return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null); + } + + protected void swapBuffersImpl() { + EGL.eglSwapBuffers(eglDisplay, eglSurface); + } + +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java new file mode 100644 index 000000000..5c634b9bd --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.egl; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.gluegen.runtime.ProcAddressTable; +import java.nio.*; +import java.util.*; + +public class EGLPbufferContext extends EGLContext { + public EGLPbufferContext(EGLPbufferDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } + + public int getFloatingPointMode() { + return 0; // FIXME ?? + } + + public void bindPbufferToTexture() { + throw new GLException("Not yet implemented"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Not yet implemented"); + } +} + diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java new file mode 100644 index 000000000..3189324d1 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java @@ -0,0 +1,102 @@ +/* + * 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.impl.egl; + +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.SurfaceChangeable; +import javax.media.opengl.GLCapabilitiesImmutable; +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) { + super(factory, target); + ownEGLDisplay = true; + + // get choosen ones .. + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + + if(useTexture) { + this.texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ; + } else { + this.texFormat = EGL.EGL_NO_TEXTURE; + } + + if (DEBUG) { + System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration()); + } + + setRealized(true); + + if (DEBUG) { + System.out.println("Created pbuffer: " + this); + } + + } + + protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) { + 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)); + } + ((SurfaceChangeable)nw).setSurfaceHandle(surf); + return surf; + } + + public GLContext createContext(GLContext shareWith) { + return new EGLPbufferContext(this, shareWith); + } + + protected void swapBuffersImpl() { + if(DEBUG) { + System.err.println("unhandled swapBuffersImpl() called for: "+this); + } + } +} + |