commit cf7394ccd989f0ff9eb2770c9f7a7a6140cbf7ef
Author: leszek <leszek@koltunski.pl>
Date:   Thu May 25 22:06:20 2017 +0100

    Split up postprocessing into queue of effects + blit with depth.

diff --git a/src/main/java/org/distorted/library/DistortedOutputSurface.java b/src/main/java/org/distorted/library/DistortedOutputSurface.java
index eca8e28..8e14291 100644
--- a/src/main/java/org/distorted/library/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/DistortedOutputSurface.java
@@ -198,6 +198,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     DistortedNode child;
     DistortedEffectsPostprocess lastP=null, currP;
     long lastB=0, currB;
+    int quality;
 
     for(int i=0; i<num; i++)
       {
@@ -205,14 +206,24 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
       currP = child.getEffectsPostprocess();
       currB = currP==null ? 0 : currP.getBucket();
 
-      if( lastB!=currB && lastB!=0 ) numRenders += lastP.postprocess(time,this);
+      if( lastB!=currB && lastB!=0 )
+        {
+        quality = lastP.getQuality();
+        numRenders += lastP.postprocess(time, this);
+        numRenders += blitWithDepth(quality,time);
+        }
 
       if( currB==0 ) numRenders += child.draw(time,this);
       else
         {
         if( mBuffer[0]==null ) createBuffers();
         numRenders += child.markStencilAndDraw(time,this,currP);
-        if( i==num-1 ) numRenders += currP.postprocess(time,this);
+        if( i==num-1 )
+          {
+          quality = currP.getQuality();
+          numRenders += currP.postprocess(time,this);
+          numRenders += blitWithDepth(quality,time);
+          }
         }
 
       lastP = currP;
@@ -222,6 +233,45 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     return numRenders;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int blitWithDepth(int quality, long currTime)
+    {
+    DistortedFramebuffer buffer = mBuffer[quality];
+
+    GLES30.glViewport(0, 0, mWidth, mHeight);
+    setAsOutput(currTime);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
+
+    GLES30.glDisable(GLES30.GL_STENCIL_TEST);
+    GLES30.glStencilMask(0x00);
+
+    DistortedEffects.blitDepthPriv(this);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
+
+    // clear buffers
+    GLES30.glStencilMask(0xff);
+    GLES30.glDepthMask(true);
+    GLES30.glColorMask(true,true,true,true);
+    GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
+    GLES30.glClearDepthf(1.0f);
+    GLES30.glClearStencil(0);
+
+    buffer.setAsOutput();
+    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
+    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
+    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
+    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
+
+    return 1;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void newJob(int t, DistortedNode n, DistortedEffectsPostprocess d)
diff --git a/src/main/java/org/distorted/library/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
index d2bc39c..700aa22 100644
--- a/src/main/java/org/distorted/library/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
@@ -49,7 +49,7 @@ class EffectQueuePostprocess extends EffectQueue
   private static final int NUM_CACHE    = 0;
   private static final int INDEX = EffectTypes.POSTPROCESS.ordinal();
 
-  private static final FloatBuffer mQuadPositions, mQuadTexture;
+  private static final FloatBuffer mQuadPositions, mQuadTexture, mQuadTextureInv;
 
   static
     {
@@ -58,11 +58,14 @@ class EffectQueuePostprocess extends EffectQueue
 
     float[] position  = { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
     float[] textureNor= {  0.0f,  0.0f,   0.0f, 1.0f,  1.0f, 0.0f,  1.0f, 1.0f };
+    float[] textureInv= {  0.0f,  0.0f,   1.0f, 0.0f,  0.0f, 1.0f,  1.0f, 1.0f };
 
     mQuadPositions = ByteBuffer.allocateDirect(POS_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
     mQuadPositions.put(position).position(0);
     mQuadTexture= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
     mQuadTexture.put(textureNor).position(0);
+    mQuadTextureInv= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
+    mQuadTextureInv.put(textureInv).position(0);
     }
 
   // BLUR effect
@@ -267,105 +270,88 @@ class EffectQueuePostprocess extends EffectQueue
 
   int postprocess(long time, DistortedOutputSurface surface)
     {
+    int numRenders = 0;
+
     if( mNumEffects>0 )
       {
       compute(time);
 
-      DistortedFramebuffer buffer = surface.mBuffer[mQualityLevel];
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, buffer.mFBOH[0]);
-
-      float w1 = buffer.mWidth;
-      float h1 = buffer.mHeight;
-      float w2 = surface.mWidth;
-      float h2 = surface.mHeight;
-
-      int radius = (int)(mUniforms[0]*mQualityScale);
-      if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
-      computeGaussianKernel(radius);
-
-      int offset = radius + radius*radius/4;
-      radius = (radius+1)/2;
-
-      // horizontal blur
-      GLES30.glViewport(0, 0, (int)w1, (int)h1);
-      mBlur1Program.useProgram();
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
-
-      GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset);
-      GLES30.glUniform1i( mRadius1H, radius);
-      GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear);
-      GLES30.glUniform1i( mColorTexture1H , 0 );
-      for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h1;
-      GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0);
-      GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-      GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-
-      DistortedRenderState.useStencilMark();
-      GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
-      DistortedRenderState.unuseStencilMark();
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-
-      // vertical blur
-      mBlur2Program.useProgram();
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[1]);
-
-      GLES30.glColorMask(true,true,true,true);
-      GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
-
-      GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
-      GLES30.glUniform1i( mRadius2H, radius);
-      GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
-      GLES30.glUniform1i( mColorTexture2H , 0 );
-      for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w1;
-      GLES30.glUniform1fv( mOffsets2H ,radius+1, mOffsets,0);
-      GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-      GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-
-      DistortedRenderState.useStencilMark();
-      GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
-      DistortedRenderState.unuseStencilMark();
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-
-      // blit the results with DEPTH to surface.
-      GLES30.glViewport(0, 0, (int)w2, (int)h2);
-      surface.setAsOutput(time);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
-
-      GLES30.glDisable(GLES30.GL_STENCIL_TEST);
-      GLES30.glStencilMask(0x00);
-
-      DistortedEffects.blitDepthPriv(surface);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-
-      // after each postprocess, clear buffers
-      GLES30.glStencilMask(0xff);
-      GLES30.glDepthMask(true);
-      GLES30.glColorMask(true,true,true,true);
-      GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
-      GLES30.glClearDepthf(1.0f);
-      GLES30.glClearStencil(0);
-
-      buffer.setAsOutput();
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
+      for(int i=0; i<mNumEffects; i++)
+        {
+        if (mName[i] == EffectNames.BLUR.ordinal() )
+          {
+          blur(mUniforms[i],surface);
+          numRenders += 2;
+          }
+        }
       }
 
-    return mNumEffects;
+    return numRenders;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void blur(float degree, DistortedOutputSurface surface)
+    {
+    DistortedFramebuffer buffer = surface.mBuffer[mQualityLevel];
+    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, buffer.mFBOH[0]);
+
+    float w1 = buffer.mWidth;
+    float h1 = buffer.mHeight;
+
+    int radius = (int)(degree*mQualityScale);
+    if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
+    computeGaussianKernel(radius);
+
+    int offset = radius + radius*radius/4;
+    radius = (radius+1)/2;
+
+    // horizontal blur
+    GLES30.glViewport(0, 0, (int)w1, (int)h1);
+    mBlur1Program.useProgram();
+    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
+
+    GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset);
+    GLES30.glUniform1i( mRadius1H, radius);
+    GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear);
+    GLES30.glUniform1i( mColorTexture1H , 0 );
+    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h1;
+    GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0);
+    GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
+    GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
+
+    DistortedRenderState.useStencilMark();
+    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    DistortedRenderState.unuseStencilMark();
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
+
+    // vertical blur
+    mBlur2Program.useProgram();
+    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[1]);
+
+    GLES30.glColorMask(true,true,true,true);
+    GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
+    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
+
+    GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
+    GLES30.glUniform1i( mRadius2H, radius);
+    GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
+    GLES30.glUniform1i( mColorTexture2H , 0 );
+    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w1;
+    GLES30.glUniform1fv( mOffsets2H ,radius+1, mOffsets,0);
+    GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
+    GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
+
+    DistortedRenderState.useStencilMark();
+    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    DistortedRenderState.unuseStencilMark();
+    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
+    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
