summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-10-14 18:39:42 +0200
committerSven Gothel <[email protected]>2010-10-14 18:39:42 +0200
commit6ced17f0325d5719e992b246ffd156e5b39694b4 (patch)
treec8618ebe347466e26c5ac8feb818b6844761121e /src/jogl/classes/com/jogamp/opengl
parent29999cf3b7616c8ab58f4483c672e30076fbb3e4 (diff)
Fix: Memory consumption
Observing memory consumption showed: 1 - 'traceLock' debug stack traces (GLContextLock) 2 - massive Iterator usage (1) is fixed, ie only enabled in DEBUG mode, like we have done in RecursiveLock before (2) Using an Iterator on ArrayLists with a low element count < 100, as it is usual in our use cases, is observed not to be faster than accessing the elements via an index (-> TestIteratorIndexCORE.java ). On the contrary, the index implementation was a bit faster. Further more, these Iterators were massively used on the fly during animation, hence their memory managment even impacts fluent processing/animation. Recoded all animation related (display, surfaceUpdated, ..) loops using an index.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java51
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java43
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java36
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java28
5 files changed, 113 insertions, 64 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
index 565ec967e..ea78f5209 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
@@ -50,11 +50,13 @@ import javax.media.opengl.*;
be raised. */
public class GLContextLock {
+ protected static final boolean DEBUG = GLContextImpl.DEBUG;
+
static class SyncData {
boolean failFastMode = true;
Thread owner = null;
int waiters = 0;
- Exception lockedStack = null;
+ Exception lockedStack = null; // only enabled if DEBUG
}
private SyncData sdata = new SyncData(); // synchronized (flow/mem) mutable access
@@ -66,12 +68,16 @@ public class GLContextLock {
Thread current = Thread.currentThread();
if (sdata.owner == null) {
sdata.owner = current;
- sdata.lockedStack = new Exception("Previously made current (1) by "+sdata.owner+", lock: "+this);
+ if(DEBUG) {
+ sdata.lockedStack = new Exception("Error: Previously made current (1) by "+sdata.owner+", lock: "+this);
+ }
} else if (sdata.owner != current) {
while (sdata.owner != null) {
if (sdata.failFastMode) {
- sdata.lockedStack.printStackTrace();
- throw new GLException("Attempt to make context current on thread " + current +
+ if(null!=sdata.lockedStack) {
+ sdata.lockedStack.printStackTrace();
+ }
+ throw new GLException("Error: Attempt to make context current on thread " + current +
" which is already current on thread " + sdata.owner);
} else {
try {
@@ -85,7 +91,9 @@ public class GLContextLock {
}
}
sdata.owner = current;
- sdata.lockedStack = new Exception("Previously made current (2) by "+sdata.owner+", lock: "+this);
+ if(DEBUG) {
+ sdata.lockedStack = new Exception("Previously made current (2) by "+sdata.owner+", lock: "+this);
+ }
} else {
throw new GLException("Attempt to make the same context current twice on thread " + current);
}
@@ -139,6 +147,7 @@ public class GLContextLock {
}
}
+ /** holding the owners stack trace when lock is acquired and DEBUG is true */
public final Exception getLockedStack() {
synchronized(sdata) {
return sdata.lockedStack;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
index 53fc34181..4ad0dd4c3 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -50,15 +50,29 @@ public class GLDrawableHelper {
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
private static final boolean VERBOSE = Debug.verbose();
private Object listenersLock = new Object();
- private List listeners = new ArrayList();
- private volatile boolean listenersIter = false; // avoid java.util.ConcurrentModificationException
- private Set listenersToBeInit = new HashSet();
- private boolean autoSwapBufferMode = true;
+ private List listeners;
+ private volatile boolean listenersIter; // avoid java.util.ConcurrentModificationException
+ private Set listenersToBeInit;
+ private boolean autoSwapBufferMode;
private Object glRunnablesLock = new Object();
- private ArrayList glRunnables = new ArrayList(); // one shot GL tasks
- private GLAnimatorControl animatorCtrl = null; // default
+ private ArrayList glRunnables;
+ private GLAnimatorControl animatorCtrl;
public GLDrawableHelper() {
+ reset();
+ }
+
+ public void reset() {
+ synchronized(listenersLock) {
+ listeners = new ArrayList();
+ listenersIter = false;
+ listenersToBeInit = new HashSet();
+ }
+ autoSwapBufferMode = true;
+ synchronized(glRunnablesLock) {
+ glRunnables = new ArrayList();
+ }
+ animatorCtrl = null;
}
public String toString() {
@@ -67,8 +81,8 @@ public class GLDrawableHelper {
synchronized(listenersLock) {
sb.append("GLEventListeners num "+listeners.size()+" [");
listenersIter = true;
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- Object l = iter.next();
+ for (int i=0; i < listeners.size(); i++) {
+ Object l = listeners.get(i);
sb.append(l);
sb.append("[init ");
sb.append( !listenersToBeInit.contains(l) );
@@ -120,8 +134,8 @@ public class GLDrawableHelper {
public void dispose(GLAutoDrawable drawable) {
synchronized(listenersLock) {
listenersIter = true;
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- GLEventListener listener = (GLEventListener) iter.next() ;
+ for (int i=0; i < listeners.size(); i++) {
+ GLEventListener listener = (GLEventListener) listeners.get(i) ;
listener.dispose(drawable);
listenersToBeInit.add(listener);
}
@@ -143,8 +157,8 @@ public class GLDrawableHelper {
public void init(GLAutoDrawable drawable) {
synchronized(listenersLock) {
listenersIter = true;
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- GLEventListener listener = (GLEventListener) iter.next() ;
+ for (int i=0; i < listeners.size(); i++) {
+ GLEventListener listener = (GLEventListener) listeners.get(i) ;
if ( ! init( listener, drawable, false ) ) {
throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
}
@@ -156,8 +170,8 @@ public class GLDrawableHelper {
public void display(GLAutoDrawable drawable) {
synchronized(listenersLock) {
listenersIter = true;
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- GLEventListener listener = (GLEventListener) iter.next() ;
+ for (int i=0; i < listeners.size(); i++) {
+ GLEventListener listener = (GLEventListener) listeners.get(i) ;
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
init( listener, drawable, true ) ;
@@ -179,9 +193,8 @@ public class GLDrawableHelper {
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
synchronized(listenersLock) {
listenersIter = true;
- int i=0;
- for (Iterator iter = listeners.iterator(); iter.hasNext(); i++) {
- reshape((GLEventListener) iter.next(), drawable, x, y, width, height, 0==i);
+ for (int i=0; i < listeners.size(); i++) {
+ reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i);
}
listenersIter = false;
}
@@ -198,8 +211,8 @@ public class GLDrawableHelper {
}
}
if(null!=_glRunnables) {
- for (Iterator iter = _glRunnables.iterator(); iter.hasNext(); ) {
- ((GLRunnable) iter.next()).run(drawable);
+ for (int i=0; i < _glRunnables.size(); i++) {
+ ((GLRunnable) _glRunnables.get(i)).run(drawable);
}
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index e3aff61c6..9dd58bb57 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -55,29 +55,36 @@ class AWTAnimatorImpl extends AnimatorImpl {
public void display(AnimatorBase animator,
boolean ignoreExceptions,
boolean printExceptions) {
- Iterator iter = animator.drawableIterator();
- while (animator.isAnimating() && !animator.getShouldStop() && !animator.getShouldPause() && iter.hasNext()) {
- GLAutoDrawable drawable = (GLAutoDrawable) iter.next();
- if (drawable instanceof JComponent) {
- // Lightweight components need a more efficient drawing
- // scheme than simply forcing repainting of each one in
- // turn since drawing one can force another one to be
- // drawn in turn
- lightweights.add(drawable);
- } else {
- try {
- drawable.display();
- } catch (RuntimeException e) {
- if (ignoreExceptions) {
- if (printExceptions) {
- e.printStackTrace();
+ List drawables = animator.acquireDrawables();
+ try {
+ for (int i=0;
+ animator.isAnimating() && !animator.getShouldStop() && !animator.getShouldPause() && i<drawables.size();
+ i++) {
+ GLAutoDrawable drawable = (GLAutoDrawable) drawables.get(i);
+ if (drawable instanceof JComponent) {
+ // Lightweight components need a more efficient drawing
+ // scheme than simply forcing repainting of each one in
+ // turn since drawing one can force another one to be
+ // drawn in turn
+ lightweights.add(drawable);
+ } else {
+ try {
+ drawable.display();
+ } catch (RuntimeException e) {
+ if (ignoreExceptions) {
+ if (printExceptions) {
+ e.printStackTrace();
+ }
+ } else {
+ throw(e);
}
- } else {
- throw(e);
}
}
}
+ } finally {
+ animator.releaseDrawables();
}
+
if (lightweights.size() > 0) {
try {
SwingUtilities.invokeAndWait(drawWithRepaintManagerRunnable);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index a54f6be57..24eee1875 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -28,9 +28,11 @@
package com.jogamp.opengl.util;
+import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.impl.Debug;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLProfile;
@@ -43,7 +45,8 @@ public abstract class AnimatorBase implements GLAnimatorControl {
private static int animatorCount = 0;
- protected volatile ArrayList/*<GLAutoDrawable>*/ drawables = new ArrayList();
+ protected ArrayList/*<GLAutoDrawable>*/ drawables = new ArrayList();
+ protected RecursiveLock drawablesLock = new RecursiveLock();
protected AnimatorImpl impl;
protected String baseName;
protected Thread thread;
@@ -75,18 +78,24 @@ public abstract class AnimatorBase implements GLAnimatorControl {
protected abstract String getBaseName(String prefix);
public synchronized void add(GLAutoDrawable drawable) {
- ArrayList newList = (ArrayList) drawables.clone();
- newList.add(drawable);
- drawables = newList;
- drawable.setAnimator(this);
+ drawablesLock.lock();
+ try {
+ drawables.add(drawable);
+ drawable.setAnimator(this);
+ } finally {
+ drawablesLock.unlock();
+ }
notifyAll();
}
public synchronized void remove(GLAutoDrawable drawable) {
- ArrayList newList = (ArrayList) drawables.clone();
- newList.remove(drawable);
- drawables = newList;
- drawable.setAnimator(null);
+ drawablesLock.lock();
+ try {
+ drawables.remove(drawable);
+ drawable.setAnimator(null);
+ } finally {
+ drawablesLock.unlock();
+ }
notifyAll();
}
@@ -101,8 +110,13 @@ public abstract class AnimatorBase implements GLAnimatorControl {
totalFrames++;
}
- public Iterator drawableIterator() {
- return drawables.iterator();
+ public List acquireDrawables() {
+ drawablesLock.lock();
+ return drawables;
+ }
+
+ public void releaseDrawables() {
+ drawablesLock.unlock();
}
public long getCurrentTime() {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java
index e4bf8d711..8f2715e0a 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorImpl.java
@@ -44,20 +44,26 @@ class AnimatorImpl {
public void display(AnimatorBase animator,
boolean ignoreExceptions,
boolean printExceptions) {
- Iterator iter = animator.drawableIterator();
- while (animator.isAnimating() && !animator.getShouldStop() && !animator.getShouldPause() && iter.hasNext()) {
- GLAutoDrawable drawable = (GLAutoDrawable) iter.next();
- try {
- drawable.display();
- } catch (RuntimeException e) {
- if (ignoreExceptions) {
- if (printExceptions) {
- e.printStackTrace();
+ List drawables = animator.acquireDrawables();
+ try {
+ for (int i=0;
+ animator.isAnimating() && !animator.getShouldStop() && !animator.getShouldPause() && i<drawables.size();
+ i++) {
+ GLAutoDrawable drawable = (GLAutoDrawable) drawables.get(i);
+ try {
+ drawable.display();
+ } catch (RuntimeException e) {
+ if (ignoreExceptions) {
+ if (printExceptions) {
+ e.printStackTrace();
+ }
+ } else {
+ throw(e);
}
- } else {
- throw(e);
}
}
+ } finally {
+ animator.releaseDrawables();
}
}