Support additional element/dim information for FieldPacker.

BUG=6009244

Change-Id: I3c439559d61b24b26f9a36f2525f0a0e05b00e77
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index 9789cab..d9b5212 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -24,6 +24,7 @@
 #include <bcc/RenderScript/RSInfo.h>
 
 #include "rsContext.h"
+#include "rsElement.h"
 #include "rsScriptC.h"
 
 #include "utils/Vector.h"
@@ -432,6 +433,47 @@
     memcpy(destPtr, data, dataLength);
 }
 
+void rsdScriptSetGlobalVarWithElemDims(
+        const android::renderscript::Context *dc,
+        const android::renderscript::Script *script,
+        uint32_t slot, void *data, size_t dataLength,
+        const android::renderscript::Element *elem,
+        const size_t *dims, size_t dimLength) {
+    DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+    int32_t *destPtr = reinterpret_cast<int32_t *>(
+                          drv->mExecutable->getExportVarAddrs()[slot]);
+    if (!destPtr) {
+        //ALOGV("Calling setVar on slot = %i which is null", slot);
+        return;
+    }
+
+    // We want to look at dimension in terms of integer components,
+    // but dimLength is given in terms of bytes.
+    dimLength /= sizeof(int);
+
+    // Only a single dimension is currently supported.
+    rsAssert(dimLength == 1);
+    if (dimLength == 1) {
+        // First do the increment loop.
+        size_t stride = elem->getSizeBytes();
+        char *cVal = reinterpret_cast<char *>(data);
+        for (size_t i = 0; i < dims[0]; i++) {
+            elem->incRefs(cVal);
+            cVal += stride;
+        }
+
+        // Decrement loop comes after (to prevent race conditions).
+        char *oldVal = reinterpret_cast<char *>(destPtr);
+        for (size_t i = 0; i < dims[0]; i++) {
+            elem->decRefs(oldVal);
+            oldVal += stride;
+        }
+    }
+
+    memcpy(destPtr, data, dataLength);
+}
+
 void rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t slot, void *data) {
     DrvScript *drv = (DrvScript *)script->mHal.drv;
     //rsAssert(!script->mFieldIsObject[slot]);
diff --git a/driver/rsdBcc.h b/driver/rsdBcc.h
index 5f83ed2..7a4b138 100644
--- a/driver/rsdBcc.h
+++ b/driver/rsdBcc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -49,6 +49,13 @@
 void rsdScriptSetGlobalVar(const android::renderscript::Context *,
                            const android::renderscript::Script *,
                            uint32_t slot, void *data, size_t dataLen);
+void rsdScriptSetGlobalVarWithElemDims(const android::renderscript::Context *,
+                                       const android::renderscript::Script *,
+                                       uint32_t slot, void *data,
+                                       size_t dataLength,
+                                       const android::renderscript::Element *,
+                                       const size_t *dims,
+                                       size_t dimLength);
 void rsdScriptSetGlobalBind(const android::renderscript::Context *,
                             const android::renderscript::Script *,
                             uint32_t slot, void *data);
diff --git a/driver/rsdCore.cpp b/driver/rsdCore.cpp
index 016e441..64b4807 100644
--- a/driver/rsdCore.cpp
+++ b/driver/rsdCore.cpp
@@ -60,6 +60,7 @@
         rsdScriptInvokeInit,
         rsdScriptInvokeFreeChildren,
         rsdScriptSetGlobalVar,
+        rsdScriptSetGlobalVarWithElemDims,
         rsdScriptSetGlobalBind,
         rsdScriptSetGlobalObj,
         rsdScriptDestroy
diff --git a/rs.spec b/rs.spec
index b373056..f32443f 100644
--- a/rs.spec
+++ b/rs.spec
@@ -330,6 +330,14 @@
     param const void * data
     }
 
+ScriptSetVarVE {
+    param RsScript s
+    param uint32_t slot
+    param const void * data
+    param RsElement e
+    param const size_t * dims
+    }
+
 
 ScriptCCreate {
         param const char * resName
diff --git a/rsScript.cpp b/rsScript.cpp
index 6a3bd4b..d39fb5e 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -64,6 +64,16 @@
     mRSC->mHal.funcs.script.setGlobalVar(mRSC, this, slot, (void *)val, len);
 }
 
+void Script::setVar(uint32_t slot, const void *val, size_t len, Element *e,
+                    const size_t *dims, size_t dimLen) {
+    if (slot >= mHal.info.exportedVariableCount) {
+        ALOGE("Script::setVar unable to set allocation, invalid slot index");
+        return;
+    }
+    mRSC->mHal.funcs.script.setGlobalVarWithElemDims(mRSC, this, slot,
+            (void *)val, len, e, dims, dimLen);
+}
+
 void Script::setVarObj(uint32_t slot, ObjectBase *val) {
     //ALOGE("setVarObj %i %p", slot, val);
     if (slot >= mHal.info.exportedVariableCount) {
@@ -166,6 +176,14 @@
     s->setVar(slot, data, len);
 }
 
+void rsi_ScriptSetVarVE(Context *rsc, RsScript vs, uint32_t slot,
+                        const void *data, size_t len, RsElement ve,
+                        const size_t *dims, size_t dimLen) {
+    Script *s = static_cast<Script *>(vs);
+    Element *e = static_cast<Element *>(ve);
+    s->setVar(slot, data, len, e, dims, dimLen);
+}
+
 }
 }
 
diff --git a/rsScript.h b/rsScript.h
index 7879ea6..acd6afb 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -69,6 +69,8 @@
 
     void setSlot(uint32_t slot, Allocation *a);
     void setVar(uint32_t slot, const void *val, size_t len);
+    void setVar(uint32_t slot, const void *val, size_t len, Element *e,
+                const size_t *dims, size_t dimLen);
     void setVarObj(uint32_t slot, ObjectBase *val);
 
     virtual bool freeChildren();
diff --git a/rs_hal.h b/rs_hal.h
index e4bf17f..b4da744 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -99,6 +99,13 @@
                              uint32_t slot,
                              void *data,
                              size_t dataLength);
+        void (*setGlobalVarWithElemDims)(const Context *rsc, const Script *s,
+                                         uint32_t slot,
+                                         void *data,
+                                         size_t dataLength,
+                                         const Element *e,
+                                         const size_t *dims,
+                                         size_t dimLength);
         void (*setGlobalBind)(const Context *rsc, const Script *s,
                               uint32_t slot,
                               void *data);