Add reduce to the dispatch table and to the RenderScript C++ API.

Bug: 22631253
Change-Id: I06eec227e122075c8a81ed501cd9efcd4e0ef13a
diff --git a/cpp/Script.cpp b/cpp/Script.cpp
index 889bb02..acea0c8 100644
--- a/cpp/Script.cpp
+++ b/cpp/Script.cpp
@@ -36,6 +36,20 @@
     tryDispatch(mRS, RS::dispatch->ScriptForEach(mRS->getContext(), getID(), slot, in_id, out_id, usr, usrLen, nullptr, 0));
 }
 
+void Script::reduce(uint32_t slot, sp<const Allocation> ain, sp<const Allocation> aout,
+                    const RsScriptCall *sc) const {
+    if (RS::dispatch->ScriptReduce == nullptr) {
+        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Reduce is not supported at the current API level");
+        return;
+    }
+    if (ain == nullptr || aout == nullptr) {
+        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Both ain and aout are required to be non-null.");
+        return;
+    }
+    void *in_id = BaseObj::getObjID(ain);
+    void *out_id = BaseObj::getObjID(aout);
+    tryDispatch(mRS, RS::dispatch->ScriptReduce(mRS->getContext(), getID(), slot, in_id, out_id, sc, sc == nullptr ? 0 : sizeof(*sc)));
+}
 
 Script::Script(void *id, sp<RS> rs) : BaseObj(id, rs) {
 }
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index d834ef5..fd531f1 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -1401,6 +1401,8 @@
     Script(void *id, sp<RS> rs);
     void forEach(uint32_t slot, sp<const Allocation> in, sp<const Allocation> out,
             const void *v, size_t) const;
+    void reduce(uint32_t slot, sp<const Allocation> in, sp<const Allocation> out,
+                const RsScriptCall *sc) const;
     void bindAllocation(sp<Allocation> va, uint32_t slot) const;
     void setVar(uint32_t index, const void *, size_t len) const;
     void setVar(uint32_t index, sp<const BaseObj> o) const;
diff --git a/cpp/rsDispatch.cpp b/cpp/rsDispatch.cpp
index 10adcf2..39c1396 100644
--- a/cpp/rsDispatch.cpp
+++ b/cpp/rsDispatch.cpp
@@ -18,8 +18,10 @@
 
 #include "rsDispatch.h"
 #include <dlfcn.h>
+#include <limits.h>
 
 #define LOG_API(...)
+#define REDUCE_API_LEVEL INT_MAX
 
 bool loadSymbols(void* handle, dispatchTable& dispatchTab, int device_api) {
     //fucntion to set the native lib path for 64bit compat lib.
@@ -417,6 +419,14 @@
             return false;
         }
     }
+    // TODO: Update the API level when reduce is added.
+    if (device_api >= REDUCE_API_LEVEL) {
+        dispatchTab.ScriptReduce = (ScriptReduceFnPtr)dlsym(handle, "rsScriptReduce");
+        if (dispatchTab.ScriptReduce == nullptr) {
+            LOG_API("Couldn't initialize dispatchTab.ScriptReduce");
+            return false;
+        }
+    }
 
     return true;
 
diff --git a/cpp/rsDispatch.h b/cpp/rsDispatch.h
index 9ce97c8..a401754 100644
--- a/cpp/rsDispatch.h
+++ b/cpp/rsDispatch.h
@@ -76,6 +76,8 @@
 typedef void (*ScriptInvokeFnPtr) (RsContext, RsScript, uint32_t);
 typedef void (*ScriptInvokeVFnPtr) (RsContext, RsScript, uint32_t, const void*, size_t);
 typedef void (*ScriptForEachFnPtr) (RsContext, RsScript, uint32_t, RsAllocation, RsAllocation, const void*, size_t, const RsScriptCall*, size_t);
+typedef void (*ScriptForEachMultiFnPtr) (RsContext, RsScript, uint32_t, RsAllocation*, size_t, RsAllocation, const void*, size_t, const RsScriptCall*, size_t);
+typedef void (*ScriptReduceFnPtr) (RsContext, RsScript, uint32_t, RsAllocation, RsAllocation, const RsScriptCall*, size_t);
 typedef void (*ScriptSetVarIFnPtr) (RsContext, RsScript, uint32_t, int);
 typedef void (*ScriptSetVarObjFnPtr) (RsContext, RsScript, uint32_t, RsObjectBase);
 typedef void (*ScriptSetVarJFnPtr) (RsContext, RsScript, uint32_t, int64_t);
@@ -94,7 +96,6 @@
 typedef void (*ScriptGroupSetOutputFnPtr) (RsContext, RsScriptGroup, RsScriptKernelID, RsAllocation);
 typedef void (*ScriptGroupSetInputFnPtr) (RsContext, RsScriptGroup, RsScriptKernelID, RsAllocation);
 typedef void (*ScriptGroupExecuteFnPtr) (RsContext, RsScriptGroup);
-typedef void (*ScriptForEachMultiFnPtr) (RsContext, RsScript, uint32_t, RsAllocation *, size_t, RsAllocation, const void *, size_t, const RsScriptCall *, size_t);
 typedef void (*AllocationIoSendFnPtr) (RsContext, RsAllocation);
 typedef void (*AllocationIoReceiveFnPtr) (RsContext, RsAllocation);
 typedef void * (*AllocationGetPointerFnPtr) (RsContext, RsAllocation, uint32_t lod, RsAllocationCubemapFace face, uint32_t z, uint32_t array, size_t *stride, size_t stride_len);
@@ -160,6 +161,8 @@
     ScriptInvokeFnPtr ScriptInvoke;
     ScriptInvokeVFnPtr ScriptInvokeV;
     ScriptForEachFnPtr ScriptForEach;
+    ScriptForEachMultiFnPtr ScriptForEachMulti;
+    ScriptReduceFnPtr ScriptReduce;
     ScriptSetVarIFnPtr ScriptSetVarI;
     ScriptSetVarObjFnPtr ScriptSetVarObj;
     ScriptSetVarJFnPtr ScriptSetVarJ;
@@ -178,7 +181,6 @@
     ScriptGroupSetOutputFnPtr ScriptGroupSetOutput;
     ScriptGroupSetInputFnPtr ScriptGroupSetInput;
     ScriptGroupExecuteFnPtr ScriptGroupExecute;
-    ScriptForEachMultiFnPtr ScriptForEachMulti;
     AllocationIoSendFnPtr AllocationIoSend;
     AllocationIoReceiveFnPtr AllocationIoReceive;
     AllocationGetPointerFnPtr AllocationGetPointer;