rsClosure.cpp revision ff2bb54ebf593b1d19d3a2e4cfa70a8ea4432c0d
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "rsClosure.h"
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "cpu_ref/rsCpuCore.h"
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "rsContext.h" // XXX: necessary to avoid compiler error on rsScript.h below
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "rsScript.h"
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "rsType.h"
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace android {
9f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesnamespace renderscript {
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesRsClosure rsi_ClosureCreate(Context* context, RsScriptKernelID kernelID,
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            RsAllocation returnValue,
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            RsScriptFieldID* fieldIDs, size_t fieldIDs_length,
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            uintptr_t* values, size_t values_length,
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            size_t* sizes, size_t sizes_length,
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            RsClosure* depClosures, size_t depClosures_length,
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            RsScriptFieldID* depFieldIDs,
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            size_t depFieldIDs_length) {
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    rsAssert(fieldIDs_length == values_length && values_length == sizes_length &&
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao             sizes_length == depClosures_length &&
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao             depClosures_length == depFieldIDs_length);
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return (RsClosure)(new Closure(
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        context, (const ScriptKernelID*)kernelID, (Allocation*)returnValue,
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values,
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        sizes, (const Closure**)depClosures,
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        (const ScriptFieldID**)depFieldIDs));
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRsClosure rsi_InvokeClosureCreate(Context* context, RsScriptInvokeID invokeID,
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const void* params, const size_t paramLength,
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const RsScriptFieldID* fieldIDs, const size_t fieldIDs_length,
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const uintptr_t* values, const size_t values_length,
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                  const size_t* sizes, const size_t sizes_length) {
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    rsAssert(fieldIDs_length == values_length && values_length == sizes_length);
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return (RsClosure)(new Closure(
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        context, (const ScriptInvokeID*)invokeID, params, paramLength,
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values,
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        sizes));
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#if 0
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid rsi_ClosureEval(Context* rsc, RsClosure closure) {
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ((Closure*)closure)->eval();
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       uintptr_t value, size_t size) {
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ((Closure*)closure)->setArg(index, (const void*)value, size);
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                          RsScriptFieldID fieldID, uintptr_t value,
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                          size_t size) {
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   (const void*)value, size);
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoClosure::Closure(Context* context,
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 const ScriptKernelID* kernelID,
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 Allocation* returnValue,
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 const int numValues,
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 const ScriptFieldID** fieldIDs,
65                 const void** values,
66                 const size_t* sizes,
67                 const Closure** depClosures,
68                 const ScriptFieldID** depFieldIDs) :
69    ObjectBase(context), mContext(context), mKernelID((ScriptKernelID*)kernelID),
70    mInvokeID(nullptr), mReturnValue(returnValue), mParams(nullptr),
71    mParamLength(0) {
72    size_t i;
73
74    for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++);
75
76    mNumArg = i;
77    mArgs = new const void*[mNumArg];
78    memcpy(mArgs, values, sizeof(const void*) * mNumArg);
79
80    for (; i < (size_t)numValues; i++) {
81        rsAssert(fieldIDs[i] != nullptr);
82        mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
83        ALOGV("Creating closure %p, binding field %p (Script %p, slot: %d)",
84              this, fieldIDs[i], fieldIDs[i]->mScript, fieldIDs[i]->mSlot);
85    }
86
87    size_t j = mNumArg;
88    for (const auto& p : mGlobals) {
89        rsAssert(p.first == fieldIDs[j]);
90        rsAssert(p.second.first == values[j]);
91        rsAssert(p.second.second == sizes[j]);
92        j++;
93    }
94
95    // mDependences.insert(depClosures, depClosures + numValues);
96
97    for (i = 0; i < mNumArg; i++) {
98        const Closure* dep = depClosures[i];
99        if (dep != nullptr) {
100            auto mapping = mArgDeps[dep];
101            if (mapping == nullptr) {
102                mapping = new Map<int, const ObjectBaseRef<ScriptFieldID>*>();
103                mArgDeps[dep] = mapping;
104            }
105            (*mapping)[i] = new ObjectBaseRef<ScriptFieldID>(
106                const_cast<ScriptFieldID*>(depFieldIDs[i]));
107        }
108    }
109
110    for (; i < (size_t)numValues; i++) {
111        const Closure* dep = depClosures[i];
112        if (dep != nullptr) {
113            auto mapping = mGlobalDeps[dep];
114            if (mapping == nullptr) {
115                mapping = new Map<const ObjectBaseRef<ScriptFieldID>*,
116                                  const ObjectBaseRef<ScriptFieldID>*>();
117                mGlobalDeps[dep] = mapping;
118            }
119            (*mapping)[new ObjectBaseRef<ScriptFieldID>(
120                const_cast<ScriptFieldID*>(fieldIDs[i]))] =
121                    new ObjectBaseRef<ScriptFieldID>(
122                        const_cast<ScriptFieldID*>(depFieldIDs[i]));
123        }
124    }
125}
126
127Closure::Closure(Context* context, const ScriptInvokeID* invokeID,
128                 const void* params, const size_t paramLength,
129                 const size_t numValues, const ScriptFieldID** fieldIDs,
130                 const void** values, const size_t* sizes) :
131    ObjectBase(context), mContext(context), mKernelID(nullptr), mInvokeID(invokeID),
132    mReturnValue(nullptr), mParams(params), mParamLength(paramLength) {
133    for (size_t i = 0; i < numValues; i++) {
134        mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
135    }
136}
137
138Closure::~Closure() {
139    for (const auto& p : mArgDeps) {
140        auto map = p.second;
141        for (const auto& p1 : *map) {
142            delete p1.second;
143        }
144        delete p.second;
145    }
146
147    for (const auto& p : mGlobalDeps) {
148        auto map = p.second;
149        for (const auto& p1 : *map) {
150            delete p1.first;
151            delete p1.second;
152        }
153        delete p.second;
154    }
155
156    delete[] mArgs;
157}
158
159void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
160    mArgs[index] = value;
161}
162
163void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
164                        const size_t size) {
165    mGlobals[fieldID] = make_pair(value, size);
166}
167
168}  // namespace renderscript
169}  // namespace android
170