1 /*
2  * Copyright (C) 2009-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 
20 namespace android {
21 namespace renderscript {
22 
Script(Context * rsc)23 Script::Script(Context *rsc) : ObjectBase(rsc) {
24     memset(&mEnviroment, 0, sizeof(mEnviroment));
25     memset(&mHal, 0, sizeof(mHal));
26 
27     mSlots = nullptr;
28     mTypes = nullptr;
29     mInitialized = false;
30     mHasObjectSlots = false;
31     mApiLevel = 0;
32 }
33 
~Script()34 Script::~Script() {
35     if (mSlots) {
36         delete [] mSlots;
37         mSlots = nullptr;
38     }
39     if (mTypes) {
40         delete [] mTypes;
41         mTypes = nullptr;
42     }
43 }
44 
setSlot(uint32_t slot,Allocation * a)45 void Script::setSlot(uint32_t slot, Allocation *a) {
46     //ALOGE("setSlot %i %p", slot, a);
47     if (slot >= mHal.info.exportedVariableCount) {
48         ALOGE("Script::setSlot unable to set allocation, invalid slot index");
49         return;
50     }
51 
52     if (mRSC->hadFatalError()) return;
53 
54     mSlots[slot].set(a);
55     mHasObjectSlots = true;
56     mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, a);
57 }
58 
setVar(uint32_t slot,const void * val,size_t len)59 void Script::setVar(uint32_t slot, const void *val, size_t len) {
60     //ALOGE("setVar %i %p %i", slot, val, len);
61     if (slot >= mHal.info.exportedVariableCount) {
62         ALOGE("Script::setVar unable to set allocation, invalid slot index");
63         return;
64     }
65     if (mRSC->hadFatalError()) return;
66 
67     mRSC->mHal.funcs.script.setGlobalVar(mRSC, this, slot, (void *)val, len);
68 }
69 
getVar(uint32_t slot,const void * val,size_t len)70 void Script::getVar(uint32_t slot, const void *val, size_t len) {
71     //ALOGE("getVar %i %p %i", slot, val, len);
72     if (slot >= mHal.info.exportedVariableCount) {
73         ALOGE("Script::getVar unable to set allocation, invalid slot index: "
74               "%u >= %zu", slot, mHal.info.exportedVariableCount);
75         return;
76     }
77     if (mRSC->hadFatalError()) return;
78 
79     mRSC->mHal.funcs.script.getGlobalVar(mRSC, this, slot, (void *)val, len);
80 }
81 
setVar(uint32_t slot,const void * val,size_t len,Element * e,const uint32_t * dims,size_t dimLen)82 void Script::setVar(uint32_t slot, const void *val, size_t len, Element *e,
83                     const uint32_t *dims, size_t dimLen) {
84     if (slot >= mHal.info.exportedVariableCount) {
85         ALOGE("Script::setVar unable to set allocation, invalid slot index: "
86               "%u >= %zu", slot, mHal.info.exportedVariableCount);
87         return;
88     }
89     if (mRSC->hadFatalError()) return;
90 
91     mRSC->mHal.funcs.script.setGlobalVarWithElemDims(mRSC, this, slot,
92             (void *)val, len, e, dims, dimLen);
93 }
94 
setVarObj(uint32_t slot,ObjectBase * val)95 void Script::setVarObj(uint32_t slot, ObjectBase *val) {
96     //ALOGE("setVarObj %i %p", slot, val);
97     if (slot >= mHal.info.exportedVariableCount) {
98         ALOGE("Script::setVarObj unable to set allocation, invalid slot index: "
99               "%u >= %zu", slot, mHal.info.exportedVariableCount);
100         return;
101     }
102     if (mRSC->hadFatalError()) return;
103 
104     mHasObjectSlots = true;
105     mRSC->mHal.funcs.script.setGlobalObj(mRSC, this, slot, val);
106 }
107 
callUpdateCacheObject(const Context * rsc,void * dstObj) const108 void Script::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
109     if (rsc->mHal.funcs.script.updateCachedObject != nullptr) {
110         rsc->mHal.funcs.script.updateCachedObject(rsc, this, (rs_script *)dstObj);
111     } else {
112         *((const void **)dstObj) = this;
113     }
114 }
115 
freeChildren()116 bool Script::freeChildren() {
117     incSysRef();
118     mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
119     return decSysRef();
120 }
121 
ScriptKernelID(Context * rsc,Script * s,int slot,int sig)122 ScriptKernelID::ScriptKernelID(Context *rsc, Script *s, int slot, int sig)
123         : IDBase(rsc, s, slot) {
124     mHasKernelInput = (sig & 1) != 0;
125     mHasKernelOutput = (sig & 2) != 0;
126 }
127 
getClassId() const128 RsA3DClassID ScriptKernelID::getClassId() const {
129     return RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID;
130 }
131 
ScriptInvokeID(Context * rsc,Script * s,int slot)132 ScriptInvokeID::ScriptInvokeID(Context *rsc, Script *s, int slot)
133     : IDBase(rsc, s, slot) {
134 }
135 
getClassId() const136 RsA3DClassID ScriptInvokeID::getClassId() const {
137     return RS_A3D_CLASS_ID_SCRIPT_INVOKE_ID;
138 }
139 
ScriptFieldID(Context * rsc,Script * s,int slot)140 ScriptFieldID::ScriptFieldID(Context *rsc, Script *s, int slot) :
141     IDBase(rsc, s, slot) {
142 }
143 
getClassId() const144 RsA3DClassID ScriptFieldID::getClassId() const {
145     return RS_A3D_CLASS_ID_SCRIPT_FIELD_ID;
146 }
147 
148 
rsi_ScriptKernelIDCreate(Context * rsc,RsScript vs,int slot,int sig)149 RsScriptKernelID rsi_ScriptKernelIDCreate(Context *rsc, RsScript vs, int slot, int sig) {
150     ScriptKernelID *kid = new ScriptKernelID(rsc, (Script *)vs, slot, sig);
151     kid->incUserRef();
152     return kid;
153 }
154 
rsi_ScriptInvokeIDCreate(Context * rsc,RsScript vs,uint32_t slot)155 RsScriptInvokeID rsi_ScriptInvokeIDCreate(Context *rsc, RsScript vs, uint32_t slot) {
156     ScriptInvokeID *iid = new ScriptInvokeID(rsc, (Script *)vs, slot);
157     iid->incUserRef();
158     return iid;
159 }
160 
rsi_ScriptFieldIDCreate(Context * rsc,RsScript vs,int slot)161 RsScriptFieldID rsi_ScriptFieldIDCreate(Context *rsc, RsScript vs, int slot) {
162     ScriptFieldID *fid = new ScriptFieldID(rsc, (Script *)vs, slot);
163     fid->incUserRef();
164     return fid;
165 }
166 
rsi_ScriptBindAllocation(Context * rsc,RsScript vs,RsAllocation va,uint32_t slot)167 void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint32_t slot) {
168     Script *s = static_cast<Script *>(vs);
169     Allocation *a = static_cast<Allocation *>(va);
170     s->setSlot(slot, a);
171 }
172 
rsi_ScriptSetTimeZone(Context * rsc,RsScript vs,const char * timeZone,size_t length)173 void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) {
174     // We unfortunately need to make a new copy of the string, since it is
175     // not nullptr-terminated. We then use setenv(), which properly handles
176     // freeing/duplicating the actual string for the environment.
177     char *tz = (char *) malloc(length + 1);
178     if (!tz) {
179         ALOGE("Couldn't allocate memory for timezone buffer");
180         return;
181     }
182     strncpy(tz, timeZone, length);
183     tz[length] = '\0';
184     if (setenv("TZ", tz, 1) == 0) {
185         tzset();
186     } else {
187         ALOGE("Error setting timezone");
188     }
189     free(tz);
190 }
191 
rsi_ScriptForEachMulti(Context * rsc,RsScript vs,uint32_t slot,RsAllocation * vains,size_t inLen,RsAllocation vaout,const void * params,size_t paramLen,const RsScriptCall * sc,size_t scLen)192 void rsi_ScriptForEachMulti(Context *rsc, RsScript vs, uint32_t slot,
193                             RsAllocation *vains, size_t inLen,
194                             RsAllocation vaout, const void *params,
195                             size_t paramLen, const RsScriptCall *sc,
196                             size_t scLen) {
197 
198     Script      *s    = static_cast<Script *>(vs);
199     Allocation **ains = (Allocation**)(vains);
200 
201     s->runForEach(rsc, slot,
202                   const_cast<const Allocation **>(ains), inLen,
203                   static_cast<Allocation *>(vaout), params, paramLen, sc);
204 
205 }
206 
rsi_ScriptForEach(Context * rsc,RsScript vs,uint32_t slot,RsAllocation vain,RsAllocation vaout,const void * params,size_t paramLen,const RsScriptCall * sc,size_t scLen)207 void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
208                        RsAllocation vain, RsAllocation vaout,
209                        const void *params, size_t paramLen,
210                        const RsScriptCall *sc, size_t scLen) {
211 
212     if (vain == nullptr) {
213         rsi_ScriptForEachMulti(rsc, vs, slot, nullptr, 0, vaout, params, paramLen,
214                                sc, scLen);
215     } else {
216         RsAllocation ains[1] = {vain};
217 
218         rsi_ScriptForEachMulti(rsc, vs, slot, ains,
219                                sizeof(ains) / sizeof(RsAllocation), vaout,
220                                params, paramLen, sc, scLen);
221     }
222 }
223 
rsi_ScriptReduce(Context * rsc,RsScript vs,uint32_t slot,RsAllocation * vains,size_t inLen,RsAllocation vaout,const RsScriptCall * sc,size_t scLen)224 void rsi_ScriptReduce(Context *rsc, RsScript vs, uint32_t slot,
225                       RsAllocation *vains, size_t inLen,
226                       RsAllocation vaout, const RsScriptCall *sc,
227                       size_t scLen) {
228   Script *s = static_cast<Script *>(vs);
229   Allocation **ains = (Allocation**)(vains);
230 
231   s->runReduce(rsc, slot,
232                const_cast<const Allocation **>(ains), inLen,
233                static_cast<Allocation *>(vaout), sc);
234 }
235 
rsi_ScriptInvoke(Context * rsc,RsScript vs,uint32_t slot)236 void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) {
237     Script *s = static_cast<Script *>(vs);
238     s->Invoke(rsc, slot, nullptr, 0);
239 }
240 
241 
rsi_ScriptInvokeData(Context * rsc,RsScript vs,uint32_t slot,void * data)242 void rsi_ScriptInvokeData(Context *rsc, RsScript vs, uint32_t slot, void *data) {
243     Script *s = static_cast<Script *>(vs);
244     s->Invoke(rsc, slot, nullptr, 0);
245 }
246 
rsi_ScriptInvokeV(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len)247 void rsi_ScriptInvokeV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
248     Script *s = static_cast<Script *>(vs);
249     s->Invoke(rsc, slot, data, len);
250 }
251 
rsi_ScriptSetVarI(Context * rsc,RsScript vs,uint32_t slot,int value)252 void rsi_ScriptSetVarI(Context *rsc, RsScript vs, uint32_t slot, int value) {
253     Script *s = static_cast<Script *>(vs);
254     s->setVar(slot, &value, sizeof(value));
255 }
256 
rsi_ScriptSetVarObj(Context * rsc,RsScript vs,uint32_t slot,RsObjectBase value)257 void rsi_ScriptSetVarObj(Context *rsc, RsScript vs, uint32_t slot, RsObjectBase value) {
258     Script *s = static_cast<Script *>(vs);
259     ObjectBase *o = static_cast<ObjectBase *>(value);
260     s->setVarObj(slot, o);
261 }
262 
rsi_ScriptSetVarJ(Context * rsc,RsScript vs,uint32_t slot,int64_t value)263 void rsi_ScriptSetVarJ(Context *rsc, RsScript vs, uint32_t slot, int64_t value) {
264     Script *s = static_cast<Script *>(vs);
265     s->setVar(slot, &value, sizeof(value));
266 }
267 
rsi_ScriptSetVarF(Context * rsc,RsScript vs,uint32_t slot,float value)268 void rsi_ScriptSetVarF(Context *rsc, RsScript vs, uint32_t slot, float value) {
269     Script *s = static_cast<Script *>(vs);
270     s->setVar(slot, &value, sizeof(value));
271 }
272 
rsi_ScriptSetVarD(Context * rsc,RsScript vs,uint32_t slot,double value)273 void rsi_ScriptSetVarD(Context *rsc, RsScript vs, uint32_t slot, double value) {
274     Script *s = static_cast<Script *>(vs);
275     s->setVar(slot, &value, sizeof(value));
276 }
277 
rsi_ScriptSetVarV(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len)278 void rsi_ScriptSetVarV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
279     Script *s = static_cast<Script *>(vs);
280     s->setVar(slot, data, len);
281 }
282 
rsi_ScriptGetVarV(Context * rsc,RsScript vs,uint32_t slot,void * data,size_t len)283 void rsi_ScriptGetVarV(Context *rsc, RsScript vs, uint32_t slot, void *data, size_t len) {
284     Script *s = static_cast<Script *>(vs);
285     s->getVar(slot, data, len);
286 }
287 
rsi_ScriptSetVarVE(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len,RsElement ve,const uint32_t * dims,size_t dimLen)288 void rsi_ScriptSetVarVE(Context *rsc, RsScript vs, uint32_t slot,
289                         const void *data, size_t len, RsElement ve,
290                         const uint32_t *dims, size_t dimLen) {
291     Script *s = static_cast<Script *>(vs);
292     Element *e = static_cast<Element *>(ve);
293     s->setVar(slot, data, len, e, dims, dimLen);
294 }
295 
296 } // namespace renderscript
297 } // namespace android
298