summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-14 19:38:49 +0100
committerSven Gothel <[email protected]>2014-01-14 19:38:49 +0100
commitf8a74c9831c65725a699320c27e62161a0378241 (patch)
treed98f024c84ab31404e4b8bb7608dd60941965f4b
parent961930f9e2cd40dc4de736201bcfa68c1ff09909 (diff)
Revert "Bug 942 - Share GLBufferStateTracker ; Unify GLBufferStateTracker and GLBufferSizeTracker (simplification)"
This reverts commit 7c5483d5b20aed9c87c5ce3f6bc840b6546edcd1.
-rw-r--r--make/config/jogl/gl-common.cfg2
-rw-r--r--make/config/jogl/gl-gl4bc.cfg2
-rw-r--r--make/config/jogl/gl-impl-CustomJavaCode-common.java6
-rw-r--r--make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java3
-rw-r--r--make/config/jogl/gl-impl-CustomJavaCode-gles1.java3
-rw-r--r--make/config/jogl/gl-impl-CustomJavaCode-gles3.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java200
-rw-r--r--src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java195
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java28
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextShareSet.java24
10 files changed, 274 insertions, 192 deletions
diff --git a/make/config/jogl/gl-common.cfg b/make/config/jogl/gl-common.cfg
index ee4af5e69..b84115445 100644
--- a/make/config/jogl/gl-common.cfg
+++ b/make/config/jogl/gl-common.cfg
@@ -557,7 +557,7 @@ JavaEpilogue glPushClientAttrib bufferStateTracker.clearBufferObjectState();
JavaEpilogue glPushClientAttrib glStateTracker.pushAttrib(mask);
JavaEpilogue glPopClientAttrib bufferStateTracker.clearBufferObjectState();
JavaEpilogue glPopClientAttrib glStateTracker.popAttrib();
-JavaEpilogue glBufferData bufferStateTracker.setBufferSize({0}, this, {1});
+JavaEpilogue glBufferData bufferSizeTracker.setBufferSize(bufferStateTracker, {0}, this, {1});
BufferObjectKind Array glColorPointer
BufferObjectKind Array glEdgeFlagPointer
diff --git a/make/config/jogl/gl-gl4bc.cfg b/make/config/jogl/gl-gl4bc.cfg
index e6e85e2e5..c3a392c52 100644
--- a/make/config/jogl/gl-gl4bc.cfg
+++ b/make/config/jogl/gl-gl4bc.cfg
@@ -59,7 +59,7 @@ Include gl2_es2-CustomJavaCode.cfg
# can only be computed by calling another routine
ManuallyImplement glMapNamedBufferEXT
ForceProcAddressGen glMapNamedBufferEXT
-JavaEpilogue glNamedBufferDataEXT bufferStateTracker.setDirectStateBufferSize({0}, this, {1});
+JavaEpilogue glNamedBufferDataEXT bufferSizeTracker.setDirectStateBufferSize({0}, this, {1});
# Manuall implement glDebugMessageCallback* using the proc address resolver
ForceProcAddressGen glDebugMessageCallback
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index 3aeda1309..b8da61065 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -11,7 +11,7 @@
@Override
public final long glGetBufferSize(int buffer) {
- return bufferStateTracker.getDirectStateBufferSize(buffer, this);
+ return bufferSizeTracker.getDirectStateBufferSize(buffer, this);
}
@Override
@@ -135,7 +135,7 @@
if (glProcAddress == 0) {
throw new GLException("Method \""+(useRange?"glMapBufferRange":"glMapBuffer")+"\" not available");
}
- final long sz = bufferStateTracker.getBufferSize(target, this);
+ final long sz = bufferSizeTracker.getBufferSize(bufferStateTracker, target, this);
if (0 == sz) {
return null;
}
@@ -188,7 +188,7 @@
if (glProcAddress == 0) {
throw new GLException("Method \"glMapNamedBufferEXT\" not available");
}
- final long sz = bufferStateTracker.getDirectStateBufferSize(bufferName, this);
+ final long sz = bufferSizeTracker.getDirectStateBufferSize(bufferName, this);
if (0 == sz) {
return null;
}
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
index 980603edc..e7389de10 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
@@ -18,9 +18,11 @@ public void setObjectTracker(GLObjectTracker tracker) {
public GL4bcImpl(GLProfile glp, GLContextImpl context) {
this._context = context;
if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
this.bufferStateTracker = context.getBufferStateTracker();
this.glStateTracker = context.getGLStateTracker();
} else {
+ this.bufferSizeTracker = null;
this.bufferStateTracker = null;
this.glStateTracker = null;
}
@@ -278,6 +280,7 @@ public final void glFreeMemoryNV(java.nio.ByteBuffer pointer) {
// Helpers for ensuring the correct amount of texture data
//
+private final GLBufferSizeTracker bufferSizeTracker;
private final GLBufferStateTracker bufferStateTracker;
private final GLStateTracker glStateTracker;
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index 1d1cf3abf..8d5dcc7a5 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -1,9 +1,11 @@
public GLES1Impl(GLProfile glp, GLContextImpl context) {
this._context = context;
if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
this.bufferStateTracker = context.getBufferStateTracker();
this.glStateTracker = context.getGLStateTracker();
} else {
+ this.bufferSizeTracker = null;
this.bufferStateTracker = null;
this.glStateTracker = null;
}
@@ -197,6 +199,7 @@ public final GL2GL3 getGL2GL3() throws GLException {
// Helpers for ensuring the correct amount of texture data
//
+private final GLBufferSizeTracker bufferSizeTracker;
private final GLBufferStateTracker bufferStateTracker;
private final GLStateTracker glStateTracker;
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles3.java b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
index 006ee4da1..d5ad16873 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles3.java
@@ -2,9 +2,11 @@
public GLES3Impl(GLProfile glp, GLContextImpl context) {
this._context = context;
if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
this.bufferStateTracker = context.getBufferStateTracker();
this.glStateTracker = context.getGLStateTracker();
} else {
+ this.bufferSizeTracker = null;
this.bufferStateTracker = null;
this.glStateTracker = null;
}
@@ -209,6 +211,7 @@ public final GL2GL3 getGL2GL3() throws GLException {
//
private final boolean _isES3;
+private final GLBufferSizeTracker bufferSizeTracker;
private final GLBufferStateTracker bufferStateTracker;
private final GLStateTracker glStateTracker;
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java
new file mode 100644
index 000000000..fa05902d5
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLBufferSizeTracker.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package jogamp.opengl;
+
+import javax.media.opengl.*;
+import com.jogamp.common.util.IntLongHashMap;
+
+/**
+ * Tracks as closely as possible the sizes of allocated OpenGL buffer
+ * objects. When glMapBuffer or glMapBufferARB is called, in order to
+ * turn the resulting base address into a java.nio.ByteBuffer, we need
+ * to know the size in bytes of the allocated OpenGL buffer object.
+ * Previously we would compute this size by using
+ * glGetBufferParameterivARB with a pname of GL_BUFFER_SIZE, but
+ * it appears doing so each time glMapBuffer is called is too costly
+ * on at least Apple's new multithreaded OpenGL implementation. <P>
+ *
+ * Instead we now try to track the sizes of allocated buffer objects.
+ * We watch calls to glBindBuffer to see which buffer is bound to
+ * which target and to glBufferData to see how large the buffer's
+ * allocated size is. When glMapBuffer is called, we consult our table
+ * of buffer sizes to see if we can return an answer without a glGet
+ * call. <P>
+ *
+ * We share the GLBufferSizeTracker objects among all GLContexts for
+ * which sharing is enabled, because the namespace for buffer objects
+ * is the same for these contexts. <P>
+ *
+ * Tracking the state of which buffer objects are bound is done in the
+ * GLBufferStateTracker and is not completely trivial. In the face of
+ * calls to glPushClientAttrib / glPopClientAttrib we currently punt
+ * and re-fetch the bound buffer object for the state in question;
+ * see, for example, glVertexPointer and the calls down to
+ * GLBufferStateTracker.getBoundBufferObject(). Note that we currently
+ * ignore new binding targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV;
+ * the fact that new binding targets may be added in the future makes
+ * it impossible to cache state for these new targets. <P>
+ *
+ * Ignoring new binding targets, the primary situation in which we may
+ * not be able to return a cached answer is in the case of an error,
+ * where glBindBuffer may not have been called before trying to call
+ * glBufferData. Also, if external native code modifies a buffer
+ * object, we may return an incorrect answer. (FIXME: this case
+ * requires more thought, and perhaps stochastic and
+ * exponential-fallback checking. However, note that it can only occur
+ * in the face of external native code which requires that the
+ * application be signed anyway, so there is no security risk in this
+ * area.)
+ */
+
+public class GLBufferSizeTracker {
+ protected static final boolean DEBUG;
+
+ static {
+ Debug.initSingleton();
+ DEBUG = Debug.isPropertyDefined("jogl.debug.GLBufferSizeTracker", true);
+ }
+
+ // Map from buffer names to sizes.
+ // Note: should probably have some way of shrinking this map, but
+ // can't just make it a WeakHashMap because nobody holds on to the
+ // keys; would have to always track creation and deletion of buffer
+ // objects, which is probably sub-optimal. The expected usage
+ // pattern of buffer objects indicates that the fact that this map
+ // never shrinks is probably not that bad.
+ private final IntLongHashMap bufferSizeMap;
+ private final long keyNotFount = 0xFFFFFFFFFFFFFFFFL;
+
+ public GLBufferSizeTracker() {
+ bufferSizeMap = new IntLongHashMap();
+ bufferSizeMap.setKeyNotFoundValue(keyNotFount);
+ }
+
+ public final void setBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target, GL caller, long size) {
+ // Need to do some similar queries to getBufferSize below
+ int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ if (buffer != 0) {
+ setDirectStateBufferSize(buffer, caller, size);
+ }
+ // We don't know the current buffer state. Note that the buffer
+ // state tracker will have made the appropriate OpenGL query if it
+ // didn't know what was going on, so at this point we have nothing
+ // left to do except drop this piece of information on the floor.
+ }
+
+ public final void setDirectStateBufferSize(int buffer, GL caller, long size) {
+ bufferSizeMap.put(buffer, size);
+ }
+
+ public final long getBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target,
+ GL caller) {
+ // See whether we know what buffer is currently bound to the given
+ // state
+ final int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ if (0 != buffer) {
+ return getBufferSizeImpl(target, buffer, caller);
+ }
+ // We don't know what's going on in this case; query the GL for an answer
+ // FIXME: both functions return 'int' types, which is not suitable,
+ // since buffer lenght is 64bit ?
+ int[] tmp = new int[1];
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information");
+ }
+ return tmp[0];
+ }
+
+ public final long getDirectStateBufferSize(int buffer, GL caller) {
+ return getBufferSizeImpl(0, buffer, caller);
+ }
+
+ private final long getBufferSizeImpl(int target, int buffer, GL caller) {
+ // See whether we know the size of this buffer object; at this
+ // point we almost certainly should if the application is
+ // written correctly
+ long sz = bufferSizeMap.get(buffer);
+ if (keyNotFount == sz) {
+ // For robustness, try to query this value from the GL as we used to
+ // FIXME: both functions return 'int' types, which is not suitable,
+ // since buffer lenght is 64bit ?
+ int[] tmp = new int[1];
+ if(0==target) {
+ // DirectState ..
+ if(caller.isFunctionAvailable("glGetNamedBufferParameterivEXT")) {
+ caller.getGL2().glGetNamedBufferParameterivEXT(buffer, GL.GL_BUFFER_SIZE, tmp, 0);
+ } else {
+ throw new GLException("Error: getDirectStateBufferSize called with unknown state and GL function 'glGetNamedBufferParameterivEXT' n/a to query size");
+ }
+ } else {
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ }
+ if (tmp[0] == 0) {
+ // Assume something is wrong rather than silently going along
+ throw new GLException("Error: buffer size returned by "+
+ ((0==target)?"glGetNamedBufferParameterivEXT":"glGetBufferParameteriv")+
+ " was zero; probably application error");
+ }
+ // Assume we just don't know what's happening
+ sz = tmp[0];
+ bufferSizeMap.put(buffer, sz);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " +
+ sz +
+ " for buffer " +
+ buffer);
+ }
+ }
+ return sz;
+ }
+
+ // This should be called on any major event where we might start
+ // producing wrong answers, such as OpenGL context creation and
+ // destruction if we don't know whether there are other currently-
+ // created contexts that might be keeping the buffer objects alive
+ // that we're dealing with
+ public final void clearCachedBufferSizes() {
+ bufferSizeMap.clear();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
index 21b7da14d..16b7edca8 100644
--- a/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
+++ b/src/jogl/classes/jogamp/opengl/GLBufferStateTracker.java
@@ -43,11 +43,8 @@ package jogamp.opengl;
import javax.media.opengl.*;
import com.jogamp.common.util.IntIntHashMap;
-import com.jogamp.common.util.IntLongHashMap;
/**
- * <b>Buffer Target Mapping (Binding)</b>
- * <p>
* Tracks as closely as possible which OpenGL buffer object is bound
* to which binding target in the current OpenGL context.
* GLBufferStateTracker objects are allocated on a per-OpenGL-context basis.
@@ -76,52 +73,9 @@ import com.jogamp.common.util.IntLongHashMap;
* the binding state if glPushClientAttrib / glPopClientAttrib are
* called, since we don't want the complexity of tracking stacks of
* these attributes.
- * </p>
*
- * <b>Buffer Size Mapping</b>
- * <p>
- * Tracks as closely as possible the sizes of allocated OpenGL buffer
- * objects. When glMapBuffer or glMapBufferARB is called, in order to
- * turn the resulting base address into a java.nio.ByteBuffer, we need
- * to know the size in bytes of the allocated OpenGL buffer object.
- * Previously we would compute this size by using
- * glGetBufferParameterivARB with a pname of GL_BUFFER_SIZE, but
- * it appears doing so each time glMapBuffer is called is too costly
- * on at least Apple's new multithreaded OpenGL implementation. <P>
- *
- * Instead we now try to track the sizes of allocated buffer objects.
- * We watch calls to glBindBuffer to see which buffer is bound to
- * which target and to glBufferData to see how large the buffer's
- * allocated size is. When glMapBuffer is called, we consult our table
- * of buffer sizes to see if we can return an answer without a glGet
- * call. <P>
- *
- * We share the GLBufferSizeTracker objects among all GLContexts for
- * which sharing is enabled, because the namespace for buffer objects
- * is the same for these contexts. <P>
- *
- * Tracking the state of which buffer objects are bound is done in the
- * GLBufferStateTracker and is not completely trivial. In the face of
- * calls to glPushClientAttrib / glPopClientAttrib we currently punt
- * and re-fetch the bound buffer object for the state in question;
- * see, for example, glVertexPointer and the calls down to
- * GLBufferStateTracker.getBoundBufferObject(). Note that we currently
- * ignore new binding targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV;
- * the fact that new binding targets may be added in the future makes
- * it impossible to cache state for these new targets. <P>
- *
- * Ignoring new binding targets, the primary situation in which we may
- * not be able to return a cached answer is in the case of an error,
- * where glBindBuffer may not have been called before trying to call
- * glBufferData. Also, if external native code modifies a buffer
- * object, we may return an incorrect answer. (FIXME: this case
- * requires more thought, and perhaps stochastic and
- * exponential-fallback checking. However, note that it can only occur
- * in the face of external native code which requires that the
- * application be signed anyway, so there is no security risk in this
- * area.)
- * </p>
*/
+
public class GLBufferStateTracker {
protected static final boolean DEBUG;
@@ -135,24 +89,14 @@ public class GLBufferStateTracker {
// known that no buffer is bound to the target, according to the
// OpenGL specifications.
// http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml
- private final IntIntHashMap bufferBindingMap;
- private final int bufferNotFound = 0xFFFFFFFF;
-
- // Map from buffer names to sizes.
- // Note: should probably have some way of shrinking this map, but
- // can't just make it a WeakHashMap because nobody holds on to the
- // keys; would have to always track creation and deletion of buffer
- // objects, which is probably sub-optimal. The expected usage
- // pattern of buffer objects indicates that the fact that this map
- // never shrinks is probably not that bad.
- private final IntLongHashMap bufferSizeMap;
- private final long sizeNotFound = 0xFFFFFFFFFFFFFFFFL;
+ private final IntIntHashMap bindingMap;
+ private final int keyNotFound = 0xFFFFFFFF;
private final int[] bufTmp = new int[1];
public GLBufferStateTracker() {
- bufferBindingMap = new IntIntHashMap();
- bufferBindingMap.setKeyNotFoundValue(bufferNotFound);
+ bindingMap = new IntIntHashMap();
+ bindingMap.setKeyNotFoundValue(keyNotFound);
// Start with known unbound targets for known keys
// setBoundBufferObject(GL2ES3.GL_VERTEX_ARRAY_BINDING, 0); // not using default VAO (removed in GL3 core) - only explicit
@@ -161,26 +105,10 @@ public class GLBufferStateTracker {
setBoundBufferObject(GL2.GL_PIXEL_PACK_BUFFER, 0);
setBoundBufferObject(GL2.GL_PIXEL_UNPACK_BUFFER, 0);
setBoundBufferObject(GL4.GL_DRAW_INDIRECT_BUFFER, 0);
-
- bufferSizeMap = new IntLongHashMap();
- bufferSizeMap.setKeyNotFoundValue(sizeNotFound);
- }
-
- /**
- * Clears all states, i.e. issues {@link #clearBufferObjectState()}
- * and {@link #clearCachedBufferSizes()}.
- */
- public final void clear() {
- clearBufferObjectState();
- clearCachedBufferSizes();
}
- //
- // Buffer target mapping (binding)
- //
-
public final void setBoundBufferObject(int target, int value) {
- bufferBindingMap.put(target, value);
+ bindingMap.put(target, value);
/***
* Test for clearing bound buffer states when unbinding VAO,
* Bug 692 Comment 5 is invalid, i.e. <https://jogamp.org/bugzilla/show_bug.cgi?id=692#c5>.
@@ -210,21 +138,21 @@ public class GLBufferStateTracker {
You must use isBoundBufferObjectKnown() to see whether the
return value is valid. */
public final int getBoundBufferObject(int target, GL caller) {
- int value = bufferBindingMap.get(target);
- if (bufferNotFound == value) {
+ int value = bindingMap.get(target);
+ if (keyNotFound == value) {
// User probably either called glPushClientAttrib /
// glPopClientAttrib or is querying an unknown target. See
// whether we know how to fetch this state.
boolean gotQueryTarget = true;
- int queryTarget;
+ int queryTarget = 0;
switch (target) {
case GL2ES3.GL_VERTEX_ARRAY_BINDING: queryTarget = GL2ES3.GL_VERTEX_ARRAY_BINDING; break;
- case GL.GL_ARRAY_BUFFER: queryTarget = GL.GL_ARRAY_BUFFER_BINDING; break;
- case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
- case GL2ES3.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break;
- case GL2ES3.GL_PIXEL_UNPACK_BUFFER: queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING; break;
- case GL4.GL_DRAW_INDIRECT_BUFFER: queryTarget = GL4.GL_DRAW_INDIRECT_BUFFER_BINDING; break;
- default: queryTarget = 0; gotQueryTarget = false; break;
+ case GL.GL_ARRAY_BUFFER: queryTarget = GL.GL_ARRAY_BUFFER_BINDING; break;
+ case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_UNPACK_BUFFER: queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING; break;
+ case GL4.GL_DRAW_INDIRECT_BUFFER: queryTarget = GL4.GL_DRAW_INDIRECT_BUFFER_BINDING; break;
+ default: gotQueryTarget = false; break;
}
if (gotQueryTarget) {
final int glerrPre = caller.glGetError(); // clear
@@ -261,101 +189,10 @@ public class GLBufferStateTracker {
the robustness of these caches in the face of external native
code manipulating OpenGL state. */
public final void clearBufferObjectState() {
- bufferBindingMap.clear();
+ bindingMap.clear();
if (DEBUG) {
System.err.println("GLBufferStateTracker.clearBufferObjectState()");
//Thread.dumpStack();
}
}
-
- //
- // Buffer size mapping
- //
-
- public final void setBufferSize(int target, GL caller, long size) {
- // Need to do some similar queries to getBufferSize below
- int buffer = getBoundBufferObject(target, caller);
- if (buffer != 0) {
- setDirectStateBufferSize(buffer, caller, size);
- }
- // We don't know the current buffer state. Note that the buffer
- // state tracker will have made the appropriate OpenGL query if it
- // didn't know what was going on, so at this point we have nothing
- // left to do except drop this piece of information on the floor.
- }
-
- public final void setDirectStateBufferSize(int buffer, GL caller, long size) {
- bufferSizeMap.put(buffer, size);
- }
-
- public final long getBufferSize(int target, GL caller) {
- // See whether we know what buffer is currently bound to the given
- // state
- final int buffer = getBoundBufferObject(target, caller);
- if (0 != buffer) {
- return getBufferSizeImpl(target, buffer, caller);
- }
- // We don't know what's going on in this case; query the GL for an answer
- // FIXME: both functions return 'int' types, which is not suitable,
- // since buffer lenght is 64bit ?
- int[] tmp = new int[1];
- caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
- if (DEBUG) {
- System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information");
- }
- return tmp[0];
- }
-
- public final long getDirectStateBufferSize(int buffer, GL caller) {
- return getBufferSizeImpl(0, buffer, caller);
- }
-
- private final long getBufferSizeImpl(int target, int buffer, GL caller) {
- // See whether we know the size of this buffer object; at this
- // point we almost certainly should if the application is
- // written correctly
- long sz = bufferSizeMap.get(buffer);
- if (sizeNotFound == sz) {
- // For robustness, try to query this value from the GL as we used to
- // FIXME: both functions return 'int' types, which is not suitable,
- // since buffer length is 64bit ?
- int[] tmp = new int[1];
- if(0==target) {
- // DirectState ..
- if(caller.isFunctionAvailable("glGetNamedBufferParameterivEXT")) {
- caller.getGL2().glGetNamedBufferParameterivEXT(buffer, GL.GL_BUFFER_SIZE, tmp, 0);
- } else {
- throw new GLException("Error: getDirectStateBufferSize called with unknown state and GL function 'glGetNamedBufferParameterivEXT' n/a to query size");
- }
- } else {
- caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
- }
- if (tmp[0] == 0) {
- // Assume something is wrong rather than silently going along
- throw new GLException("Error: buffer size returned by "+
- ((0==target)?"glGetNamedBufferParameterivEXT":"glGetBufferParameteriv")+
- " was zero; probably application error");
- }
- // Assume we just don't know what's happening
- sz = tmp[0];
- bufferSizeMap.put(buffer, sz);
- if (DEBUG) {
- System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " +
- sz +
- " for buffer " +
- buffer);
- }
- }
- return sz;
- }
-
- // This should be called on any major event where we might start
- // producing wrong answers, such as OpenGL context creation and
- // destruction if we don't know whether there are other currently-
- // created contexts that might be keeping the buffer objects alive
- // that we're dealing with
- public final void clearCachedBufferSizes() {
- bufferSizeMap.clear();
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 8bbc82b5a..8f1ba4585 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -102,7 +102,8 @@ public abstract class GLContextImpl extends GLContext {
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
- private final GLBufferStateTracker bufferStateTracker;
+ private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
+ private final GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
private final GLStateTracker glStateTracker = new GLStateTracker();
private GLDebugMessageHandler glDebugHandler = null;
private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
@@ -137,13 +138,10 @@ public abstract class GLContextImpl extends GLContext {
public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) {
super();
- if ( null != shareWith ) {
+ if (shareWith != null) {
GLContextShareSet.registerSharing(this, shareWith);
- bufferStateTracker = ((GLContextImpl)shareWith).getBufferStateTracker();
- assert (bufferStateTracker != null) : "shared context hash null bufferStateTracker: "+shareWith;
- } else {
- bufferStateTracker = new GLBufferStateTracker();
}
+ GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
this.drawable = drawable;
this.drawableRead = drawable;
@@ -152,9 +150,15 @@ public abstract class GLContextImpl extends GLContext {
}
private final void clearStates() {
- if( !GLContextShareSet.hasCreatedSharedLeft(this) ) {
- bufferStateTracker.clear();
+ // Because we don't know how many other contexts we might be
+ // sharing with (and it seems too complicated to implement the
+ // GLObjectTracker's ref/unref scheme for the buffer-related
+ // optimizations), simply clear the cache of known buffers' sizes
+ // when we destroy contexts
+ if (bufferSizeTracker != null) {
+ bufferSizeTracker.clearCachedBufferSizes();
}
+ bufferStateTracker.clearBufferObjectState();
glStateTracker.setEnabled(false);
glStateTracker.clearStates();
}
@@ -2119,6 +2123,14 @@ public abstract class GLContextImpl extends GLContext {
//----------------------------------------------------------------------
// Helpers for buffer object optimizations
+ public final void setBufferSizeTracker(GLBufferSizeTracker bufferSizeTracker) {
+ this.bufferSizeTracker = bufferSizeTracker;
+ }
+
+ public final GLBufferSizeTracker getBufferSizeTracker() {
+ return bufferSizeTracker;
+ }
+
public final GLBufferStateTracker getBufferStateTracker() {
return bufferStateTracker;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextShareSet.java b/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
index c057c904c..483767b44 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextShareSet.java
@@ -262,6 +262,30 @@ public class GLContextShareSet {
return false;
}
+ /** In order to avoid glGet calls for buffer object checks related
+ to glVertexPointer, etc. calls as well as glMapBuffer calls, we
+ need to share the same GLBufferSizeTracker object between
+ contexts sharing textures and display lists. For now we keep
+ this mechanism orthogonal to the GLObjectTracker to hopefully
+ keep things easier to understand. (The GLObjectTracker is
+ currently only needed in a fairly esoteric case, when the
+ Java2D/JOGL bridge is active, but the GLBufferSizeTracker
+ mechanism is now always required.) */
+ public static void synchronizeBufferObjectSharing(final GLContext olderContextOrNull, final GLContext newContext) {
+ final GLContextImpl older = (GLContextImpl) olderContextOrNull;
+ final GLContextImpl newer = (GLContextImpl) newContext;
+ GLBufferSizeTracker tracker = null;
+ if (older != null) {
+ tracker = older.getBufferSizeTracker();
+ assert (tracker != null)
+ : "registerForBufferObjectSharing was not called properly for the older context, or has a bug in it";
+ }
+ if (tracker == null) {
+ tracker = new GLBufferSizeTracker();
+ }
+ newer.setBufferSizeTracker(tracker);
+ }
+
//----------------------------------------------------------------------
// Internals only below this point