commit ce1540147878aed35d8b317b2392069c3603e70c
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Apr 6 15:02:36 2018 +0100

    Make the postprocessing buffers static.

diff --git a/src/main/java/org/distorted/library/main/Distorted.java b/src/main/java/org/distorted/library/main/Distorted.java
index 2a755dd..70be620 100644
--- a/src/main/java/org/distorted/library/main/Distorted.java
+++ b/src/main/java/org/distorted/library/main/Distorted.java
@@ -153,6 +153,7 @@ public class Distorted
     DistortedNode.onDestroy();
     DistortedEffects.onDestroy();
     DistortedMaster.onDestroy();
+    DistortedOutputSurface.onDestroy();
     EffectQueue.onDestroy();
     Effect.onDestroy();
     VertexEffect.onDestroy();
diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
index 7d8558c..2898540 100644
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
@@ -79,8 +79,8 @@ public static final int DEBUG_FPS = 1;
 
   private ArrayList<Job> mJobs = new ArrayList<>();
 
-  // buffers used for postprocessing.
-  private DistortedOutputSurface[] mBuffer;
+  // Global buffers used for postprocessing.
+  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[1+EffectQuality.LENGTH];
 
   private long mTime;
   private float mFOV;
@@ -170,8 +170,6 @@ public static final int DEBUG_FPS = 1;
     mClearStencil = 0;
     mClear = GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_COLOR_BUFFER_BIT;
 
-    mBuffer = new DistortedOutputSurface[1+EffectQuality.LENGTH];
-
     mMipmap = 1.0f;
 
     createProjection();
@@ -289,22 +287,20 @@ public static final int DEBUG_FPS = 1;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void createBuffers()
+  private static void createBuffers(int width, int height, float near)
     {
     float mipmap=1.0f;
 
     for(int j=0; j<EffectQuality.LENGTH; j++)
       {
-      mBuffer[j] = new DistortedFramebuffer(2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(mWidth*mipmap), (int)(mHeight*mipmap) );
+      mBuffer[j] = new DistortedFramebuffer(2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
       mBuffer[j].mMipmap = mipmap;
-      mBuffer[j].mNear   = mNear;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
+      mBuffer[j].mNear   = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
       mBuffer[j].glClearColor(1.0f,1.0f,1.0f,0.0f);
 
       mipmap *= EffectQuality.MULTIPLIER;
       }
 
-    mBuffer[EffectQuality.LENGTH] = this;
-
     DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
 
     GLES31.glStencilMask(0xff);
@@ -326,23 +322,46 @@ public static final int DEBUG_FPS = 1;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void cloneSize(DistortedOutputSurface from)
+  static synchronized void onDestroy()
     {
-    mWidth = from.mWidth;
-    mHeight= from.mHeight;
-
-    createProjection();
+    for(int j=0; j<=EffectQuality.LENGTH; j++)
+      {
+      mBuffer[j] = null;
+      }
+    }
 
-    int maxw = mWidth >mRealWidth  ? mWidth :mRealWidth ;
-    int maxh = mHeight>mRealHeight ? mHeight:mRealHeight;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    if( maxw>mRealWidth || maxh>mRealHeight )
+  private static void cloneViewport(DistortedOutputSurface from)
+    {
+    if( mBuffer[EffectQuality.LENGTH] != from )
       {
-      mRealWidth = maxw;
-      mRealHeight= maxh;
+      mBuffer[EffectQuality.LENGTH]=from;
+      DistortedOutputSurface surface;
+
+      for(int i=0; i<EffectQuality.LENGTH; i++)
+        {
+        surface = mBuffer[i];
+
+        surface.mWidth  = (int)(from.mWidth *surface.mMipmap);
+        surface.mHeight = (int)(from.mHeight*surface.mMipmap);
+
+        surface.mNear   = from.mNear;  // Near plane is independent of the mipmap level
+
+        surface.createProjection();
+
+        int maxw = surface.mWidth  > surface.mRealWidth  ? surface.mWidth  : surface.mRealWidth;
+        int maxh = surface.mHeight > surface.mRealHeight ? surface.mHeight : surface.mRealHeight;
 
-      recreateSurface();
-      createSurface();
+        if (maxw > surface.mRealWidth || maxh > surface.mRealHeight)
+          {
+          surface.mRealWidth = maxw;
+          surface.mRealHeight = maxh;
+
+          surface.recreateSurface();
+          surface.createSurface();
+          }
+        }
       }
     }
 
@@ -404,7 +423,7 @@ public static final int DEBUG_FPS = 1;
       if( currBucket==0 ) numRenders += child1.draw(time,this);
       else
         {
-        if( mBuffer[0]==null ) createBuffers();
+        if( mBuffer[0]==null ) createBuffers(mWidth,mHeight,mNear);
 
         if( lastBucket!=currBucket )
           {
@@ -423,6 +442,8 @@ public static final int DEBUG_FPS = 1;
           internalQuality = currQueue.getInternalQuality();
           quality         = currQueue.getQuality();
           bucketChange    = i;
+
+          cloneViewport(this);
           }
 
         child1.draw(time,mBuffer[quality]);
@@ -565,7 +586,7 @@ public static final int DEBUG_FPS = 1;
           {
           android.util.Log.d("surface", "id " + mSurfaceID +
               (mType == TYPE_USER ? " USER" : (mType == TYPE_SYST ? " SYST" : " TREE")) +
-              "viewport: (" + mWidth + "x" + mHeight + ") last frame: " + (value - mLastValue[mLastIndex])
+              " viewport: (" + mWidth + "x" + mHeight + ") last frame: " + (value - mLastValue[mLastIndex])
               + " avg: " + (mAvgSum/RUNNING_AVERAGE)
           );
           }
