blob: 17ef2113f630e44658ae298de9d48ff002abc61b [file] [log] [blame]
Jason Samsdbe66d62012-09-17 13:54:41 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include <time.h>
19
20using namespace android;
21using namespace android::renderscript;
22
23ScriptGroup::ScriptGroup(Context *rsc) : ObjectBase(rsc) {
24}
25
26ScriptGroup::~ScriptGroup() {
27 if (mRSC->mHal.funcs.scriptgroup.destroy) {
28 mRSC->mHal.funcs.scriptgroup.destroy(mRSC, this);
29 }
30
31 for (size_t ct=0; ct < mLinks.size(); ct++) {
32 delete mLinks[ct];
33 }
34}
35
36ScriptGroup::IO::IO(const ScriptKernelID *kid) {
37 mKernel = kid;
38}
39
40ScriptGroup::Node::Node(Script *s) {
41 mScript = s;
42 mSeen = false;
43 mOrder = 0;
44}
45
46ScriptGroup::Node * ScriptGroup::findNode(Script *s) const {
47 //ALOGE("find %p %i", s, (int)mNodes.size());
48 for (size_t ct=0; ct < mNodes.size(); ct++) {
49 Node *n = mNodes[ct];
50 for (size_t ct2=0; ct2 < n->mKernels.size(); ct2++) {
51 if (n->mKernels[ct2]->mScript == s) {
52 return n;
53 }
54 }
55 }
56 return NULL;
57}
58
59bool ScriptGroup::calcOrderRecurse(Node *n, int depth) {
60 n->mSeen = true;
61 if (n->mOrder < depth) {
62 n->mOrder = depth;
63 }
64 bool ret = true;
65 for (size_t ct=0; ct < n->mOutputs.size(); ct++) {
66 const Link *l = n->mOutputs[ct];
67 Node *nt = NULL;
68 if (l->mDstField.get()) {
69 nt = findNode(l->mDstField->mScript);
70 } else {
71 nt = findNode(l->mDstKernel->mScript);
72 }
73 if (nt->mSeen) {
74 return false;
75 }
76 ret &= calcOrderRecurse(nt, n->mOrder + 1);
77 }
78 return ret;
79}
80
Stephen Hinesb0934b62013-07-03 17:27:38 -070081#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
Jason Samsdbe66d62012-09-17 13:54:41 -070082static int CompareNodeForSort(ScriptGroup::Node *const* lhs,
83 ScriptGroup::Node *const* rhs) {
84 if (lhs[0]->mOrder > rhs[0]->mOrder) {
85 return 1;
86 }
87 return 0;
88}
Tim Murray0b575de2013-03-15 15:56:43 -070089#else
90class NodeCompare {
91public:
92 bool operator() (const ScriptGroup::Node* lhs,
93 const ScriptGroup::Node* rhs) {
94 if (lhs->mOrder > rhs->mOrder) {
95 return true;
96 }
97 return false;
98 }
99};
100#endif
Jason Samsdbe66d62012-09-17 13:54:41 -0700101
102bool ScriptGroup::calcOrder() {
103 // Make nodes
104 for (size_t ct=0; ct < mKernels.size(); ct++) {
105 const ScriptKernelID *k = mKernels[ct].get();
106 //ALOGE(" kernel %i, %p s=%p", (int)ct, k, mKernels[ct]->mScript);
107 Node *n = findNode(k->mScript);
108 //ALOGE(" n = %p", n);
109 if (n == NULL) {
110 n = new Node(k->mScript);
111 mNodes.add(n);
112 }
113 n->mKernels.add(k);
114 }
115
116 // add links
117 //ALOGE("link count %i", (int)mLinks.size());
118 for (size_t ct=0; ct < mLinks.size(); ct++) {
119 Link *l = mLinks[ct];
120 //ALOGE("link %i %p", (int)ct, l);
121 Node *n = findNode(l->mSource->mScript);
122 //ALOGE("link n %p", n);
123 n->mOutputs.add(l);
124
125 if (l->mDstKernel.get()) {
126 //ALOGE("l->mDstKernel.get() %p", l->mDstKernel.get());
127 n = findNode(l->mDstKernel->mScript);
128 //ALOGE(" n1 %p", n);
129 n->mInputs.add(l);
130 } else {
131 n = findNode(l->mDstField->mScript);
132 //ALOGE(" n2 %p", n);
133 n->mInputs.add(l);
134 }
135 }
136
137 //ALOGE("node count %i", (int)mNodes.size());
138 // Order nodes
139 bool ret = true;
140 for (size_t ct=0; ct < mNodes.size(); ct++) {
141 Node *n = mNodes[ct];
142 if (n->mInputs.size() == 0) {
143 for (size_t ct2=0; ct2 < mNodes.size(); ct2++) {
144 mNodes[ct2]->mSeen = false;
145 }
146 ret &= calcOrderRecurse(n, 0);
147 }
148 }
149
150 for (size_t ct=0; ct < mKernels.size(); ct++) {
151 const ScriptKernelID *k = mKernels[ct].get();
152 const Node *n = findNode(k->mScript);
153
154 if (k->mHasKernelOutput) {
155 bool found = false;
156 for (size_t ct2=0; ct2 < n->mOutputs.size(); ct2++) {
157 if (n->mOutputs[ct2]->mSource.get() == k) {
158 found = true;
159 break;
160 }
161 }
162 if (!found) {
163 //ALOGE("add io out %p", k);
164 mOutputs.add(new IO(k));
165 }
166 }
167
168 if (k->mHasKernelInput) {
169 bool found = false;
170 for (size_t ct2=0; ct2 < n->mInputs.size(); ct2++) {
171 if (n->mInputs[ct2]->mDstKernel.get() == k) {
172 found = true;
173 break;
174 }
175 }
176 if (!found) {
177 //ALOGE("add io in %p", k);
178 mInputs.add(new IO(k));
179 }
180 }
181 }
182
183 // sort
Stephen Hinesb0934b62013-07-03 17:27:38 -0700184#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
Jason Samsdbe66d62012-09-17 13:54:41 -0700185 mNodes.sort(&CompareNodeForSort);
Tim Murray0b575de2013-03-15 15:56:43 -0700186#else
187 std::sort(mNodes.begin(), mNodes.end(), NodeCompare());
188#endif
Jason Samsdbe66d62012-09-17 13:54:41 -0700189
190 return ret;
191}
192
193ScriptGroup * ScriptGroup::create(Context *rsc,
194 ScriptKernelID ** kernels, size_t kernelsSize,
195 ScriptKernelID ** src, size_t srcSize,
196 ScriptKernelID ** dstK, size_t dstKSize,
197 ScriptFieldID ** dstF, size_t dstFSize,
198 const Type ** type, size_t typeSize) {
199
200 size_t kernelCount = kernelsSize / sizeof(ScriptKernelID *);
201 size_t linkCount = typeSize / sizeof(Type *);
202
203 //ALOGE("ScriptGroup::create kernels=%i links=%i", (int)kernelCount, (int)linkCount);
204
205
206 // Start by counting unique kernel sources
207
208 ScriptGroup *sg = new ScriptGroup(rsc);
209
210 sg->mKernels.reserve(kernelCount);
211 for (size_t ct=0; ct < kernelCount; ct++) {
212 sg->mKernels.add(kernels[ct]);
213 }
214
215 sg->mLinks.reserve(linkCount);
216 for (size_t ct=0; ct < linkCount; ct++) {
217 Link *l = new Link();
218 l->mType = type[ct];
219 l->mSource = src[ct];
220 l->mDstField = dstF[ct];
221 l->mDstKernel = dstK[ct];
222 sg->mLinks.add(l);
223 }
224
225 sg->calcOrder();
226
227 // allocate links
228 for (size_t ct=0; ct < sg->mNodes.size(); ct++) {
229 const Node *n = sg->mNodes[ct];
230 for (size_t ct2=0; ct2 < n->mOutputs.size(); ct2++) {
231 Link *l = n->mOutputs[ct2];
232 if (l->mAlloc.get()) {
233 continue;
234 }
235 const ScriptKernelID *k = l->mSource.get();
236
237 Allocation * alloc = Allocation::createAllocation(rsc,
238 l->mType.get(), RS_ALLOCATION_USAGE_SCRIPT);
239 l->mAlloc = alloc;
240
241 for (size_t ct3=ct2+1; ct3 < n->mOutputs.size(); ct3++) {
242 if (n->mOutputs[ct3]->mSource.get() == l->mSource.get()) {
243 n->mOutputs[ct3]->mAlloc = alloc;
244 }
245 }
246 }
247 }
248
249 if (rsc->mHal.funcs.scriptgroup.init) {
250 rsc->mHal.funcs.scriptgroup.init(rsc, sg);
251 }
Stephen Hines61c86952013-04-09 17:34:43 -0700252 sg->incUserRef();
Jason Samsdbe66d62012-09-17 13:54:41 -0700253 return sg;
254}
255
256void ScriptGroup::setInput(Context *rsc, ScriptKernelID *kid, Allocation *a) {
257 for (size_t ct=0; ct < mInputs.size(); ct++) {
258 if (mInputs[ct]->mKernel == kid) {
259 mInputs[ct]->mAlloc = a;
260
261 if (rsc->mHal.funcs.scriptgroup.setInput) {
262 rsc->mHal.funcs.scriptgroup.setInput(rsc, this, kid, a);
263 }
264 return;
265 }
266 }
267 rsAssert(!"ScriptGroup:setInput kid not found");
268}
269
270void ScriptGroup::setOutput(Context *rsc, ScriptKernelID *kid, Allocation *a) {
271 for (size_t ct=0; ct < mOutputs.size(); ct++) {
272 if (mOutputs[ct]->mKernel == kid) {
273 mOutputs[ct]->mAlloc = a;
274
275 if (rsc->mHal.funcs.scriptgroup.setOutput) {
276 rsc->mHal.funcs.scriptgroup.setOutput(rsc, this, kid, a);
277 }
278 return;
279 }
280 }
281 rsAssert(!"ScriptGroup:setOutput kid not found");
282}
283
284void ScriptGroup::execute(Context *rsc) {
285 //ALOGE("ScriptGroup::execute");
286 if (rsc->mHal.funcs.scriptgroup.execute) {
287 rsc->mHal.funcs.scriptgroup.execute(rsc, this);
288 return;
289 }
290
291 for (size_t ct=0; ct < mNodes.size(); ct++) {
292 Node *n = mNodes[ct];
293 //ALOGE("node %i, order %i, in %i out %i", (int)ct, n->mOrder, (int)n->mInputs.size(), (int)n->mOutputs.size());
294
295 for (size_t ct2=0; ct2 < n->mKernels.size(); ct2++) {
296 const ScriptKernelID *k = n->mKernels[ct2];
297 Allocation *ain = NULL;
298 Allocation *aout = NULL;
299
300 for (size_t ct3=0; ct3 < n->mInputs.size(); ct3++) {
301 if (n->mInputs[ct3]->mDstKernel.get() == k) {
302 ain = n->mInputs[ct3]->mAlloc.get();
303 //ALOGE(" link in %p", ain);
304 }
305 }
306 for (size_t ct3=0; ct3 < mInputs.size(); ct3++) {
307 if (mInputs[ct3]->mKernel == k) {
308 ain = mInputs[ct3]->mAlloc.get();
309 //ALOGE(" io in %p", ain);
310 }
311 }
312
313 for (size_t ct3=0; ct3 < n->mOutputs.size(); ct3++) {
314 if (n->mOutputs[ct3]->mSource.get() == k) {
315 aout = n->mOutputs[ct3]->mAlloc.get();
316 //ALOGE(" link out %p", aout);
317 }
318 }
319 for (size_t ct3=0; ct3 < mOutputs.size(); ct3++) {
320 if (mOutputs[ct3]->mKernel == k) {
321 aout = mOutputs[ct3]->mAlloc.get();
322 //ALOGE(" io out %p", aout);
323 }
324 }
325
326 n->mScript->runForEach(rsc, k->mSlot, ain, aout, NULL, 0);
327 }
328
329 }
330
331}
332
333void ScriptGroup::serialize(Context *rsc, OStream *stream) const {
334}
335
336RsA3DClassID ScriptGroup::getClassId() const {
337 return RS_A3D_CLASS_ID_SCRIPT_GROUP;
338}
339
340ScriptGroup::Link::Link() {
341}
342
343ScriptGroup::Link::~Link() {
344}
345
346namespace android {
347namespace renderscript {
348
349
350RsScriptGroup rsi_ScriptGroupCreate(Context *rsc,
351 RsScriptKernelID * kernels, size_t kernelsSize,
352 RsScriptKernelID * src, size_t srcSize,
353 RsScriptKernelID * dstK, size_t dstKSize,
354 RsScriptFieldID * dstF, size_t dstFSize,
355 const RsType * type, size_t typeSize) {
356
357
358 return ScriptGroup::create(rsc,
359 (ScriptKernelID **) kernels, kernelsSize,
360 (ScriptKernelID **) src, srcSize,
361 (ScriptKernelID **) dstK, dstKSize,
362 (ScriptFieldID **) dstF, dstFSize,
363 (const Type **) type, typeSize);
364}
365
366
367void rsi_ScriptGroupSetInput(Context *rsc, RsScriptGroup sg, RsScriptKernelID kid,
368 RsAllocation alloc) {
369 //ALOGE("rsi_ScriptGroupSetInput");
370 ScriptGroup *s = (ScriptGroup *)sg;
371 s->setInput(rsc, (ScriptKernelID *)kid, (Allocation *)alloc);
372}
373
374void rsi_ScriptGroupSetOutput(Context *rsc, RsScriptGroup sg, RsScriptKernelID kid,
375 RsAllocation alloc) {
376 //ALOGE("rsi_ScriptGroupSetOutput");
377 ScriptGroup *s = (ScriptGroup *)sg;
378 s->setOutput(rsc, (ScriptKernelID *)kid, (Allocation *)alloc);
379}
380
381void rsi_ScriptGroupExecute(Context *rsc, RsScriptGroup sg) {
382 //ALOGE("rsi_ScriptGroupExecute");
383 ScriptGroup *s = (ScriptGroup *)sg;
384 s->execute(rsc);
385}
386
387}
388}
389