commit df4d7edc59b4a24e46119cab498b21fc0f01ca3a
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Mar 29 16:58:40 2018 +0100

    SSBO: correct various things.

diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
index c4ff622..73c7617 100644
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
@@ -101,8 +101,8 @@ public static final int DEBUG_FPS = 1;
 
   ////////////////////////////////////////////////////////////////////////////////
   // section dealing with Shader Storage Buffer Object (for counting transparency)
-  private static final int BUFFERING = 3;
-  private static int mBufferSize     =10;
+  private static final int FRAME_DELAY = 3;
+  private static int mBufferSize       =10;
   private static DistortedObjectCounter mSurfaceCounter = new DistortedObjectCounter();
   private static int[] mSSBO = new int[1];
   private static IntBuffer mIntBuffer;
@@ -114,7 +114,7 @@ public static final int DEBUG_FPS = 1;
 
   private int mSurfaceID;
   private int mLastIndex;
-  private int mLastValue =-1;
+  private int[] mLastValue = new int[FRAME_DELAY];
   // end section
   ////////////////////////////////////////////////////////////////////////////////
 
@@ -173,8 +173,8 @@ public static final int DEBUG_FPS = 1;
 
       // here bind the new SSBO and map it
       GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mSSBO[0]);
-      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, BUFFERING*mBufferSize*4 , null, GLES31.GL_DYNAMIC_READ);
-      ByteBuffer buf = (ByteBuffer) GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, BUFFERING*mBufferSize*4, GLES31.GL_MAP_READ_BIT );
+      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, FRAME_DELAY *mBufferSize*4 , null, GLES31.GL_DYNAMIC_READ);
+      ByteBuffer buf = (ByteBuffer) GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, FRAME_DELAY *mBufferSize*4, GLES31.GL_MAP_READ_BIT );
       mIntBuffer = buf.order(ByteOrder.nativeOrder()).asIntBuffer();
       GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER,0, mSSBO[0]);
       }
@@ -184,8 +184,8 @@ public static final int DEBUG_FPS = 1;
     if( mSurfaceID>=mBufferSize )
       {
       // increase size of the Buffer, copy over old values, remap.
-      int[] tmp = new int[BUFFERING*mBufferSize];
-      for(int i=0;i<BUFFERING*mBufferSize;i++) tmp[i] = mIntBuffer.get(i);
+      int[] tmp = new int[FRAME_DELAY *mBufferSize];
+      for(int i = 0; i< FRAME_DELAY *mBufferSize; i++) tmp[i] = mIntBuffer.get(i);
 
       mBufferSize*= 2;
 
@@ -194,8 +194,8 @@ public static final int DEBUG_FPS = 1;
       GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER,0);
 
       GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mSSBO[0]);
-      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, BUFFERING*mBufferSize*4 , null, GLES31.GL_DYNAMIC_READ);
-      ByteBuffer buf = (ByteBuffer) GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, BUFFERING*mBufferSize*4, GLES31.GL_MAP_READ_BIT );
+      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, FRAME_DELAY *mBufferSize*4 , null, GLES31.GL_DYNAMIC_READ);
+      ByteBuffer buf = (ByteBuffer) GLES31.glMapBufferRange(GLES31.GL_SHADER_STORAGE_BUFFER, 0, FRAME_DELAY *mBufferSize*4, GLES31.GL_MAP_READ_BIT );
       mIntBuffer = buf.order(ByteOrder.nativeOrder()).asIntBuffer();
       GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER,0, mSSBO[0]);
 
@@ -218,8 +218,8 @@ public static final int DEBUG_FPS = 1;
 
   void recreate()
     {
-    mSSBO[0]   = -1;
-    mLastValue = -1;
+    for(int i = 0; i< FRAME_DELAY; i++) mLastValue[i] = 0;
+    mSSBO[0]= -1;
     mSurfaceCounter.releaseAll();
     recreateSurface();
     }
@@ -228,15 +228,7 @@ public static final int DEBUG_FPS = 1;
 
   int getNewCounter()
     {
-    int value = mIntBuffer.get(BUFFERING*mSurfaceID+(mLastIndex==0 ? BUFFERING-1:mLastIndex-1));
-
-    if( value!=mLastValue )
-      {
-      mLastValue = value;
-      android.util.Log.d("surface", "surface id: "+mSurfaceID+" value now: "+mLastValue);
-      }
-
-    return BUFFERING*mSurfaceID + mLastIndex;
+    return FRAME_DELAY*mSurfaceID + mLastIndex;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -524,9 +516,17 @@ public static final int DEBUG_FPS = 1;
       GLES31.glClear(mClear);
       DistortedRenderState.colorDepthStencilRestore();
 
-      mLastIndex++;
-      if( mLastIndex>=BUFFERING ) mLastIndex=0;
-      mIntBuffer.put(BUFFERING*mSurfaceID+mLastIndex,0);
+      if( ++mLastIndex >= FRAME_DELAY ) mLastIndex=0;
+
+      int index = (mLastIndex==0 ? FRAME_DELAY-1 : mLastIndex-1);
+      int value =  mIntBuffer.get(FRAME_DELAY *mSurfaceID+index);
+
+      if( value!=mLastValue[index] )
+        {
+        // yes, this DOES keep on working when 'value' overflows into negative territory.
+        android.util.Log.d("surface", "surface id: "+mSurfaceID+" last frame: "+(value-mLastValue[index]) );
+        mLastValue[index] = value;
+        }
       }
     }
 
diff --git a/src/main/res/raw/main_fragment_shader.glsl b/src/main/res/raw/main_fragment_shader.glsl
index b9c92c7..8128574 100644
--- a/src/main/res/raw/main_fragment_shader.glsl
+++ b/src/main/res/raw/main_fragment_shader.glsl
@@ -48,6 +48,11 @@ layout (std430,binding=0) buffer SSBO   // PER-SURFACE count of transparent frag
   int ssbocount[];                      // triple-buffered, then surfaceID=N uses 3
   };                                    // consecutive counts (N,N+1,N+2) during 3
                                         // consecutive frames.
+                                        // Cannot be an 'uint' because the Java application that's
+                                        // reading this does not have unsigned types so it's reading
+                                        // this into a signed int... Doesn't matter as things keep on
+                                        // working even when this overflows into negative territory :)
+
 uniform int u_currentIndex;             // Index into the count[] array we are supposed to be using
                                         // during this very invocation.
 
