commit f89f791a60aafbf10d876c1c9b8b217b2156eee2
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Wed Apr 19 17:38:35 2017 +0100

    Preliminary support for MIPMAP levels of the postprocessing buffers. (doesn't work yet)

diff --git a/src/main/java/org/distorted/library/DistortedOutputSurface.java b/src/main/java/org/distorted/library/DistortedOutputSurface.java
index cb69fa5..d0b2a55 100644
--- a/src/main/java/org/distorted/library/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/DistortedOutputSurface.java
@@ -27,6 +27,9 @@ import java.util.ArrayList;
 
 abstract class DistortedOutputSurface extends DistortedSurface implements DistortedSlave
 {
+  private static final int NUM_MIPMAP = 4;
+          static final int CUR_MIPMAP = 1;
+
   private static final int ATTACH = 0;
   private static final int DETACH = 1;
   private static final int DETALL = 2;
@@ -51,7 +54,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
 
   private ArrayList<Job> mJobs = new ArrayList<>();
 
-  DistortedFramebuffer mBuffer1, mBuffer2;
+  DistortedFramebuffer[] mBuffer1, mBuffer2;
 
   private long mTime;
   private float mFOV;
@@ -95,6 +98,9 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
 
     mClearDepth = 1.0f;
 
+    mBuffer1 = new DistortedFramebuffer[NUM_MIPMAP];
+    mBuffer2 = new DistortedFramebuffer[NUM_MIPMAP];
+
     createProjection();
     }
 
@@ -171,13 +177,22 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
         }
       else
         {
-        if( mBuffer1==null )
+        if( mBuffer1[0]==null )
           {
-          mBuffer1 = new DistortedFramebuffer(mDepthCreated!=DONT_CREATE, DistortedSurface.TYPE_SYST, mWidth, mHeight);
-          mBuffer2 = new DistortedFramebuffer(false                     , DistortedSurface.TYPE_SYST, mWidth, mHeight);
+          int sizeX = mWidth;
+          int sizeY = mHeight;
+
+          for(int j=0; j<NUM_MIPMAP; j++)
+            {
+            mBuffer1[j] = new DistortedFramebuffer(mDepthCreated!=DONT_CREATE, DistortedSurface.TYPE_SYST, sizeX, sizeY);
+            mBuffer2[j] = new DistortedFramebuffer(false                     , DistortedSurface.TYPE_SYST, sizeX, sizeY);
+
+            sizeX *= 0.9f;
+            sizeY *= 0.9f;
+            }
           }
 
-        numRenders += child.draw(time,mBuffer1);
+        numRenders += child.draw(time,mBuffer1[CUR_MIPMAP]);
         if( i==num-1 )
           {
           numRenders += currP.postprocess(time,this);
diff --git a/src/main/java/org/distorted/library/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
index 02e29e3..c415036 100644
--- a/src/main/java/org/distorted/library/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
@@ -93,8 +93,8 @@ class EffectQueuePostprocess extends EffectQueue
   private static float[] offsetsCache = new float[MAX_BLUR + MAX_BLUR*MAX_BLUR/4];
 
   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 mRadius1H,mOffsets1H,mWeights1H,mDepth1H, mScale1H, mColorTexture1H;
+  private static int mRadius2H,mOffsets2H,mWeights2H,mDepth2H, mScale2H, mColorTexture2H, mDepthTexture2H;
   private static float[] mWeights = new float[MAX_BLUR];
   private static float[] mOffsets = new float[MAX_BLUR];
   // another effect ....
@@ -131,6 +131,7 @@ class EffectQueuePostprocess extends EffectQueue
     mOffsets1H      = GLES30.glGetUniformLocation( blur1ProgramH, "u_Offsets");
     mWeights1H      = GLES30.glGetUniformLocation( blur1ProgramH, "u_Weights");
     mDepth1H        = GLES30.glGetUniformLocation( blur1ProgramH, "u_Depth");
+    mScale1H        = GLES30.glGetUniformLocation( blur1ProgramH, "u_Scale");
     mColorTexture1H = GLES30.glGetUniformLocation( blur1ProgramH, "u_ColorTexture");
 
     final InputStream blur2VertexStream   = resources.openRawResource(R.raw.blur_vertex_shader);
@@ -154,6 +155,7 @@ class EffectQueuePostprocess extends EffectQueue
     mOffsets2H      = GLES30.glGetUniformLocation( blur2ProgramH, "u_Offsets");
     mWeights2H      = GLES30.glGetUniformLocation( blur2ProgramH, "u_Weights");
     mDepth2H        = GLES30.glGetUniformLocation( blur2ProgramH, "u_Depth");
+    mScale2H        = GLES30.glGetUniformLocation( blur2ProgramH, "u_Scale");
     mColorTexture2H = GLES30.glGetUniformLocation( blur2ProgramH, "u_ColorTexture");
     mDepthTexture2H = GLES30.glGetUniformLocation( blur2ProgramH, "u_DepthTexture");
     }
@@ -259,9 +261,9 @@ class EffectQueuePostprocess extends EffectQueue
       {
       compute(time);
 
-      surface.mBuffer1.setAsInput();
-      float w = surface.mWidth;
-      float h = surface.mHeight;
+      surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsInput();
+      float w = surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].mWidth;
+      float h = surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].mHeight;
 
       int radius = (int)mUniforms[0];
       if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
@@ -274,11 +276,12 @@ class EffectQueuePostprocess extends EffectQueue
 
       // horizontal blur
       mBlur1Program.useProgram();
-      surface.mBuffer2.setAsOutput(time);
+      surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsOutput(time);
 
       GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset);
       GLES30.glUniform1i( mRadius1H, radius);
       GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear);
+      GLES30.glUniform1f( mScale1H , 1.0f);
       GLES30.glUniform1i( mColorTexture1H , 0 );
       for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h;
       GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0);
@@ -288,13 +291,14 @@ class EffectQueuePostprocess extends EffectQueue
 
       // vertical blur
       mBlur2Program.useProgram();
-      surface.mBuffer2.setAsInput();
-      surface.mBuffer1.setAsDepth();
+      surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsInput();
+      surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsDepth();
       surface.setAsOutput(time);
 
       GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
       GLES30.glUniform1i( mRadius2H, radius);
       GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
+      GLES30.glUniform1f( mScale2H , 0.9f);
       GLES30.glUniform1i( mColorTexture2H , 0 );
       GLES30.glUniform1i( mDepthTexture2H , 1 );
       for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
diff --git a/src/main/res/raw/blur_vertex_shader.glsl b/src/main/res/raw/blur_vertex_shader.glsl
index 59a33c5..f020009 100644
--- a/src/main/res/raw/blur_vertex_shader.glsl
+++ b/src/main/res/raw/blur_vertex_shader.glsl
@@ -30,11 +30,12 @@ varying vec2 v_TexCoordinate;    //
 #endif
 
 uniform float u_Depth;    // distance from the near plane to render plane, in clip coords
+uniform float u_Scale;
 
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 void main()
   {
-  v_TexCoordinate = a_TexCoordinate;
+  v_TexCoordinate = u_Scale*a_TexCoordinate;
   gl_Position     = vec4(2.0*a_Position,u_Depth,1.0);
   }
\ No newline at end of file
