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 using namespace android;
21 using namespace android::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 
149 namespace android {
150 namespace renderscript {
151 
rsi_ScriptKernelIDCreate(Context * rsc,RsScript vs,int slot,int sig)152 RsScriptKernelID rsi_ScriptKernelIDCreate(Context *rsc, RsScript vs, int slot, int sig) {
153     ScriptKernelID *kid = new ScriptKernelID(rsc, (Script *)vs, slot, sig);
154     kid->incUserRef();
155     return kid;
156 }
157 
rsi_ScriptInvokeIDCreate(Context * rsc,RsScript vs,uint32_t slot)158 RsScriptInvokeID rsi_ScriptInvokeIDCreate(Context *rsc, RsScript vs, uint32_t slot) {
159     ScriptInvokeID *iid = new ScriptInvokeID(rsc, (Script *)vs, slot);
160     iid->incUserRef();
161     return iid;
162 }
163 
rsi_ScriptFieldIDCreate(Context * rsc,RsScript vs,int slot)164 RsScriptFieldID rsi_ScriptFieldIDCreate(Context *rsc, RsScript vs, int slot) {
165     ScriptFieldID *fid = new ScriptFieldID(rsc, (Script *)vs, slot);
166     fid->incUserRef();
167     return fid;
168 }
169 
rsi_ScriptBindAllocation(Context * rsc,RsScript vs,RsAllocation va,uint32_t slot)170 void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint32_t slot) {
171     Script *s = static_cast<Script *>(vs);
172     Allocation *a = static_cast<Allocation *>(va);
173     s->setSlot(slot, a);
174 }
175 
rsi_ScriptSetTimeZone(Context * rsc,RsScript vs,const char * timeZone,size_t length)176 void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) {
177     // We unfortunately need to make a new copy of the string, since it is
178     // not nullptr-terminated. We then use setenv(), which properly handles
179     // freeing/duplicating the actual string for the environment.
180     char *tz = (char *) malloc(length + 1);
181     if (!tz) {
182         ALOGE("Couldn't allocate memory for timezone buffer");
183         return;
184     }
185     strncpy(tz, timeZone, length);
186     tz[length] = '\0';
187     if (setenv("TZ", tz, 1) == 0) {
188         tzset();
189     } else {
190         ALOGE("Error setting timezone");
191     }
192     free(tz);
193 }
194 
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)195 void rsi_ScriptForEachMulti(Context *rsc, RsScript vs, uint32_t slot,
196                             RsAllocation *vains, size_t inLen,
197                             RsAllocation vaout, const void *params,
198                             size_t paramLen, const RsScriptCall *sc,
199                             size_t scLen) {
200 
201     Script      *s    = static_cast<Script *>(vs);
202     Allocation **ains = (Allocation**)(vains);
203 
204     s->runForEach(rsc, slot,
205                   const_cast<const Allocation **>(ains), inLen,
206                   static_cast<Allocation *>(vaout), params, paramLen, sc);
207 
208 }
209 
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)210 void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
211                        RsAllocation vain, RsAllocation vaout,
212                        const void *params, size_t paramLen,
213                        const RsScriptCall *sc, size_t scLen) {
214 
215     if (vain == nullptr) {
216         rsi_ScriptForEachMulti(rsc, vs, slot, nullptr, 0, vaout, params, paramLen,
217                                sc, scLen);
218     } else {
219         RsAllocation ains[1] = {vain};
220 
221         rsi_ScriptForEachMulti(rsc, vs, slot, ains,
222                                sizeof(ains) / sizeof(RsAllocation), vaout,
223                                params, paramLen, sc, scLen);
224     }
225 }
226 
rsi_ScriptInvoke(Context * rsc,RsScript vs,uint32_t slot)227 void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) {
228     Script *s = static_cast<Script *>(vs);
229     s->Invoke(rsc, slot, nullptr, 0);
230 }
231 
232 
rsi_ScriptInvokeData(Context * rsc,RsScript vs,uint32_t slot,void * data)233 void rsi_ScriptInvokeData(Context *rsc, RsScript vs, uint32_t slot, void *data) {
234     Script *s = static_cast<Script *>(vs);
235     s->Invoke(rsc, slot, nullptr, 0);
236 }
237 
rsi_ScriptInvokeV(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len)238 void rsi_ScriptInvokeV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
239     Script *s = static_cast<Script *>(vs);
240     s->Invoke(rsc, slot, data, len);
241 }
242 
rsi_ScriptSetVarI(Context * rsc,RsScript vs,uint32_t slot,int value)243 void rsi_ScriptSetVarI(Context *rsc, RsScript vs, uint32_t slot, int value) {
244     Script *s = static_cast<Script *>(vs);
245     s->setVar(slot, &value, sizeof(value));
246 }
247 
rsi_ScriptSetVarObj(Context * rsc,RsScript vs,uint32_t slot,RsObjectBase value)248 void rsi_ScriptSetVarObj(Context *rsc, RsScript vs, uint32_t slot, RsObjectBase value) {
249     Script *s = static_cast<Script *>(vs);
250     ObjectBase *o = static_cast<ObjectBase *>(value);
251     s->setVarObj(slot, o);
252 }
253 
rsi_ScriptSetVarJ(Context * rsc,RsScript vs,uint32_t slot,int64_t value)254 void rsi_ScriptSetVarJ(Context *rsc, RsScript vs, uint32_t slot, int64_t value) {
255     Script *s = static_cast<Script *>(vs);
256     s->setVar(slot, &value, sizeof(value));
257 }
258 
rsi_ScriptSetVarF(Context * rsc,RsScript vs,uint32_t slot,float value)259 void rsi_ScriptSetVarF(Context *rsc, RsScript vs, uint32_t slot, float value) {
260     Script *s = static_cast<Script *>(vs);
261     s->setVar(slot, &value, sizeof(value));
262 }
263 
rsi_ScriptSetVarD(Context * rsc,RsScript vs,uint32_t slot,double value)264 void rsi_ScriptSetVarD(Context *rsc, RsScript vs, uint32_t slot, double value) {
265     Script *s = static_cast<Script *>(vs);
266     s->setVar(slot, &value, sizeof(value));
267 }
268 
rsi_ScriptSetVarV(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len)269 void rsi_ScriptSetVarV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) {
270     Script *s = static_cast<Script *>(vs);
271     s->setVar(slot, data, len);
272 }
273 
rsi_ScriptGetVarV(Context * rsc,RsScript vs,uint32_t slot,void * data,size_t len)274 void rsi_ScriptGetVarV(Context *rsc, RsScript vs, uint32_t slot, void *data, size_t len) {
275     Script *s = static_cast<Script *>(vs);
276     s->getVar(slot, data, len);
277 }
278 
rsi_ScriptSetVarVE(Context * rsc,RsScript vs,uint32_t slot,const void * data,size_t len,RsElement ve,const uint32_t * dims,size_t dimLen)279 void rsi_ScriptSetVarVE(Context *rsc, RsScript vs, uint32_t slot,
280                         const void *data, size_t len, RsElement ve,
281                         const uint32_t *dims, size_t dimLen) {
282     Script *s = static_cast<Script *>(vs);
283     Element *e = static_cast<Element *>(ve);
284     s->setVar(slot, data, len, e, dims, dimLen);
285 }
286 
287 }
288 }
289