rsClosure.cpp revision eb9aa675754c49f613c6ad71d41472b30f38b007
1#include "rsClosure.h" 2 3#include "cpu_ref/rsCpuCore.h" 4#include "rsContext.h" // XXX: necessary to avoid compiler error on rsScript.h below 5#include "rsScript.h" 6#include "rsType.h" 7 8namespace android { 9namespace renderscript { 10 11RsClosure rsi_ClosureCreate(Context* context, RsScriptKernelID kernelID, 12 RsAllocation returnValue, 13 RsScriptFieldID* fieldIDs, size_t fieldIDs_length, 14 uintptr_t* values, size_t values_length, 15 size_t* sizes, size_t sizes_length, 16 RsClosure* depClosures, size_t depClosures_length, 17 RsScriptFieldID* depFieldIDs, 18 size_t depFieldIDs_length) { 19 rsAssert(fieldIDs_length == values_length && values_length == sizes_length && 20 sizes_length == depClosures_length && 21 depClosures_length == depFieldIDs_length); 22 23 return (RsClosure)(new Closure( 24 context, (const ScriptKernelID*)kernelID, (Allocation*)returnValue, 25 fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values, 26 sizes, (const Closure**)depClosures, 27 (const ScriptFieldID**)depFieldIDs)); 28} 29 30RsClosure rsi_InvokeClosureCreate(Context* context, RsScriptInvokeID invokeID, 31 const void* params, const size_t paramLength, 32 const RsScriptFieldID* fieldIDs, const size_t fieldIDs_length, 33 const uintptr_t* values, const size_t values_length, 34 const size_t* sizes, const size_t sizes_length) { 35 rsAssert(fieldIDs_length == values_length && values_length == sizes_length); 36 return (RsClosure)(new Closure( 37 context, (const ScriptInvokeID*)invokeID, params, paramLength, 38 fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values, 39 sizes)); 40} 41 42void rsi_ClosureEval(Context* rsc, RsClosure closure) { 43 ((Closure*)closure)->eval(); 44} 45 46void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index, 47 uintptr_t value, size_t size) { 48 ((Closure*)closure)->setArg(index, (const void*)value, size); 49} 50 51void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure, 52 RsScriptFieldID fieldID, uintptr_t value, 53 size_t size) { 54 ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID, 55 (const void*)value, size); 56} 57 58Closure::Closure(Context* context, 59 const ScriptKernelID* kernelID, 60 Allocation* returnValue, 61 const int numValues, 62 const ScriptFieldID** fieldIDs, 63 const void** values, 64 const size_t* sizes, 65 const Closure** depClosures, 66 const ScriptFieldID** depFieldIDs) : 67 ObjectBase(context), mContext(context), mKernelID((ScriptKernelID*)kernelID), 68 mInvokeID(nullptr), mReturnValue(returnValue), mParams(nullptr), 69 mParamLength(0) { 70 size_t i; 71 72 for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++); 73 74 vector<const void*> args(values, values + i); 75 mArgs.swap(args); 76 77 for (; i < (size_t)numValues; i++) { 78 mGlobals[fieldIDs[i]] = std::make_pair(values[i], sizes[i]); 79 } 80 81 mDependences.insert(depClosures, depClosures + numValues); 82 83 for (i = 0; i < mArgs.size(); i++) { 84 const Closure* dep = depClosures[i]; 85 if (dep != nullptr) { 86 auto mapping = mArgDeps[dep]; 87 if (mapping == nullptr) { 88 mapping = new map<int, const ObjectBaseRef<ScriptFieldID>*>(); 89 mArgDeps[dep] = mapping; 90 } 91 (*mapping)[i] = new ObjectBaseRef<ScriptFieldID>( 92 const_cast<ScriptFieldID*>(depFieldIDs[i])); 93 } 94 } 95 96 for (; i < (size_t)numValues; i++) { 97 const Closure* dep = depClosures[i]; 98 if (dep != nullptr) { 99 auto mapping = mGlobalDeps[dep]; 100 if (mapping == nullptr) { 101 mapping = new map<const ObjectBaseRef<ScriptFieldID>*, 102 const ObjectBaseRef<ScriptFieldID>*>(); 103 mGlobalDeps[dep] = mapping; 104 } 105 (*mapping)[new ObjectBaseRef<ScriptFieldID>( 106 const_cast<ScriptFieldID*>(fieldIDs[i]))] = 107 new ObjectBaseRef<ScriptFieldID>( 108 const_cast<ScriptFieldID*>(depFieldIDs[i])); 109 } 110 } 111} 112 113Closure::Closure(Context* context, const ScriptInvokeID* invokeID, 114 const void* params, const size_t paramLength, 115 const size_t numValues, const ScriptFieldID** fieldIDs, 116 const void** values, const size_t* sizes) : 117 ObjectBase(context), mContext(context), mKernelID(nullptr), mInvokeID(invokeID), 118 mReturnValue(nullptr), mParams(params), mParamLength(paramLength) { 119 for (size_t i = 0; i < numValues; i++) { 120 mGlobals[fieldIDs[i]] = std::make_pair(values[i], sizes[i]); 121 } 122} 123 124Closure::~Closure() { 125 for (const auto& p : mArgDeps) { 126 auto map = p.second; 127 for (const auto& p1 : *map) { 128 delete p1.second; 129 } 130 delete p.second; 131 } 132 133 for (const auto& p : mGlobalDeps) { 134 auto map = p.second; 135 for (const auto& p1 : *map) { 136 delete p1.first; 137 delete p1.second; 138 } 139 delete p.second; 140 } 141} 142 143void Closure::eval() { 144 Script *s = mKernelID->mScript; 145 146 for (const auto& p : mGlobals) { 147 const void* value = p.second.first; 148 int size = p.second.second; 149 // We use -1 size to indicate an ObjectBase rather than a primitive type 150 if (size < 0) { 151 s->setVarObj(p.first->mSlot, (ObjectBase*)value); 152 } else { 153 s->setVar(p.first->mSlot, (const void*)&value, size); 154 } 155 } 156 157 s->runForEach(mContext, mKernelID->mSlot, (const Allocation **)(&mArgs[0]), 158 mArgs.size(), mReturnValue, nullptr, 0, nullptr); 159} 160 161void Closure::setArg(const uint32_t index, const void* value, const size_t size) { 162 mArgs[index] = value; 163} 164 165void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value, 166 const size_t size) { 167 mGlobals[fieldID] = std::make_pair(value, size); 168} 169 170} // namespace renderscript 171} // namespace android 172