Support running ForEach on non-root functions.

BUG=6000538

Change-Id: Ie2b16893b150cc5955ee4b9d028c988f69a82744
diff --git a/driver/rsdBcc.cpp b/driver/rsdBcc.cpp
index bec6fff..dd78684 100644
--- a/driver/rsdBcc.cpp
+++ b/driver/rsdBcc.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 #include "rsdCore.h"
 #include "rsdBcc.h"
 #include "rsdRuntime.h"
@@ -30,7 +29,6 @@
 #include "libdex/ZipArchive.h"
 }
 
-
 using namespace android;
 using namespace android::renderscript;
 
@@ -45,6 +43,7 @@
     bcinfo::MetadataExtractor *ME;
 
     InvokeFunc_t *mInvokeFunctions;
+    ForEachFunc_t *mForEachFunctions;
     void ** mFieldAddress;
     bool * mFieldIsObject;
     const uint32_t *mExportForEachSignatureList;
@@ -162,8 +161,16 @@
     }
 
     exportForEachSignatureCount = drv->ME->getExportForEachSignatureCount();
-    rsAssert(exportForEachSignatureCount <= 1);
     drv->mExportForEachSignatureList = drv->ME->getExportForEachSignatureList();
+    if (exportForEachSignatureCount > 0) {
+        drv->mForEachFunctions =
+            (ForEachFunc_t*) calloc(exportForEachSignatureCount,
+                                    sizeof(ForEachFunc_t));
+        bccGetExportForEachList(drv->mBccScript, exportForEachSignatureCount,
+                                (void **) drv->mForEachFunctions);
+    } else {
+        drv->mForEachFunctions = NULL;
+    }
 
     // Copy info over to runtime
     script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
@@ -196,6 +203,7 @@
 typedef struct {
     Context *rsc;
     Script *script;
+    ForEachFunc_t kernel;
     uint32_t sig;
     const Allocation * ain;
     Allocation * aout;
@@ -235,7 +243,7 @@
     RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
     uint32_t sig = mtls->sig;
 
-    outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+    outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
     while (1) {
         uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
         uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
@@ -265,7 +273,7 @@
     RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
     uint32_t sig = mtls->sig;
 
-    outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+    outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
     while (1) {
         uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
         uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
@@ -299,8 +307,8 @@
     memset(&mtls, 0, sizeof(mtls));
 
     DrvScript *drv = (DrvScript *)s->mHal.drv;
-    // We only support slot 0 (root) at this point in time.
-    rsAssert(slot == 0);
+    mtls.kernel = drv->mForEachFunctions[slot];
+    rsAssert(mtls.kernel != NULL);
     mtls.sig = 0x1f;  // temp fix for old apps, full table in slang_rs_export_foreach.cpp
     if (drv->mExportForEachSignatureList) {
         mtls.sig = drv->mExportForEachSignatureList[slot];
@@ -391,7 +399,7 @@
         uint32_t sig = mtls.sig;
 
         //ALOGE("launch 3");
-        outer_foreach_t fn = (outer_foreach_t) mtls.script->mHal.info.root;
+        outer_foreach_t fn = (outer_foreach_t) mtls.kernel;
         for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
             for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
                 for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
@@ -517,6 +525,11 @@
         drv->mInvokeFunctions = NULL;
     }
 
+    if (drv->mForEachFunctions) {
+        free(drv->mForEachFunctions);
+        drv->mForEachFunctions = NULL;
+    }
+
     delete drv->ME;
     drv->ME = NULL;
 
diff --git a/driver/rsdCore.h b/driver/rsdCore.h
index 168bdf3..05ca13b 100644
--- a/driver/rsdCore.h
+++ b/driver/rsdCore.h
@@ -25,6 +25,7 @@
 #include "rsdGL.h"
 
 typedef void (* InvokeFunc_t)(void);
+typedef void (* ForEachFunc_t)(void);
 typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
 
 typedef struct RsdSymbolTableRec {
diff --git a/rsScript.cpp b/rsScript.cpp
index 357dbe3..6a3bd4b 100644
--- a/rsScript.cpp
+++ b/rsScript.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -113,7 +113,7 @@
                        RsAllocation vain, RsAllocation vaout,
                        const void *params, size_t paramLen) {
     Script *s = static_cast<Script *>(vs);
-    s->runForEach(rsc,
+    s->runForEach(rsc, slot,
                   static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout),
                   params, paramLen);
 
diff --git a/rsScript.h b/rsScript.h
index 99dceaf..7879ea6 100644
--- a/rsScript.h
+++ b/rsScript.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -74,6 +74,7 @@
     virtual bool freeChildren();
 
     virtual void runForEach(Context *rsc,
+                            uint32_t slot,
                             const Allocation * ain,
                             Allocation * aout,
                             const void * usr,
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index b4eb995..79725b9 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -128,6 +128,7 @@
 
 
 void ScriptC::runForEach(Context *rsc,
+                         uint32_t slot,
                          const Allocation * ain,
                          Allocation * aout,
                          const void * usr,
@@ -138,7 +139,7 @@
 
     setupGLState(rsc);
     setupScript(rsc);
-    rsc->mHal.funcs.script.invokeForEach(rsc, this, 0, ain, aout, usr, usrBytes, sc);
+    rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc);
 }
 
 void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) {
diff --git a/rsScriptC.h b/rsScriptC.h
index c65a5bf..c89d9b1 100644
--- a/rsScriptC.h
+++ b/rsScriptC.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -47,6 +47,7 @@
     virtual uint32_t run(Context *);
 
     virtual void runForEach(Context *rsc,
+                            uint32_t slot,
                             const Allocation * ain,
                             Allocation * aout,
                             const void * usr,
diff --git a/rsScriptC_Lib.cpp b/rsScriptC_Lib.cpp
index 183e207..a5a0fae 100644
--- a/rsScriptC_Lib.cpp
+++ b/rsScriptC_Lib.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -157,7 +157,7 @@
                 Allocation *in, Allocation *out,
                 const void *usr, uint32_t usrBytes,
                 const RsScriptCall *call) {
-    target->runForEach(rsc, in, out, usr, usrBytes, call);
+    target->runForEach(rsc, /* root slot */ 0, in, out, usr, usrBytes, call);
 }
 
 void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) {