summaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl/GLObjectTracker.java
diff options
context:
space:
mode:
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;
+ }
+ }
+ }
}