rsClosure.cpp revision bd0af2d161e36e52e6782ccb2d15dd5a36467704
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                            int* 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    Closure* c = 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    c->incUserRef();
29    return static_cast<RsClosure>(c);
30}
31
32RsClosure rsi_InvokeClosureCreate(Context* context, RsScriptInvokeID invokeID,
33                                  const void* params, const size_t paramLength,
34                                  const RsScriptFieldID* fieldIDs, const size_t fieldIDs_length,
35                                  const uintptr_t* values, const size_t values_length,
36                                  const int* sizes, const size_t sizes_length) {
37    rsAssert(fieldIDs_length == values_length && values_length == sizes_length);
38    Closure* c = new Closure(
39        context, (const ScriptInvokeID*)invokeID, params, paramLength,
40        fieldIDs_length, (const ScriptFieldID**)fieldIDs, (const void**)values,
41        sizes);
42    c->incUserRef();
43    return static_cast<RsClosure>(c);
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 int* sizes,
65                 const Closure** depClosures,
66                 const ScriptFieldID** depFieldIDs) :
67    ObjectBase(context), mContext(context), mFunctionID((IDBase*)kernelID),
68    mIsKernel(true), 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    mNumArg = i;
75    mArgs = new const void*[mNumArg];
76    memcpy(mArgs, values, sizeof(const void*) * mNumArg);
77
78    for (; i < (size_t)numValues; i++) {
79        rsAssert(fieldIDs[i] != nullptr);
80        mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
81    }
82
83    for (i = 0; i < mNumArg; 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, ObjectBaseRef<ScriptFieldID>>();
89                mArgDeps[dep] = mapping;
90            }
91            (*mapping)[i].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
92        }
93    }
94
95    for (; i < (size_t)numValues; i++) {
96        const Closure* dep = depClosures[i];
97        if (dep != nullptr) {
98            auto mapping = mGlobalDeps[dep];
99            if (mapping == nullptr) {
100                mapping = new Map<const ScriptFieldID*,
101                                  ObjectBaseRef<ScriptFieldID>>();
102                mGlobalDeps[dep] = mapping;
103            }
104            fieldIDs[i]->incSysRef();
105            (*mapping)[fieldIDs[i]].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
106        }
107    }
108}
109
110Closure::Closure(Context* context, const ScriptInvokeID* invokeID,
111                 const void* params, const size_t paramLength,
112                 const size_t numValues, const ScriptFieldID** fieldIDs,
113                 const void** values, const int* sizes) :
114    ObjectBase(context), mContext(context), mFunctionID((IDBase*)invokeID), mIsKernel(false),
115    mArgs(nullptr), mNumArg(0),
116    mReturnValue(nullptr), mParams(params), mParamLength(paramLength) {
117    for (size_t i = 0; i < numValues; i++) {
118        mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
119    }
120}
121
122Closure::~Closure() {
123    for (const auto& p : mArgDeps) {
124        auto map = p.second;
125        delete p.second;
126    }
127
128    for (const auto& p : mGlobalDeps) {
129        auto map = p.second;
130        for (const auto& p1 : *map) {
131            p1.first->decSysRef();
132        }
133        delete p.second;
134    }
135
136    delete[] mArgs;
137}
138
139void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
140    mArgs[index] = value;
141}
142
143void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
144                        const int size) {
145    mGlobals[fieldID] = make_pair(value, size);
146}
147
148}  // namespace renderscript
149}  // namespace android
150