summaryrefslogtreecommitdiffstats
path: root/rsClosure.cpp
diff options
context:
space:
mode:
authorYang Ni <yangni@google.com>2015-01-07 09:16:40 -0800
committerYang Ni <yangni@google.com>2015-01-07 09:16:40 -0800
commit1ffd86b448d78366190c540f98f8b6d641cdb6cf (patch)
tree65dc9b2f0c6d53ce4858ae990ab82f34cc26fd06 /rsClosure.cpp
parent82f515b5a40d030f88bf622b8c05a03ec80083ee (diff)
downloadandroid_frameworks_rs-1ffd86b448d78366190c540f98f8b6d641cdb6cf.tar.gz
android_frameworks_rs-1ffd86b448d78366190c540f98f8b6d641cdb6cf.tar.bz2
android_frameworks_rs-1ffd86b448d78366190c540f98f8b6d641cdb6cf.zip
New Script Group API: runtime and cpu driver support.
Change-Id: I9c612cf8874aabaf0ca7d1640567464c71ed3070
Diffstat (limited to 'rsClosure.cpp')
-rw-r--r--rsClosure.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/rsClosure.cpp b/rsClosure.cpp
new file mode 100644
index 00000000..8530fc16
--- /dev/null
+++ b/rsClosure.cpp
@@ -0,0 +1,147 @@
+#include "rsClosure.h"
+
+#include "cpu_ref/rsCpuCore.h"
+#include "rsContext.h" // XXX: necessary to avoid compiler error on rsScript.h below
+#include "rsScript.h"
+#include "rsType.h"
+
+namespace android {
+namespace renderscript {
+
+RsClosure rsi_ClosureCreate(Context* context, RsScriptKernelID kernelID,
+ RsAllocation returnValue,
+ RsScriptFieldID* fieldIDs, size_t fieldIDs_length,
+ uintptr_t* values, size_t values_length,
+ size_t* sizes, size_t sizes_length,
+ RsClosure* depClosures, size_t depClosures_length,
+ RsScriptFieldID* depFieldIDs,
+ size_t depFieldIDs_length) {
+ rsAssert(fieldIDs_length == values_length && values_length == sizes_length &&
+ sizes_length == depClosures_length &&
+ depClosures_length == depFieldIDs_length);
+
+ return (RsClosure)(new Closure(
+ context, (const ScriptKernelID*)kernelID, (Allocation*)returnValue,
+ fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values,
+ sizes, (const Closure**)depClosures,
+ (const ScriptFieldID**)depFieldIDs));
+}
+
+void rsi_ClosureEval(Context* rsc, RsClosure closure) {
+ ((Closure*)closure)->eval();
+}
+
+void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
+ uintptr_t value, size_t size) {
+ ((Closure*)closure)->setArg(index, (const void*)value, size);
+}
+
+void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
+ RsScriptFieldID fieldID, uintptr_t value,
+ size_t size) {
+ ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
+ (const void*)value, size);
+}
+
+Closure::Closure(Context* context,
+ const ScriptKernelID* kernelID,
+ Allocation* returnValue,
+ const int numValues,
+ const ScriptFieldID** fieldIDs,
+ const void** values,
+ const size_t* sizes,
+ const Closure** depClosures,
+ const ScriptFieldID** depFieldIDs) :
+ ObjectBase(context), mContext(context), mKernelID((ScriptKernelID*)kernelID),
+ mReturnValue(returnValue) {
+ size_t i;
+
+ for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++);
+
+ vector<const void*> args(values, values + i);
+ mArgs.swap(args);
+
+ for (; i < (size_t)numValues; i++) {
+ mGlobals[fieldIDs[i]] = std::make_pair(values[i], sizes[i]);
+ }
+
+ mDependences.insert(depClosures, depClosures + numValues);
+
+ for (i = 0; i < mArgs.size(); i++) {
+ const Closure* dep = depClosures[i];
+ if (dep != nullptr) {
+ auto mapping = mArgDeps[dep];
+ if (mapping == nullptr) {
+ mapping = new map<int, const ObjectBaseRef<ScriptFieldID>*>();
+ mArgDeps[dep] = mapping;
+ }
+ (*mapping)[i] = new ObjectBaseRef<ScriptFieldID>(
+ const_cast<ScriptFieldID*>(depFieldIDs[i]));
+ }
+ }
+
+ for (; i < (size_t)numValues; i++) {
+ const Closure* dep = depClosures[i];
+ if (dep != nullptr) {
+ auto mapping = mGlobalDeps[dep];
+ if (mapping == nullptr) {
+ mapping = new map<const ObjectBaseRef<ScriptFieldID>*,
+ const ObjectBaseRef<ScriptFieldID>*>();
+ mGlobalDeps[dep] = mapping;
+ }
+ (*mapping)[new ObjectBaseRef<ScriptFieldID>(
+ const_cast<ScriptFieldID*>(fieldIDs[i]))] =
+ new ObjectBaseRef<ScriptFieldID>(
+ const_cast<ScriptFieldID*>(depFieldIDs[i]));
+ }
+ }
+}
+
+Closure::~Closure() {
+ for (const auto& p : mArgDeps) {
+ auto map = p.second;
+ for (const auto& p1 : *map) {
+ delete p1.second;
+ }
+ delete p.second;
+ }
+
+ for (const auto& p : mGlobalDeps) {
+ auto map = p.second;
+ for (const auto& p1 : *map) {
+ delete p1.first;
+ delete p1.second;
+ }
+ delete p.second;
+ }
+}
+
+void Closure::eval() {
+ Script *s = mKernelID->mScript;
+
+ for (const auto& p : mGlobals) {
+ const void* value = p.second.first;
+ int size = p.second.second;
+ // We use -1 size to indicate an ObjectBase rather than a primitive type
+ if (size < 0) {
+ s->setVarObj(p.first->mSlot, (ObjectBase*)value);
+ } else {
+ s->setVar(p.first->mSlot, (const void*)&value, size);
+ }
+ }
+
+ s->runForEach(mContext, mKernelID->mSlot, (const Allocation **)(&mArgs[0]),
+ mArgs.size(), mReturnValue, nullptr, 0, nullptr);
+}
+
+void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
+ mArgs[index] = value;
+}
+
+void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
+ const size_t size) {
+ mGlobals[fieldID] = std::make_pair(value, size);
+}
+
+} // namespace renderscript
+} // namespace android