aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java185
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java33
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java27
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java40
4 files changed, 247 insertions, 38 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 5e3731984..cad780a89 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -52,6 +52,7 @@ import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLSharedContextSetter;
import javax.media.opengl.Threading;
import jogamp.nativewindow.x11.X11Util;
@@ -85,7 +86,7 @@ import com.jogamp.opengl.JoglVersion;
* Implementation allows use of custom {@link GLCapabilities}.
* </p>
*/
-public class GLCanvas extends Canvas implements GLAutoDrawable {
+public class GLCanvas extends Canvas implements GLAutoDrawable, GLSharedContextSetter {
private static final boolean DEBUG = Debug.debug("GLCanvas");
/*
@@ -103,13 +104,12 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
- private final GLContext shareWith;
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
private volatile Rectangle clientArea;
private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
- private volatile GLContextImpl context;
+ private volatile GLContextImpl context; // volatile: avoid locking for read-only access
/* Native window surface */
private final boolean useX11GTK;
@@ -124,6 +124,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
/* Flag indicating whether an unprocessed reshape is pending. */
private volatile boolean sendReshape; // volatile: maybe written by WindowManager thread w/o locking
+ private static String getThreadName() { return Thread.currentThread().getName(); }
+ private static String toHexString(int v) { return "0x"+Integer.toHexString(v); }
+ private static String toHexString(long v) { return "0x"+Long.toHexString(v); }
+
/*
* Invokes init(...) on all GLEventListeners. Assumes context is current when run.
*/
@@ -263,6 +267,36 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/**
+ * Creates an instance using {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser)}
+ * on the SWT thread.
+ *
+ * @param parent
+ * Required (non-null) parent Composite.
+ * @param style
+ * Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
+ * Canvas constructor, so OpenGL handles the background.
+ * @param caps
+ * Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
+ * graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
+ * actually used may differ based on the capabilities of the graphics device.
+ * @param chooser
+ * Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
+ * requested GLCapabilities, and the available capabilities of the graphics device.
+ * @return a new instance
+ */
+ public static GLCanvas create(final Composite parent, final int style, final GLCapabilitiesImmutable caps,
+ final GLCapabilitiesChooser chooser) {
+ final GLCanvas[] res = new GLCanvas[] { null };
+ parent.getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ res[0] = new GLCanvas( parent, style, caps, chooser );
+ }
+ });
+ return res[0];
+ }
+
+ /**
* Creates an instance using {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser, GLContext)}
* on the SWT thread.
*
@@ -281,6 +315,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
* @param shareWith
* Optional GLContext to share state (textures, vbos, shaders, etc.) with.
* @return a new instance
+ * @deprecated Use {@link #create(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser)}
+ * and set shared GLContext via {@link #setSharedContext(GLContext)} or {@link #setSharedAutoDrawable(GLAutoDrawable)}.
*/
public static GLCanvas create(final Composite parent, final int style, final GLCapabilitiesImmutable caps,
final GLCapabilitiesChooser chooser, final GLContext shareWith) {
@@ -309,8 +345,31 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
* @param capsChooser
* Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
* requested GLCapabilities, and the available capabilities of the graphics device.
+ */
+ public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable capsReqUser,
+ final GLCapabilitiesChooser capsChooser) {
+ this(parent, style, capsReqUser, capsChooser, null);
+ }
+
+ /**
+ * Creates a new SWT GLCanvas.
+ *
+ * @param parent
+ * Required (non-null) parent Composite.
+ * @param style
+ * Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
+ * Canvas constructor, so OpenGL handles the background.
+ * @param capsReqUser
+ * Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
+ * graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
+ * actually used may differ based on the capabilities of the graphics device.
+ * @param capsChooser
+ * Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
+ * requested GLCapabilities, and the available capabilities of the graphics device.
* @param shareWith
* Optional GLContext to share state (textures, vbos, shaders, etc.) with.
+ * @deprecated Use {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser)}
+ * and set shared GLContext via {@link #setSharedContext(GLContext)} or {@link #setSharedAutoDrawable(GLAutoDrawable)}.
*/
public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable capsReqUser,
final GLCapabilitiesChooser capsChooser, final GLContext shareWith) {
@@ -347,7 +406,9 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
this.capsRequested = capsReqUser;
this.capsChooser = capsChooser;
- this.shareWith = shareWith;
+ if( null != shareWith ) {
+ helper.setSharedContext(null, shareWith);
+ }
// post create .. when ready
gdkWindow = 0;
@@ -376,6 +437,16 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
addListener (SWT.Dispose, listener);
}
+ @Override
+ public final void setSharedContext(GLContext sharedContext) throws IllegalStateException {
+ helper.setSharedContext(this.context, sharedContext);
+ }
+
+ @Override
+ public final void setSharedAutoDrawable(GLAutoDrawable sharedAutoDrawable) throws IllegalStateException {
+ helper.setSharedAutoDrawable(this, sharedAutoDrawable);
+ }
+
private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -411,7 +482,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
final boolean drawableOK = null != _drawable && _drawable.isRealized();
if(DEBUG) {
final long dh = drawableOK ? _drawable.getHandle() : 0;
- System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - drawableHandle 0x"+Long.toHexString(dh));
+ System.err.println(getThreadName()+": GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - drawableHandle "+toHexString(dh));
}
if( drawableOK ) {
if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
@@ -451,7 +522,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
}
- /** assumes drawable == null || !drawable.isRealized() ! Checks of !isDispose() and isVisible() */
+ /** assumes drawable == null (implying !drawable.isRealized()) ! Checks of !isDispose() and isVisible() */
protected final boolean validateDrawableAndContextWithCheck() {
if( !isValidAndVisibleOnEDT() ) {
return false;
@@ -459,41 +530,55 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return validateDrawableAndContextPostCheck();
}
- /** assumes drawable == null || !drawable.isRealized() ! No check of !isDispose() and isVisible() */
- protected final boolean validateDrawableAndContextPostCheck() {
- final Rectangle nClientArea = clientArea;
- if(0 >= nClientArea.width || 0 >= nClientArea.height) {
- return false;
- }
+ private final boolean isDrawableAndContextValid() {
+ // drawable != null implies drawable.isRealized()==true
+ return null != drawable && null != context;
+ }
- final boolean res;
+ /** assumes drawable == null (implying !drawable.isRealized()) || context == null ! No check of !isDispose() and isVisible() */
+ private final boolean validateDrawableAndContextPostCheck() {
+ boolean res;
final RecursiveLock _lock = lock;
_lock.lock();
try {
if(null == drawable) {
- createDrawableAndContext();
+ // 'displayable' (isValidAndVisibleOnEDT()) must have been checked upfront if appropriate!
+ createDrawableImpl(); // checks clientArea size (i.e. drawable size) and perf. realization
}
- if(null != drawable) {
- drawable.setRealized(true);
- res = drawable.isRealized();
+ final GLDrawable _drawable = drawable;
+ if ( null != _drawable ) {
+ // drawable realization goes in-hand w/ it's construction
+ if( null == context ) {
+ // re-try context creation
+ res = createContextImpl(_drawable); // pending creation.
+ } else {
+ res = true;
+ }
+ if(res) {
+ sendReshape = true;
+ }
} else {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": null drawable");
+ }
res = false;
}
- } finally {
- _lock.unlock();
- }
-
- if(res) {
- sendReshape = true;
if(DEBUG) {
- System.err.println("SWT GLCanvas realized! "+this+", "+drawable);
- // Thread.dumpStack();
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": "+res+", drawable-realized "+drawable.isRealized()+", has context "+(null!=context));
}
+ } finally {
+ _lock.unlock();
}
return res;
}
-
- private final void createDrawableAndContext() {
+ private final void createDrawableImpl() {
+ final Rectangle nClientArea = clientArea;
+ if(0 >= nClientArea.width || 0 >= nClientArea.height) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": drawable could not be created: size < 0x0");
+ }
+ return; // early out
+ }
final AbstractGraphicsDevice device = screen.getDevice();
device.open();
@@ -503,7 +588,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
capsRequested, capsRequested, capsChooser, screen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG) {
- System.err.println("SWT.GLCanvas.X11 factory: "+factory+", chosen config: "+cfg);
+ System.err.println(getThreadName()+": SWT.GLCanvas.X11 "+toHexString(hashCode())+": factory: "+factory+", chosen config: "+cfg);
}
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
@@ -515,7 +600,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientArea.width, clientArea.height);
nativeWindowHandle = x11Window;
} else {
- throw new GLException("Could not choose valid visualID: 0x"+Integer.toHexString(visualID)+", "+this);
+ throw new GLException("Could not choose valid visualID: "+toHexString(visualID)+", "+this);
}
} else {
nativeWindowHandle = SWTAccessor.getWindowHandle(this);
@@ -526,9 +611,35 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
ProxySurface proxySurface = glFactory.createProxySurface(device, screen.getIndex(), nativeWindowHandle,
capsRequested, capsChooser, swtCanvasUpStreamHook);
// Associate a GL surface with the proxy
- drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setContextCreationFlags(additionalCtxCreationFlags);
+ final GLDrawableImpl _drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
+ _drawable.setRealized(true);
+ if(!_drawable.isRealized()) {
+ // oops
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate.X "+toHexString(hashCode())+": Drawable could not be realized: "+_drawable);
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Drawable created and realized");
+ }
+ drawable = _drawable;
+ }
+ }
+ private boolean createContextImpl(final GLDrawable drawable) {
+ final GLContext[] shareWith = { null };
+ if( !helper.isSharedGLContextPending(shareWith) ) {
+ context = (GLContextImpl) drawable.createContext(shareWith[0]);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Context created: has shared "+(null != shareWith[0]));
+ }
+ return true;
+ } else {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": SWT.GLCanvas.validate "+toHexString(hashCode())+": Context !created: pending share");
+ }
+ return false;
+ }
}
@Override
@@ -555,8 +666,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final void displayIfNoAnimatorNoCheck() {
if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
- final boolean drawableOK = null != drawable && drawable.isRealized();
- if( drawableOK || validateDrawableAndContextPostCheck() ) {
+ if( isDrawableAndContextValid() || validateDrawableAndContextPostCheck() ) {
runInGLThread(makeCurrentAndDisplayOnGLAction);
}
}
@@ -568,8 +678,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void display() {
- final boolean drawableOK = null != drawable && drawable.isRealized();
- if( drawableOK || validateDrawableAndContextWithCheck() ) {
+ if( isDrawableAndContextValid() || validateDrawableAndContextWithCheck() ) {
runInGLThread(makeCurrentAndDisplayOnGLAction);
}
}
@@ -876,7 +985,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return "SWT-GLCanvas[Realized "+isRealized()+
",\n\t"+((null!=_drawable)?_drawable.getClass().getName():"null-drawable")+
",\n\tFactory "+getFactory()+
- ",\n\thandle 0x"+Long.toHexString(getHandle())+
+ ",\n\thandle "+toHexString(getHandle())+
",\n\tDrawable size "+dw+"x"+dh+
",\n\tSWT size "+getWidth()+"x"+getHeight()+"]";
}
@@ -895,7 +1004,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
shell.setSize(128,128);
shell.setLayout(new FillLayout());
- final GLCanvas canvas = new GLCanvas(shell, 0, caps, null, null);
+ final GLCanvas canvas = new GLCanvas(shell, 0, caps, null);
canvas.addGLEventListener(new GLEventListener() {
@Override
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index f480c4bde..f84342e88 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -28,6 +28,7 @@
package com.jogamp.opengl.util;
+import java.lang.reflect.Constructor;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
@@ -444,6 +445,38 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
protected GLArrayDataClient() { }
+ /**
+ * Copy Constructor
+ * <p>
+ * Buffer is {@link Buffers#slice(Buffer) sliced}, i.e. sharing content but using own state.
+ * </p>
+ * <p>
+ * All other values are simply copied.
+ * </p>
+ */
+ public GLArrayDataClient(GLArrayDataClient src) {
+ super(src);
+ this.isValidated = src.isValidated;
+ this.sealed = src.sealed;
+ this.bufferEnabled = src.bufferEnabled;
+ this.bufferWritten = src.bufferWritten;
+ this.enableBufferAlways = src.enableBufferAlways;
+ this.initialElementCount = src.initialElementCount;
+ if( null != src.glArrayHandler ) {
+ final Class<? extends GLArrayHandler> clazz = src.glArrayHandler.getClass();
+ try {
+ final Constructor<? extends GLArrayHandler> ctor = clazz.getConstructor(GLArrayDataEditable.class);
+ this.glArrayHandler = ctor.newInstance(this);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not ctor "+clazz.getName()+"("+this.getClass().getName()+")", e);
+ }
+ } else {
+ this.glArrayHandler = null;
+ }
+ this.usesGLSL = src.usesGLSL;
+ this.shaderState = src.shaderState;
+ }
+
protected boolean sealed;
protected boolean bufferEnabled;
protected boolean bufferWritten;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
index 96643ae72..4a12ff1ae 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java
@@ -29,6 +29,7 @@
package com.jogamp.opengl.util;
import java.nio.Buffer;
+import java.nio.FloatBuffer;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
@@ -36,6 +37,8 @@ import javax.media.opengl.GLArrayData;
import javax.media.opengl.GLException;
import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+import com.jogamp.common.nio.Buffers;
+
import jogamp.opengl.util.GLArrayHandler;
import jogamp.opengl.util.GLArrayHandlerInterleaved;
import jogamp.opengl.util.GLDataArrayHandler;
@@ -364,6 +367,14 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
return ad;
}
+ public final void setInterleavedOffset(int interleavedOffset) {
+ this.interleavedOffset = interleavedOffset;
+ }
+
+ public final int getInterleavedOffset() {
+ return interleavedOffset;
+ }
+
//
// Data matters GLArrayData
//
@@ -458,6 +469,22 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE
}
}
+ protected GLArrayDataServer() { }
+
+ /**
+ * Copy Constructor
+ * <p>
+ * Buffer is {@link Buffers#slice(Buffer) sliced}, i.e. sharing content but using own state.
+ * </p>
+ * <p>
+ * All other values are simply copied.
+ * </p>
+ */
+ public GLArrayDataServer(GLArrayDataServer src) {
+ super(src);
+ this.interleavedOffset = src.interleavedOffset;
+ }
+
private int interleavedOffset = 0;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
index 290f47a6d..068ab5203 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataWrapper.java
@@ -42,6 +42,8 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
+import com.jogamp.common.nio.Buffers;
+
import jogamp.opengl.Debug;
public class GLArrayDataWrapper implements GLArrayData {
@@ -373,6 +375,44 @@ public class GLArrayDataWrapper implements GLArrayData {
protected GLArrayDataWrapper() { }
+ /**
+ * Copy Constructor
+ * <p>
+ * Buffer is {@link Buffers#slice(Buffer) sliced}, i.e. sharing content but using own state.
+ * </p>
+ * <p>
+ * All other values are simply copied.
+ * </p>
+ */
+ public GLArrayDataWrapper(GLArrayDataWrapper src) {
+ this.alive = src.alive;
+ this.index = src.index;
+ this.location = src.location;
+ this.name = src.name;
+ this.components = src.components;
+ this.componentType = src.componentType;
+ this.componentClazz = src.componentClazz;
+ this.componentByteSize = src.componentByteSize;
+ this.normalized = src.normalized;
+ this.strideB = src.strideB;
+ this.strideL = src.strideL;
+ if( null != src.buffer ) {
+ if( src.buffer.position() == 0 ) {
+ this.buffer = Buffers.slice(src.buffer);
+ } else {
+ this.buffer = Buffers.slice(src.buffer, 0, src.buffer.limit());
+ }
+ } else {
+ this.buffer = null;
+ }
+ this.isVertexAttribute = src.isVertexAttribute;
+ this.vboOffset = src.vboOffset;
+ this.vboName = src.vboName;
+ this.vboEnabled = src.vboEnabled;
+ this.vboUsage = src.vboUsage;
+ this.vboTarget = src.vboTarget;
+ }
+
protected boolean alive;
protected int index;
protected int location;