Reconcile with ics-mr0-release ics-mr1-release

Change-Id: I31643242d240b4d1efef685583ec21934a88cc02
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 2ebfe0a..e79cd0f 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -256,7 +256,7 @@
 
     if (drv->bufferID) {
         // Causes a SW crash....
-        //LOGV(" mBufferID %i", mBufferID);
+        //ALOGV(" mBufferID %i", mBufferID);
         //glDeleteBuffers(1, &mBufferID);
         //mBufferID = 0;
     }
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index 4ecf8e8..c16091c 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -450,7 +450,7 @@
 
     int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
     if (!destPtr) {
-        //LOGV("Calling setVar on slot = %i which is null", slot);
+        //ALOGV("Calling setVar on slot = %i which is null", slot);
         return;
     }
 
@@ -464,7 +464,7 @@
 
     int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
     if (!destPtr) {
-        //LOGV("Calling setVar on slot = %i which is null", slot);
+        //ALOGV("Calling setVar on slot = %i which is null", slot);
         return;
     }
 
@@ -478,7 +478,7 @@
 
     int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
     if (!destPtr) {
-        //LOGV("Calling setVar on slot = %i which is null", slot);
+        //ALOGV("Calling setVar on slot = %i which is null", slot);
         return;
     }
 
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
index 247f4dc..9292fa1 100644
--- a/driver/rsdCore.cpp
+++ b/driver/rsdCore.cpp
@@ -139,7 +139,7 @@
 
     uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
 
-    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+    //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
 
     dc->mWorkers.mLaunchSignals[idx].init();
     dc->mWorkers.mNativeThreadId[idx] = gettid();
@@ -168,7 +168,7 @@
         dc->mWorkers.mCompleteSignal.set();
     }
 
-    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
+    //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
     return NULL;
 }
 
@@ -219,7 +219,7 @@
 
 
     int cpu = sysconf(_SC_NPROCESSORS_ONLN);
-    LOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
+    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
     if (cpu < 2) cpu = 0;
 
     dc->mWorkers.mCount = (uint32_t)cpu;
diff --git a/driver/rsdGL.cpp b/driver/rsdGL.cpp
index 98d9486..d4deefb 100644
--- a/driver/rsdGL.cpp
+++ b/driver/rsdGL.cpp
@@ -101,7 +101,7 @@
         EGLint value = -1;
         EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
         if (returnVal) {
-            LOGV(" %s: %d (0x%x)", names[j].name, value, value);
+            ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
         }
     }
 }
@@ -116,12 +116,12 @@
     LOGE(" GL Extensions: %s", dc->gl.gl.extensions);
     LOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
 
-    LOGV("MAX Textures %i, %i  %i", dc->gl.gl.maxVertexTextureUnits,
+    ALOGV("MAX Textures %i, %i  %i", dc->gl.gl.maxVertexTextureUnits,
          dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
-    LOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
-    LOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
+    ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
+    ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
          dc->gl.gl.maxFragmentUniformVectors);
-    LOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
+    ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
 }
 
 void rsdGLShutdown(const Context *rsc) {
@@ -199,7 +199,7 @@
     configAttribsPtr[0] = EGL_NONE;
     rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
 
-    LOGV("%p initEGL start", rsc);
+    ALOGV("%p initEGL start", rsc);
     rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
     dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     checkEglError("eglGetDisplay");
@@ -303,11 +303,11 @@
     dc->gl.gl.renderer = glGetString(GL_RENDERER);
     dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
 
-    //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
-    //LOGV("GL Version %s", mGL.mVersion);
-    //LOGV("GL Vendor %s", mGL.mVendor);
-    //LOGV("GL Renderer %s", mGL.mRenderer);
-    //LOGV("GL Extensions %s", mGL.mExtensions);
+    //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+    //ALOGV("GL Version %s", mGL.mVersion);
+    //ALOGV("GL Vendor %s", mGL.mVendor);
+    //ALOGV("GL Renderer %s", mGL.mRenderer);
+    //ALOGV("GL Extensions %s", mGL.mExtensions);
 
     const char *verptr = NULL;
     if (strlen((const char *)dc->gl.gl.version) > 9) {
@@ -360,7 +360,7 @@
     dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
     dc->gl.currentFrameBuffer = NULL;
 
-    LOGV("%p initGLThread end", rsc);
+    ALOGV("%p initGLThread end", rsc);
     rsc->setWatchdogGL(NULL, 0, NULL);
     return true;
 }
diff --git a/driver/rsdProgram.cpp b/driver/rsdProgram.cpp
index 7556e50..54484df 100644
--- a/driver/rsdProgram.cpp
+++ b/driver/rsdProgram.cpp
@@ -68,7 +68,7 @@
     if(pv->mHal.drv) {
         drv = (RsdShader*)pv->mHal.drv;
         if (rsc->props.mLogShaders) {
-            LOGV("Destroying vertex shader with ID %u", drv->getShaderID());
+            ALOGV("Destroying vertex shader with ID %u", drv->getShaderID());
         }
         if (drv->getShaderID()) {
             dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
@@ -99,7 +99,7 @@
     if(pf->mHal.drv) {
         drv = (RsdShader*)pf->mHal.drv;
         if (rsc->props.mLogShaders) {
-            LOGV("Destroying fragment shader with ID %u", drv->getShaderID());
+            ALOGV("Destroying fragment shader with ID %u", drv->getShaderID());
         }
         if (drv->getShaderID()) {
             dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
diff --git a/driver/rsdShader.cpp b/driver/rsdShader.cpp
index bdb60c2..e9ce7c2 100644
--- a/driver/rsdShader.cpp
+++ b/driver/rsdShader.cpp
@@ -172,8 +172,8 @@
     rsAssert(mShaderID);
 
     if (rsc->props.mLogShaders) {
-        LOGV("Loading shader type %x, ID %i", mType, mShaderID);
-        LOGV("%s", mShader.string());
+        ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
+        ALOGV("%s", mShader.string());
     }
 
     if (mShaderID) {
@@ -202,7 +202,7 @@
     }
 
     if (rsc->props.mLogShaders) {
-        LOGV("--Shader load result %x ", glGetError());
+        ALOGV("--Shader load result %x ", glGetError());
     }
     mIsValid = true;
     return true;
@@ -252,36 +252,36 @@
     uint32_t elementSize = field->getSizeBytes() / sizeof(float);
     for (uint32_t i = 0; i < arraySize; i ++) {
         if (arraySize > 1) {
-            LOGV("Array Element [%u]", i);
+            ALOGV("Array Element [%u]", i);
         }
         if (dataType == RS_TYPE_MATRIX_4X4) {
-            LOGV("Matrix4x4");
-            LOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
-            LOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
-            LOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
-            LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
+            ALOGV("Matrix4x4");
+            ALOGV("{%f, %f, %f, %f",  fd[0], fd[4], fd[8], fd[12]);
+            ALOGV(" %f, %f, %f, %f",  fd[1], fd[5], fd[9], fd[13]);
+            ALOGV(" %f, %f, %f, %f",  fd[2], fd[6], fd[10], fd[14]);
+            ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
         } else if (dataType == RS_TYPE_MATRIX_3X3) {
-            LOGV("Matrix3x3");
-            LOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
-            LOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
-            LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
+            ALOGV("Matrix3x3");
+            ALOGV("{%f, %f, %f",  fd[0], fd[3], fd[6]);
+            ALOGV(" %f, %f, %f",  fd[1], fd[4], fd[7]);
+            ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
         } else if (dataType == RS_TYPE_MATRIX_2X2) {
-            LOGV("Matrix2x2");
-            LOGV("{%f, %f",  fd[0], fd[2]);
-            LOGV(" %f, %f}", fd[1], fd[3]);
+            ALOGV("Matrix2x2");
+            ALOGV("{%f, %f",  fd[0], fd[2]);
+            ALOGV(" %f, %f}", fd[1], fd[3]);
         } else {
             switch (field->getComponent().getVectorSize()) {
             case 1:
-                LOGV("Uniform 1 = %f", fd[0]);
+                ALOGV("Uniform 1 = %f", fd[0]);
                 break;
             case 2:
-                LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
+                ALOGV("Uniform 2 = %f %f", fd[0], fd[1]);
                 break;
             case 3:
-                LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+                ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
                 break;
             case 4:
-                LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+                ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
                 break;
             default:
                 rsAssert(0);
@@ -479,7 +479,7 @@
                 arraySize = sc->fragUniformSize(uidx);
             }
             if (rsc->props.mLogShadersUniforms) {
-                LOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
+                ALOGV("Uniform  slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
                      slot, offset, ct, field, uidx, fieldName);
             }
             uidx ++;
diff --git a/driver/rsdShaderCache.cpp b/driver/rsdShaderCache.cpp
index d11490c..2871a12 100644
--- a/driver/rsdShaderCache.cpp
+++ b/driver/rsdShaderCache.cpp
@@ -54,7 +54,7 @@
         }
 
         if (rsc->props.mLogShaders) {
-             LOGV("%s U, %s = %d, arraySize = %d\n", logTag,
+             ALOGV("%s U, %s = %d, arraySize = %d\n", logTag,
                   prog->getUniformName(ct).string(), data[ct].slot, data[ct].arraySize);
         }
     }
@@ -119,22 +119,22 @@
     if (!vtx->getShaderID() || !frag->getShaderID()) {
         return false;
     }
-    //LOGV("rsdShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
+    //ALOGV("rsdShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
     uint32_t entryCount = mEntries.size();
     for (uint32_t ct = 0; ct < entryCount; ct ++) {
         if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
             (mEntries[ct]->frag == frag->getShaderID())) {
 
-            //LOGV("SC using program %i", mEntries[ct]->program);
+            //ALOGV("SC using program %i", mEntries[ct]->program);
             glUseProgram(mEntries[ct]->program);
             mCurrent = mEntries[ct];
-            //LOGV("RsdShaderCache hit, using %i", ct);
+            //ALOGV("RsdShaderCache hit, using %i", ct);
             rsdGLCheckError(rsc, "RsdShaderCache::link (hit)");
             return true;
         }
     }
 
-    //LOGV("RsdShaderCache miss");
+    //ALOGV("RsdShaderCache miss");
     //LOGE("e0 %x", glGetError());
     ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
                                        vtx->getUniformCount(),
@@ -180,7 +180,7 @@
             e->vtxAttrs[ct].slot = glGetAttribLocation(pgm, vtx->getAttribName(ct));
             e->vtxAttrs[ct].name = vtx->getAttribName(ct).string();
             if (rsc->props.mLogShaders) {
-                LOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->vtxAttrs[ct].slot);
+                ALOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->vtxAttrs[ct].slot);
             }
         }
 
@@ -229,7 +229,7 @@
         }
     }
 
-    //LOGV("SC made program %i", e->program);
+    //ALOGV("SC made program %i", e->program);
     glUseProgram(e->program);
     rsdGLCheckError(rsc, "RsdShaderCache::link (miss)");
 
diff --git a/driver/rsdVertexArray.cpp b/driver/rsdVertexArray.cpp
index 62ec107..1836e67 100644
--- a/driver/rsdVertexArray.cpp
+++ b/driver/rsdVertexArray.cpp
@@ -65,9 +65,9 @@
 
 void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
     if (idx == 0) {
-        LOGV("Starting vertex attribute binding");
+        ALOGV("Starting vertex attribute binding");
     }
-    LOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%x",
+    ALOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%x",
          idx, slot,
          mAttribs[idx].name.string(),
          mAttribs[idx].buffer,
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index e732630..c1192fe 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -191,10 +191,85 @@
         mHal.state.type->dumpLOGV(s.string());
     }
 
-    LOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
+    ALOGV("%s allocation ptr=%p  mUsageFlags=0x04%x, mMipmapControl=0x%04x",
          prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl);
 }
 
+uint32_t Allocation::getPackedSize() const {
+    uint32_t numItems = mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes();
+    return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
+}
+
+void Allocation::writePackedData(const Type *type,
+                                 uint8_t *dst, const uint8_t *src, bool dstPadded) {
+    const Element *elem = type->getElement();
+    uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
+    uint32_t paddedBytes = elem->getSizeBytes();
+    uint32_t numItems = type->getSizeBytes() / paddedBytes;
+
+    uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
+    uint32_t dstInc =  dstPadded ? paddedBytes : unpaddedBytes;
+
+    // no sub-elements
+    uint32_t fieldCount = elem->getFieldCount();
+    if (fieldCount == 0) {
+        for (uint32_t i = 0; i < numItems; i ++) {
+            memcpy(dst, src, unpaddedBytes);
+            src += srcInc;
+            dst += dstInc;
+        }
+        return;
+    }
+
+    // Cache offsets
+    uint32_t *offsetsPadded = new uint32_t[fieldCount];
+    uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
+    uint32_t *sizeUnpadded = new uint32_t[fieldCount];
+
+    for (uint32_t i = 0; i < fieldCount; i++) {
+        offsetsPadded[i] = elem->getFieldOffsetBytes(i);
+        offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
+        sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
+    }
+
+    uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
+    uint32_t *dstOffsets =  dstPadded ? offsetsPadded : offsetsUnpadded;
+
+    // complex elements, need to copy subelem after subelem
+    for (uint32_t i = 0; i < numItems; i ++) {
+        for (uint32_t fI = 0; fI < fieldCount; fI++) {
+            memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
+        }
+        src += srcInc;
+        dst += dstInc;
+    }
+
+    delete[] offsetsPadded;
+    delete[] offsetsUnpadded;
+    delete[] sizeUnpadded;
+}
+
+void Allocation::unpackVec3Allocation(const void *data, uint32_t dataSize) {
+    const uint8_t *src = (const uint8_t*)data;
+    uint8_t *dst = (uint8_t*)getPtr();
+
+    writePackedData(getType(), dst, src, true);
+}
+
+void Allocation::packVec3Allocation(OStream *stream) const {
+    uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
+    uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
+    uint32_t numItems = mHal.state.type->getSizeBytes() / paddedBytes;
+
+    const uint8_t *src = (const uint8_t*)getPtr();
+    uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
+
+    writePackedData(getType(), dst, src, false);
+    stream->addByteArray(dst, getPackedSize());
+
+    delete[] dst;
+}
+
 void Allocation::serialize(OStream *stream) const {
     // Need to identify ourselves
     stream->addU32((uint32_t)getClassId());
@@ -207,10 +282,17 @@
     mHal.state.type->serialize(stream);
 
     uint32_t dataSize = mHal.state.type->getSizeBytes();
+    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
+    uint32_t packedSize = getPackedSize();
     // Write how much data we are storing
-    stream->addU32(dataSize);
-    // Now write the data
-    stream->addByteArray(getPtr(), dataSize);
+    stream->addU32(packedSize);
+    if (dataSize == packedSize) {
+        // Now write the data
+        stream->addByteArray(getPtr(), dataSize);
+    } else {
+        // Now write the data
+        packVec3Allocation(stream);
+    }
 }
 
 Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
@@ -230,22 +312,30 @@
     }
     type->compute();
 
+    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
+    type->decUserRef();
+
     // Number of bytes we wrote out for this allocation
     uint32_t dataSize = stream->loadU32();
-    if (dataSize != type->getSizeBytes()) {
+    // 3 element vectors are padded to 4 in memory, but padding isn't serialized
+    uint32_t packedSize = alloc->getPackedSize();
+    if (dataSize != type->getSizeBytes() &&
+        dataSize != packedSize) {
         LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
+        ObjectBase::checkDelete(alloc);
         ObjectBase::checkDelete(type);
         return NULL;
     }
 
-    Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
     alloc->setName(name.string(), name.size());
-    type->decUserRef();
 
-    uint32_t count = dataSize / type->getElementSizeBytes();
-
-    // Read in all of our allocation data
-    alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
+    if (dataSize == type->getSizeBytes()) {
+        uint32_t count = dataSize / type->getElementSizeBytes();
+        // Read in all of our allocation data
+        alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
+    } else {
+        alloc->unpackVec3Allocation(stream->getPtr() + stream->getPos(), dataSize);
+    }
     stream->reset(stream->getPos() + dataSize);
 
     return alloc;
diff --git a/rsAllocation.h b/rsAllocation.h
index 714798a..4ce863a 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -135,6 +135,11 @@
 private:
     void freeChildrenUnlocked();
     Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
+
+    uint32_t getPackedSize() const;
+    static void writePackedData(const Type *type, uint8_t *dst, const uint8_t *src, bool dstPadded);
+    void unpackVec3Allocation(const void *data, uint32_t dataSize);
+    void packVec3Allocation(OStream *stream) const;
 };
 
 }
diff --git a/rsComponent.cpp b/rsComponent.cpp
index ce06306..21b98f6 100644
--- a/rsComponent.cpp
+++ b/rsComponent.cpp
@@ -169,7 +169,8 @@
         break;
     }
 
-    mBits = mTypeBits * mVectorSize;
+    mBitsUnpadded = mTypeBits * mVectorSize;
+    mBits = mTypeBits * rsHigherPow2(mVectorSize);
 }
 
 bool Component::isReference() const {
@@ -228,10 +229,10 @@
 
 void Component::dumpLOGV(const char *prefix) const {
     if (mType >= RS_TYPE_ELEMENT) {
-        LOGV("%s   Component: %s, %s, vectorSize=%i, bits=%i",
+        ALOGV("%s   Component: %s, %s, vectorSize=%i, bits=%i",
              prefix, gTypeObjStrings[mType - RS_TYPE_ELEMENT], gKindStrings[mKind], mVectorSize, mBits);
     } else {
-        LOGV("%s   Component: %s, %s, vectorSize=%i, bits=%i",
+        ALOGV("%s   Component: %s, %s, vectorSize=%i, bits=%i",
              prefix, gTypeBasicStrings[mType], gKindStrings[mKind], mVectorSize, mBits);
     }
 }
diff --git a/rsComponent.h b/rsComponent.h
index 6ddc990..8629d0d 100644
--- a/rsComponent.h
+++ b/rsComponent.h
@@ -41,6 +41,7 @@
     bool getIsFloat() const {return mIsFloat;}
     bool getIsSigned() const {return mIsSigned;}
     uint32_t getBits() const {return mBits;}
+    uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
 
     // Helpers for reading / writing this class out
     void serialize(OStream *stream) const;
@@ -56,6 +57,7 @@
 
     // derived
     uint32_t mBits;
+    uint32_t mBitsUnpadded;
     uint32_t mTypeBits;
     bool mIsFloat;
     bool mIsSigned;
diff --git a/rsContext.cpp b/rsContext.cpp
index 5291a1f..293fc3a 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -152,7 +152,7 @@
 
 
     if (props.mLogTimes) {
-        LOGV("RS: Frame (%i),   Script %2.1f%% (%i),  Swap %2.1f%% (%i),  Idle %2.1f%% (%lli),  Internal %2.1f%% (%lli), Avg fps: %u",
+        ALOGV("RS: Frame (%i),   Script %2.1f%% (%i),  Swap %2.1f%% (%i),  Idle %2.1f%% (%lli),  Internal %2.1f%% (%lli), Avg fps: %u",
              mTimeMSLastFrame,
              100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
              100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
@@ -284,7 +284,7 @@
         }
     }
 
-    LOGV("%p RS Thread exiting", rsc);
+    ALOGV("%p RS Thread exiting", rsc);
 
     if (rsc->mIsGraphicsContext) {
         pthread_mutex_lock(&gInitMutex);
@@ -292,12 +292,12 @@
         pthread_mutex_unlock(&gInitMutex);
     }
 
-    LOGV("%p RS Thread exited", rsc);
+    ALOGV("%p RS Thread exited", rsc);
     return NULL;
 }
 
 void Context::destroyWorkerThreadResources() {
-    //LOGV("destroyWorkerThreadResources 1");
+    //ALOGV("destroyWorkerThreadResources 1");
     ObjectBase::zeroAllUserRef(this);
     if (mIsGraphicsContext) {
          mRaster.clear();
@@ -315,7 +315,7 @@
          mFBOCache.deinit(this);
     }
     ObjectBase::freeAllChildren(this);
-    //LOGV("destroyWorkerThreadResources 2");
+    //ALOGV("destroyWorkerThreadResources 2");
     mExit = true;
 }
 
@@ -431,7 +431,7 @@
 }
 
 Context::~Context() {
-    LOGV("%p Context::~Context", this);
+    ALOGV("%p Context::~Context", this);
 
     if (!mIsContextLite) {
         mIO.coreFlush();
@@ -455,7 +455,7 @@
         }
         pthread_mutex_unlock(&gInitMutex);
     }
-    LOGV("%p Context::~Context done", this);
+    ALOGV("%p Context::~Context done", this);
 }
 
 void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
@@ -472,6 +472,30 @@
     }
 }
 
+uint32_t Context::getCurrentSurfaceWidth() const {
+    for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
+        if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
+            return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimX();
+        }
+    }
+    if (mFBOCache.mHal.state.depthTarget != NULL) {
+        return mFBOCache.mHal.state.depthTarget->getType()->getDimX();
+    }
+    return mWidth;
+}
+
+uint32_t Context::getCurrentSurfaceHeight() const {
+    for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
+        if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
+            return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimY();
+        }
+    }
+    if (mFBOCache.mHal.state.depthTarget != NULL) {
+        return mFBOCache.mHal.state.depthTarget->getType()->getDimY();
+    }
+    return mHeight;
+}
+
 void Context::pause() {
     rsAssert(mIsGraphicsContext);
     mPaused = true;
@@ -672,10 +696,10 @@
 }
 
 void rsi_ContextDestroy(Context *rsc) {
-    LOGV("%p rsContextDestroy", rsc);
+    ALOGV("%p rsContextDestroy", rsc);
     rsContextDestroyWorker(rsc);
     delete rsc;
-    LOGV("%p rsContextDestroy done", rsc);
+    ALOGV("%p rsContextDestroy done", rsc);
 }
 
 
@@ -706,7 +730,7 @@
 
 RsContext rsContextCreate(RsDevice vdev, uint32_t version,
                           uint32_t sdkVersion) {
-    LOGV("rsContextCreate dev=%p", vdev);
+    ALOGV("rsContextCreate dev=%p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, NULL);
     if (rsc) {
@@ -718,14 +742,14 @@
 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
                             uint32_t sdkVersion, RsSurfaceConfig sc,
                             uint32_t dpi) {
-    LOGV("rsContextCreateGL dev=%p", vdev);
+    ALOGV("rsContextCreateGL dev=%p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, &sc);
     if (rsc) {
         rsc->setTargetSdkVersion(sdkVersion);
         rsc->setDPI(dpi);
     }
-    LOGV("%p rsContextCreateGL ret", rsc);
+    ALOGV("%p rsContextCreateGL ret", rsc);
     return rsc;
 }
 
diff --git a/rsContext.h b/rsContext.h
index 199cc5a..c6582c9 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -164,6 +164,9 @@
     uint32_t getWidth() const {return mWidth;}
     uint32_t getHeight() const {return mHeight;}
 
+    uint32_t getCurrentSurfaceWidth() const;
+    uint32_t getCurrentSurfaceHeight() const;
+
     mutable ThreadIO mIO;
 
     // Timers
diff --git a/rsElement.cpp b/rsElement.cpp
index 71e1b91..56c31b6 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -23,6 +23,7 @@
 
 Element::Element(Context *rsc) : ObjectBase(rsc) {
     mBits = 0;
+    mBitsUnpadded = 0;
     mFields = NULL;
     mFieldCount = 0;
     mHasReference = false;
@@ -60,13 +61,25 @@
     return total;
 }
 
+size_t Element::getSizeBitsUnpadded() const {
+    if (!mFieldCount) {
+        return mBitsUnpadded;
+    }
+
+    size_t total = 0;
+    for (size_t ct=0; ct < mFieldCount; ct++) {
+        total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
+    }
+    return total;
+}
+
 void Element::dumpLOGV(const char *prefix) const {
     ObjectBase::dumpLOGV(prefix);
-    LOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
+    ALOGV("%s Element: fieldCount: %zu,  size bytes: %zu", prefix, mFieldCount, getSizeBytes());
     mComponent.dumpLOGV(prefix);
     for (uint32_t ct = 0; ct < mFieldCount; ct++) {
-        LOGV("%s Element field index: %u ------------------", prefix, ct);
-        LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
+        ALOGV("%s Element field index: %u ------------------", prefix, ct);
+        ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
              prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
         mFields[ct].e->dumpLOGV(prefix);
     }
@@ -146,14 +159,18 @@
 void Element::compute() {
     if (mFieldCount == 0) {
         mBits = mComponent.getBits();
+        mBitsUnpadded = mComponent.getBitsUnpadded();
         mHasReference = mComponent.isReference();
         return;
     }
 
     size_t bits = 0;
+    size_t bitsUnpadded = 0;
     for (size_t ct=0; ct < mFieldCount; ct++) {
         mFields[ct].offsetBits = bits;
+        mFields[ct].offsetBitsUnpadded = bitsUnpadded;
         bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
+        bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
 
         if (mFields[ct].e->mHasReference) {
             mHasReference = true;
diff --git a/rsElement.h b/rsElement.h
index bfdec53..04010fa 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -43,6 +43,11 @@
     uint32_t getGLType() const;
     uint32_t getGLFormat() const;
 
+    size_t getSizeBitsUnpadded() const;
+    size_t getSizeBytesUnpadded() const {
+        return (getSizeBitsUnpadded() + 7) >> 3;
+    }
+
     size_t getSizeBits() const;
     size_t getSizeBytes() const {
         return (getSizeBits() + 7) >> 3;
@@ -55,6 +60,10 @@
         return mFields[componentNumber].offsetBits >> 3;
     }
 
+    size_t getFieldOffsetBytesUnpadded(uint32_t componentNumber) const {
+        return mFields[componentNumber].offsetBitsUnpadded >> 3;
+    }
+
     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();}
@@ -64,6 +73,7 @@
     RsDataType getType() const {return mComponent.getType();}
     RsDataKind getKind() const {return mComponent.getKind();}
     uint32_t getBits() const {return mBits;}
+    uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
 
     void dumpLOGV(const char *prefix) const;
     virtual void serialize(OStream *stream) const;
@@ -112,6 +122,7 @@
         String8 name;
         ObjectBaseRef<const Element> e;
         uint32_t offsetBits;
+        uint32_t offsetBitsUnpadded;
         uint32_t arraySize;
     } ElementField_t;
     ElementField_t *mFields;
@@ -123,6 +134,7 @@
     Element(Context *);
 
     Component mComponent;
+    uint32_t mBitsUnpadded;
     uint32_t mBits;
 
     void compute();
diff --git a/rsFileA3D.cpp b/rsFileA3D.cpp
index df5dc12..530e79e 100644
--- a/rsFileA3D.cpp
+++ b/rsFileA3D.cpp
@@ -68,7 +68,7 @@
     for (uint32_t i = 0; i < numIndexEntries; i ++) {
         A3DIndexEntry *entry = new A3DIndexEntry();
         headerStream->loadString(&entry->mObjectName);
-        //LOGV("Header data, entry name = %s", entry->mObjectName.string());
+        //ALOGV("Header data, entry name = %s", entry->mObjectName.string());
         entry->mType = (RsA3DClassID)headerStream->loadU32();
         if (mUse64BitOffsets){
             entry->mOffset = headerStream->loadOffset();
@@ -145,7 +145,7 @@
     char magicString[12];
     size_t len;
 
-    LOGV("file open 1");
+    ALOGV("file open 1");
     len = fread(magicString, 1, 12, f);
     if ((len != 12) ||
         memcmp(magicString, "Android3D_ff", 12)) {
@@ -181,7 +181,7 @@
         return false;
     }
 
-    LOGV("file open size = %lli", mDataSize);
+    ALOGV("file open size = %lli", mDataSize);
 
     // We should know enough to read the file in at this point.
     mAlloc = malloc(mDataSize);
@@ -196,7 +196,7 @@
 
     mReadStream = new IStream(mData, mUse64BitOffsets);
 
-    LOGV("Header is read an stream initialized");
+    ALOGV("Header is read an stream initialized");
     return true;
 }
 
@@ -369,7 +369,7 @@
     }
 
     ObjectBase *obj = fa3d->initializeFromEntry(index);
-    //LOGV("Returning object with name %s", obj->getName());
+    //ALOGV("Returning object with name %s", obj->getName());
 
     return obj;
 }
diff --git a/rsFont.cpp b/rsFont.cpp
index 7efed9d..7b3aa70 100644
--- a/rsFont.cpp
+++ b/rsFont.cpp
@@ -651,14 +651,10 @@
                                float x4, float y4, float z4,
                                float u4, float v4) {
     const uint32_t vertsPerQuad = 4;
-    const uint32_t floatsPerVert = 5;
+    const uint32_t floatsPerVert = 6;
     float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
 
-    // Cull things that are off the screen
-    float width = (float)mRSC->getWidth();
-    float height = (float)mRSC->getHeight();
-
-    if (x1 > width || y1 < 0.0f || x2 < 0 || y4 > height) {
+    if (x1 > mSurfaceWidth || y1 < 0.0f || x2 < 0 || y4 > mSurfaceHeight) {
         return;
     }
 
@@ -670,24 +666,28 @@
     (*currentPos++) = x1;
     (*currentPos++) = y1;
     (*currentPos++) = z1;
+    (*currentPos++) = 0;
     (*currentPos++) = u1;
     (*currentPos++) = v1;
 
     (*currentPos++) = x2;
     (*currentPos++) = y2;
     (*currentPos++) = z2;
+    (*currentPos++) = 0;
     (*currentPos++) = u2;
     (*currentPos++) = v2;
 
     (*currentPos++) = x3;
     (*currentPos++) = y3;
     (*currentPos++) = z3;
+    (*currentPos++) = 0;
     (*currentPos++) = u3;
     (*currentPos++) = v3;
 
     (*currentPos++) = x4;
     (*currentPos++) = y4;
     (*currentPos++) = z4;
+    (*currentPos++) = 0;
     (*currentPos++) = u4;
     (*currentPos++) = v4;
 
@@ -746,6 +746,10 @@
         return;
     }
 
+    // Cull things that are off the screen
+    mSurfaceWidth = (float)mRSC->getCurrentSurfaceWidth();
+    mSurfaceHeight = (float)mRSC->getCurrentSurfaceHeight();
+
     currentFont->renderUTF(text, len, x, y, startIndex, numGlyphs,
                            mode, bounds, bitmap, bitmapW, bitmapH);
 
diff --git a/rsFont.h b/rsFont.h
index 679591c..4ca794d 100644
--- a/rsFont.h
+++ b/rsFont.h
@@ -160,6 +160,9 @@
 
 protected:
 
+    float mSurfaceWidth;
+    float mSurfaceHeight;
+
     friend class Font;
 
     struct CacheTextureLine {
diff --git a/rsLocklessFifo.cpp b/rsLocklessFifo.cpp
index 8879805..ce69a60 100644
--- a/rsLocklessFifo.cpp
+++ b/rsLocklessFifo.cpp
@@ -231,7 +231,7 @@
 }
 
 void LocklessCommandFifo::dumpState(const char *s) const {
-    LOGV("%s %p  put %p, get %p,  buf %p,  end %p", s, this, mPut, mGet, mBuffer, mEnd);
+    ALOGV("%s %p  put %p, get %p,  buf %p,  end %p", s, this, mPut, mGet, mBuffer, mEnd);
 }
 
 void LocklessCommandFifo::printDebugData() const {
@@ -244,7 +244,7 @@
 
 
     for (int ct=0; ct < 16; ct++) {
-        LOGV("fifo %p = 0x%08x  0x%08x  0x%08x  0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
+        ALOGV("fifo %p = 0x%08x  0x%08x  0x%08x  0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
         pptr += 4;
     }
 
diff --git a/rsMatrix4x4.cpp b/rsMatrix4x4.cpp
index f34af47..c6f96d8 100644
--- a/rsMatrix4x4.cpp
+++ b/rsMatrix4x4.cpp
@@ -307,8 +307,8 @@
 }
 
 void Matrix4x4::logv(const char *s) const {
-    LOGV("%s {%f, %f, %f, %f",  s, m[0], m[4], m[8], m[12]);
-    LOGV("%s  %f, %f, %f, %f",  s, m[1], m[5], m[9], m[13]);
-    LOGV("%s  %f, %f, %f, %f",  s, m[2], m[6], m[10], m[14]);
-    LOGV("%s  %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
+    ALOGV("%s {%f, %f, %f, %f",  s, m[0], m[4], m[8], m[12]);
+    ALOGV("%s  %f, %f, %f, %f",  s, m[1], m[5], m[9], m[13]);
+    ALOGV("%s  %f, %f, %f, %f",  s, m[2], m[6], m[10], m[14]);
+    ALOGV("%s  %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
 }
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index f5ced26..addf932 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -35,11 +35,11 @@
 
     rsAssert(rsc);
     add();
-    //LOGV("ObjectBase %p con", this);
+    //ALOGV("ObjectBase %p con", this);
 }
 
 ObjectBase::~ObjectBase() {
-    //LOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
+    //ALOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
 #if RS_OBJECT_DEBUG
     mStack.dump();
 #endif
@@ -60,22 +60,22 @@
 
 void ObjectBase::dumpLOGV(const char *op) const {
     if (mName.size()) {
-        LOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
+        ALOGV("%s RSobj %p, name %s, refs %i,%i  links %p,%p,%p",
              op, this, mName.string(), mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
     } else {
-        LOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
+        ALOGV("%s RSobj %p, no-name, refs %i,%i  links %p,%p,%p",
              op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
     }
 }
 
 void ObjectBase::incUserRef() const {
     android_atomic_inc(&mUserRefCount);
-    //LOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
+    //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
 }
 
 void ObjectBase::incSysRef() const {
     android_atomic_inc(&mSysRefCount);
-    //LOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
+    //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
 }
 
 void ObjectBase::preDestroy() const {
@@ -111,7 +111,7 @@
 bool ObjectBase::decUserRef() const {
     rsAssert(mUserRefCount > 0);
 #if RS_OBJECT_DEBUG
-    LOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
+    ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
     if (mUserRefCount <= 0) {
         mStack.dump();
     }
@@ -126,7 +126,7 @@
 }
 
 bool ObjectBase::zeroUserRef() const {
-    //LOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
+    //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
     android_atomic_acquire_store(0, &mUserRefCount);
     if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
         return checkDelete(this);
@@ -135,7 +135,7 @@
 }
 
 bool ObjectBase::decSysRef() const {
-    //LOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
+    //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
     rsAssert(mSysRefCount > 0);
     if ((android_atomic_dec(&mSysRefCount) <= 1) &&
         (android_atomic_acquire_load(&mUserRefCount) <= 0)) {
@@ -165,7 +165,7 @@
 
     rsAssert(!mNext);
     rsAssert(!mPrev);
-    //LOGV("calling add  rsc %p", mRSC);
+    //ALOGV("calling add  rsc %p", mRSC);
     mNext = mRSC->mObjHead;
     if (mRSC->mObjHead) {
         mRSC->mObjHead->mPrev = this;
@@ -176,7 +176,7 @@
 }
 
 void ObjectBase::remove() const {
-    //LOGV("calling remove  rsc %p", mRSC);
+    //ALOGV("calling remove  rsc %p", mRSC);
     if (!mRSC) {
         rsAssert(!mPrev);
         rsAssert(!mNext);
@@ -198,7 +198,7 @@
 
 void ObjectBase::zeroAllUserRef(Context *rsc) {
     if (rsc->props.mLogObjects) {
-        LOGV("Forcing release of all outstanding user refs.");
+        ALOGV("Forcing release of all outstanding user refs.");
     }
 
     // This operation can be slow, only to be called during context cleanup.
@@ -216,14 +216,14 @@
     }
 
     if (rsc->props.mLogObjects) {
-        LOGV("Objects remaining.");
+        ALOGV("Objects remaining.");
         dumpAll(rsc);
     }
 }
 
 void ObjectBase::freeAllChildren(Context *rsc) {
     if (rsc->props.mLogObjects) {
-        LOGV("Forcing release of all child objects.");
+        ALOGV("Forcing release of all child objects.");
     }
 
     // This operation can be slow, only to be called during context cleanup.
@@ -238,7 +238,7 @@
     }
 
     if (rsc->props.mLogObjects) {
-        LOGV("Objects remaining.");
+        ALOGV("Objects remaining.");
         dumpAll(rsc);
     }
 }
@@ -246,10 +246,10 @@
 void ObjectBase::dumpAll(Context *rsc) {
     asyncLock();
 
-    LOGV("Dumping all objects");
+    ALOGV("Dumping all objects");
     const ObjectBase * o = rsc->mObjHead;
     while (o) {
-        LOGV(" Object %p", o);
+        ALOGV(" Object %p", o);
         o->dumpLOGV("  ");
         o = o->mNext;
     }
diff --git a/rsProgramVertex.cpp b/rsProgramVertex.cpp
index 4a13622..871caac 100644
--- a/rsProgramVertex.cpp
+++ b/rsProgramVertex.cpp
@@ -206,8 +206,11 @@
 void ProgramVertexState::updateSize(Context *rsc) {
     float *f = static_cast<float *>(mDefaultAlloc->getPtr());
 
+    float surfaceWidth = (float)rsc->getCurrentSurfaceWidth();
+    float surfaceHeight = (float)rsc->getCurrentSurfaceHeight();
+
     Matrix4x4 m;
-    m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
+    m.loadOrtho(0, surfaceWidth, surfaceHeight, 0, -1, 1);
     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
     memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
 
diff --git a/rsScript.cpp b/rsScript.cpp
index 93513fe..16446dd 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "rsContext.h"
+#include <time.h>
 
 using namespace android;
 using namespace android::renderscript;
@@ -89,8 +90,22 @@
 }
 
 void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) {
-    Script *s = static_cast<Script *>(vs);
-    s->mEnviroment.mTimeZone = timeZone;
+    // We unfortunately need to make a new copy of the string, since it is
+    // not NULL-terminated. We then use setenv(), which properly handles
+    // freeing/duplicating the actual string for the environment.
+    char *tz = (char *) malloc(length + 1);
+    if (!tz) {
+        LOGE("Couldn't allocate memory for timezone buffer");
+        return;
+    }
+    strncpy(tz, timeZone, length);
+    tz[length] = '\0';
+    if (setenv("TZ", tz, 1) == 0) {
+        tzset();
+    } else {
+        LOGE("Error setting timezone");
+    }
+    free(tz);
 }
 
 void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
diff --git a/rsScript.h b/rsScript.h
index d645421..abb55b8 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -59,7 +59,6 @@
     struct Enviroment_t {
         int64_t mStartTimeMillis;
         int64_t mLastDtTime;
-        const char* mTimeZone;
 
         ObjectBaseRef<ProgramVertex> mVertex;
         ObjectBaseRef<ProgramFragment> mFragment;
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 2e7f213..b45366b 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -111,13 +111,13 @@
     uint32_t ret = 0;
 
     if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::run invoking root,  ptr %p", rsc, mHal.info.root);
+        ALOGV("%p ScriptC::run invoking root,  ptr %p", rsc, mHal.info.root);
     }
 
     ret = rsc->mHal.funcs.script.invokeRoot(rsc, this);
 
     if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
+        ALOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
     }
 
     return ret;
@@ -146,7 +146,7 @@
     setupScript(rsc);
 
     if (rsc->props.mLogScripts) {
-        LOGV("%p ScriptC::Invoke invoking slot %i,  ptr %p", rsc, slot, this);
+        ALOGV("%p ScriptC::Invoke invoking slot %i,  ptr %p", rsc, slot, this);
     }
     rsc->mHal.funcs.script.invokeFunction(rsc, this, slot, data, len);
 }
diff --git a/rsScriptC_LibGL.cpp b/rsScriptC_LibGL.cpp
index 7862f3c..26e2374 100644
--- a/rsScriptC_LibGL.cpp
+++ b/rsScriptC_LibGL.cpp
@@ -79,23 +79,28 @@
 void rsrBindFrameBufferObjectColorTarget(Context *rsc, Script *sc, Allocation *a, uint32_t slot) {
     CHECK_OBJ(va);
     rsc->mFBOCache.bindColorTarget(rsc, a, slot);
+    rsc->mStateVertex.updateSize(rsc);
 }
 
 void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Script *sc, Allocation *a) {
     CHECK_OBJ(va);
     rsc->mFBOCache.bindDepthTarget(rsc, a);
+    rsc->mStateVertex.updateSize(rsc);
 }
 
 void rsrClearFrameBufferObjectColorTarget(Context *rsc, Script *sc, uint32_t slot) {
     rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
+    rsc->mStateVertex.updateSize(rsc);
 }
 
 void rsrClearFrameBufferObjectDepthTarget(Context *rsc, Script *sc) {
     rsc->mFBOCache.bindDepthTarget(rsc, NULL);
+    rsc->mStateVertex.updateSize(rsc);
 }
 
 void rsrClearFrameBufferObjectTargets(Context *rsc, Script *sc) {
     rsc->mFBOCache.resetAll(rsc);
+    rsc->mStateVertex.updateSize(rsc);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
index b1a579a..13e789d 100644
--- a/rsThreadIO.cpp
+++ b/rsThreadIO.cpp
@@ -145,7 +145,7 @@
             con->timerSet(Context::RS_TIMER_INTERNAL);
         }
         waitForCommand = false;
-        //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
+        //ALOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
 
         if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
             rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
diff --git a/rsType.cpp b/rsType.cpp
index 9a6a31b..271c9e2 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -141,7 +141,7 @@
 void Type::dumpLOGV(const char *prefix) const {
     char buf[1024];
     ObjectBase::dumpLOGV(prefix);
-    LOGV("%s   Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
+    ALOGV("%s   Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
     snprintf(buf, sizeof(buf), "%s element: ", prefix);
     mElement->dumpLOGV(buf);
 }