commit 9becf30e367c3420c8c640584bdf5986e7eac098
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Aug 24 00:29:20 2020 +0100

    Speedup: remember the mesh associations of VertexEffects only once, when they actually change, and not every time we compute() a VertexQueue.

diff --git a/src/main/java/org/distorted/library/effect/VertexEffect.java b/src/main/java/org/distorted/library/effect/VertexEffect.java
index 46610ee..5591a58 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffect.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffect.java
@@ -19,6 +19,7 @@
 
 package org.distorted.library.effect;
 
+import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.type.Static4D;
 
 import java.lang.reflect.Method;
@@ -212,5 +213,7 @@ public abstract class VertexEffect extends Effect
     {
     mAndAssociation = andAssociation;
     mEquAssociation = equAssociation;
+
+    DistortedEffects.setAssociation(getID());
     }
   }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
index 876dfea..183e6b4 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
@@ -267,17 +267,30 @@ public abstract class EffectQueue implements InternalMaster.Slave
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // this assumes 0<=effect
 
-  protected void remove(int effect)
+  private void removeNow(int pos)
     {
-    if( mNumEffects>effect )
+    if( mNumEffects>pos )
       {
       mNumEffects--;
-      System.arraycopy(mEffects, effect+1, mEffects, effect, mNumEffects-effect);
-      System.arraycopy(mIntUniforms, mNumIntUniforms*(effect+1), mIntUniforms, mNumIntUniforms*effect, mNumIntUniforms*(mNumEffects-effect) );
+      System.arraycopy(mEffects, pos+1, mEffects, pos, mNumEffects-pos);
+      System.arraycopy(mIntUniforms, mNumIntUniforms*(pos+1), mIntUniforms, mNumIntUniforms*pos, mNumIntUniforms*(mNumEffects-pos) );
       mEffects[mNumEffects] = null;
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void addNow(int pos, Effect effect)
+    {
+    mEffects[pos]                     = effect;
+    mIntUniforms[mNumIntUniforms*pos] = effect.getName().ordinal();
+
+    if( mIndex==EffectType.VERTEX.ordinal() )
+      {
+      effect.writeAssociations(mIntUniforms, mNumIntUniforms*pos+1, mNumIntUniforms*pos+3);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public synchronized int removeByName(EffectName name)
@@ -437,22 +450,17 @@ public abstract class EffectQueue implements InternalMaster.Slave
                        {                            // added effects and then lowered mMax
                        int position = job.num1;
 
-                       if( position==-1 )
+                       if( position<0 )
                          {
-                         mEffects[mNumEffects]                     = job.effect;
-                         mIntUniforms[mNumIntUniforms*mNumEffects] = job.effect.getName().ordinal();
-
+                         addNow(mNumEffects,job.effect);
                          mNumEffects++;
                          changed = true;
                          }
-                       else if( position>=0 && position<=mNumEffects )
+                       else if( position<=mNumEffects )
                          {
                          System.arraycopy(mEffects    , position, mEffects    , position+1, mNumEffects-position);
                          System.arraycopy(mIntUniforms, mNumIntUniforms*position, mIntUniforms, mNumIntUniforms*(position+1), mNumIntUniforms*(mNumEffects-position) );
-
-                         mEffects[position]                     = job.effect;
-                         mIntUniforms[mNumIntUniforms*position] = job.effect.getName().ordinal();
-
+                         addNow(position,job.effect);
                          mNumEffects++;
                          changed = true;
                          }
@@ -466,7 +474,7 @@ public abstract class EffectQueue implements InternalMaster.Slave
                        {
                        if (mEffects[j] == job.effect)
                          {
-                         remove(j);
+                         removeNow(j);
                          changed = true;
                          break;
                          }
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
index 3d60efb..f44d2d4 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
@@ -67,6 +67,23 @@ public class EffectQueueVertex extends EffectQueue
     mUniformsH[variant]  = GLES30.glGetUniformLocation( mProgramH, "vUniforms");
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Not part of public API, do not document (public only because has to be called from DistortedEffects)
+ *
+ * @y.exclude
+ */
+  public void setAssociation(long effectID)
+    {
+    for(int j=0; j<mNumEffects; j++)
+      {
+      if (mEffects[j].getID() == effectID)
+        {
+        mEffects[j].writeAssociations(mIntUniforms, NUM_INT_UNIFORMS*j+1, NUM_INT_UNIFORMS*j+3);
+        }
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Not part of public API, do not document (public only because has to be used in Meshes)
@@ -81,8 +98,6 @@ public class EffectQueueVertex extends EffectQueue
 
     for(int i=0; i<mNumEffects; i++)
       {
-      mEffects[i].writeAssociations(mIntUniforms, NUM_INT_UNIFORMS*i+1, NUM_INT_UNIFORMS*i+3);
-
       if( mEffects[i].compute(mFloatUniforms, NUM_FLOAT_UNIFORMS*i, currTime, step) )
         {
         EffectMessageSender.newMessage(mEffects[i]);
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index 80f8e18..dbe15cd 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -23,6 +23,9 @@ import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.EffectName;
 import org.distorted.library.effectqueue.EffectQueue;
 import org.distorted.library.effect.EffectType;
+import org.distorted.library.effectqueue.EffectQueueVertex;
+
+import java.util.ArrayList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -32,6 +35,7 @@ import org.distorted.library.effect.EffectType;
  */
 public class DistortedEffects
   {
+  private static ArrayList<DistortedEffects> mAllEffectQueues = new ArrayList<>();
   private static long mNextID =0;
   private long mID;
   private EffectQueue[] mQueues;
@@ -50,6 +54,23 @@ public class DistortedEffects
   static void onDestroy()
     {
     mNextID =  0;
+    mAllEffectQueues.clear();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * @y.exclude
+ */
+  public static void setAssociation(long effectID)
+    {
+    EffectQueue[] queues;
+    int numQueues = mAllEffectQueues.size();
+
+    for(int i=0; i<numQueues; i++)
+      {
+      queues = mAllEffectQueues.get(i).getQueues();
+      ((EffectQueueVertex)queues[1]).setAssociation(effectID);
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -63,6 +84,7 @@ public class DistortedEffects
     mID = ++mNextID;
     mQueues = new EffectQueue[EffectType.LENGTH];
     EffectQueue.allocateQueues(mQueues,null,0);
+    mAllEffectQueues.add(this);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -80,6 +102,7 @@ public class DistortedEffects
     mID = ++mNextID;
     mQueues = new EffectQueue[EffectType.LENGTH];
     EffectQueue.allocateQueues(mQueues,dc.getQueues(),flags);
+    mAllEffectQueues.add(this);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
