blob: 8530fc163cf7476bc66eabbe715bce7b37f26d4f [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) {
19 rsAssert(fieldIDs_length == values_length && values_length == sizes_length &&
20 sizes_length == depClosures_length &&
21 depClosures_length == depFieldIDs_length);
22
23 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));
28}
29
30void rsi_ClosureEval(Context* rsc, RsClosure closure) {
31 ((Closure*)closure)->eval();
32}
33
34void rsi_ClosureSetArg(Context* rsc, RsClosure closure, uint32_t index,
35 uintptr_t value, size_t size) {
36 ((Closure*)closure)->setArg(index, (const void*)value, size);
37}
38
39void rsi_ClosureSetGlobal(Context* rsc, RsClosure closure,
40 RsScriptFieldID fieldID, uintptr_t value,
41 size_t size) {
42 ((Closure*)closure)->setGlobal((const ScriptFieldID*)fieldID,
43 (const void*)value, size);
44}
45
46Closure::Closure(Context* context,
47 const ScriptKernelID* kernelID,
48 Allocation* returnValue,
49 const int numValues,
50 const ScriptFieldID** fieldIDs,
51 const void** values,
52 const size_t* sizes,
53 const Closure** depClosures,
54 const ScriptFieldID** depFieldIDs) :
55 ObjectBase(context), mContext(context), mKernelID((ScriptKernelID*)kernelID),
56 mReturnValue(returnValue) {
57 size_t i;
58
59 for (i = 0; i < (size_t)numValues && fieldIDs[i] == nullptr; i++);
60
61 vector<const void*> args(values, values + i);
62 mArgs.swap(args);
63
64 for (; i < (size_t)numValues; i++) {
65 mGlobals[fieldIDs[i]] = std::make_pair(values[i], sizes[i]);
66 }
67
68 mDependences.insert(depClosures, depClosures + numValues);
69
70 for (i = 0; i < mArgs.size(); i++) {
71 const Closure* dep = depClosures[i];
72 if (dep != nullptr) {
73 auto mapping = mArgDeps[dep];
74 if (mapping == nullptr) {
75 mapping = new map<int, const ObjectBaseRef<ScriptFieldID>*>();
76 mArgDeps[dep] = mapping;
77 }
78 (*mapping)[i] = new ObjectBaseRef<ScriptFieldID>(
79 const_cast<ScriptFieldID*>(depFieldIDs[i]));
80 }
81 }
82
83 for (; i < (size_t)numValues; i++) {
84 const Closure* dep = depClosures[i];
85 if (dep != nullptr) {
86 auto mapping = mGlobalDeps[dep];
87 if (mapping == nullptr) {
88 mapping = new map<const ObjectBaseRef<ScriptFieldID>*,
89 const ObjectBaseRef<ScriptFieldID>*>();
90 mGlobalDeps[dep] = mapping;
91 }
92 (*mapping)[new ObjectBaseRef<ScriptFieldID>(
93 const_cast<ScriptFieldID*>(fieldIDs[i]))] =
94 new ObjectBaseRef<ScriptFieldID>(
95 const_cast<ScriptFieldID*>(depFieldIDs[i]));
96 }
97 }
98}
99
100Closure::~Closure() {
101 for (const auto& p : mArgDeps) {
102 auto map = p.second;
103 for (const auto& p1 : *map) {
104 delete p1.second;
105 }
106 delete p.second;
107 }
108
109 for (const auto& p : mGlobalDeps) {
110 auto map = p.second;
111 for (const auto& p1 : *map) {
112 delete p1.first;
113 delete p1.second;
114 }
115 delete p.second;
116 }
117}
118
119void Closure::eval() {
120 Script *s = mKernelID->mScript;
121
122 for (const auto& p : mGlobals) {
123 const void* value = p.second.first;
124 int size = p.second.second;
125 // We use -1 size to indicate an ObjectBase rather than a primitive type
126 if (size < 0) {
127 s->setVarObj(p.first->mSlot, (ObjectBase*)value);
128 } else {
129 s->setVar(p.first->mSlot, (const void*)&value, size);
130 }
131 }
132
133 s->runForEach(mContext, mKernelID->mSlot, (const Allocation **)(&mArgs[0]),
134 mArgs.size(), mReturnValue, nullptr, 0, nullptr);
135}
136
137void Closure::setArg(const uint32_t index, const void* value, const size_t size) {
138 mArgs[index] = value;
139}
140
141void Closure::setGlobal(const ScriptFieldID* fieldID, const void* value,
142 const size_t size) {
143 mGlobals[fieldID] = std::make_pair(value, size);
144}
145
146} // namespace renderscript
147} // namespace android