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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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