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 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 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 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 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 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 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 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 108 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 116 bool Script::freeChildren() { 117 incSysRef(); 118 mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this); 119 return decSysRef(); 120 } 121 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 128 RsA3DClassID ScriptKernelID::getClassId() const { 129 return RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID; 130 } 131 132 ScriptInvokeID::ScriptInvokeID(Context *rsc, Script *s, int slot) 133 : IDBase(rsc, s, slot) { 134 } 135 136 RsA3DClassID ScriptInvokeID::getClassId() const { 137 return RS_A3D_CLASS_ID_SCRIPT_INVOKE_ID; 138 } 139 140 ScriptFieldID::ScriptFieldID(Context *rsc, Script *s, int slot) : 141 IDBase(rsc, s, slot) { 142 } 143 144 RsA3DClassID ScriptFieldID::getClassId() const { 145 return RS_A3D_CLASS_ID_SCRIPT_FIELD_ID; 146 } 147 148 149 namespace android { 150 namespace renderscript { 151 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 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 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 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 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 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 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 227 void rsi_ScriptReduce(Context *rsc, RsScript vs, uint32_t slot, 228 RsAllocation *vains, size_t inLen, 229 RsAllocation vaout, const RsScriptCall *sc, 230 size_t scLen) { 231 Script *s = static_cast<Script *>(vs); 232 Allocation **ains = (Allocation**)(vains); 233 234 s->runReduce(rsc, slot, 235 const_cast<const Allocation **>(ains), inLen, 236 static_cast<Allocation *>(vaout), sc); 237 } 238 239 void rsi_ScriptInvoke(Context *rsc, RsScript vs, uint32_t slot) { 240 Script *s = static_cast<Script *>(vs); 241 s->Invoke(rsc, slot, nullptr, 0); 242 } 243 244 245 void rsi_ScriptInvokeData(Context *rsc, RsScript vs, uint32_t slot, void *data) { 246 Script *s = static_cast<Script *>(vs); 247 s->Invoke(rsc, slot, nullptr, 0); 248 } 249 250 void rsi_ScriptInvokeV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) { 251 Script *s = static_cast<Script *>(vs); 252 s->Invoke(rsc, slot, data, len); 253 } 254 255 void rsi_ScriptSetVarI(Context *rsc, RsScript vs, uint32_t slot, int value) { 256 Script *s = static_cast<Script *>(vs); 257 s->setVar(slot, &value, sizeof(value)); 258 } 259 260 void rsi_ScriptSetVarObj(Context *rsc, RsScript vs, uint32_t slot, RsObjectBase value) { 261 Script *s = static_cast<Script *>(vs); 262 ObjectBase *o = static_cast<ObjectBase *>(value); 263 s->setVarObj(slot, o); 264 } 265 266 void rsi_ScriptSetVarJ(Context *rsc, RsScript vs, uint32_t slot, int64_t value) { 267 Script *s = static_cast<Script *>(vs); 268 s->setVar(slot, &value, sizeof(value)); 269 } 270 271 void rsi_ScriptSetVarF(Context *rsc, RsScript vs, uint32_t slot, float value) { 272 Script *s = static_cast<Script *>(vs); 273 s->setVar(slot, &value, sizeof(value)); 274 } 275 276 void rsi_ScriptSetVarD(Context *rsc, RsScript vs, uint32_t slot, double value) { 277 Script *s = static_cast<Script *>(vs); 278 s->setVar(slot, &value, sizeof(value)); 279 } 280 281 void rsi_ScriptSetVarV(Context *rsc, RsScript vs, uint32_t slot, const void *data, size_t len) { 282 Script *s = static_cast<Script *>(vs); 283 s->setVar(slot, data, len); 284 } 285 286 void rsi_ScriptGetVarV(Context *rsc, RsScript vs, uint32_t slot, void *data, size_t len) { 287 Script *s = static_cast<Script *>(vs); 288 s->getVar(slot, data, len); 289 } 290 291 void rsi_ScriptSetVarVE(Context *rsc, RsScript vs, uint32_t slot, 292 const void *data, size_t len, RsElement ve, 293 const uint32_t *dims, size_t dimLen) { 294 Script *s = static_cast<Script *>(vs); 295 Element *e = static_cast<Element *>(ve); 296 s->setVar(slot, data, len, e, dims, dimLen); 297 } 298 299 } 300 } 301