Update allocation from bitmap.
GL attribute cleanup in type.

Change-Id: I504dcf6744ad13d65e068e784b6608c999ab48c6
diff --git a/rs.spec b/rs.spec
index 8a25a97..27bb006 100644
--- a/rs.spec
+++ b/rs.spec
@@ -127,6 +127,12 @@
 	ret RsAllocation
 	}
 
+AllocationUpdateFromBitmap {
+	param RsAllocation alloc
+	param RsElement srcFmt
+	param const void * data
+	}
+
 AllocationCreateBitmapRef {
 	param RsType type
 	param void * bmpPtr
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 2e9e0b3..172d07d 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -26,6 +26,8 @@
 #include <OpenGl/glext.h>
 #endif
 
+#include "utils/StopWatch.h"
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -150,6 +152,8 @@
         return;
     }
 
+    bool isFirstUpload = false;
+
     if (!mTextureID) {
         glGenTextures(1, &mTextureID);
 
@@ -162,6 +166,7 @@
             mUploadDefered = true;
             return;
         }
+        isFirstUpload = true;
     }
     glBindTexture(GL_TEXTURE_2D, mTextureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -171,9 +176,15 @@
         adapt.setLOD(lod+mTextureLOD);
 
         uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
-        glTexImage2D(GL_TEXTURE_2D, lod, format,
-                     adapt.getDimX(), adapt.getDimY(),
-                     0, format, type, ptr);
+        if(isFirstUpload) {
+            glTexImage2D(GL_TEXTURE_2D, lod, format,
+                         adapt.getDimX(), adapt.getDimY(),
+                         0, format, type, ptr);
+        } else {
+            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
+                         adapt.getDimX(), adapt.getDimY(),
+                         format, type, ptr);
+        }
     }
     if (mTextureGenMipmap) {
 #ifndef ANDROID_RS_BUILD_FOR_HOST
@@ -751,6 +762,32 @@
     return alloc;
 }
 
+void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, RsElement _src, const void *data)
+{
+    Allocation *texAlloc = static_cast<Allocation *>(va);
+    const Element *src = static_cast<const Element *>(_src);
+    const Element *dst = texAlloc->getType()->getElement();
+    uint32_t w = texAlloc->getType()->getDimX();
+    uint32_t h = texAlloc->getType()->getDimY();
+    bool genMips = texAlloc->getType()->getDimLOD();
+
+    ElementConverter_t cvt = pickConverter(dst, src);
+    if (cvt) {
+        cvt(texAlloc->getPtr(), data, w * h);
+        if (genMips) {
+            Adapter2D adapt(rsc, texAlloc);
+            Adapter2D adapt2(rsc, texAlloc);
+            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+                adapt.setLOD(lod);
+                adapt2.setLOD(lod + 1);
+                mip(adapt2, adapt);
+            }
+        }
+    } else {
+        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
+    }
+}
+
 RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data)
 {
     const Element *src = static_cast<const Element *>(_src);
diff --git a/rsElement.cpp b/rsElement.cpp
index 0b9e28c..2becab0 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -65,7 +65,7 @@
 
     size_t total = 0;
     for (size_t ct=0; ct < mFieldCount; ct++) {
-        total += mFields[ct].e->mBits * mFields[ct].arraySize;;
+        total += mFields[ct].e->mBits * mFields[ct].arraySize;
     }
     return total;
 }
diff --git a/rsElement.h b/rsElement.h
index 50bca85..70e2619 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -50,6 +50,7 @@
     uint32_t getFieldCount() const {return mFieldCount;}
     const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
     const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}
+    uint32_t getFieldArraySize(uint32_t idx) const {return mFields[idx].arraySize;}
 
     const Component & getComponent() const {return mComponent;}
     RsDataType getType() const {return mComponent.getType();}
diff --git a/rsType.cpp b/rsType.cpp
index 33776c3..e0716eb 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -149,13 +149,37 @@
     return offset;
 }
 
+bool Type::isValidGLComponent(uint32_t fieldIdx) {
+    // Do not create attribs for padding
+    if(mElement->getFieldName(fieldIdx)[0] == '#') {
+        return false;
+    }
+
+    // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
+    // Filter rs types accordingly
+    RsDataType dt = mElement->getField(fieldIdx)->getComponent().getType();
+    if(dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
+       dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
+       dt != RS_TYPE_SIGNED_16) {
+        return false;
+    }
+
+    // Now make sure they are not arrays
+    uint32_t arraySize = mElement->getFieldArraySize(fieldIdx);
+    if(arraySize != 1) {
+        return false;
+    }
+
+    return true;
+}
 
 void Type::makeGLComponents()
 {
     // Count the number of gl attrs to initialize
     mAttribsSize = 0;
-    for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
-        if(getElement()->getFieldName(ct)[0] != '#') {
+
+    for (uint32_t ct=0; ct < mElement->getFieldCount(); ct++) {
+        if(isValidGLComponent(ct)) {
             mAttribsSize ++;
         }
     }
@@ -168,10 +192,10 @@
     }
 
     uint32_t userNum = 0;
-    for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
-        const Component &c = getElement()->getField(ct)->getComponent();
+    for (uint32_t ct=0; ct < mElement->getFieldCount(); ct++) {
+        const Component &c = mElement->getField(ct)->getComponent();
 
-        if(getElement()->getFieldName(ct)[0] == '#') {
+        if(!isValidGLComponent(ct)) {
             continue;
         }
 
@@ -180,7 +204,7 @@
         mAttribs[userNum].type = c.getGLType();
         mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
         String8 tmp(RS_SHADER_ATTR);
-        tmp.append(getElement()->getFieldName(ct));
+        tmp.append(mElement->getFieldName(ct));
         mAttribs[userNum].name.setTo(tmp.string());
 
         userNum ++;
diff --git a/rsType.h b/rsType.h
index 9099bf1..891edd4 100644
--- a/rsType.h
+++ b/rsType.h
@@ -121,6 +121,7 @@
 
     VertexArray::Attrib *mAttribs;
     uint32_t mAttribsSize;
+    bool isValidGLComponent(uint32_t fieldIdx);
     void makeGLComponents();
 
 private: