Merge "Fix bug in on-device linking." into honeycomb
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 2ed7774..6e4c22e 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -188,12 +188,7 @@
         isFirstUpload = true;
     }
 
-    GLenum target = (GLenum)getGLTarget();
-    if (target == GL_TEXTURE_2D) {
-        upload2DTexture(isFirstUpload, mPtr);
-    } else if (target == GL_TEXTURE_CUBE_MAP) {
-        uploadCubeTexture(isFirstUpload);
-    }
+    upload2DTexture(isFirstUpload);
 
     if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
         freeScriptMemory();
@@ -202,6 +197,15 @@
     rsc->checkError("Allocation::uploadToTexture");
 }
 
+const static GLenum gFaceOrder[] = {
+    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+};
+
 void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
                                  uint32_t lod, RsAllocationCubemapFace face,
                                  uint32_t w, uint32_t h) {
@@ -210,10 +214,14 @@
     GLenum target = (GLenum)getGLTarget();
     glBindTexture(target, mTextureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    glTexSubImage2D(GL_TEXTURE_2D, lod, xoff, yoff, w, h, format, type, ptr);
+    GLenum t = GL_TEXTURE_2D;
+    if (mType->getDimFaces()) {
+        t = gFaceOrder[face];
+    }
+    glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
 }
 
-void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
+void Allocation::upload2DTexture(bool isFirstUpload) {
     GLenum type = mType->getElement()->getComponent().getGLType();
     GLenum format = mType->getElement()->getComponent().getGLFormat();
 
@@ -221,62 +229,29 @@
     glBindTexture(target, mTextureID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
-    for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
-        const uint8_t *p = (const uint8_t *)ptr;
-        p += mType->getLODOffset(lod);
-
-        if (isFirstUpload) {
-            glTexImage2D(GL_TEXTURE_2D, lod, format,
-                         mType->getLODDimX(lod), mType->getLODDimY(lod),
-                         0, format, type, p);
-        } else {
-            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
-                            mType->getLODDimX(lod), mType->getLODDimY(lod),
-                            format, type, p);
-        }
+    uint32_t faceCount = 1;
+    if (mType->getDimFaces()) {
+        faceCount = 6;
     }
 
-    if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-        glGenerateMipmap(target);
-#endif //ANDROID_RS_BUILD_FOR_HOST
-    }
-}
-
-void Allocation::uploadCubeTexture(bool isFirstUpload) {
-    GLenum type = mType->getElement()->getComponent().getGLType();
-    GLenum format = mType->getElement()->getComponent().getGLFormat();
-
-    GLenum target = (GLenum)getGLTarget();
-    glBindTexture(target, mTextureID);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-    GLenum faceOrder[] = {
-        GL_TEXTURE_CUBE_MAP_POSITIVE_X,
-        GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
-        GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
-        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
-        GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
-        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
-    };
-
-    Adapter2D adapt(getContext(), this);
-    for (uint32_t face = 0; face < 6; face ++) {
-        adapt.setFace(face);
-
+    for (uint32_t face = 0; face < faceCount; face ++) {
         for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
-            adapt.setLOD(lod);
+            const uint8_t *p = (const uint8_t *)mPtr;
+            p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
 
-            uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
+            GLenum t = GL_TEXTURE_2D;
+            if (mType->getDimFaces()) {
+                t = gFaceOrder[face];
+            }
 
             if (isFirstUpload) {
-                glTexImage2D(faceOrder[face], lod, format,
-                             adapt.getDimX(), adapt.getDimY(),
-                             0, format, type, ptr);
+                glTexImage2D(t, lod, format,
+                             mType->getLODDimX(lod), mType->getLODDimY(lod),
+                             0, format, type, p);
             } else {
-                glTexSubImage2D(faceOrder[face], lod, 0, 0,
-                                adapt.getDimX(), adapt.getDimY(),
-                                format, type, ptr);
+                glTexSubImage2D(t, lod, 0, 0,
+                                mType->getLODDimX(lod), mType->getLODDimY(lod),
+                                format, type, p);
             }
         }
     }
@@ -364,7 +339,7 @@
     if (mPtr) {
         const uint8_t *src = static_cast<const uint8_t *>(data);
         uint8_t *dst = static_cast<uint8_t *>(mPtr);
-        dst += mType->getLODOffset(lod, xoff, yoff);
+        dst += mType->getLODFaceOffset(lod, face, xoff, yoff);
 
         //LOGE("            %p  %p  %i  ", dst, src, eSize);
         for (uint32_t line=yoff; line < (yoff+h); line++) {
diff --git a/rsAllocation.h b/rsAllocation.h
index a160765..4f5d5a8 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -105,9 +105,6 @@
         return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE;
     }
 
-    void upload2DTexture(bool isFirstUpload, const void *ptr);
-    void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
-                         uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h);
 
 protected:
     ObjectBaseRef<const Type> mType;
@@ -149,7 +146,9 @@
 
 private:
     void init(Context *rsc, const Type *);
-    void uploadCubeTexture(bool isFirstUpload);
+    void upload2DTexture(bool isFirstUpload);
+    void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
+                         uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h);
 
     void allocScriptMemory();
     void freeScriptMemory();
diff --git a/rsType.cpp b/rsType.cpp
index 670ea33..d7b5f12 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -132,6 +132,17 @@
     return offset;
 }
 
+uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const {
+    uint32_t offset = mLODs[lod].mOffset;
+    offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+
+    if (face != 0) {
+        uint32_t faceOffset = getSizeBytes() / 6;
+        offset += faceOffset * face;
+    }
+    return offset;
+}
+
 void Type::dumpLOGV(const char *prefix) const {
     char buf[1024];
     ObjectBase::dumpLOGV(prefix);
diff --git a/rsType.h b/rsType.h
index 34498f0..90ae039 100644
--- a/rsType.h
+++ b/rsType.h
@@ -44,12 +44,14 @@
     uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
     uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
     uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
-    uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}
 
+    uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}
     uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
     uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
     uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const;
 
+    uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const;
+
     uint32_t getLODCount() const {return mLODCount;}
     bool getIsNp2() const;