From 87ff90fb03216737df70ff83246664b7fba2663e Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 22 Aug 2011 16:38:45 +0200
Subject: Fix regression of commit 6c346d98f04e2355210960fe9ffde47432f04d62,
 where VBO/attribute binding wasn't updated (VBO data written, shader
 change/switch attribute on same location) ; Optimized interleaved GLSL VBO
 binding, hence split up GLArrayHandler syncData/enableState

---
 .../jogamp/opengl/util/GLDataArrayHandler.java     |  9 +++-
 .../jogamp/opengl/util/GLFixedArrayHandler.java    | 54 +++++++++++-----------
 .../opengl/util/GLFixedArrayHandlerFlat.java       | 40 ++++++++--------
 .../util/GLFixedArrayHandlerInterleaved.java       | 18 +++++---
 .../jogamp/opengl/util/glsl/GLSLArrayHandler.java  | 38 +++++++++++----
 .../opengl/util/glsl/GLSLArrayHandlerFlat.java     | 14 ++++--
 .../util/glsl/GLSLArrayHandlerInterleaved.java     | 46 ++++++++++++++----
 7 files changed, 143 insertions(+), 76 deletions(-)

(limited to 'src/jogl/classes/jogamp/opengl/util')

diff --git a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
index 718b63822..259b8ae23 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLDataArrayHandler.java
@@ -29,6 +29,7 @@
 package jogamp.opengl.util;
 
 import javax.media.opengl.*;
+
 import com.jogamp.opengl.util.*;
 
 import java.nio.*;
@@ -52,7 +53,7 @@ public class GLDataArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void enableBuffer(GL gl, boolean enable) {
+  public final void syncData(GL gl, boolean enable) {
     if(enable) {
         Buffer buffer = ad.getBuffer();
 
@@ -67,7 +68,11 @@ public class GLDataArrayHandler implements GLArrayHandler {
         }
     } else {
         gl.glBindBuffer(ad.getVBOTarget(), 0);
-    }
+    }      
+  }
+  
+  public final void enableState(GL gl, boolean enable) { 
+      // no array association
   }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
index e365f0f4b..2cce72ff4 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandler.java
@@ -51,30 +51,9 @@ public class GLFixedArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  private final void passArrayPointer(GLPointerFunc gl) {
-    switch(ad.getIndex()) {
-        case GLPointerFunc.GL_VERTEX_ARRAY:
-            gl.glVertexPointer(ad);
-            break;
-        case GLPointerFunc.GL_NORMAL_ARRAY:
-            gl.glNormalPointer(ad);
-            break;
-        case GLPointerFunc.GL_COLOR_ARRAY:
-            gl.glColorPointer(ad);
-            break;
-        case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
-            gl.glTexCoordPointer(ad);
-            break;
-        default:
-            throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
-    }
-  }
-
-  public final void enableBuffer(GL gl, boolean enable) {
-    GLPointerFunc glp = gl.getGL2ES1();
+  public final void syncData(GL gl, boolean enable) {
     if(enable) {
-        Buffer buffer = ad.getBuffer();
-
+        final Buffer buffer = ad.getBuffer();
         if(ad.isVBO()) {
             // always bind and refresh the VBO mgr, 
             // in case more than one gl*Pointer objects are in use
@@ -86,13 +65,34 @@ public class GLFixedArrayHandler implements GLArrayHandler {
                 ad.setVBOWritten(true);
             }
         }
-        passArrayPointer(glp);
+        final GLPointerFunc glp = gl.getGL2ES1();
+        switch(ad.getIndex()) {
+            case GLPointerFunc.GL_VERTEX_ARRAY:
+                glp.glVertexPointer(ad);
+                break;
+            case GLPointerFunc.GL_NORMAL_ARRAY:
+                glp.glNormalPointer(ad);
+                break;
+            case GLPointerFunc.GL_COLOR_ARRAY:
+                glp.glColorPointer(ad);
+                break;
+            case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+                glp.glTexCoordPointer(ad);
+                break;
+            default:
+                throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
+        }
+    } else if(ad.isVBO()) {
+        gl.glBindBuffer(ad.getVBOTarget(), 0);
+    }
+  }
+  
+  public final void enableState(GL gl, boolean enable) {
+    final GLPointerFunc glp = gl.getGL2ES1();
+    if(enable) {
         glp.glEnableClientState(ad.getIndex());        
     } else {
         glp.glDisableClientState(ad.getIndex());
-        if(ad.isVBO()) {
-            gl.glBindBuffer(ad.getVBOTarget(), 0);
-        }
     }
   }
 }
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
index e1cf5d572..4dda9c6a1 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerFlat.java
@@ -50,29 +50,31 @@ public class GLFixedArrayHandlerFlat implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  private final void passArrayPointer(GLPointerFunc gl) {
-    switch(ad.getIndex()) {
-        case GLPointerFunc.GL_VERTEX_ARRAY:
-            gl.glVertexPointer(ad);
-            break;
-        case GLPointerFunc.GL_NORMAL_ARRAY:
-            gl.glNormalPointer(ad);
-            break;
-        case GLPointerFunc.GL_COLOR_ARRAY:
-            gl.glColorPointer(ad);
-            break;
-        case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
-            gl.glTexCoordPointer(ad);
-            break;
-        default:
-            throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
+  public final void syncData(GL gl, boolean enable) {
+    if(enable) {
+        final GLPointerFunc glp = gl.getGL2ES1();
+        switch(ad.getIndex()) {
+            case GLPointerFunc.GL_VERTEX_ARRAY:
+                glp.glVertexPointer(ad);
+                break;
+            case GLPointerFunc.GL_NORMAL_ARRAY:
+                glp.glNormalPointer(ad);
+                break;
+            case GLPointerFunc.GL_COLOR_ARRAY:
+                glp.glColorPointer(ad);
+                break;
+            case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+                glp.glTexCoordPointer(ad);
+                break;
+            default:
+                throw new GLException("invalid glArrayIndex: "+ad.getIndex()+":\n\t"+ad); 
+        }
     }
   }
 
-  public final void enableBuffer(GL gl, boolean enable) {
-    GLPointerFunc glp = gl.getGL2ES1();
+  public final void enableState(GL gl, boolean enable) {
+    final GLPointerFunc glp = gl.getGL2ES1();
     if(enable) {
-        passArrayPointer(glp);
         glp.glEnableClientState(ad.getIndex());        
     } else {
         glp.glDisableClientState(ad.getIndex());
diff --git a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerInterleaved.java b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerInterleaved.java
index 838032646..4bac20217 100644
--- a/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/GLFixedArrayHandlerInterleaved.java
@@ -54,15 +54,15 @@ public class GLFixedArrayHandlerInterleaved implements GLArrayHandler {
       subArrays.add(handler);
   }
 
-  private final void enableSubBuffer(GL gl, boolean enable) {
+  private final void syncSubData(GL gl, boolean enable) {
       for(int i=0; i<subArrays.size(); i++) {
-          subArrays.get(i).enableBuffer(gl, enable);
+          subArrays.get(i).syncData(gl, enable);
       }      
   }
   
-  public final void enableBuffer(GL gl, boolean enable) {
+  public final void syncData(GL gl, boolean enable) {
     if(enable) {
-        Buffer buffer = ad.getBuffer();
+        final Buffer buffer = ad.getBuffer();
 
         if(ad.isVBO()) {
             // always bind and refresh the VBO mgr, 
@@ -75,13 +75,19 @@ public class GLFixedArrayHandlerInterleaved implements GLArrayHandler {
                 ad.setVBOWritten(true);
             }
         }
-        enableSubBuffer(gl, true);
+        syncSubData(gl, true);
     } else {
-        enableSubBuffer(gl, false);
+        syncSubData(gl, false);
         if(ad.isVBO()) {
             gl.glBindBuffer(ad.getVBOTarget(), 0);
         }
     }
   }
+  
+  public final void enableState(GL gl, boolean enable) {
+    for(int i=0; i<subArrays.size(); i++) {
+        subArrays.get(i).enableState(gl, enable);
+    }      
+  }
 }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
index b4b7b5ace..d2fc52d5c 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandler.java
@@ -32,7 +32,7 @@ import java.nio.Buffer;
 
 import javax.media.opengl.GL;
 import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLException;
+
 import com.jogamp.opengl.util.GLArrayDataEditable;
 import com.jogamp.opengl.util.GLArrayHandler;
 import com.jogamp.opengl.util.glsl.ShaderState;
@@ -54,12 +54,25 @@ public class GLSLArrayHandler implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void enableBuffer(GL gl, boolean enable) {
-    GL2ES2 glsl = gl.getGL2ES2();
+  public final void syncData(GL gl, boolean enable) {
+    final GL2ES2 glsl = gl.getGL2ES2();
 
     if(enable) {
-        Buffer buffer = ad.getBuffer();
-
+        final Buffer buffer = ad.getBuffer();
+        /*
+         * This would be the non optimized code path:
+         * 
+        if(ad.isVBO()) {
+            glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+            if(!ad.isVBOWritten()) {
+                if(null!=buffer) {
+                    glsl.glBufferData(ad.getVBOTarget(), ad.getSizeInBytes(), buffer, ad.getVBOUsage());
+                }
+                ad.setVBOWritten(true);
+            }
+        }
+        st.vertexAttribPointer(glsl, ad);
+        */
         if(ad.isVBO()) {
             // bind and refresh the VBO / vertex-attr only if necessary
             if(!ad.isVBOWritten()) {
@@ -69,8 +82,9 @@ public class GLSLArrayHandler implements GLArrayHandler {
                 }
                 ad.setVBOWritten(true);
                 st.vertexAttribPointer(glsl, ad);
-            } else if(ad.getLocation() >= 0) {
+            } else if(st.getAttribLocation(glsl, ad) >= 0) {
                 // didn't experience a performance hit on this query ..
+                // (using ShaderState's location query above to validate the location)
                 final int[] qi = new int[1];
                 glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
                 if(ad.getVBOName() != qi[0]) {
@@ -81,12 +95,18 @@ public class GLSLArrayHandler implements GLArrayHandler {
         } else if(null!=buffer) {
             st.vertexAttribPointer(glsl, ad);
         }
+    } else if(ad.isVBO()) {
+        glsl.glBindBuffer(ad.getVBOTarget(), 0);
+    }      
+  }
+  
+  public final void enableState(GL gl, boolean enable) {
+    final GL2ES2 glsl = gl.getGL2ES2();
+
+    if(enable) {
         st.enableVertexAttribArray(glsl, ad);
     } else {
         st.disableVertexAttribArray(glsl, ad);
-        if(ad.isVBO()) {
-            glsl.glBindBuffer(ad.getVBOTarget(), 0);
-        }
     }
   }
 
diff --git a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
index 38379877f..5c4aa718c 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerFlat.java
@@ -51,16 +51,20 @@ public class GLSLArrayHandlerFlat implements GLArrayHandler {
       throw new UnsupportedOperationException();
   }
   
-  public final void enableBuffer(GL gl, boolean enable) {
-    GL2ES2 glsl = gl.getGL2ES2();
+  public final void syncData(GL gl, boolean enable) {
+    if(enable) {
+        st.vertexAttribPointer(gl.getGL2ES2(), ad);
+    }
+  }
+
+  public final void enableState(GL gl, boolean enable) {
+    final GL2ES2 glsl = gl.getGL2ES2();
 
     if(enable) {
-        st.vertexAttribPointer(glsl, ad);
         st.enableVertexAttribArray(glsl, ad);
     } else {
         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 ba5814a09..c662c13d2 100644
--- a/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
+++ b/src/jogl/classes/jogamp/opengl/util/glsl/GLSLArrayHandlerInterleaved.java
@@ -60,21 +60,22 @@ public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
       subArrays.add(handler);
   }
 
-  private final void enableSubBuffer(GL gl, boolean enable) {
+  private final void syncSubData(GL gl, boolean enable) {
       for(int i=0; i<subArrays.size(); i++) {
-          subArrays.get(i).enableBuffer(gl, enable);
+          subArrays.get(i).syncData(gl, enable);
       }      
   }
   
-  public final void enableBuffer(GL gl, boolean enable) {
+  public final void syncData(GL gl, boolean enable) {
     GL2ES2 glsl = gl.getGL2ES2();
 
     if(enable) {
         Buffer buffer = ad.getBuffer();
 
+        /*
+         * This would be the non optimized code path:
+         * 
         if(ad.isVBO()) {
-            // always bind and refresh the VBO mgr, 
-            // in case more than one attributes are in use
             glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
             if(!ad.isVBOWritten()) {
                 if(null!=buffer) {
@@ -83,13 +84,42 @@ public class GLSLArrayHandlerInterleaved implements GLArrayHandler {
                 ad.setVBOWritten(true);
             }
         }
-        enableSubBuffer(gl, true);
+        syncSubData(gl, true);
+        */
+        if(ad.isVBO()) {
+            // bind and refresh the VBO / vertex-attr only if necessary
+            if(!ad.isVBOWritten()) {
+                glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+                if(null!=buffer) {
+                    glsl.glBufferData(ad.getVBOTarget(), ad.getSizeInBytes(), buffer, ad.getVBOUsage());
+                }
+                ad.setVBOWritten(true);
+                syncSubData(gl, true);
+            } else if(st.getAttribLocation(glsl, ad) >= 0) {
+                // didn't experience a performance hit on this query ..
+                // (using ShaderState's location query above to validate the location)
+                final int[] qi = new int[1];
+                glsl.glGetVertexAttribiv(ad.getLocation(), GL2ES2.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, qi, 0);
+                if(ad.getVBOName() != qi[0]) {
+                    glsl.glBindBuffer(ad.getVBOTarget(), ad.getVBOName());
+                    syncSubData(gl, true);
+                }
+            }
+        } else if(null!=buffer) {
+            syncSubData(gl, true);
+        }
     } else {
-        enableSubBuffer(gl, false);
+        syncSubData(gl, false);
         if(ad.isVBO()) {
             glsl.glBindBuffer(ad.getVBOTarget(), 0);
         }
-    }
+    }      
+  }
+  
+  public final void enableState(GL gl, boolean enable) {
+    for(int i=0; i<subArrays.size(); i++) {
+        subArrays.get(i).enableState(gl, enable);
+    }      
   }
 
 }
-- 
cgit v1.2.3