Add 64bit large object support

Add HAL hooks for filling in LO fields.

Change-Id: Ib9bdee714a062de519d2a9708c1016404a1b11a4

Conflicts:
	driver/rsdBcc.cpp
	driver/rsdCore.cpp
	rsAllocation.h
	rs_hal.h
diff --git a/Android.mk b/Android.mk
index 48b9c2c..685e555 100644
--- a/Android.mk
+++ b/Android.mk
@@ -25,6 +25,7 @@
 	driver/rsdAllocation.cpp \
 	driver/rsdBcc.cpp \
 	driver/rsdCore.cpp \
+	driver/rsdElement.cpp \
 	driver/rsdFrameBuffer.cpp \
 	driver/rsdFrameBufferObj.cpp \
 	driver/rsdGL.cpp \
@@ -39,6 +40,7 @@
 	driver/rsdScriptGroup.cpp \
 	driver/rsdShader.cpp \
 	driver/rsdShaderCache.cpp \
+	driver/rsdType.cpp \
 	driver/rsdVertexArray.cpp
 
 
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index b9f8aba..c4fec9f 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -1237,11 +1237,6 @@
     //rsAssert(script->mFieldIsObject[slot]);
     //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
 
-    //if (mIntrinsicID) {
-        //mIntrinsicFuncs.setVarObj(dc, script, drv->mIntrinsicData, slot, alloc);
-        //return;
-    //}
-
 #ifndef RS_COMPATIBILITY_LIB
     int32_t *destPtr = reinterpret_cast<int32_t *>(
                           mExecutable->getExportVarAddrs()[slot]);
@@ -1277,7 +1272,7 @@
             ObjectBase **obj_addr =
                 reinterpret_cast<ObjectBase **>(*var_addr_iter);
             if (*is_object_iter) {
-                if (*var_addr_iter != NULL) {
+                if (*var_addr_iter != NULL && mCtx->getContext() != NULL) {
                     rsrClearObject(mCtx->getContext(), obj_addr);
                 }
             }
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 05951b9..248e7b6 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -1196,3 +1196,22 @@
     return 0;
 }
 
+void rsdAllocationUpdateCachedObject(const Context *rsc,
+                                     const Allocation *alloc,
+                                     rs_allocation *obj)
+{
+    obj->p = alloc;
+#ifdef __LP64__
+    if (alloc != NULL) {
+        obj->r = alloc->mHal.drvState.lod[0].mallocPtr;
+        obj->v1 = alloc->mHal.drv;
+        obj->v2 = (void *)alloc->mHal.drvState.lod[0].stride;
+    } else {
+        obj->r = NULL;
+        obj->v1 = NULL;
+        obj->v2 = NULL;
+    }
+#endif
+}
+
+
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index ff47f03..510b497 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -168,6 +168,9 @@
 void rsdAllocationGenerateMipmaps(const android::renderscript::Context *rsc,
                                   const android::renderscript::Allocation *alloc);
 
+void rsdAllocationUpdateCachedObject(const android::renderscript::Context *rsc,
+                                     const android::renderscript::Allocation *alloc,
+                                     android::renderscript::rs_allocation *obj);
 
 
 #endif
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index b62709e..27029cf 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -159,3 +159,19 @@
     RsdCpuReference::CpuScript *cs = (RsdCpuReference::CpuScript *)sc->mHal.drv;
     return cs->getAllocationForPointer(ptr);
 }
+
+void rsdScriptUpdateCachedObject(const Context *rsc,
+                                 const Script *script,
+                                 rs_script *obj)
+{
+    obj->p = script;
+#ifdef __LP64__
+    obj->r = NULL;
+    if (script != NULL) {
+        obj->v1 = script->mHal.drv;
+    } else {
+        obj->v1 = NULL;
+    }
+    obj->v2 = NULL;
+#endif
+}
diff --git a/driver/rsdBcc.h b/driver/rsdBcc.h
index 3932aeb..d51fb80 100644
--- a/driver/rsdBcc.h
+++ b/driver/rsdBcc.h
@@ -98,5 +98,10 @@
                         const android::renderscript::Script *script,
                         const void *);
 
+void rsdScriptUpdateCachedObject(const android::renderscript::Context *rsc,
+                                 const android::renderscript::Script *script,
+                                 android::renderscript::rs_script *obj);
+
+
 
 #endif
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
index 065597a..37c9755 100644
--- a/driver/rsdCore.cpp
+++ b/driver/rsdCore.cpp
@@ -19,6 +19,8 @@
 #include "rsdCore.h"
 #include "rsdAllocation.h"
 #include "rsdBcc.h"
+#include "rsdElement.h"
+#include "rsdType.h"
 #ifndef RS_COMPATIBILITY_LIB
     #include "MemChunk.h"
     #include "rsdGL.h"
@@ -80,7 +82,8 @@
         rsdScriptSetGlobalBind,
         rsdScriptSetGlobalObj,
         rsdScriptDestroy,
-        rsdScriptInvokeForEachMulti
+        rsdScriptInvokeForEachMulti,
+        rsdScriptUpdateCachedObject
     },
 
     {
@@ -106,7 +109,8 @@
         rsdAllocationData3D_alloc,
         rsdAllocationElementData1D,
         rsdAllocationElementData2D,
-        rsdAllocationGenerateMipmaps
+        rsdAllocationGenerateMipmaps,
+        rsdAllocationUpdateCachedObject
     },
 
 
@@ -149,7 +153,8 @@
 
     {
         rsdSamplerInit,
-        rsdSamplerDestroy
+        rsdSamplerDestroy,
+        rsdSamplerUpdateCachedObject
     },
 
     {
@@ -163,7 +168,20 @@
         rsdScriptGroupSetInput,
         rsdScriptGroupSetOutput,
         rsdScriptGroupExecute,
-        rsdScriptGroupDestroy
+        rsdScriptGroupDestroy,
+        NULL
+    },
+
+    {
+        rsdTypeInit,
+        rsdTypeDestroy,
+        rsdTypeUpdateCachedObject
+    },
+
+    {
+        rsdElementInit,
+        rsdElementDestroy,
+        rsdElementUpdateCachedObject
     },
 
     NULL // finish
diff --git a/driver/rsdElement.cpp b/driver/rsdElement.cpp
new file mode 100644
index 0000000..c0413e4
--- /dev/null
+++ b/driver/rsdElement.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "rsdCore.h"
+#include "rsElement.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+bool rsdElementInit(const Context *, const Element *e) {
+    return true;
+}
+
+void rsdElementDestroy(const Context *rsc, const Element *e) {
+}
+
+void rsdElementUpdateCachedObject(const Context *rsc,
+                                  const Element *element,
+                                  rs_element *obj)
+{
+    obj->p = element;
+#ifdef __LP64__
+    obj->r = NULL;
+    obj->v1 = NULL;
+    obj->v2 = NULL;
+#endif
+}
+
diff --git a/driver/rsdElement.h b/driver/rsdElement.h
new file mode 100644
index 0000000..312d70b
--- /dev/null
+++ b/driver/rsdElement.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_ELEMENT_H
+#define RSD_ELEMENT_H
+
+#include <rs_hal.h>
+
+
+bool rsdElementInit(const android::renderscript::Context *rsc,
+                    const android::renderscript::Element *);
+
+void rsdElementDestroy(const android::renderscript::Context *rsc,
+                       const android::renderscript::Element *);
+
+void rsdElementUpdateCachedObject(const android::renderscript::Context *rsc,
+                                  const android::renderscript::Element *,
+                                  android::renderscript::rs_element *obj);
+
+#endif // RSD_ELEMENT_H
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index d1f29f0..8f1020b 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/driver/rsdRuntimeStubs.cpp
@@ -429,10 +429,19 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
+#ifndef RS_COMPATIBILITY_LIB
+static void SC_SetObject(ObjectBase **dst, rs_allocation src) {
+    //    ALOGE("SC_SetObject: dst = %p, src = %p", dst, src.p);
+    //    ALOGE("SC_SetObject: dst[0] = %p", dst[0]);
+    Context *rsc = RsdCpuReference::getTlsContext();
+    rsrSetObject(rsc, dst, (ObjectBase*)src.p);
+}
+#else
+static void SC_SetObject(ObjectBase **dst, ObjectBase *src) {
     Context *rsc = RsdCpuReference::getTlsContext();
     rsrSetObject(rsc, dst, src);
 }
+#endif
 
 static void SC_ClearObject(ObjectBase **dst) {
     Context *rsc = RsdCpuReference::getTlsContext();
@@ -1236,41 +1245,41 @@
         return SC_SetObject((ObjectBase**) dst, (ObjectBase*) src.p); \
     }
 
-IS_CLEAR_SET_OBJ(rs_element)
-IS_CLEAR_SET_OBJ(rs_type)
-IS_CLEAR_SET_OBJ(rs_allocation)
-IS_CLEAR_SET_OBJ(rs_sampler)
-IS_CLEAR_SET_OBJ(rs_script)
+IS_CLEAR_SET_OBJ(android::renderscript::rs_element)
+IS_CLEAR_SET_OBJ(android::renderscript::rs_type)
+IS_CLEAR_SET_OBJ(android::renderscript::rs_allocation)
+IS_CLEAR_SET_OBJ(android::renderscript::rs_sampler)
+IS_CLEAR_SET_OBJ(android::renderscript::rs_script)
 #undef IS_CLEAR_SET_OBJ
 
 const Allocation * rsGetAllocation(const void *ptr) {
     return SC_GetAllocation(ptr);
 }
 
-void __attribute__((overloadable)) rsAllocationIoSend(rs_allocation a) {
+void __attribute__((overloadable)) rsAllocationIoSend(::rs_allocation a) {
     SC_AllocationIoSend((Allocation *)a.p);
 }
 
-void __attribute__((overloadable)) rsAllocationIoReceive(rs_allocation a) {
+void __attribute__((overloadable)) rsAllocationIoReceive(::rs_allocation a) {
     SC_AllocationIoReceive((Allocation *)a.p);
 }
 
 
 void __attribute__((overloadable)) rsAllocationCopy1DRange(
-        rs_allocation dstAlloc,
+        ::rs_allocation dstAlloc,
         uint32_t dstOff, uint32_t dstMip, uint32_t count,
-        rs_allocation srcAlloc,
+        ::rs_allocation srcAlloc,
         uint32_t srcOff, uint32_t srcMip) {
     SC_AllocationCopy1DRange((Allocation *)dstAlloc.p, dstOff, dstMip, count,
                              (Allocation *)srcAlloc.p, srcOff, srcMip);
 }
 
 void __attribute__((overloadable)) rsAllocationCopy2DRange(
-        rs_allocation dstAlloc,
+        ::rs_allocation dstAlloc,
         uint32_t dstXoff, uint32_t dstYoff,
         uint32_t dstMip, rs_allocation_cubemap_face dstFace,
         uint32_t width, uint32_t height,
-        rs_allocation srcAlloc,
+        ::rs_allocation srcAlloc,
         uint32_t srcXoff, uint32_t srcYoff,
         uint32_t srcMip, rs_allocation_cubemap_face srcFace) {
     SC_AllocationCopy2DRange((Allocation *)dstAlloc.p, dstXoff, dstYoff,
@@ -1279,31 +1288,31 @@
                              srcMip, srcFace);
 }
 
-void __attribute__((overloadable)) rsForEach(rs_script script,
-                                             rs_allocation in,
-                                             rs_allocation out,
+void __attribute__((overloadable)) rsForEach(::rs_script script,
+                                             ::rs_allocation in,
+                                             ::rs_allocation out,
                                              const void *usr,
                                              const rs_script_call *call) {
     return SC_ForEach_SAAUS((Script *)script.p, (Allocation*)in.p, (Allocation*)out.p, usr, (RsScriptCall*)call);
 }
 
-void __attribute__((overloadable)) rsForEach(rs_script script,
-                                             rs_allocation in,
-                                             rs_allocation out) {
+void __attribute__((overloadable)) rsForEach(::rs_script script,
+                                             ::rs_allocation in,
+                                             ::rs_allocation out) {
     return SC_ForEach_SAA((Script *)script.p, (Allocation*)in.p, (Allocation*)out.p);
 }
 
-void __attribute__((overloadable)) rsForEach(rs_script script,
-                                             rs_allocation in,
-                                             rs_allocation out,
+void __attribute__((overloadable)) rsForEach(::rs_script script,
+                                             ::rs_allocation in,
+                                             ::rs_allocation out,
                                              const void *usr,
                                              uint32_t usrLen) {
     return SC_ForEach_SAAUL((Script *)script.p, (Allocation*)in.p, (Allocation*)out.p, usr, usrLen);
 }
 
-void __attribute__((overloadable)) rsForEach(rs_script script,
-                                             rs_allocation in,
-                                             rs_allocation out,
+void __attribute__((overloadable)) rsForEach(::rs_script script,
+                                             ::rs_allocation in,
+                                             ::rs_allocation out,
                                              const void *usr,
                                              uint32_t usrLen,
                                              const rs_script_call *call) {
diff --git a/driver/rsdSampler.cpp b/driver/rsdSampler.cpp
index 095fca1..1a72fd4 100644
--- a/driver/rsdSampler.cpp
+++ b/driver/rsdSampler.cpp
@@ -40,3 +40,20 @@
 void rsdSamplerDestroy(const android::renderscript::Context *rsc,
                        const android::renderscript::Sampler *s) {
 }
+
+void rsdSamplerUpdateCachedObject(const Context *rsc,
+                                  const Sampler *alloc,
+                                  rs_sampler *obj)
+{
+    obj->p = alloc;
+#ifdef __LP64__
+    obj->r = NULL;
+    if (alloc != NULL) {
+        obj->v1 = alloc->mHal.drv;
+    } else {
+        obj->v1 = NULL;
+    }
+    obj->v2 = NULL;
+#endif
+}
+
diff --git a/driver/rsdSampler.h b/driver/rsdSampler.h
index 3a64e9e..378e2ca 100644
--- a/driver/rsdSampler.h
+++ b/driver/rsdSampler.h
@@ -26,5 +26,8 @@
 void rsdSamplerDestroy(const android::renderscript::Context *rsc,
                        const android::renderscript::Sampler *);
 
+void rsdSamplerUpdateCachedObject(const android::renderscript::Context *rsc,
+                                  const android::renderscript::Sampler *,
+                                  android::renderscript::rs_sampler *obj);
 
 #endif // RSD_SAMPLER_H
diff --git a/driver/rsdScriptGroup.cpp b/driver/rsdScriptGroup.cpp
index ef802a2..6162c11 100644
--- a/driver/rsdScriptGroup.cpp
+++ b/driver/rsdScriptGroup.cpp
@@ -53,4 +53,20 @@
     delete sgi;
 }
 
+void rsdScriptGroupUpdateCachedObject(const Context *rsc,
+                                      const ScriptGroup *sg,
+                                      rs_script_group *obj)
+{
+    obj->p = sg;
+#ifdef __LP64__
+    obj->r = NULL;
+    if (sg != NULL) {
+        obj->v1 = sg->mHal.drv;
+    } else {
+        obj->v1 = NULL;
+    }
+    obj->v2 = NULL;
+#endif
+}
+
 
diff --git a/driver/rsdScriptGroup.h b/driver/rsdScriptGroup.h
index ee8cd69..db44e23 100644
--- a/driver/rsdScriptGroup.h
+++ b/driver/rsdScriptGroup.h
@@ -33,6 +33,8 @@
                            const android::renderscript::ScriptGroup *sg);
 void rsdScriptGroupDestroy(const android::renderscript::Context *rsc,
                            const android::renderscript::ScriptGroup *sg);
-
+void rsdScriptGroupUpdateCachedObject(const android::renderscript::Context *rsc,
+                                      const android::renderscript::ScriptGroup *sg,
+                                      android::renderscript::rs_script_group *obj);
 
 #endif // RSD_SCRIPT_GROUP_H
diff --git a/driver/rsdType.cpp b/driver/rsdType.cpp
new file mode 100644
index 0000000..fa7b46c
--- /dev/null
+++ b/driver/rsdType.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "rsdCore.h"
+#include "rsdSampler.h"
+
+#include "rsContext.h"
+#include "rsSampler.h"
+
+#ifndef RS_COMPATIBILITY_LIB
+#include "rsProgramVertex.h"
+#include "rsProgramFragment.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#endif
+
+using namespace android;
+using namespace android::renderscript;
+
+
+bool rsdTypeInit(const Context *, const Type *t) {
+    return true;
+}
+
+void rsdTypeDestroy(const Context *rsc, const Type *t) {
+}
+
+void rsdTypeUpdateCachedObject(const Context *rsc,
+                               const Type *t,
+                               rs_type *obj)
+{
+    obj->p = t;
+#ifdef __LP64__
+    obj->r = NULL;
+    obj->v1 = NULL;
+    obj->v2 = NULL;
+#endif
+}
+
diff --git a/driver/rsdType.h b/driver/rsdType.h
new file mode 100644
index 0000000..d5ac700
--- /dev/null
+++ b/driver/rsdType.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_TYPE_H
+#define RSD_TYPE_H
+
+#include <rs_hal.h>
+
+
+bool rsdTypeInit(const android::renderscript::Context *rsc,
+                 const android::renderscript::Type *);
+
+void rsdTypeDestroy(const android::renderscript::Context *rsc,
+                    const android::renderscript::Type *);
+
+void rsdTypeUpdateCachedObject(const android::renderscript::Context *rsc,
+                               const android::renderscript::Type *,
+                               android::renderscript::rs_type *obj);
+
+#endif // RSD_TYPE_H
diff --git a/driver/runtime/rs_allocation.c b/driver/runtime/rs_allocation.c
index bf37713..a5368cd 100644
--- a/driver/runtime/rs_allocation.c
+++ b/driver/runtime/rs_allocation.c
@@ -104,8 +104,12 @@
 rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y,
          uint32_t z) {
     Allocation_t *alloc = (Allocation_t *)a.p;
+#ifdef __LP64__
+    uint8_t *p = (uint8_t *)a.r;
+#else
     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
-    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
+#endif
+    const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride;
     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
     uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
                      (z * stride * dimY)];
@@ -115,7 +119,11 @@
 uint8_t*
 rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
     Allocation_t *alloc = (Allocation_t *)a.p;
+#ifdef __LP64__
+    uint8_t *p = (uint8_t *)a.r;
+#else
     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
+#endif
     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
     const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index afa3a8a..59967e9 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -438,6 +438,15 @@
     mHal.state.type->decRefs(ptr, ct, startOff);
 }
 
+void Allocation::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
+    if (rsc->mHal.funcs.allocation.updateCachedObject != NULL) {
+        rsc->mHal.funcs.allocation.updateCachedObject(rsc, this, (rs_allocation *)dstObj);
+    } else {
+        *((const void **)dstObj) = this;
+    }
+}
+
+
 void Allocation::freeChildrenUnlocked () {
     void *ptr = mRSC->mHal.funcs.allocation.lock1D(mRSC, this);
     decRefs(ptr, mHal.state.type->getCellCount(), 0);
diff --git a/rsAllocation.h b/rsAllocation.h
index 1b842b8..f197efc 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -151,6 +151,7 @@
 
     void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
     void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
+    virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
     virtual bool freeChildren();
 
     void sendDirty(const Context *rsc) const;
diff --git a/rsContext.cpp b/rsContext.cpp
index 9af9f6e..d3d8349 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -890,7 +890,7 @@
 }
 
 void rsi_ContextDestroy(Context *rsc) {
-    //ALOGV("%p rsContextDestroy", rsc);
+    //ALOGE("%p rsContextDestroy", rsc);
     rsContextDestroyWorker(rsc);
     delete rsc;
     //ALOGV("%p rsContextDestroy done", rsc);
diff --git a/rsElement.cpp b/rsElement.cpp
index 474f535..3509b12 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -382,6 +382,14 @@
     }
 }
 
+void Element::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
+    if (rsc->mHal.funcs.element.updateCachedObject != NULL) {
+        rsc->mHal.funcs.element.updateCachedObject(rsc, this, (rs_element *)dstObj);
+    } else {
+        *((const void **)dstObj) = this;
+    }
+}
+
 ElementState::ElementState() {
 }
 
diff --git a/rsElement.h b/rsElement.h
index b97dfe5..57cde18 100644
--- a/rsElement.h
+++ b/rsElement.h
@@ -130,6 +130,7 @@
 
     void incRefs(const void *) const;
     void decRefs(const void *) const;
+    virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
     bool getHasReferences() const {return mHasReference;}
 
 protected:
diff --git a/rsObjectBase.cpp b/rsObjectBase.cpp
index bf5d3b5..0a0961f 100644
--- a/rsObjectBase.cpp
+++ b/rsObjectBase.cpp
@@ -41,7 +41,7 @@
 }
 
 ObjectBase::~ObjectBase() {
-    //ALOGV("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
+    //ALOGE("~ObjectBase %p  ref %i,%i", this, mUserRefCount, mSysRefCount);
 #if RS_OBJECT_DEBUG
     mDH->dump();
     delete mDH;
@@ -178,7 +178,6 @@
 
     rsAssert(!mNext);
     rsAssert(!mPrev);
-    //ALOGV("calling add  rsc %p", mRSC);
     mNext = mRSC->mObjHead;
     if (mRSC->mObjHead) {
         mRSC->mObjHead->mPrev = this;
@@ -189,7 +188,6 @@
 }
 
 void ObjectBase::remove() const {
-    //ALOGV("calling remove  rsc %p", mRSC);
     if (!mRSC) {
         rsAssert(!mPrev);
         rsAssert(!mNext);
@@ -284,3 +282,9 @@
     asyncUnlock();
     return false;
 }
+
+void ObjectBase::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
+    //ALOGE("ObjectBase::callUpdateCacheObject %p  %p", this, dstObj);
+    *((const void **)dstObj) = this;
+}
+
diff --git a/rsObjectBase.h b/rsObjectBase.h
index 85f8fd8..66977a9 100644
--- a/rsObjectBase.h
+++ b/rsObjectBase.h
@@ -66,6 +66,8 @@
     static void asyncLock();
     static void asyncUnlock();
 
+    virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
+
 protected:
     // Called inside the async lock for any object list management that is
     // necessary in derived classes.
diff --git a/rsRuntime.h b/rsRuntime.h
index 73cfefb..f00f724 100644
--- a/rsRuntime.h
+++ b/rsRuntime.h
@@ -139,8 +139,8 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-void rsrSetObject(const Context *, ObjectBase **dst, ObjectBase * src);
-void rsrClearObject(const Context *, ObjectBase **dst);
+void rsrSetObject(const Context *, void *dst, ObjectBase * src);
+void rsrClearObject(const Context *, void *dst);
 bool rsrIsObject(const Context *, const ObjectBase *src);
 
 void rsrAllocationIncRefs(const Context *, const Allocation *, void *ptr,
diff --git a/rsScript.cpp b/rsScript.cpp
index 5918c59..dd962d1 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -91,10 +91,17 @@
         return;
     }
     mHasObjectSlots = true;
-    //ALOGE("setvarobj  %i %p", slot, val);
     mRSC->mHal.funcs.script.setGlobalObj(mRSC, this, slot, val);
 }
 
+void Script::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
+    if (rsc->mHal.funcs.script.updateCachedObject != NULL) {
+        rsc->mHal.funcs.script.updateCachedObject(rsc, this, (rs_script *)dstObj);
+    } else {
+        *((const void **)dstObj) = this;
+    }
+}
+
 bool Script::freeChildren() {
     incSysRef();
     mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
diff --git a/rsScript.h b/rsScript.h
index 06e52de..1ad013f 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -132,6 +132,8 @@
     bool hasObjectSlots() const {
         return mHasObjectSlots;
     }
+    virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
+
 protected:
     bool mInitialized;
     bool mHasObjectSlots;
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 9435a4a..26d8fb0 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -134,26 +134,36 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-void rsrSetObject(const Context *rsc, ObjectBase **dst, ObjectBase * src) {
-    //ALOGE("rsiSetObject  %p,%p  %p", vdst, *vdst, vsrc);
+static void SetObjectRef(const Context *rsc, const ObjectBase *dst, const ObjectBase *src) {
+    //ALOGE("setObjectRef  %p,%p  %p", rsc, dst, src);
     if (src) {
         CHECK_OBJ(src);
         src->incSysRef();
     }
-    if (dst[0]) {
-        CHECK_OBJ(dst[0]);
-        dst[0]->decSysRef();
+    if (dst) {
+        CHECK_OBJ(dst);
+        dst->decSysRef();
     }
-    *dst = src;
 }
 
-void rsrClearObject(const Context *rsc, ObjectBase **dst) {
-    //ALOGE("rsiClearObject  %p,%p", vdst, *vdst);
-    if (dst[0]) {
-        CHECK_OBJ(dst[0]);
-        dst[0]->decSysRef();
+void rsrSetObject(const Context *rsc, void *dst, ObjectBase *src) {
+    ObjectBase **odst = (ObjectBase **)dst;
+    //ALOGE("rsrSetObject (base) %p,%p  %p", dst, *odst, src);
+    SetObjectRef(rsc, odst[0], src);
+    if (src != NULL) {
+        src->callUpdateCacheObject(rsc, dst);
     }
-    *dst = NULL;
+}
+
+
+void rsrClearObject(const Context *rsc, void *dst) {
+    ObjectBase **odst = (ObjectBase **)dst;
+    //ALOGE("rsrClearObject  %p,%p", odst, *odst);
+    if (odst[0]) {
+        CHECK_OBJ(odst[0]);
+        odst[0]->decSysRef();
+    }
+    *odst = NULL;
 }
 
 bool rsrIsObject(const Context *rsc, const ObjectBase *src) {
diff --git a/rsType.cpp b/rsType.cpp
index d13f047..04a3b79 100644
--- a/rsType.cpp
+++ b/rsType.cpp
@@ -300,6 +300,13 @@
     }
 }
 
+void Type::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
+    if (rsc->mHal.funcs.type.updateCachedObject != NULL) {
+        rsc->mHal.funcs.type.updateCachedObject(rsc, this, (rs_type *)dstObj);
+    } else {
+        *((const void **)dstObj) = this;
+    }
+}
 
 //////////////////////////////////////////////////
 //
diff --git a/rsType.h b/rsType.h
index 26dacfc..b4ae107 100644
--- a/rsType.h
+++ b/rsType.h
@@ -111,6 +111,7 @@
 
     void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
     void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
+    virtual void callUpdateCacheObject(const Context *rsc, void *dstObj) const;
 
 protected:
     void makeLODTable();
diff --git a/rs_hal.h b/rs_hal.h
index 467c815..5eec3b1 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -45,6 +45,41 @@
 class Sampler;
 class FBOCache;
 
+/**
+ * Define the internal object types.  This ia a mirror of the
+ * definition in rs_types.rsh except with the p value typed
+ * correctly.
+ *
+ * p = pointer to internal object implementation
+ * r = reserved by libRS runtime
+ * v1 = Mirror of p->mHal.drv
+ * v2 = reserved for use by vendor drivers
+ */
+
+#ifndef __LP64__
+#define RS_BASE_OBJ(_t_) typedef struct { const _t_* p; } __attribute__((packed, aligned(4)))
+#else
+#define RS_BASE_OBJ(_t_) typedef struct { const _t_* p; const void* r; const void* v1; const void* v2; }
+#endif
+
+RS_BASE_OBJ(Element) rs_element;
+RS_BASE_OBJ(Type) rs_type;
+RS_BASE_OBJ(Allocation) rs_allocation;
+RS_BASE_OBJ(Sampler) rs_sampler;
+RS_BASE_OBJ(Script) rs_script;
+RS_BASE_OBJ(ScriptGroup) rs_script_group;
+
+#ifndef __LP64__
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_mesh;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_path;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_program_fragment;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_program_vertex;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_program_raster;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_program_store;
+typedef struct { const int* p; } __attribute__((packed, aligned(4))) rs_font;
+#endif // __LP64__
+
+
 typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
 
 /**
@@ -122,6 +157,7 @@
                                    const void * usr,
                                    size_t usrLen,
                                    const RsScriptCall *sc);
+        void (*updateCachedObject)(const Context *rsc, const Script *, rs_script *obj);
     } script;
 
     struct {
@@ -203,6 +239,8 @@
                               const void *data, uint32_t elementOff, size_t sizeBytes);
 
         void (*generateMipmaps)(const Context *rsc, const Allocation *alloc);
+
+        void (*updateCachedObject)(const Context *rsc, const Allocation *alloc, rs_allocation *obj);
     } allocation;
 
     struct {
@@ -251,6 +289,7 @@
     struct {
         bool (*init)(const Context *rsc, const Sampler *m);
         void (*destroy)(const Context *rsc, const Sampler *m);
+        void (*updateCachedObject)(const Context *rsc, const Sampler *s, rs_sampler *obj);
     } sampler;
 
     struct {
@@ -267,8 +306,21 @@
                           const ScriptKernelID *kid, Allocation *);
         void (*execute)(const Context *rsc, const ScriptGroup *sg);
         void (*destroy)(const Context *rsc, const ScriptGroup *sg);
+        void (*updateCachedObject)(const Context *rsc, const ScriptGroup *sg, rs_script_group *obj);
     } scriptgroup;
 
+    struct {
+        bool (*init)(const Context *rsc, const Type *m);
+        void (*destroy)(const Context *rsc, const Type *m);
+        void (*updateCachedObject)(const Context *rsc, const Type *s, rs_type *obj);
+    } type;
+
+    struct {
+        bool (*init)(const Context *rsc, const Element *m);
+        void (*destroy)(const Context *rsc, const Element *m);
+        void (*updateCachedObject)(const Context *rsc, const Element *s, rs_element *obj);
+    } element;
+
     void (*finish)(const Context *rsc);
 } RsdHalFunctions;