commit f8377ef8b1f3c18a2aa2e80da99478b0a08af957
Author: leszek <leszek@koltunski.pl>
Date:   Mon Feb 13 00:02:44 2017 +0000

    New, cleaner way to create/destroy DistortedSurfaces.
    
    Serious regression in StarWars (crashes!). Looks like the Node's internal FBO is being deleted and not re-created in time.

diff --git a/src/main/java/org/distorted/library/DistortedFramebuffer.java b/src/main/java/org/distorted/library/DistortedFramebuffer.java
index 9b1ea76..2f5d816 100644
--- a/src/main/java/org/distorted/library/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/DistortedFramebuffer.java
@@ -38,7 +38,7 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
 // Must be called from a thread holding OpenGL Context
 // Watch out - this has the side-effect of binding a Texture and a Framebuffer!
 
-  public void create()
+  void create()
     {
     if( mColorH[0]==NOT_CREATED_YET )
       {
@@ -71,7 +71,7 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
 
       checkStatus("depth");
       }
-    if( !mDepthEnabled && mDepthH[0]!=NOT_CREATED_YET ) // we need to detach and destroy the DEPTH attachment.
+    if( !mDepthEnabled && mDepthH[0]!=NOT_CREATED_YET ) // we need to detach and recreate the DEPTH attachment.
       {
       GLES30.glDeleteTextures(1, mDepthH, 0);
       mDepthH[0]=NOT_CREATED_YET;
@@ -125,7 +125,7 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // called from onDestroy(); mark OpenGL assets as 'not created'
 
-  void destroy()
+  void recreate()
     {
     if( mColorH[0]!=DONT_CREATE ) mColorH[0] = NOT_CREATED_YET;
     if( mDepthEnabled           ) mDepthH[0] = NOT_CREATED_YET;
@@ -231,14 +231,18 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Create a new DEPTH buffer and attach it or (param=false) detach an existing DEPTh attachment and destroy it.
+ * Create a new DEPTH buffer and attach it or (param=false) detach an existing DEPTh attachment and recreate it.
  *
  * @param enable <bold>true</bold> if we want to attach a new DEPTH buffer to the FBO.<br>
  *               <bold>false</bold> if we want to detach the DEPTH attachment.
  */
   public void enableDepthAttachment(boolean enable)
     {
-    mDepthEnabled = enable;
+    if( mDepthEnabled!=enable )
+      {
+      mDepthEnabled = enable;
+      moveToToDo();
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/DistortedInputSurface.java b/src/main/java/org/distorted/library/DistortedInputSurface.java
index 0e63ae4..31b4b94 100644
--- a/src/main/java/org/distorted/library/DistortedInputSurface.java
+++ b/src/main/java/org/distorted/library/DistortedInputSurface.java
@@ -26,10 +26,6 @@ package org.distorted.library;
 
 interface DistortedInputSurface
 {
-/**
- * Create the underlying OpenGL part of the Surface.
- */
-  void create();
 /**
  * Return a unique ID of this Surface.
  */
diff --git a/src/main/java/org/distorted/library/DistortedNode.java b/src/main/java/org/distorted/library/DistortedNode.java
index 4afc4c4..97fccc6 100644
--- a/src/main/java/org/distorted/library/DistortedNode.java
+++ b/src/main/java/org/distorted/library/DistortedNode.java
@@ -58,6 +58,8 @@ public class DistortedNode
       numPointingNodes= 1;
       numRendered     = 0;
       mFBO            = null;
+
+      android.util.Log.e("DistortedNode", "new NodeData");
       }
     }
  
@@ -125,12 +127,18 @@ public class DistortedNode
       if( newList.size()>1 )
         {
         if( mData.mFBO ==null )
+          {
+          android.util.Log.e("DistortedNode", "creating a new FBO");
+
           mData.mFBO = new DistortedFramebuffer(mSurface.getWidth(), mSurface.getHeight());
+          }
         }
       else
         {
         if( mData.mFBO !=null )
           {
+          android.util.Log.e("DistortedNode", "marking FBO for deletion and setting it to NULL");
+
           mData.mFBO.markForDeletion();
           mData.mFBO = null;
           }
@@ -200,7 +208,6 @@ public class DistortedNode
 
   void drawRecursive(long currTime, DistortedOutputSurface surface)
     {
-    mSurface.create();
     float halfX = mSurface.getWidth()/2.0f;
     float halfY = mSurface.getHeight()/2.0f;
 
@@ -210,8 +217,6 @@ public class DistortedNode
       }
     else
       {
-      mData.mFBO.create();
-
       if( mData.numRendered==0 )
         {
         mData.mFBO.setAsOutput();
@@ -345,7 +350,10 @@ public class DistortedNode
     ArrayList<Long> prev = generateIDList(); 
    
     if( mChildren==null ) mChildren = new ArrayList<>(2);
-     
+
+    android.util.Log.e("DistortedNode", "ATTACH1");
+
+
     node.mParent = this;
     mChildren.add(node);
     mNumChildren[0]++;
@@ -365,7 +373,9 @@ public class DistortedNode
   public synchronized DistortedNode attach(DistortedInputSurface surface, DistortedEffects effects, MeshObject mesh)
     {
     ArrayList<Long> prev = generateIDList(); 
-      
+
+    android.util.Log.e("DistortedNode", "ATTACH2");
+
     if( mChildren==null ) mChildren = new ArrayList<>(2);
     DistortedNode node = new DistortedNode(surface,effects,mesh);
     node.mParent = this;
@@ -392,7 +402,9 @@ public class DistortedNode
          
       if( mChildren.remove(node) )
         {
-        node.mParent = null;  
+android.util.Log.e("DistortedNode", "DETACH1");
+
+        node.mParent = null;
         mNumChildren[0]--;
      
         RecomputeNodeID(prev);
@@ -425,6 +437,9 @@ public class DistortedNode
 
       if( node.mEffects.getID()==id )
         {
+android.util.Log.e("DistortedNode", "DETACH2");
+
+
         ArrayList<Long> prev = generateIDList();
 
         node.mParent = null;
diff --git a/src/main/java/org/distorted/library/DistortedOutputSurface.java b/src/main/java/org/distorted/library/DistortedOutputSurface.java
index ded8177..c26c8d0 100644
--- a/src/main/java/org/distorted/library/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/DistortedOutputSurface.java
@@ -99,8 +99,7 @@ abstract class DistortedOutputSurface extends DistortedSurface
  */
   public void render(long time)
     {
-    DistortedSurface.deleteAllMarked();
-    create();
+    toDo();
 
     for(int i=0; i<mNumChildren; i++)
       {
@@ -144,10 +143,16 @@ abstract class DistortedOutputSurface extends DistortedSurface
       {
       mWidth = width;
       mHeight= height;
-      createProjection();
       mSizeX = width;
       mSizeY = height;
-      if( mColorH[0]>0 ) markForDeletion();
+
+      createProjection();
+
+      if( mColorH[0]>0 )
+        {
+        moveToToDo();
+        recreate();
+        }
       }
     }
 
diff --git a/src/main/java/org/distorted/library/DistortedScreen.java b/src/main/java/org/distorted/library/DistortedScreen.java
index ea12e0a..da1b469 100644
--- a/src/main/java/org/distorted/library/DistortedScreen.java
+++ b/src/main/java/org/distorted/library/DistortedScreen.java
@@ -32,9 +32,9 @@ public class DistortedScreen extends DistortedOutputSurface
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // here we don't manage underlying OpenGL assets ourselves
 
-  public void create() {}
-  void delete() {}
-  void destroy() {}
+  void create()  {}
+  void delete()  {}
+  void recreate() {}
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
diff --git a/src/main/java/org/distorted/library/DistortedSurface.java b/src/main/java/org/distorted/library/DistortedSurface.java
index 0b6d141..35fd901 100644
--- a/src/main/java/org/distorted/library/DistortedSurface.java
+++ b/src/main/java/org/distorted/library/DistortedSurface.java
@@ -19,7 +19,6 @@
 
 package org.distorted.library;
 
-import java.util.Iterator;
 import java.util.LinkedList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -36,8 +35,9 @@ abstract class DistortedSurface
   static final int NOT_CREATED_YET  = -2;
   static final int DONT_CREATE      = -3;
 
-  private static boolean mListMarked = false;
-  private static LinkedList<DistortedSurface> mList = new LinkedList<>();
+  private static boolean mToDo = false;
+  private static LinkedList<DistortedSurface> mDoneList = new LinkedList<>();
+  private static LinkedList<DistortedSurface> mToDoList = new LinkedList<>();
 
   private boolean mMarked;
   int[] mColorH = new int[1];
@@ -45,33 +45,38 @@ abstract class DistortedSurface
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public abstract void create();
+  abstract void create();
   abstract void delete();
-  abstract void destroy();
+  abstract void recreate();
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // must be called form a thread holding OpenGL Context
 
-  static synchronized void deleteAllMarked()
+  static synchronized void toDo()
     {
-    if( mListMarked )
+    if( mToDo )
       {
-      DistortedSurface tmp;
-      Iterator<DistortedSurface> iterator = mList.iterator();
+      DistortedSurface surface;
 
-      while(iterator.hasNext())
+      int num = mToDoList.size();
+
+      for(int i=0; i<num; i++)
         {
-        tmp = iterator.next();
+        surface = mToDoList.removeFirst();
 
-        if( tmp.mMarked )
+        if(surface.mMarked)
+          {
+          surface.delete();
+          surface.mMarked = false;
+          }
+        else
           {
-          tmp.delete();
-          tmp.mMarked = false;
-          iterator.remove();
+          surface.create();
+          mDoneList.add(surface);
           }
         }
 
-      mListMarked = false;
+      mToDo = false;
       }
     }
 
@@ -79,13 +84,33 @@ abstract class DistortedSurface
 
   static synchronized void onDestroy()
     {
-    for( DistortedSurface surface : mList)
+    DistortedSurface surface;
+
+    int num = mDoneList.size();
+
+    for(int i=0; i<num; i++)
       {
-      surface.destroy();
-      surface.mMarked = false;
+      surface = mDoneList.removeFirst();
+
+      if( !surface.mMarked )
+        {
+        surface.recreate();
+        mToDoList.add(surface);
+        }
       }
 
-    mListMarked = false;
+    mToDo = true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized void moveToToDo()
+    {
+    if ( mDoneList.remove(this) )
+      {
+      mToDoList.add(this);
+      mToDo = true;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -96,7 +121,12 @@ abstract class DistortedSurface
     mSizeY    = height;
     mColorH[0]= color;
     mMarked   = false;
-    mList.add(this);
+
+    if( color!=DONT_CREATE )
+      {
+      mToDoList.add(this);
+      mToDo = true;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -107,8 +137,13 @@ abstract class DistortedSurface
  */
   public void markForDeletion()
     {
-    mListMarked = true;
-    mMarked     = true;
+    if( !mMarked )
+      {
+      mToDo   = true;
+      mMarked = true;
+      mDoneList.remove(this);
+      mToDoList.add(this);
+      }
     }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/DistortedTexture.java b/src/main/java/org/distorted/library/DistortedTexture.java
index ffc3230..c7248e6 100644
--- a/src/main/java/org/distorted/library/DistortedTexture.java
+++ b/src/main/java/org/distorted/library/DistortedTexture.java
@@ -55,7 +55,7 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // must be called from a thread holding OpenGL Context
 
-  public void create()
+  void create()
     {
     if( mBmp!=null && mColorH !=null )
       {
@@ -94,7 +94,7 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // called from onDestroy(); mark OpenGL assets as 'not created'
 
-  void destroy()
+  void recreate()
     {
     if( mColorH[0]!=DONT_CREATE ) mColorH[0] = NOT_CREATED_YET;
     }
@@ -148,5 +148,6 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
   public void setTexture(Bitmap bmp)
     {
     mBmp= bmp;
+    moveToToDo();
     }
   }
