commit 8fa96e69d10c1e208c361f8c846bef5f62fac4f9
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Sun Jan 15 23:31:12 2017 +0000

    Move more intelligence to EffectQueuePostprocess.

diff --git a/src/main/java/org/distorted/library/Distorted.java b/src/main/java/org/distorted/library/Distorted.java
index 27039e2..452eb4f 100644
--- a/src/main/java/org/distorted/library/Distorted.java
+++ b/src/main/java/org/distorted/library/Distorted.java
@@ -163,7 +163,8 @@ public class Distorted
 
     EffectQueuePostprocess.getUniforms(postProgramH);
 
-    DistortedEffects.setPrograms(mainProgram,postProgram);
+    DistortedEffects.setProgram(mainProgram);
+    EffectQueuePostprocess.setProgram(postProgram);
     DistortedTree.reset();
     EffectMessageSender.startSending();
     }
diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index 0f381f1..9bf1f58 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -20,6 +20,7 @@
 package org.distorted.library;
 
 import android.opengl.GLES20;
+import android.opengl.Matrix;
 
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.program.DistortedProgram;
@@ -42,20 +43,19 @@ import java.nio.FloatBuffer;
  */
 public class DistortedEffects
   {
-  private static final int BYTES_PER_FLOAT   = 4; //
-  private static final int MAIN_POSITION_DATA_SIZE= 3; // Size of the position data in elements
-  private static final int MAIN_NORMAL_DATA_SIZE  = 3; // Size of the position data in elements
-  private static final int MAIN_TEX_DATA_SIZE     = 2; // Size of the texture coordinate data in elements.
-  private static final int POST_POSITION_DATA_SIZE= 2; // Size of the position data in elements
-  private static final int POST_TEX_DATA_SIZE     = 2; // Size of the texture coordinate data in elements.
+  private static final int POSITION_DATA_SIZE= 3; // Main Program: size of the position data in elements
+  private static final int NORMAL_DATA_SIZE  = 3; // Main Program: size of the normal data in elements
+  private static final int TEX_DATA_SIZE     = 2; // Main Program: size of the texture coordinate data in elements.
 
-  private static final FloatBuffer mQuadPositions, mQuadTexture;
-  private static DistortedProgram mMainProgram, mPostProgram;
+  private static DistortedProgram mProgram;
+
+  private static float[] mMVPMatrix = new float[16];
+  private static float[] mTmpMatrix = new float[16];
 
   private static long mNextID =0;
   private long mID;
 
-  private static DistortedFramebuffer mBufferFBO;
+  private static DistortedFramebuffer mBufferFBO = new DistortedFramebuffer(1,1);
 
   private EffectQueueMatrix      mM;
   private EffectQueueFragment    mF;
@@ -64,27 +64,11 @@ public class DistortedEffects
 
   private boolean matrixCloned, vertexCloned, fragmentCloned, postprocessCloned;
 
-  static
-    {
-    int dataLength = 4;
-
-    float[] positionData= { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
-    float[] textureData = {  0.0f,  0.0f,   0.0f, 1.0f,  1.0f, 0.0f,  1.0f, 1.0f };
-
-    mQuadPositions = ByteBuffer.allocateDirect(POST_POSITION_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
-    mQuadPositions.put(positionData).position(0);
-    mQuadTexture   = ByteBuffer.allocateDirect(POST_TEX_DATA_SIZE     *dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
-    mQuadTexture.put(textureData).position(0);
-
-    mBufferFBO = new DistortedFramebuffer(1,1);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  static void setPrograms(DistortedProgram main, DistortedProgram post)
+  static void setProgram(DistortedProgram p)
     {
-    mMainProgram = main;
-    mPostProgram = post;
+    mProgram = p;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -150,46 +134,44 @@ public class DistortedEffects
 
     if( mP.mNumEffects==0 )
       {
-      mMainProgram.useProgram();
+      mProgram.useProgram();
+      df.setAsOutput();
       mM.send(df,halfInputW,halfInputH,halfZ);
       mV.send(halfInputW,halfInputH,halfZ);
       mF.send(halfInputW,halfInputH);
-      GLES20.glVertexAttribPointer(mMainProgram.mAttribute[0], MAIN_POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
-      GLES20.glVertexAttribPointer(mMainProgram.mAttribute[1], MAIN_NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
-      GLES20.glVertexAttribPointer(mMainProgram.mAttribute[2], MAIN_TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
+      GLES20.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
+      GLES20.glVertexAttribPointer(mProgram.mAttribute[1], NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
+      GLES20.glVertexAttribPointer(mProgram.mAttribute[2], TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
       GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
       }
     else
       {
       if( mV.mNumEffects>0 || mF.mNumEffects>0 )
         {
-        mMainProgram.useProgram();
+        mProgram.useProgram();
         mBufferFBO.resizeFast(df.mWidth, df.mHeight);
         mBufferFBO.setAsOutput();
+        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+        GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
         mM.send(mBufferFBO,halfInputW,halfInputH,halfZ);
         mV.send(halfInputW,halfInputH,halfZ);
         mF.send(halfInputW,halfInputH);
-        GLES20.glVertexAttribPointer(mMainProgram.mAttribute[0], MAIN_POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
-        GLES20.glVertexAttribPointer(mMainProgram.mAttribute[1], MAIN_NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
-        GLES20.glVertexAttribPointer(mMainProgram.mAttribute[2], MAIN_TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
+        GLES20.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
+        GLES20.glVertexAttribPointer(mProgram.mAttribute[1], NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
+        GLES20.glVertexAttribPointer(mProgram.mAttribute[2], TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
         GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
 
-        mPostProgram.useProgram();
+        Matrix.setIdentityM(mTmpMatrix, 0);
+        Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
+        Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
+
         mBufferFBO.setAsInput();
-        df.setAsOutput();
-        mP.send(df);
-        GLES20.glVertexAttribPointer(mPostProgram.mAttribute[0], POST_POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mQuadPositions);
-        GLES20.glVertexAttribPointer(mPostProgram.mAttribute[1], POST_TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mQuadTexture);
-        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+        mP.render(df.mWidth, df.mHeight, mMVPMatrix, df);
         }
       else
         {
-        mPostProgram.useProgram();
         mM.constructMatrices(df,halfInputW,halfInputH);
-        mP.send(2*halfInputW,2*halfInputH, mM.getMVP() );
-        GLES20.glVertexAttribPointer(mPostProgram.mAttribute[0], POST_POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mQuadPositions);
-        GLES20.glVertexAttribPointer(mPostProgram.mAttribute[1], POST_TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mQuadTexture);
-        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+        mP.render(2*halfInputW, 2*halfInputH, mM.getMVP(), df);
         }
       }
     }
@@ -200,14 +182,18 @@ public class DistortedEffects
     {
     GLES20.glViewport(0, 0, df.mWidth, df.mHeight);
 
+    Matrix.setIdentityM(mTmpMatrix, 0);
+    Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
+    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
+
     EffectQueueMatrix.sendZero(df,halfInputW,halfInputH,halfInputW*mesh.zFactor);
     EffectQueueVertex.sendZero();
     EffectQueueFragment.sendZero();
-    EffectQueuePostprocess.sendZero(df);
+    EffectQueuePostprocess.sendZero(df.mWidth, df.mHeight, mMVPMatrix);
 
-    GLES20.glVertexAttribPointer(mMainProgram.mAttribute[0], MAIN_POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
-    GLES20.glVertexAttribPointer(mMainProgram.mAttribute[1], MAIN_NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
-    GLES20.glVertexAttribPointer(mMainProgram.mAttribute[2], MAIN_TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
+    GLES20.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mesh.mMeshPositions);
+    GLES20.glVertexAttribPointer(mProgram.mAttribute[1], NORMAL_DATA_SIZE  , GLES20.GL_FLOAT, false, 0, mesh.mMeshNormals);
+    GLES20.glVertexAttribPointer(mProgram.mAttribute[2], TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mesh.mMeshTexture);
     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
     }
     
diff --git a/src/main/java/org/distorted/library/DistortedFramebuffer.java b/src/main/java/org/distorted/library/DistortedFramebuffer.java
index 545f0ba..fe11f58 100644
--- a/src/main/java/org/distorted/library/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/DistortedFramebuffer.java
@@ -363,7 +363,6 @@ public class DistortedFramebuffer
     DistortedTexture.deleteAllMarked();
     createFBO();
     tex.setAsInput();
-    setAsOutput();
     effects.drawPriv(tex.mHalfX, tex.mHalfY, mesh, this, time);
     }
 
@@ -389,7 +388,6 @@ public class DistortedFramebuffer
       DistortedFramebuffer.deleteAllMarked();
       DistortedTexture.deleteAllMarked();
       createFBO();
-      setAsOutput();
       GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.colorIds[0]);
       effects.drawPriv(fbo.mWidth/2, fbo.mHeight/2, mesh, this, time);
       }
@@ -409,7 +407,6 @@ public class DistortedFramebuffer
     DistortedFramebuffer.deleteAllMarked();
     DistortedTexture.deleteAllMarked();
     createFBO();
-    setAsOutput();
     dt.drawRecursive(time,this);
     }
 
diff --git a/src/main/java/org/distorted/library/DistortedTree.java b/src/main/java/org/distorted/library/DistortedTree.java
index 14b3956..4b16f0d 100644
--- a/src/main/java/org/distorted/library/DistortedTree.java
+++ b/src/main/java/org/distorted/library/DistortedTree.java
@@ -231,8 +231,6 @@ public class DistortedTree
 
       mData.numRendered++;
       mData.numRendered %= mData.numPointingNodes;
-
-      df.setAsOutput();
       mData.mFBO.setAsInput();
       }
 
diff --git a/src/main/java/org/distorted/library/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
index 1dd4385..13ab397 100644
--- a/src/main/java/org/distorted/library/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
@@ -20,9 +20,9 @@
 package org.distorted.library;
 
 import android.opengl.GLES20;
-import android.opengl.Matrix;
 
 import org.distorted.library.message.EffectMessage;
+import org.distorted.library.program.DistortedProgram;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data2D;
 import org.distorted.library.type.Dynamic1D;
@@ -30,10 +30,18 @@ import org.distorted.library.type.Dynamic2D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static2D;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class EffectQueuePostprocess extends EffectQueue
   {
+  private static final int BYTES_PER_FLOAT   = 4;
+  private static final int POSITION_DATA_SIZE= 2; // Post Program: size of the position data in elements
+  private static final int TEX_DATA_SIZE     = 2; // Post Program: size of the texture coordinate data in elements.
+
   private static final int NUM_UNIFORMS = 3;
   private static final int NUM_CACHE    = 0;
   private static final int INDEX = EffectTypes.POSTPROCESS.ordinal();
@@ -44,8 +52,21 @@ class EffectQueuePostprocess extends EffectQueue
   private static int mObjDH;
   private static int mMVPMatrixH;
 
-  private static float[] mMVPMatrix = new float[16];
-  private static float[] mTmpMatrix = new float[16];
+  private static final FloatBuffer mQuadPositions, mQuadTexture;
+  private static DistortedProgram mProgram;
+
+  static
+    {
+    int dataLength = 4;
+
+    float[] positionData= { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
+    float[] textureData = {  0.0f,  0.0f,   0.0f, 1.0f,  1.0f, 0.0f,  1.0f, 1.0f };
+
+    mQuadPositions = ByteBuffer.allocateDirect(POSITION_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
+    mQuadPositions.put(positionData).position(0);
+    mQuadTexture   = ByteBuffer.allocateDirect(TEX_DATA_SIZE     *dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
+    mQuadTexture.put(textureData).position(0);
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -65,6 +86,13 @@ class EffectQueuePostprocess extends EffectQueue
     mMVPMatrixH = GLES20.glGetUniformLocation(mProgramH, "u_MVPMatrix");
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void setProgram(DistortedProgram p)
+    {
+    mProgram = p;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
   
   synchronized void compute(long currTime) 
@@ -115,49 +143,33 @@ class EffectQueuePostprocess extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized void send(float w, float h, float[] mvp)
+  synchronized static void sendZero(float w, float h, float[] mvp)
     {
-    GLES20.glUniform1i( mNumEffectsH, mNumEffects);
-    GLES20.glUniform2f( mObjDH , w, h );
+    GLES20.glUniform1i( mNumEffectsH, 0);
+    GLES20.glUniform2f( mObjDH , w, h);
     GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mvp , 0);
-
-    if( mNumEffects>0 )
-      {
-      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName    ,0);
-      GLES20.glUniform4fv( mUniformsH,2*mNumEffects, mUniforms,0);
-      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized void send(DistortedFramebuffer df)
+  synchronized void render(float w, float h, float[] mvp, DistortedFramebuffer df)
     {
-    Matrix.setIdentityM(mTmpMatrix, 0);
-    Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
-    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
+    mProgram.useProgram();
+    df.setAsOutput();
 
     GLES20.glUniform1i( mNumEffectsH, mNumEffects);
-    GLES20.glUniform2f( mObjDH , df.mWidth, df.mHeight);
-    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
+    GLES20.glUniform2f( mObjDH , w, h );
+    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mvp , 0);
 
     if( mNumEffects>0 )
       {
       GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName    ,0);
       GLES20.glUniform4fv( mUniformsH,2*mNumEffects, mUniforms,0);
       }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized static void sendZero(DistortedFramebuffer df)
-    {
-    Matrix.setIdentityM(mTmpMatrix, 0);
-    Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
-    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
-
-    GLES20.glUniform1i( mNumEffectsH, 0);
-    GLES20.glUniform2f( mObjDH , df.mWidth, df.mHeight);
-    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
+    GLES20.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 0, mQuadPositions);
+    GLES20.glVertexAttribPointer(mProgram.mAttribute[1], TEX_DATA_SIZE     , GLES20.GL_FLOAT, false, 0, mQuadTexture);
+    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
