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,uintptr_t * values,size_t values_length,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 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
rsi_InvokeClosureCreate(Context * context,RsScriptInvokeID invokeID,const void * params,const size_t paramLength,const RsScriptFieldID * fieldIDs,const size_t fieldIDs_length,const uintptr_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 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
rsi_ClosureSetArg(Context * rsc,RsClosure closure,uint32_t index,uintptr_t value,size_t size)46 void 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
rsi_ClosureSetGlobal(Context * rsc,RsClosure closure,RsScriptFieldID fieldID,uintptr_t value,size_t size)51 void 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
Closure(Context * context,const ScriptKernelID * kernelID,Allocation * returnValue,const int numValues,const ScriptFieldID ** fieldIDs,const void ** 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 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
Closure(Context * context,const ScriptInvokeID * invokeID,const void * params,const size_t paramLength,const size_t numValues,const ScriptFieldID ** fieldIDs,const void ** values,const int * sizes)110 Closure::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), mParamLength(paramLength) {
117 mParams = new uint8_t[mParamLength];
118 memcpy(mParams, params, mParamLength);
119 for (size_t i = 0; i < numValues; i++) {
120 mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
121 }
122 }
123
~Closure()124 Closure::~Closure() {
125 for (const auto& p : mArgDeps) {
126 auto map = p.second;
127 delete p.second;
128 }
129
130 for (const auto& p : mGlobalDeps) {
131 auto map = p.second;
132 for (const auto& p1 : *map) {
133 p1.first->decSysRef();
134 }
135 delete p.second;
136 }
137
138 delete[] mArgs;
139 delete[] mParams;
140 }
141
setArg(const uint32_t index,const void * value,const size_t size)142 void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
143 mArgs[index] = value;
144 }
145
setGlobal(const ScriptFieldID * fieldID,const void * value,const int size)146 void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
147 const int size) {
148 mGlobals[fieldID] = make_pair(value, size);
149 }
150
151 } // namespace renderscript
152 } // namespace android
153