Przeglądaj źródła

Sort of fixed a streaming related memory leak. Well,
streams won't leak anymore but the buffered case
technically will if you create them and drop them because
that's a different level of fix.
Also made the deleteAudioData synchronized since it can
be called from another thread pretty trivially.
And fixed a race condition that caused an IndexOutOfBounds
exception if you happen to try adjusting an AudioNode's
parameters right as it was finishing playing.


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7506 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

PSp..om 14 lat temu
rodzic
commit
c75f157cbb

+ 57 - 21
engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java

@@ -298,6 +298,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
             }
             }
             if (audioDisabled)
             if (audioDisabled)
                 return;
                 return;
+ 
+            // There is a race condition in AudioNode that can
+            // cause this to be called for a node that has been
+            // detached from its channel.  For example, setVolume()
+            // called from the render thread may see that that AudioNode
+            // still has a channel value but the audio thread may
+            // clear that channel before setVolume() gets to call
+            // updateSourceParam() (because the audio stopped playing
+            // on its own right as the volume was set).  In this case, 
+            // it should be safe to just ignore the update
+            if (src.getChannel() < 0) 
+                return;
            
            
             assert src.getChannel() >= 0;
             assert src.getChannel() >= 0;
 
 
@@ -745,6 +757,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
                         src.setChannel(-1);
                         src.setChannel(-1);
                         clearChannel(i);
                         clearChannel(i);
                         freeChannel(i);
                         freeChannel(i);
+ 
+                        // And free the audio since it cannot be
+                        // played again anyway.
+                        deleteAudioData(stream);
                     }
                     }
                 }
                 }
             }else if (!streaming){
             }else if (!streaming){
@@ -913,6 +929,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
                 src.setChannel(-1);
                 src.setChannel(-1);
                 clearChannel(chan);
                 clearChannel(chan);
                 freeChannel(chan);
                 freeChannel(chan);
+                
+                if (src.getAudioData() instanceof AudioStream) {
+                    
+                    AudioStream stream = (AudioStream)src.getAudioData();
+                    if (stream.isOpen()) {
+                        stream.close();
+                    }
+                
+                    // And free the audio since it cannot be
+                    // played again anyway.
+                    deleteAudioData(src.getAudioData());
+                }                    
             }
             }
         }
         }
     }
     }
@@ -958,7 +986,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
         int[] ids = new int[STREAMING_BUFFER_COUNT];
         int[] ids = new int[STREAMING_BUFFER_COUNT];
         ib.position(0).limit(STREAMING_BUFFER_COUNT);
         ib.position(0).limit(STREAMING_BUFFER_COUNT);
         alGenBuffers(ib);
         alGenBuffers(ib);
-        ib.position(0).limit(STREAMING_BUFFER_COUNT);
+        ib.position(0).limit(STREAMING_BUFFER_COUNT);        
         ib.get(ids);
         ib.get(ids);
         
         
         as.setIds(ids);
         as.setIds(ids);
@@ -974,28 +1002,36 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
     }
     }
 
 
     public void deleteAudioData(AudioData ad){
     public void deleteAudioData(AudioData ad){
-        if (audioDisabled)
-            return;
-        
-        if (ad instanceof AudioBuffer){
-            AudioBuffer ab = (AudioBuffer) ad;
-            int id = ab.getId();
-            if (id != -1){
-                ib.put(0,id);
-                ib.position(0).limit(1);
-                alDeleteBuffers(ib);
-                ab.resetObject();
+        synchronized (threadLock){
+            while (!threadLock.get()){
+                try {
+                    threadLock.wait();
+                } catch (InterruptedException ex) {
+                }
             }
             }
-        }else if (ad instanceof AudioStream){
-            AudioStream as = (AudioStream) ad;
-            int[] ids = as.getIds();
-            if (ids != null){
-                ib.clear();
-                ib.put(ids).flip();
-                alDeleteBuffers(ib);
-                as.resetObject();
+            if (audioDisabled)
+                return;
+        
+            if (ad instanceof AudioBuffer){
+                AudioBuffer ab = (AudioBuffer) ad;
+                int id = ab.getId();
+                if (id != -1){
+                    ib.put(0,id);
+                    ib.position(0).limit(1);
+                    alDeleteBuffers(ib);
+                    ab.resetObject();
+                }
+            }else if (ad instanceof AudioStream){
+                AudioStream as = (AudioStream) ad;
+                int[] ids = as.getIds();
+                if (ids != null){
+                    ib.clear();
+                    ib.put(ids).flip();
+                    alDeleteBuffers(ib);
+                    as.resetObject();
+                }
             }
             }
-        }
+        }            
     }
     }
 
 
 }
 }