From 1992d24671f8d99abccb671b8f9d5a7cd474fd00 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Fri, 12 Oct 2012 21:38:36 +0200
Subject: GLArrayData* VBO binding: Properly document and impl. bindBuffer(..)
 in detail w/ data sync within GLArrayHandle, which also removed redundant
 code (VBO data sync and binding).

Refines commit 8582ece7dc7f65271b3184261697a542766d9864
           and f49f8e22953ed2426fd4264ee407e2dc3fc07cfc
---
 .../com/jogamp/opengl/util/GLArrayDataClient.java  | 26 ++++++--
 .../jogamp/opengl/util/GLArrayDataEditable.java    | 30 ++++++---
 .../jogamp/graph/curve/opengl/VBORegion2PES2.java  | 18 +++---
 .../jogamp/graph/curve/opengl/VBORegionSPES2.java  | 10 ++-
 .../classes/jogamp/opengl/util/GLArrayHandler.java | 20 +++++-
 .../opengl/util/GLArrayHandlerInterleaved.java     | 26 ++------
 .../jogamp/opengl/util/GLDataArrayHandler.java     | 26 +++-----
 .../jogamp/opengl/util/GLFixedArrayHandler.java    | 32 +++-------
 .../jogamp/opengl/util/GLVBOArrayHandler.java      | 73 ++++++++++++++++++++++
 .../jogamp/opengl/util/glsl/GLSLArrayHandler.java  | 11 ++--
 .../util/glsl/GLSLArrayHandlerInterleaved.java     | 23 ++-----
 11 files changed, 175 insertions(+), 120 deletions(-)
 create mode 100644 src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java

(limited to 'src/jogl')

diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
index 30fc0012b..af091d52b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataClient.java
@@ -124,33 +124,41 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   // Data read access
   //
 
+  @Override
   public final boolean isVBOWritten() { return bufferWritten; }
 
+  @Override
   public final boolean sealed() { return sealed; }
   
+  @Override
   public final boolean enabled() { return bufferEnabled; }
 
   //
   // Data and GL state modification ..
   //
 
+  @Override
   public final void setVBOWritten(boolean written) { bufferWritten=written; }
 
+  @Override
   public void destroy(GL gl) {
     reset(gl);
     super.destroy(gl);
   }
 
+  @Override
   public void reset(GL gl) {
     enableBuffer(gl, false);
     reset();
   }
 
+  @Override
   public void seal(GL gl, boolean seal) {
     seal(seal);
     enableBuffer(gl, seal);
   }
 
+  @Override
   public void enableBuffer(GL gl, boolean enable) {
     if( enableBufferAlways || bufferEnabled != enable ) { 
         if(enable) {
@@ -172,12 +180,12 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     }
   }
   
-  public void bindBuffer(GL gl, boolean bind) {
-      if(isVBO()) {
-          gl.glBindBuffer(getVBOTarget(), bind ? getVBOName() : 0);
-      }
+  @Override
+  public boolean bindBuffer(GL gl, boolean bind) {
+      return glArrayHandler.bindBuffer(gl, bind);
   }
   
+  @Override
   public void setEnableAlways(boolean always) {
     enableBufferAlways = always;
   }
@@ -186,6 +194,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   // Data modification ..
   //
 
+  @Override
   public void reset() {
     if(buffer!=null) {
         buffer.clear();
@@ -195,6 +204,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     this.bufferWritten=false;
   }
 
+  @Override
   public void seal(boolean seal)
   {
     if(sealed==seal) return;
@@ -211,12 +221,14 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
   }
 
 
+  @Override
   public void rewind() {
     if(buffer!=null) {
         buffer.rewind();
     }
   }
 
+  @Override
   public void padding(int doneInByteSize) {
     if ( buffer==null || sealed ) return;
     while(doneInByteSize<strideB) {
@@ -231,6 +243,7 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
    * This class buffer Class must match the arguments buffer class.
    * The arguments remaining elements must be a multiple of this arrays element stride.
    */
+  @Override
   public void put(Buffer v) {
     if ( sealed ) return;
     /** FIXME: isn't true for interleaved arrays !
@@ -241,28 +254,33 @@ public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayData
     Buffers.put(buffer, v);
   }
 
+  @Override
   public void putb(byte v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.putb(buffer, v);
   }
 
+  @Override
   public void puts(short v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.puts(buffer, v);
   }
 
+  @Override
   public void puti(int v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
     Buffers.puti(buffer, v);
   }
 
+  @Override
   public void putx(int v) {
     puti(v);
   }
 
+  @Override
   public void putf(float v) {
     if ( sealed ) return;
     growBufferIfNecessary(1);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
index 588e90d1e..9b04a48aa 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataEditable.java
@@ -14,7 +14,7 @@ import java.nio.*;
 public interface GLArrayDataEditable extends GLArrayData {
 
     public boolean sealed();
-    
+
     public boolean enabled();
 
     /**
@@ -45,12 +45,11 @@ public interface GLArrayDataEditable extends GLArrayData {
     public void seal(GL gl, boolean seal);
 
     /**
-     * <p>
      * Enables the buffer if <code>enable</code> is <code>true</code>, 
      * and transfers the data if required.
-     * In case {@link #isVBO() VBO is used}, it is bound accordingly for the data transfer and data association.
+     * In case {@link #isVBO() VBO is used}, it is bound accordingly for the data transfer and association,
+     * i.e. it issued {@link #bindBuffer(GL, boolean)}.
      * The VBO buffer is unbound when the method returns. 
-     * </p>
      * <p>
      * Disables the buffer if <code>enable</code> is <code>false</code>. 
      * </p>
@@ -67,15 +66,26 @@ public interface GLArrayDataEditable extends GLArrayData {
      * @see #setEnableAlways(boolean)
      */
     public void enableBuffer(GL gl, boolean enable);
-    
+
     /**
-     * In case {@link #isVBO() VBO is used}, the buffer is bound 
-     * if <code>bind</code> is <code>true</code>, otherwise the buffer is unbound.
+     * if <code>bind</code> is true and the data uses {@link #isVBO() VBO}, 
+     * the latter will be bound and data written to the GPU if required.
+     * <p>
+     * If  <code>bind</code> is false and the data uses {@link #isVBO() VBO},
+     * the latter will be unbound.
+     * </p>
+     * <p>
+     * This method is exposed to allow data VBO arrays, i.e. {@link GL#GL_ELEMENT_ARRAY_BUFFER},
+     * to be bounded and written while keeping the VBO bound. The latter is in contrast to {@link #enableBuffer(GL, boolean)},
+     * which leaves the VBO unbound, since it's not required for vertex attributes or pointers.
+     * </p>
      * 
-     * @param gl
-     * @param bind
+     * @param gl current GL object
+     * @param bind true if VBO shall be bound and data written, 
+     *        otherwise clear VBO binding. 
+     * @return true if data uses VBO and action was performed, otherwise false 
      */
-    public void bindBuffer(GL gl, boolean bind);
+    public boolean bindBuffer(GL gl, boolean bind);
 
     /**
      * Affects the behavior of 'enableBuffer'.
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index 765b94855..85d3ad5a7 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -220,16 +220,14 @@ public class VBORegion2PES2  extends GLRegion {
         gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
         fbo.use(gl, texA);                        
         verticeFboAttr.enableBuffer(gl, true);       
-        texCoordFboAttr.enableBuffer(gl, true);
-        indicesFbo.enableBuffer(gl, true);
+        texCoordFboAttr.enableBuffer(gl, true);        
+        indicesFbo.bindBuffer(gl, true); // keeps VBO binding
         
-        indicesFbo.bindBuffer(gl, true);
         gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesFbo.getElementCount() * indicesFbo.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
-        indicesFbo.bindBuffer(gl, false);
         
-        verticeFboAttr.enableBuffer(gl, false);       
+        indicesFbo.bindBuffer(gl, false);        
         texCoordFboAttr.enableBuffer(gl, false);
-        indicesFbo.enableBuffer(gl, false);        
+        verticeFboAttr.enableBuffer(gl, false);       
         fbo.unuse(gl);
         
         // setback: gl.glActiveTexture(currentActiveTextureEngine[0]);
@@ -289,15 +287,13 @@ public class VBORegion2PES2  extends GLRegion {
     private void renderRegion(GL2ES2 gl) {
         verticeTxtAttr.enableBuffer(gl, true);       
         texCoordTxtAttr.enableBuffer(gl, true);
-        indicesTxt.enableBuffer(gl, true);        
+        indicesTxt.bindBuffer(gl, true); // keeps VBO binding
         
-        indicesTxt.bindBuffer(gl, true);
         gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesTxt.getElementCount() * indicesTxt.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
-        indicesTxt.bindBuffer(gl, false);
         
-        verticeTxtAttr.enableBuffer(gl, false);       
+        indicesTxt.bindBuffer(gl, false);        
         texCoordTxtAttr.enableBuffer(gl, false);
-        indicesTxt.enableBuffer(gl, false);        
+        verticeTxtAttr.enableBuffer(gl, false);       
     }
     
     public void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
index 7f3e937e1..0cba444ad 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java
@@ -127,16 +127,14 @@ public class VBORegionSPES2 extends GLRegion {
 
     protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) {
         verticeAttr.enableBuffer(gl, true);       
-        texCoordAttr.enableBuffer(gl, true);
-        indices.enableBuffer(gl, true);
+        texCoordAttr.enableBuffer(gl, true);        
+        indices.bindBuffer(gl, true); // keeps VBO binding
         
-        indices.bindBuffer(gl, true);
         gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
+        
         indices.bindBuffer(gl, false);
-
-        verticeAttr.enableBuffer(gl, false);       
         texCoordAttr.enableBuffer(gl, false);
-        indices.enableBuffer(gl, false);
+        verticeAttr.enableBuffer(gl, false);       
     }    
 
     public final void destroy(GL2ES2 gl, RenderState rs) {
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
index 2049f9618..a6314a216 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandler.java
@@ -37,12 +37,28 @@ import javax.media.opengl.*;
  */
 public interface GLArrayHandler {
 
+    
+  /**
+   * if <code>bind</code> is true and the data uses VBO, 
+   * the latter will be bound and data written to the GPU if required.
+   * <p>
+   * If  <code>bind</code> is false and the data uses VBO,
+   * the latter will be unbound.
+   * </p>
+   * 
+   * @param gl current GL object
+   * @param bind true if VBO shall be bound and data written, 
+   *        otherwise clear VBO binding.
+   * @return true if data uses VBO and action was performed, otherwise false 
+   */
+  public boolean bindBuffer(GL gl, boolean bind);
+  
   /**
    * Implementation shall enable or disable the array state.
    * <p>
    * Before enabling the array state,
-   * implementation shall associate the data with the array
-   * and synchronize the data with the GPU.
+   * implementation shall synchronize the data with the GPU
+   * and associate the data with the array.
    * </p>
    * 
    * @param gl current GL object
diff --git a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
index ab916c329..98f711b8e 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLArrayHandlerInterleaved.java
@@ -28,8 +28,6 @@
 
 package jogamp.opengl.util;
 
-
-import java.nio.Buffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -41,12 +39,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
  * Interleaved fixed function arrays, i.e. where this buffer data 
  * represents many arrays. 
  */
-public class GLArrayHandlerInterleaved implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
   private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
 
   public GLArrayHandlerInterleaved(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -67,24 +64,11 @@ public class GLArrayHandlerInterleaved implements GLArrayHandler {
   
   public final void enableState(GL gl, boolean enable, Object ext) {
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
-        final boolean vboBound = ad.isVBO();
-        if(vboBound) {
-            // always bind and refresh the VBO mgr, 
-            // in case more than one gl*Pointer objects are in use
-            gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-            if(!ad.isVBOWritten()) {
-                if(null!=buffer) {
-                    gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-                }
-                ad.setVBOWritten(true);
-            }
-        }
+        final boolean vboBound = bindBuffer(gl, true);
         syncSubData(gl, ext);
         if(vboBound) {
-            gl.glBindBuffer(ad.getVBOTarget(), 0);
-        }
-        
+            bindBuffer(gl, false);
+        }        
     }
     for(int i=0; i<subArrays.size(); i++) {
         subArrays.get(i).enableState(gl, enable, ext);
diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
index 1e882e080..862d49d1d 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
@@ -28,21 +28,20 @@
 
 package jogamp.opengl.util;
 
-import javax.media.opengl.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
 
-import com.jogamp.opengl.util.*;
+import com.jogamp.opengl.util.GLArrayDataEditable;
 
-import java.nio.*;
 
 /**
  * Used for pure VBO data arrays, i.e. where the buffer data 
  * does not represents a specific array name. 
  */
-public class GLDataArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLDataArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
 
   public GLDataArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
 
   public final void setSubArrayVBOName(int vboName) {
@@ -59,19 +58,8 @@ public class GLDataArrayHandler implements GLArrayHandler {
             // makes no sense otherwise
             throw new GLException("GLDataArrayHandler can only handle VBOs.");
         }
-        Buffer buffer = ad.getBuffer();
-        
-        // always bind and refresh the VBO mgr, 
-        // in case more than one gl*Pointer objects are in use
-        gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-        if(!ad.isVBOWritten()) {
-            if(null!=buffer) {
-                gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-            }
-            ad.setVBOWritten(true);
-        }
-        gl.glBindBuffer(ad.getVBOTarget(), 0);
-          
+        bindBuffer(gl, true);
+        bindBuffer(gl, false);
     }
     // no array association
   }
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
index 3ed41893a..32bba896f 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -28,22 +28,19 @@
 
 package jogamp.opengl.util;
 
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 
-import java.nio.*;
-
 /**
  * Used for 1:1 fixed function arrays, i.e. where the buffer data 
  * represents this array only. 
  */
-public class GLFixedArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
-
+public class GLFixedArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
   public GLFixedArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -57,19 +54,7 @@ public class GLFixedArrayHandler implements GLArrayHandler {
   public final void enableState(GL gl, boolean enable, Object ext) {
     final GLPointerFunc glp = gl.getGL2ES1();
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
-        final boolean vboBound = ad.isVBO();
-        if(vboBound) {
-            // always bind and refresh the VBO mgr, 
-            // in case more than one gl*Pointer objects are in use
-            gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-            if(!ad.isVBOWritten()) {
-                if(null!=buffer) {
-                    gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-                }
-                ad.setVBOWritten(true);
-            }
-        }
+        final boolean vboBound = bindBuffer(gl, true);
         switch(ad.getIndex()) {
             case GLPointerFunc.GL_VERTEX_ARRAY:
                 glp.glVertexPointer(ad);
@@ -86,8 +71,9 @@ public class GLFixedArrayHandler implements GLArrayHandler {
             default:
                 throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
         }
-        gl.glBindBuffer(ad.getVBOTarget(), 0);
-        
+        if(vboBound) {
+            bindBuffer(gl, false);
+        }        
         glp.glEnableClientState(ad.getIndex());        
     } else {
         glp.glDisableClientState(ad.getIndex());
diff --git a/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
new file mode 100644
index 000000000..ad88a7030
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/GLVBOArrayHandler.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice, this list of
+ *       conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *       of conditions and the following disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl.util;
+
+
+import java.nio.Buffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.opengl.GL;
+
+import com.jogamp.opengl.util.GLArrayDataEditable;
+
+/**
+ * Interleaved fixed function arrays, i.e. where this buffer data 
+ * represents many arrays. 
+ */
+public abstract class GLVBOArrayHandler implements GLArrayHandler {
+  protected GLArrayDataEditable ad;
+
+  public GLVBOArrayHandler(GLArrayDataEditable ad) {
+    this.ad = ad;
+  }
+  
+  public final boolean bindBuffer(GL gl, boolean bind) {
+    if( !ad.isVBO() ) {
+        return false;
+    }
+    if(bind) {
+        // always bind and refresh the VBO mgr, 
+        // in case more than one gl*Pointer objects are in use
+        gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+        if(!ad.isVBOWritten()) {
+            final Buffer buffer = ad.getBuffer();
+            if(null!=buffer) {
+                gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
+            }
+            ad.setVBOWritten(true);
+        }
+    } else {
+        gl.glBindBuffer(ad.getVBOTarget(), 0);
+    }
+    return true;
+  }
+  
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index d7327a4e8..79bed90c9 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -35,6 +35,7 @@ import javax.media.opengl.GL2ES2;
 
 import jogamp.opengl.util.GLArrayHandler;
 import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -43,11 +44,10 @@ import com.jogamp.opengl.util.glsl.ShaderState;
  * Used for 1:1 GLSL arrays, i.e. where the buffer data 
  * represents this array only. 
  */
-public class GLSLArrayHandler implements GLArrayHandler {
-  private GLArrayDataEditable ad;
-
+public class GLSLArrayHandler extends GLVBOArrayHandler implements GLArrayHandler {
+    
   public GLSLArrayHandler(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -63,7 +63,6 @@ public class GLSLArrayHandler implements GLArrayHandler {
     final ShaderState st = (ShaderState) ext;    
     
     if(enable) {
-        final Buffer buffer = ad.getBuffer();
         /*
          * This would be the non optimized code path:
          * 
@@ -78,6 +77,7 @@ public class GLSLArrayHandler implements GLArrayHandler {
         }
         st.vertexAttribPointer(glsl, ad);
         */
+        final Buffer buffer = ad.getBuffer();
         if(ad.isVBO()) {
             // bind and refresh the VBO / vertex-attr only if necessary
             if(!ad.isVBOWritten()) {
@@ -108,6 +108,5 @@ public class GLSLArrayHandler implements GLArrayHandler {
         st.disableVertexAttribArray(glsl, ad);
     }
   }
-
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
index 6c80e31fa..f36693e19 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
@@ -28,7 +28,6 @@
 
 package jogamp.opengl.util.glsl;
 
-import java.nio.Buffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,6 +35,7 @@ import javax.media.opengl.GL;
 
 import jogamp.opengl.util.GLArrayHandler;
 import jogamp.opengl.util.GLArrayHandlerFlat;
+import jogamp.opengl.util.GLVBOArrayHandler;
 
 import com.jogamp.opengl.util.GLArrayDataEditable;
 
@@ -43,12 +43,11 @@ import com.jogamp.opengl.util.GLArrayDataEditable;
  * Interleaved fixed function arrays, i.e. where this buffer data 
  * represents many arrays. 
  */
-public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
-  private GLArrayDataEditable ad;
+public class GLSLArrayHandlerInterleaved extends GLVBOArrayHandler implements GLArrayHandler {
   private List<GLArrayHandlerFlat> subArrays = new ArrayList<GLArrayHandlerFlat>();
 
   public GLSLArrayHandlerInterleaved(GLArrayDataEditable ad) {
-    this.ad = ad;
+    super(ad);
   }
   
   public final void setSubArrayVBOName(int vboName) {
@@ -72,22 +71,10 @@ public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
         if(!ad.isVBO()) {
             throw new InternalError("Interleaved handle is not VBO: "+ad);
         }
-        
-        final Buffer buffer = ad.getBuffer();
-        final boolean vboWritten = ad.isVBOWritten();
-        
-        // always bind and refresh the VBO mgr, 
-        // in case more than one gl*Pointer objects are in use
-        gl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
-        if(!vboWritten) {
-            if(null!=buffer) {
-                gl.glBufferData(ad.getVBOTarget(), buffer.limit() * ad.getComponentSizeInBytes(), buffer, ad.getVBOUsage());
-            }
-            ad.setVBOWritten(true);
-        }
+        bindBuffer(gl, true);
         // sub data will decide weather to update the vertex attrib pointer
         syncSubData(gl, ext);
-        gl.glBindBuffer(ad.getVBOTarget(), 0);        
+        bindBuffer(gl, false);
     }
     for(int i=0; i<subArrays.size(); i++) {
         subArrays.get(i).enableState(gl, enable, ext);
-- 
cgit v1.2.3