commit 7170e4eb1fc1c13e4bbf968d2a9ea5736026d637
Author: leszek <leszek@koltunski.pl>
Date:   Thu May 25 00:16:29 2017 +0100

    Move on to Stencil on both stages of the BLUR + separate 'blit with depth'.
    
    This works wonders on Nexus 5X ( r=50 quality=HIGHIEST  1,4,8 cubes: 59.3,43.6,41.0 FPS! ) but it somehow fails to clear the DEPTH and STENCIL buffers on Nexus 4....

diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index 413a273..8fc1ac6 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -78,6 +78,12 @@ public class DistortedEffects
     mQuadPositions.put(positionData).position(0);
     }
 
+  /// BLIT DEPTH PROGRAM ///
+  private static DistortedProgram mBlitDepthProgram;
+  private static int mBlitDepthTextureH;
+  private static int mBlitDepthDepthTextureH;
+  private static int mBlitDepthDepthH;
+
   /// NORMAL PROGRAM /////
   private static DistortedProgram mNormalProgram;
   private static int mNormalMVPMatrixH;
@@ -166,6 +172,25 @@ public class DistortedEffects
     mBlitTextureH  = GLES30.glGetUniformLocation( blitProgramH, "u_Texture");
     mBlitDepthH    = GLES30.glGetUniformLocation( blitProgramH, "u_Depth");
 
+    // BLIT DEPTH PROGRAM ////////////////////////////////////
+    final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
+    final InputStream blitDepthFragStream = resources.openRawResource(R.raw.blit_depth_fragment_shader);
+
+    try
+      {
+      mBlitDepthProgram = new DistortedProgram(blitDepthVertStream,blitDepthFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
+      }
+    catch(Exception e)
+      {
+      android.util.Log.e("EFFECTS", "exception trying to compile BLIT DEPTH program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
+    mBlitDepthTextureH      = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Texture");
+    mBlitDepthDepthTextureH = GLES30.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
+    mBlitDepthDepthH        = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Depth");
+
     // NORMAL PROGRAM //////////////////////////////////////
     final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
     final InputStream normalFragmentStream = resources.openRawResource(R.raw.normal_fragment_shader);
@@ -297,7 +322,21 @@ public class DistortedEffects
     GLES30.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
     }
-    
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void blitDepthPriv(DistortedOutputSurface surface)
+    {
+    mBlitDepthProgram.useProgram();
+
+    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES30.glUniform1i(mBlitDepthTextureH, 0);
+    GLES30.glUniform1i(mBlitDepthDepthTextureH, 1);
+    GLES30.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
+    GLES30.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
+    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
   private void releasePriv()
diff --git a/src/main/java/org/distorted/library/DistortedNode.java b/src/main/java/org/distorted/library/DistortedNode.java
index 3706759..ff799a6 100644
--- a/src/main/java/org/distorted/library/DistortedNode.java
+++ b/src/main/java/org/distorted/library/DistortedNode.java
@@ -271,12 +271,12 @@ public class DistortedNode implements DistortedSlave
       float w = mSurface.getWidth() /2.0f;
       float h = mSurface.getHeight()/2.0f;
 
-      // Actually draw our object.
+      // Draw the color buffer of the object.
       buffer1.setAsOutput();
       mState.apply();
       mEffects.drawPriv(w, h, mMesh, buffer1, currTime, 0);
 
-      // Mark area of our object + marginInPixels pixels around with 1s in Stencil buffer
+      // Draw stencil + depth buffers of the object enlarged by HALO pixels around.
       buffer2.setAsOutput();
       DistortedRenderState.setUpStencilMark();
       mEffects.drawPriv(w, h, mMesh, buffer2, currTime, effects.getHalo()*buffer2.mMipmap);
diff --git a/src/main/java/org/distorted/library/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
index 75a92bc..53f9927 100644
--- a/src/main/java/org/distorted/library/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
@@ -94,7 +94,7 @@ class EffectQueuePostprocess extends EffectQueue
 
   private static DistortedProgram mBlur1Program, mBlur2Program;
   private static int mRadius1H,mOffsets1H,mWeights1H,mDepth1H, mColorTexture1H;
-  private static int mRadius2H,mOffsets2H,mWeights2H,mDepth2H, mColorTexture2H, mDepthTexture2H;
+  private static int mRadius2H,mOffsets2H,mWeights2H,mDepth2H, mColorTexture2H;
   private static float[] mWeights = new float[MAX_BLUR];
   private static float[] mOffsets = new float[MAX_BLUR];
   // another effect ....
@@ -161,7 +161,6 @@ class EffectQueuePostprocess extends EffectQueue
     mWeights2H      = GLES30.glGetUniformLocation( blur2ProgramH, "u_Weights");
     mDepth2H        = GLES30.glGetUniformLocation( blur2ProgramH, "u_Depth");
     mColorTexture2H = GLES30.glGetUniformLocation( blur2ProgramH, "u_ColorTexture");
-    mDepthTexture2H = GLES30.glGetUniformLocation( blur2ProgramH, "u_DepthTexture");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -307,22 +306,39 @@ class EffectQueuePostprocess extends EffectQueue
       DistortedRenderState.unuseStencilMark();
 
       // vertical blur
-      GLES30.glViewport(0, 0, (int)w2, (int)h2);
       mBlur2Program.useProgram();
       buffer2.setAsInput();
-      buffer2.setAsDepth();
-      surface.setAsOutput(time);
+      buffer1.setAsOutput();
+
+      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);
+      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
 
       GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
       GLES30.glUniform1i( mRadius2H, radius);
       GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
       GLES30.glUniform1i( mColorTexture2H , 0 );
-      GLES30.glUniform1i( mDepthTexture2H , 1 );
       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);
+
+      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_STENCIL_ATTACHMENT, GLES30.GL_TEXTURE_2D, buffer2.mDepthStencilH[0], 0);
+      DistortedRenderState.useStencilMark();
       GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+      DistortedRenderState.unuseStencilMark();
+      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_STENCIL_ATTACHMENT, GLES30.GL_TEXTURE_2D, buffer1.mDepthStencilH[0], 0);
+
+      // blit the results with DEPTH to surface.
+      GLES30.glViewport(0, 0, (int)w2, (int)h2);
+      buffer1.setAsInput();
+      buffer2.setAsDepth();
+      surface.setAsOutput(time);
+      DistortedEffects.blitDepthPriv(surface);
 
       // after each postprocess, clear buffers
       GLES30.glStencilMask(0xff);
@@ -331,11 +347,10 @@ class EffectQueuePostprocess extends EffectQueue
       GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
       GLES30.glClearDepthf(1.0f);
       GLES30.glClearStencil(0);
-
       buffer1.setAsOutput();
       GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
       buffer2.setAsOutput();
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT);
+      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
       }
 
     return mNumEffects;
diff --git a/src/main/res/raw/blit_depth_fragment_shader.glsl b/src/main/res/raw/blit_depth_fragment_shader.glsl
new file mode 100644
index 0000000..5e72e64
--- /dev/null
+++ b/src/main/res/raw/blit_depth_fragment_shader.glsl
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                          //
+//                                                                                          //
+// This file is part of Distorted.                                                          //
+//                                                                                          //
+// Distorted is free software: you can redistribute it and/or modify                        //
+// it under the terms of the GNU General Public License as published by                     //
+// the Free Software Foundation, either version 2 of the License, or                        //
+// (at your option) any later version.                                                      //
+//                                                                                          //
+// Distorted is distributed in the hope that it will be useful,                             //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
+// GNU General Public License for more details.                                             //
+//                                                                                          //
+// You should have received a copy of the GNU General Public License                        //
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+precision lowp float;
+
+#if __VERSION__ != 100
+out vec4 fragColor;           // The output color
+in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
+#define TEXTURE texture
+#define FRAG_COLOR fragColor
+#else
+varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
+#define TEXTURE texture2D
+#define FRAG_COLOR gl_FragColor
+#endif
+
+uniform sampler2D u_Texture;
+uniform sampler2D u_DepthTexture;
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+void main()                    		
+  {
+  gl_FragDepth = TEXTURE(u_DepthTexture,v_TexCoordinate).r;
+  FRAG_COLOR   = TEXTURE(u_Texture     ,v_TexCoordinate);
+  }
\ No newline at end of file
diff --git a/src/main/res/raw/blit_depth_vertex_shader.glsl b/src/main/res/raw/blit_depth_vertex_shader.glsl
new file mode 100644
index 0000000..7080267
--- /dev/null
+++ b/src/main/res/raw/blit_depth_vertex_shader.glsl
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                          //
+//                                                                                          //
+// This file is part of Distorted.                                                          //
+//                                                                                          //
+// Distorted is free software: you can redistribute it and/or modify                        //
+// it under the terms of the GNU General Public License as published by                     //
+// the Free Software Foundation, either version 2 of the License, or                        //
+// (at your option) any later version.                                                      //
+//                                                                                          //
+// Distorted is distributed in the hope that it will be useful,                             //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
+// GNU General Public License for more details.                                             //
+//                                                                                          //
+// You should have received a copy of the GNU General Public License                        // 
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+precision lowp float;
+
+#if __VERSION__ != 100
+in vec2 a_Position;           // Per-vertex position.
+out vec2 v_TexCoordinate;     //
+#else
+attribute vec2 a_Position;    // Per-vertex position.
+varying vec2 v_TexCoordinate; //
+#endif
+
+uniform float u_Depth;        // distance from the near plane to render plane, in clip coords
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+void main()
+  {
+  v_TexCoordinate = a_Position + 0.5;
+  gl_Position     = vec4(2.0*a_Position,u_Depth,1.0);
+  }
diff --git a/src/main/res/raw/blur2_fragment_shader.glsl b/src/main/res/raw/blur2_fragment_shader.glsl
index 9138d6c..ba6a4c5 100644
--- a/src/main/res/raw/blur2_fragment_shader.glsl
+++ b/src/main/res/raw/blur2_fragment_shader.glsl
@@ -31,7 +31,6 @@ varying vec2 v_TexCoordinate;
 #endif
 
 uniform sampler2D u_ColorTexture;
-uniform sampler2D u_DepthTexture;
 uniform float u_Offsets[MAX_BLUR];
 uniform float u_Weights[MAX_BLUR];
 uniform int u_Radius;
@@ -40,8 +39,6 @@ uniform int u_Radius;
 
 void main()
   {
-  gl_FragDepth = TEXTURE(u_DepthTexture,v_TexCoordinate).r;
-
   vec4 pixel= TEXTURE(u_ColorTexture,v_TexCoordinate) * u_Weights[0];
 
   for (int i=1; i<=u_Radius; i+=1)
