diff options
author | Kenneth Russel <[email protected]> | 2006-03-08 17:14:04 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2006-03-08 17:14:04 +0000 |
commit | 6b66ec1550a1f022db2dda2db3fe473cbebfec85 (patch) | |
tree | 72dca2fe3e14e7b1410f60f0d01305206285c202 /src/classes/com/sun/opengl/impl/GLObjectTracker.java | |
parent | ec11d8b213d18fc9dbcc2add3d86265044f629c9 (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-x | src/classes/com/sun/opengl/impl/GLObjectTracker.java | 127 |
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; + } + } + } } |