blob: 8fb12b81c3a698785809b5e3ee1b2030163edb7d [file] [log] [blame]
Yang Ni1ffd86b2015-01-07 09:16:40 -08001#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) {
Yang Niff2bb542015-02-02 14:33:47 -080019 rsAssert(fieldIDs_length == values_length && values_length == sizes_length &&
20 sizes_length == depClosures_length &&
21 depClosures_length == depFieldIDs_length);
Yang Ni1ffd86b2015-01-07 09:16:40 -080022
Yang Niff2bb542015-02-02 14:33:47 -080023 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));
Yang Ni1ffd86b2015-01-07 09:16:40 -080028}
29
Yang Nieb9aa672015-01-27 14:32:25 -080030RsClosure 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
Yang Niff2bb542015-02-02 14:33:47 -080042#if 0
Yang Ni1ffd86b2015-01-07 09:16:40 -080043void rsi_ClosureEval(Context* rsc, RsClosure closure) {
Yang Nieb9aa672015-01-27 14:32:25 -080044 ((Closure*)closure)->eval();
Yang Ni1ffd86b2015-01-07 09:16:40 -080045}
Yang Niff2bb542015-02-02 14:33:47 -080046#endif
Yang Ni1ffd86b2015-01-07 09:16:40 -080047
48void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
49 uintptr_t value, size_t size) {
Yang Nieb9aa672015-01-27 14:32:25 -080050 ((Closure*)closure)->setArg(index, (const void*)value, size);
Yang Ni1ffd86b2015-01-07 09:16:40 -080051}
52
53void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
54 RsScriptFieldID fieldID, uintptr_t value,
55 size_t size) {
Yang Nieb9aa672015-01-27 14:32:25 -080056 ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
57 (const void*)value, size);
Yang Ni1ffd86b2015-01-07 09:16:40 -080058}
59
60Closure::Closure(Context* context,
61 const ScriptKernelID* kernelID,
62 Allocation* returnValue,
63 const int numValues,
64 const ScriptFieldID** fieldIDs,
65 const void** values,
66 const size_t* sizes,
67 const Closure** depClosures,
68 const ScriptFieldID** depFieldIDs) :
Yang Ni062c2872015-02-20 15:20:00 -080069 ObjectBase(context), mContext(context), mFunctionID((IDBase*)kernelID),
70 mIsKernel(true), mReturnValue(returnValue), mParams(nullptr),
Yang Nieb9aa672015-01-27 14:32:25 -080071 mParamLength(0) {
Yang Niff2bb542015-02-02 14:33:47 -080072 size_t i;
Yang Ni1ffd86b2015-01-07 09:16:40 -080073
Yang Niff2bb542015-02-02 14:33:47 -080074 for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++);
Yang Ni1ffd86b2015-01-07 09:16:40 -080075
Yang Niff2bb542015-02-02 14:33:47 -080076 mNumArg = i;
77 mArgs = new const void*[mNumArg];
78 memcpy(mArgs, values, sizeof(const void*) * mNumArg);
Yang Ni1ffd86b2015-01-07 09:16:40 -080079
Yang Niff2bb542015-02-02 14:33:47 -080080 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);
Yang Ni1ffd86b2015-01-07 09:16:40 -080085 }
Yang Ni1ffd86b2015-01-07 09:16:40 -080086
Yang Niff2bb542015-02-02 14:33:47 -080087 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++;
Yang Ni1ffd86b2015-01-07 09:16:40 -080093 }
Yang Niff2bb542015-02-02 14:33:47 -080094
Yang Niff2bb542015-02-02 14:33:47 -080095 for (i = 0; i < mNumArg; i++) {
96 const Closure* dep = depClosures[i];
97 if (dep != nullptr) {
98 auto mapping = mArgDeps[dep];
99 if (mapping == nullptr) {
100 mapping = new Map<int, const ObjectBaseRef<ScriptFieldID>*>();
101 mArgDeps[dep] = mapping;
102 }
103 (*mapping)[i] = new ObjectBaseRef<ScriptFieldID>(
104 const_cast<ScriptFieldID*>(depFieldIDs[i]));
105 }
106 }
107
108 for (; i < (size_t)numValues; i++) {
109 const Closure* dep = depClosures[i];
110 if (dep != nullptr) {
111 auto mapping = mGlobalDeps[dep];
112 if (mapping == nullptr) {
113 mapping = new Map<const ObjectBaseRef<ScriptFieldID>*,
114 const ObjectBaseRef<ScriptFieldID>*>();
115 mGlobalDeps[dep] = mapping;
116 }
117 (*mapping)[new ObjectBaseRef<ScriptFieldID>(
118 const_cast<ScriptFieldID*>(fieldIDs[i]))] =
119 new ObjectBaseRef<ScriptFieldID>(
120 const_cast<ScriptFieldID*>(depFieldIDs[i]));
121 }
122 }
Yang Ni1ffd86b2015-01-07 09:16:40 -0800123}
124
Yang Nieb9aa672015-01-27 14:32:25 -0800125Closure::Closure(Context* context, const ScriptInvokeID* invokeID,
126 const void* params, const size_t paramLength,
127 const size_t numValues, const ScriptFieldID** fieldIDs,
128 const void** values, const size_t* sizes) :
Yang Ni062c2872015-02-20 15:20:00 -0800129 ObjectBase(context), mContext(context), mFunctionID((IDBase*)invokeID), mIsKernel(false),
Yang Nieb9aa672015-01-27 14:32:25 -0800130 mReturnValue(nullptr), mParams(params), mParamLength(paramLength) {
131 for (size_t i = 0; i < numValues; i++) {
Yang Niff2bb542015-02-02 14:33:47 -0800132 mGlobals[fieldIDs[i]] = make_pair(values[i], sizes[i]);
Yang Ni1ffd86b2015-01-07 09:16:40 -0800133 }
Yang Nieb9aa672015-01-27 14:32:25 -0800134}
Yang Ni1ffd86b2015-01-07 09:16:40 -0800135
Yang Nieb9aa672015-01-27 14:32:25 -0800136Closure::~Closure() {
137 for (const auto& p : mArgDeps) {
138 auto map = p.second;
139 for (const auto& p1 : *map) {
140 delete p1.second;
141 }
142 delete p.second;
Yang Ni1ffd86b2015-01-07 09:16:40 -0800143 }
Yang Nieb9aa672015-01-27 14:32:25 -0800144
145 for (const auto& p : mGlobalDeps) {
146 auto map = p.second;
147 for (const auto& p1 : *map) {
148 delete p1.first;
149 delete p1.second;
150 }
151 delete p.second;
152 }
Yang Ni1ffd86b2015-01-07 09:16:40 -0800153
Yang Niff2bb542015-02-02 14:33:47 -0800154 delete[] mArgs;
Yang Ni1ffd86b2015-01-07 09:16:40 -0800155}
156
157void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
Yang Nieb9aa672015-01-27 14:32:25 -0800158 mArgs[index] = value;
Yang Ni1ffd86b2015-01-07 09:16:40 -0800159}
160
161void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
162 const size_t size) {
Yang Niff2bb542015-02-02 14:33:47 -0800163 mGlobals[fieldID] = make_pair(value, size);
Yang Ni1ffd86b2015-01-07 09:16:40 -0800164}
165
166} // namespace renderscript
167} // namespace android