diff options
| author | Yang Ni <yangni@google.com> | 2015-01-07 09:16:40 -0800 |
|---|---|---|
| committer | Yang Ni <yangni@google.com> | 2015-01-07 09:16:40 -0800 |
| commit | 1ffd86b448d78366190c540f98f8b6d641cdb6cf (patch) | |
| tree | 65dc9b2f0c6d53ce4858ae990ab82f34cc26fd06 /rsClosure.cpp | |
| parent | 82f515b5a40d030f88bf622b8c05a03ec80083ee (diff) | |
| download | android_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.cpp | 147 |
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 |
