Fix ref counting for globals when set from java code.

Change-Id: I415b6ddeaab277e60233e905a6bae357cd5193eb
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index df03e13..20949a4 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -389,6 +389,10 @@
     synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
         rsnScriptSetVarV(mContext, id, slot, val);
     }
+    native void rsnScriptSetVarObj(int con, int id, int slot, int val);
+    synchronized void nScriptSetVarObj(int id, int slot, int val) {
+        rsnScriptSetVarObj(mContext, id, slot, val);
+    }
 
     native void rsnScriptCBegin(int con);
     synchronized void nScriptCBegin() {
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 7d7dd6d..ea616c6 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -88,6 +88,10 @@
         mRS.nScriptSetVarI(getID(), index, v ? 1 : 0);
     }
 
+    public void setVar(int index, BaseObj o) {
+        mRS.nScriptSetVarObj(getID(), index, (o == null) ? 0 : o.getID());
+    }
+
     public void setVar(int index, FieldPacker v) {
         mRS.nScriptSetVarV(getID(), index, v.getData());
     }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index dd84848..8888459 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -829,6 +829,13 @@
 }
 
 static void
+nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
+{
+    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
+    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
+}
+
+static void
 nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
 {
     LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
@@ -1335,6 +1342,7 @@
 {"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
 {"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
 {"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
+{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
 
 {"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
 {"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ac9abe0..76db14f 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -280,6 +280,12 @@
 	param int value
 	}
 
+ScriptSetVarObj {
+	param RsScript s
+	param uint32_t slot
+	param RsObjectBase value
+	}
+
 ScriptSetVarJ {
 	param RsScript s
 	param uint32_t slot
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 4ffdbfd..efdc626 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -67,6 +67,22 @@
     }
 }
 
+void Script::setVarObj(uint32_t slot, ObjectBase *val) {
+    ObjectBase **destPtr = ((ObjectBase ***)mEnviroment.mFieldAddress)[slot];
+
+    if (destPtr) {
+        if (val != NULL) {
+            val->incSysRef();
+        }
+        if (*destPtr) {
+            (*destPtr)->decSysRef();
+        }
+        *destPtr = val;
+    } else {
+        LOGV("Calling setVarObj on slot = %i which is null.  This is dangerous because the script will not hold a ref count on the object.", slot);
+    }
+}
+
 namespace android {
 namespace renderscript {
 
@@ -103,6 +119,12 @@
     s->setVar(slot, &value, sizeof(value));
 }
 
+void rsi_ScriptSetVarObj(Context *rsc, RsScript vs, uint32_t slot, RsObjectBase value) {
+    Script *s = static_cast<Script *>(vs);
+    ObjectBase *o = static_cast<ObjectBase *>(value);
+    s->setVarObj(slot, o);
+}
+
 void rsi_ScriptSetVarJ(Context *rsc, RsScript vs, uint32_t slot, long long value) {
     Script *s = static_cast<Script *>(vs);
     s->setVar(slot, &value, sizeof(value));
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 9b6d8a9..bad095b 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -61,6 +61,7 @@
     void initSlots();
     void setSlot(uint32_t slot, Allocation *a);
     void setVar(uint32_t slot, const void *val, uint32_t len);
+    void setVarObj(uint32_t slot, ObjectBase *val);
 
     virtual void runForEach(Context *rsc,
                             const Allocation * ain,