diff options
author | Kenneth Russel <[email protected]> | 2008-05-28 02:37:45 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2008-05-28 02:37:45 +0000 |
commit | 95c3974708231607d729830ae711a0864a961b71 (patch) | |
tree | 2fb2df4cdf04851b73234353538d2dd0dd087ed1 /src | |
parent | fbcbb9ab19b0e2e85250f5e3653c3a3d7bf12e8d (diff) |
Filled out EGLContext, EGLDrawable, and EGLDrawableFactory
implementations on top of autogenerated EGL binding. Added
GLDrawableFactory.initialize(String) taking the profile name
(PROFILE_GL_20, PROFILE_GLES1, and PROFILE_GLES2 defined in
GLDrawableFactory) to bootstrap the system and allow run-time
selection of the window system binding. Modified eglplatform.h to
extend EGLNativeDisplayType to pointer size. Changed egl.cfg to change
most EGL types to opaque longs. Still missing pieces include the
function pointer lookup and autogeneration of the EGL binding in all
situations.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1643 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src')
8 files changed, 347 insertions, 45 deletions
diff --git a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java index 7f0718c44..d0e9118ea 100644 --- a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java @@ -68,6 +68,10 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory implements */ public abstract void unlockAWTForJava2D(); + protected GLDrawableFactoryImpl(String profile) { + super(profile); + } + public static GLDrawableFactoryImpl getFactoryImpl() { return (GLDrawableFactoryImpl) getFactory(); } diff --git a/src/classes/com/sun/opengl/impl/egl/EGLContext.java b/src/classes/com/sun/opengl/impl/egl/EGLContext.java index f1aa9172b..f55b611ca 100755 --- a/src/classes/com/sun/opengl/impl/egl/EGLContext.java +++ b/src/classes/com/sun/opengl/impl/egl/EGLContext.java @@ -39,16 +39,117 @@ import javax.media.opengl.*; import com.sun.opengl.impl.*; import java.nio.*; -public abstract class EGLContext extends GLContextImpl { +public class EGLContext extends GLContextImpl { + private EGLDrawable drawable; + private long context; + public EGLContext(EGLDrawable drawable, GLContext shareWith) { super(shareWith); + this.drawable = drawable; } - public Object getPlatformGLExtensions() { - return null; + public GLDrawable getGLDrawable() { + return drawable; } - public GLDrawable getGLDrawable() { + public long getContext() { + return context; + } + + protected int makeCurrentImpl() throws GLException { + boolean created = false; + if (context == 0) { + create(); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Created GL context 0x" + + Long.toHexString(context) + " for " + getClass().getName()); + } + created = true; + } + + if (!EGL.eglMakeCurrent(drawable.getDisplay(), + drawable.getSurface(), + drawable.getSurface(), + context)) { + throw new GLException("Error making context 0x" + + Long.toHexString(context) + " current: error code " + EGL.eglGetError()); + } + + if (created) { + resetGLFunctionAvailability(); + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } + + protected void releaseImpl() throws GLException { + if (!EGL.eglMakeCurrent(drawable.getDisplay(), + EGL.EGL_NO_SURFACE, + EGL.EGL_NO_SURFACE, + EGL.EGL_NO_CONTEXT)) { + throw new GLException("Error freeing OpenGL context 0x" + + Long.toHexString(context) + ": error code " + EGL.eglGetError()); + } + } + + protected void destroyImpl() throws GLException { + if (context != 0) { + if (!EGL.eglDestroyContext(drawable.getDisplay(), context)) { + throw new GLException("Error destroying OpenGL context 0x" + + Long.toHexString(context) + ": error code " + EGL.eglGetError()); + } + context = 0; + GLContextShareSet.contextDestroyed(this); + } + } + + protected void create() throws GLException { + long display = drawable.getDisplay(); + _EGLConfig config = drawable.getConfig(); + long shareWith = 0; + + if (display == 0) { + throw new GLException("Error: attempted to create an OpenGL context without a display connection"); + } + if (config == null) { + throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration"); + } + EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this); + if (other != null) { + shareWith = other.getContext(); + if (shareWith == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getFactory(); + int clientVersion = (EGLDrawableFactory.PROFILE_GLES2.equals(factory.getProfile()) ? 2 : 1); + int[] contextAttrs = new int[] { + EGL.EGL_CONTEXT_CLIENT_VERSION, clientVersion, + EGL.EGL_NONE + }; + context = EGL.eglCreateContext(display, config, shareWith, contextAttrs, 0); + if (context == 0) { + throw new GLException("Error creating OpenGL context"); + } + GLContextShareSet.contextCreated(this); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" + + Long.toHexString(context) + " for " + this + + ", surface 0x" + Long.toHexString(drawable.getSurface()) + + ", sharing with 0x" + Long.toHexString(shareWith)); + } + } + + public boolean isCreated() { + return (context != 0); + } + + //---------------------------------------------------------------------- + // Currently unimplemented stuff + // + + public Object getPlatformGLExtensions() { return null; } diff --git a/src/classes/com/sun/opengl/impl/egl/EGLDrawable.java b/src/classes/com/sun/opengl/impl/egl/EGLDrawable.java index 2f0903a2b..c9cc19913 100755 --- a/src/classes/com/sun/opengl/impl/egl/EGLDrawable.java +++ b/src/classes/com/sun/opengl/impl/egl/EGLDrawable.java @@ -35,5 +35,93 @@ package com.sun.opengl.impl.egl; -public class EGLDrawable { +import javax.media.opengl.*; + +public class EGLDrawable implements GLDrawable { + private long nativeWindow; + private long display; + private GLCapabilities capabilities; + private GLCapabilitiesChooser chooser; + private _EGLConfig config; + private long surface; + private int[] tmp = new int[1]; + + public EGLDrawable(long nativeWindow, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser) throws GLException { + this.nativeWindow = nativeWindow; + this.capabilities = capabilities; + this.chooser = chooser; + + // Set things up + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getFactory(); + // FIXME: need to ultimately fetch this from the native window, at least on X11 platforms + display = factory.getDisplay(); + int[] attrs = factory.glCapabilities2AttribList(capabilities); + _EGLConfig[] configs = new _EGLConfig[1]; + int[] numConfigs = new int[1]; + if (!EGL.eglChooseConfig(display, + attrs, 0, + configs, 1, + numConfigs, 0)) { + throw new GLException("Graphics configuration selection (eglChooseConfig) failed"); + } + if (numConfigs[0] == 0) { + throw new GLException("No valid graphics configuration selected from eglChooseConfig"); + } + config = configs[0]; + } + + public long getDisplay() { + return display; + } + + public _EGLConfig getConfig() { + return config; + } + + public long getSurface() { + return surface; + } + + public GLContext createContext(GLContext shareWith) { + return new EGLContext(this, shareWith); + } + + public void setRealized(boolean realized) { + if (realized) { + // Create the window surface + surface = EGL.eglCreateWindowSurface(display, config, nativeWindow, null); + if (surface == 0) { + throw new GLException("Creation of window surface (eglCreateWindowSurface) failed"); + } + } + } + + public void setSize(int width, int height) { + // FIXME: anything to do here? + } + + public int getWidth() { + if (!EGL.eglQuerySurface(display, surface, EGL.EGL_WIDTH, tmp, 0)) { + throw new GLException("Error querying surface width"); + } + return tmp[0]; + } + + public int getHeight() { + if (!EGL.eglQuerySurface(display, surface, EGL.EGL_HEIGHT, tmp, 0)) { + throw new GLException("Error querying surface height"); + } + return tmp[0]; + } + + public void swapBuffers() throws GLException { + EGL.eglSwapBuffers(display, surface); + } + + public GLCapabilities getChosenGLCapabilities() { + // FIXME + return null; + } } diff --git a/src/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java index 06ba5b640..667afc2ac 100755 --- a/src/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/egl/EGLDrawableFactory.java @@ -43,6 +43,28 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { NativeLibLoader.loadCore(); } + // FIXME: this state should probably not be here + private long display; + private _EGLConfig config; + + public EGLDrawableFactory(String profile) { + super(profile); + + // FIXME: this initialization sequence needs to be refactored + // at least for X11 platforms to allow a little window + // system-specific code to run (to open the display, in + // particular) + + display = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); + if (display == EGL.EGL_NO_DISPLAY) { + throw new GLException("eglGetDisplay failed"); + } + if (!EGL.eglInitialize(display, null, null)) { + throw new GLException("eglInitialize failed"); + } + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, GLCapabilitiesChooser chooser, AbstractGraphicsDevice device) { @@ -52,7 +74,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { public GLDrawable getGLDrawable(Object target, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - throw new GLException("Not yet implemented"); + return new EGLDrawable(((Long) target).longValue(), + capabilities, + chooser); } public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities, @@ -111,6 +135,37 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return false; } + public long getDisplay() { + return display; + } + + public int[] glCapabilities2AttribList(GLCapabilities caps) { + int renderBit; + + if (PROFILE_GLES1.equals(getProfile())) { + renderBit = EGL.EGL_OPENGL_ES_BIT; + } else if (PROFILE_GLES2.equals(getProfile())) { + renderBit = EGL.EGL_OPENGL_ES2_BIT; + } else { + throw new GLException("Unknown profile \"" + getProfile() + "\" (expected OpenGL ES 1 or OpenGL ES 2)"); + } + + return new int[] { + EGL.EGL_RENDERABLE_TYPE, renderBit, + EGL.EGL_DEPTH_SIZE, caps.getDepthBits(), + // FIXME: does this need to be configurable? + EGL.EGL_SURFACE_TYPE, EGL.EGL_WINDOW_BIT, + EGL.EGL_RED_SIZE, caps.getRedBits(), + EGL.EGL_GREEN_SIZE, caps.getGreenBits(), + EGL.EGL_BLUE_SIZE, caps.getBlueBits(), + EGL.EGL_ALPHA_SIZE, caps.getAlphaBits(), + EGL.EGL_STENCIL_SIZE, (caps.getStencilBits() > 0 ? caps.getStencilBits() : EGL.EGL_DONT_CARE), + EGL.EGL_NONE + }; + } + + /* + // FIXME: this is the OpenGL ES 2 initialization order // Initialize everything @@ -159,6 +214,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { updateWindowSize(); } + */ + /* // FIXME: this is the OpenGL ES 1 initialization order @@ -214,6 +271,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { */ + /* + // Process incoming events -- must be called every frame public void processEvents() { if (shouldExit()) { @@ -250,6 +309,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } public native int getDirectBufferAddress(java.nio.Buffer buf); + */ + /* public GLContext createContextOnJava2DSurface(Graphics g, GLContext shareWith) throws GLException { diff --git a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java index 6c56a2b6d..15cccb7e8 100644 --- a/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/macosx/MacOSXGLDrawableFactory.java @@ -53,6 +53,10 @@ public class MacOSXGLDrawableFactory extends GLDrawableFactoryImpl { NativeLibLoader.loadCore(); } + public MacOSXGLDrawableFactory(String profile) { + super(profile); + } + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, GLCapabilitiesChooser chooser, AbstractGraphicsDevice device) { diff --git a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java index 6e1b4ca99..ddccfda4f 100644 --- a/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/windows/WindowsGLDrawableFactory.java @@ -60,6 +60,10 @@ public class WindowsGLDrawableFactory extends GLDrawableFactoryImpl { NativeLibLoader.loadCore(); } + public WindowsGLDrawableFactory(String profile) { + super(profile); + } + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, GLCapabilitiesChooser chooser, AbstractGraphicsDevice device) { diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java index 6ff112348..dcb9a0b37 100644 --- a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java @@ -105,7 +105,8 @@ public class X11GLDrawableFactory extends GLDrawableFactoryImpl { isHeadless = GraphicsEnvironment.isHeadless(); } - public X11GLDrawableFactory() { + public X11GLDrawableFactory(String profile) { + super(profile); // Must initialize GLX support eagerly in case a pbuffer is the // first thing instantiated ProcAddressHelper.resetProcAddressTable(GLX.getGLXProcAddressTable(), this); diff --git a/src/classes/javax/media/opengl/GLDrawableFactory.java b/src/classes/javax/media/opengl/GLDrawableFactory.java index 3945f42fc..42727fc48 100644 --- a/src/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/classes/javax/media/opengl/GLDrawableFactory.java @@ -39,6 +39,7 @@ package javax.media.opengl; +import java.lang.reflect.*; import java.security.*; import com.sun.opengl.impl.*; @@ -78,60 +79,98 @@ import com.sun.opengl.impl.*; public abstract class GLDrawableFactory { private static GLDrawableFactory factory; - protected GLDrawableFactory() {} + /** The desktop (OpenGL 2.0) profile */ + public static final String PROFILE_GL_20 = "GL20"; - /** Returns the sole GLDrawableFactory instance. */ - public static GLDrawableFactory getFactory() { - if (factory == null) { + /** The OpenGL ES 1 (really, 1.1) profile */ + public static final String PROFILE_GLES1 = "GLES1"; - // FIXME: hook this in to the normal reflective mechanism - factory = new com.sun.opengl.impl.egl.EGLDrawableFactory(); + /** The OpenGL ES 2 (really, 2.0) profile */ + public static final String PROFILE_GLES2 = "GLES2"; - /* + private String profile; + /** Initializes the sole GLDrawableFactory instance for the given profile. */ + public static void initialize(String profile) throws GLException { + if (factory != null) { + throw new GLException("Already initialized"); + } + + // See if the user is requesting one of the embedded profiles, + // and if so, try to instantiate the EGLDrawableFactory + if (PROFILE_GLES1.equals(profile) || + PROFILE_GLES2.equals(profile)) { try { - String factoryClassName = - (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("opengl.factory.class.name"); - } - }); - String osName = System.getProperty("os.name"); - String osNameLowerCase = osName.toLowerCase(); - Class factoryClass = null; + Class clazz = Class.forName("com.sun.opengl.impl.egl.EGLDrawableFactory"); + Constructor c = clazz.getDeclaredConstructor(new Class[] { String.class }); + factory = (GLDrawableFactory) c.newInstance(new Object[] { profile }); + } catch (Exception e) { + } + } else if (!PROFILE_GL_20.equals(profile)) { + // We require that the user passes in one of the known profiles + throw new GLException("Unknown or unsupported profile \"" + profile + "\""); + } - // Because there are some complications with generating all - // platforms' Java glue code on all platforms (among them that we - // would have to include jawt.h and jawt_md.h in the jogl - // sources, which we currently don't have to do) we break the only - // static dependencies with platform-specific code here using reflection. + // Use the desktop OpenGL as the fallback always + try { + String factoryClassName = + (String) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty("opengl.factory.class.name"); + } + }); + String osName = System.getProperty("os.name"); + String osNameLowerCase = osName.toLowerCase(); + Class factoryClass = null; - if (factoryClassName != null) { - factoryClass = Class.forName(factoryClassName); - } else if (osNameLowerCase.startsWith("wind")) { - factoryClass = Class.forName("com.sun.opengl.impl.windows.WindowsGLDrawableFactory"); - } else if (osNameLowerCase.startsWith("mac os x")) { - factoryClass = Class.forName("com.sun.opengl.impl.macosx.MacOSXGLDrawableFactory"); - } else { - // Assume Linux, Solaris, etc. Should probably test for these explicitly. - factoryClass = Class.forName("com.sun.opengl.impl.x11.X11GLDrawableFactory"); - } + // Because there are some complications with generating all + // platforms' Java glue code on all platforms (among them that we + // would have to include jawt.h and jawt_md.h in the jogl + // sources, which we currently don't have to do) we break the only + // static dependencies with platform-specific code here using reflection. - if (factoryClass == null) { - throw new GLException("OS " + osName + " not yet supported"); - } + if (factoryClassName != null) { + factoryClass = Class.forName(factoryClassName); + } else if (osNameLowerCase.startsWith("wind")) { + factoryClass = Class.forName("com.sun.opengl.impl.windows.WindowsGLDrawableFactory"); + } else if (osNameLowerCase.startsWith("mac os x")) { + factoryClass = Class.forName("com.sun.opengl.impl.macosx.MacOSXGLDrawableFactory"); + } else { + // Assume Linux, Solaris, etc. Should probably test for these explicitly. + factoryClass = Class.forName("com.sun.opengl.impl.x11.X11GLDrawableFactory"); + } - factory = (GLDrawableFactory) factoryClass.newInstance(); - } catch (Exception e) { - throw new GLException(e); + if (factoryClass == null) { + throw new GLException("OS " + osName + " not yet supported"); } - */ + Constructor c = factoryClass.getDeclaredConstructor(new Class[] { String.class }); + factory = (GLDrawableFactory) c.newInstance(new Object[] { profile }); + } catch (Exception e) { + throw new GLException(e); + } + } + + /** Creates a new GLDrawableFactory instance. End users do not need + to call this method. */ + protected GLDrawableFactory(String profile) { + this.profile = profile; + } + + /** Returns the sole GLDrawableFactory instance for the specified profile. */ + public static GLDrawableFactory getFactory() { + if (factory == null) { + throw new GLException("Must call initialize() first"); } return factory; } + /** Indicates which profile this GLDrawableFactory was created for. */ + public String getProfile() { + return profile; + } + /** * <P> Selects a graphics configuration on the specified graphics * device compatible with the supplied GLCapabilities. This method |