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 
8 namespace android {
9 namespace renderscript {
10 
rsi_ClosureCreate(Context * context,RsScriptKernelID kernelID,RsAllocation returnValue,RsScriptFieldID * fieldIDs,size_t fieldIDs_length,const int64_t * values,size_t values_length,const int * sizes,size_t sizes_length,RsClosure * depClosures,size_t depClosures_length,RsScriptFieldID * depFieldIDs,size_t depFieldIDs_length)11 RsClosure rsi_ClosureCreate(Context* context, RsScriptKernelID kernelID,
12                             RsAllocation returnValue,
13                             RsScriptFieldID* fieldIDs, size_t fieldIDs_length,
14                             const int64_t* values, size_t values_length,
15                             const 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, values,
26         sizes, (const Closure**)depClosures,
27         (const ScriptFieldID**)depFieldIDs);
28     c->incUserRef();
29     return static_cast<RsClosure>(c);
30 }
31 
rsi_InvokeClosureCreate(Context * context,RsScriptInvokeID invokeID,const void * params,const size_t paramLength,const RsScriptFieldID * fieldIDs,const size_t fieldIDs_length,const int64_t * values,const size_t values_length,const int * sizes,const size_t sizes_length)32 RsClosure 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 int64_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, values,
41         sizes);
42     c->incUserRef();
43     return static_cast<RsClosure>(c);
44 }
45 
rsi_ClosureSetArg(Context * rsc,RsClosure closure,uint32_t index,uintptr_t value,int size)46 void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
47                        uintptr_t value, int size) {
48     ((Closure*)closure)->setArg(index, (const void*)value, size);
49 }
50 
rsi_ClosureSetGlobal(Context * rsc,RsClosure closure,RsScriptFieldID fieldID,int64_t value,int size)51 void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
52                           RsScriptFieldID fieldID, int64_t value,
53                           int size) {
54     ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
55                                    value, size);
56 }
57 
Closure(Context * context,const ScriptKernelID * kernelID,Allocation * returnValue,const int numValues,const ScriptFieldID ** fieldIDs,const int64_t * values,const int * sizes,const Closure ** depClosures,const ScriptFieldID ** depFieldIDs)58 Closure::Closure(Context* context,
59                  const ScriptKernelID* kernelID,
60                  Allocation* returnValue,
61                  const int numValues,
62                  const ScriptFieldID** fieldIDs,
63                  const int64_t* 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     for (size_t j = 0; j < mNumArg; j++) {
77         mArgs[j] = (const void*)values[j];
78     }
79 
80     for (; i < (size_t)numValues; i++) {
81         rsAssert(fieldIDs[i] != nullptr);
82         mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
83     }
84 
85     for (i = 0; i < mNumArg; i++) {
86         const Closure* dep = depClosures[i];
87         if (dep != nullptr) {
88             auto mapping = mArgDeps[dep];
89             if (mapping == nullptr) {
90                 mapping = new Map<int, ObjectBaseRef<ScriptFieldID>>();
91                 mArgDeps[dep] = mapping;
92             }
93             (*mapping)[i].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
94         }
95     }
96 
97     for (; i < (size_t)numValues; i++) {
98         const Closure* dep = depClosures[i];
99         if (dep != nullptr) {
100             auto mapping = mGlobalDeps[dep];
101             if (mapping == nullptr) {
102                 mapping = new Map<const ScriptFieldID*,
103                                   ObjectBaseRef<ScriptFieldID>>();
104                 mGlobalDeps[dep] = mapping;
105             }
106             fieldIDs[i]->incSysRef();
107             (*mapping)[fieldIDs[i]].set(const_cast<ScriptFieldID*>(depFieldIDs[i]));
108         }
109     }
110 }
111 
Closure(Context * context,const ScriptInvokeID * invokeID,const void * params,const size_t paramLength,const size_t numValues,const ScriptFieldID ** fieldIDs,const int64_t * values,const int * sizes)112 Closure::Closure(Context* context, const ScriptInvokeID* invokeID,
113                  const void* params, const size_t paramLength,
114                  const size_t numValues, const ScriptFieldID** fieldIDs,
115                  const int64_t* values, const int* sizes) :
116     ObjectBase(context), mContext(context), mFunctionID((IDBase*)invokeID), mIsKernel(false),
117     mArgs(nullptr), mNumArg(0),
118     mReturnValue(nullptr), mParamLength(paramLength) {
119     mParams = new uint8_t[mParamLength];
120     memcpy(mParams, params, mParamLength);
121     for (size_t i = 0; i < numValues; i++) {
122         mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
123     }
124 }
125 
~Closure()126 Closure::~Closure() {
127     for (const auto& p : mArgDeps) {
128         auto map = p.second;
129         delete p.second;
130     }
131 
132     for (const auto& p : mGlobalDeps) {
133         auto map = p.second;
134         for (const auto& p1 : *map) {
135             p1.first->decSysRef();
136         }
137         delete p.second;
138     }
139 
140     delete[] mArgs;
141     delete[] mParams;
142 }
143 
setArg(const uint32_t index,const void * value,const int size)144 void Closure::setArg(const uint32_t index, const void* value, const int size) {
145     mArgs[index] = value;
146 }
147 
setGlobal(const ScriptFieldID * fieldID,const int64_t value,const int size)148 void Closure::setGlobal(const ScriptFieldID* fieldID, const int64_t value,
149                         const int size) {
150     mGlobals[fieldID] = make_pair(value, size);
151 }
152 
153 }  // namespace renderscript
154 }  // namespace android
155