summaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl/GLObjectTracker.java
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2006-03-08 17:14:04 +0000
committerKenneth Russel <[email protected]>2006-03-08 17:14:04 +0000
commit6b66ec1550a1f022db2dda2db3fe473cbebfec85 (patch)
tree72dca2fe3e14e7b1410f60f0d01305206285c202 /src/classes/com/sun/opengl/impl/GLObjectTracker.java
parentec11d8b213d18fc9dbcc2add3d86265044f629c9 (diff)
Restructured how GLObjectTracker destroys tracked objects during
context destruction. Now, in addition to tracking sharing between contexts requested by the user, also tracks the behind-the-scenes sharing going on with e.g. Java2D. Makes determination of whether objects can be immediately destroyed by checking current context and seeing whether it shares the same deleted object pool as the one being destroyed. If objects can not be destroyed immediately, their destruction is deferred until the next makeCurrent of a context sharing objects with the one currently being destroyed (if one exists -- the case of this being the last context actually referencing the objects is handled by the OpenGL drivers). This fixes the resizing problems seen when -Dsun.java2d.opengl.fobject=true is specified along with -Dsun.java2d.opengl=true in Mustang. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@654 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl/impl/GLObjectTracker.java')
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/GLObjectTracker.java127
1 files changed, 115 insertions, 12 deletions
diff --git a/src/classes/com/sun/opengl/impl/GLObjectTracker.java b/src/classes/com/sun/opengl/impl/GLObjectTracker.java
index 663a7df70..dec7892de 100755
--- a/src/classes/com/sun/opengl/impl/GLObjectTracker.java
+++ b/src/classes/com/sun/opengl/impl/GLObjectTracker.java
@@ -402,22 +402,96 @@ public class GLObjectTracker {
remove(getList(VERTEX_SHADERS_EXT), obj, 1);
}
+ //----------------------------------------------------------------------
+ // Reference count maintenance and manual deletion
+ //
+
+ public synchronized void transferAll(GLObjectTracker other) {
+ for (int i = 0; i < lists.length; i++) {
+ getList(i).addAll(other.lists[i]);
+ if (other.lists[i] != null) {
+ other.lists[i].clear();
+ }
+ }
+ dirty = true;
+ }
+
public synchronized void ref() {
++refCount;
}
- public synchronized void unref(GL gl) {
- if (--refCount == 0) {
- for (int i = 0; i < lists.length; i++) {
- ObjectList list = lists[i];
- if (list != null) {
- list.delete(gl);
- lists[i] = null;
+ public void unref(GLObjectTracker deletedObjectPool) {
+ boolean tryDelete = false;
+ synchronized (this) {
+ if (--refCount == 0) {
+ tryDelete = true;
+ }
+ }
+ if (tryDelete) {
+ // See whether we should try to do the work now or whether we
+ // have to postpone
+ GLContext cur = GLContext.getCurrent();
+ if ((cur != null) &&
+ (cur instanceof GLContextImpl)) {
+ GLContextImpl curImpl = (GLContextImpl) cur;
+ if (deletedObjectPool != null &&
+ deletedObjectPool == curImpl.getDeletedObjectTracker()) {
+ // Should be safe to delete these objects now
+ try {
+ delete(curImpl.getGL());
+ return;
+ } catch (GLException e) {
+ // Shouldn't happen, but if it does, transfer all objects
+ // to the deleted object pool hoping we can later clean
+ // them up
+ deletedObjectPool.transferAll(this);
+ throw(e);
+ }
+ }
+ }
+ // If we get here, we couldn't attempt to delete the objects
+ // right now; instead try to transfer them to the
+ // deletedObjectPool for later cleanup (FIXME: should consider
+ // throwing an exception if deletedObjectPool is null, since
+ // that shouldn't happen)
+ if (DEBUG) {
+ String s = null;
+ if (cur == null) {
+ s = "current context was null";
+ } else if (!(cur instanceof GLContextImpl)) {
+ s = "current context was not a GLContextImpl";
+ } else if (deletedObjectPool == null) {
+ s = "no current deletedObjectPool";
+ } else if (deletedObjectPool != ((GLContextImpl) cur).getDeletedObjectTracker()) {
+ s = "deletedObjectTracker didn't match";
+ if (((GLContextImpl) cur).getDeletedObjectTracker() == null) {
+ s += " (other was null)";
+ }
+ } else {
+ s = "unknown reason";
}
+ System.err.println("Deferred destruction of server-side OpenGL objects into " + deletedObjectPool + ": " + s);
+ }
+
+ if (deletedObjectPool != null) {
+ deletedObjectPool.transferAll(this);
+ }
+ }
+ }
+
+ public void clean(GL gl) {
+ if (dirty) {
+ try {
+ delete(gl);
+ dirty = false;
+ } catch (GLException e) {
+ // FIXME: not sure what to do here; probably a bad idea to be
+ // throwing exceptions during an otherwise-successful makeCurrent
}
}
}
+
//----------------------------------------------------------------------
// Internals only below this point
//
@@ -459,8 +533,7 @@ public class GLObjectTracker {
public ObjectList(Deleter deleter) {
this.deleter = deleter;
- capacity = MIN_CAPACITY;
- data = new int[capacity];
+ clear();
}
public void add(int obj) {
@@ -475,6 +548,15 @@ public class GLObjectTracker {
data[size++] = obj;
}
+ public void addAll(ObjectList other) {
+ if (other == null) {
+ return;
+ }
+ for (int i = 0; i < other.size; i++) {
+ add(other.data[i]);
+ }
+ }
+
public boolean remove(int value) {
for (int i = 0; i < size; i++) {
if (data[i] == value) {
@@ -506,19 +588,30 @@ public class GLObjectTracker {
}
public void delete(GL gl) {
- for (int i = 0; i < size; i++) {
+ // Just in case we start throwing exceptions during deletion,
+ // make sure we make progress rather than going into an infinite
+ // loop
+ while (size > 0) {
+ int obj = data[size - 1];
+ --size;
if (DEBUG) {
- System.err.println("Deleting server-side OpenGL object " + data[i] +
+ System.err.println("Deleting server-side OpenGL object " + obj +
((name != null) ? (" (" + name + ")") : ""));
}
- deleter.delete(gl, data[i]);
+ deleter.delete(gl, obj);
}
+ }
+
+ public void clear() {
size = 0;
+ capacity = MIN_CAPACITY;
+ data = new int[capacity];
}
}
private ObjectList[] lists = new ObjectList[NUM_OBJECT_TYPES];
private int refCount;
+ private boolean dirty;
private void add(ObjectList list, int n, IntBuffer ids) {
int pos = ids.position();
@@ -727,4 +820,14 @@ public class GLObjectTracker {
}
return list;
}
+
+ private void delete(GL gl) {
+ for (int i = 0; i < lists.length; i++) {
+ ObjectList list = lists[i];
+ if (list != null) {
+ list.delete(gl);
+ lists[i] = null;
+ }
+ }
+ }
}