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 20namespace android { 21namespace renderscript { 22 23Script::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 34Script::~Script() { 35 if (mSlots) { 36 delete [] mSlots; 37 mSlots = nullptr; 38 } 39 if (mTypes) { 40 delete [] mTypes; 41 mTypes = nullptr; 42 } 43} 44 45void 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 59void 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 70void 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 82void 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 95void 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 108void 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 116bool Script::freeChildren() { 117 incSysRef(); 118 mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this); 119 return decSysRef(); 120} 121 122ScriptKernelID::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 128RsA3DClassID ScriptKernelID::getClassId() const { 129 return RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID; 130} 131 132ScriptInvokeID::ScriptInvokeID(Context *rsc, Script *s, int slot) 133 : IDBase(rsc, s, slot) { 134} 135 136RsA3DClassID ScriptInvokeID::getClassId() const { 137 return RS_A3D_CLASS_ID_SCRIPT_INVOKE_ID; 138} 139 140ScriptFieldID::ScriptFieldID(Context *rsc, Script *s, int slot) : 141 IDBase(rsc, s, slot) { 142} 143 144RsA3DClassID ScriptFieldID::getClassId() const { 145 return RS_A3D_CLASS_ID_SCRIPT_FIELD_ID; 146} 147 148 149RsScriptKernelID 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 155RsScriptInvokeID 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 161RsScriptFieldID 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 167void 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 173void 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 192void 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 207void 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 224void 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 236void 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 242void 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 247void 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 252void 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 257void 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 263void 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 268void 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 273void 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 278void 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 283void 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 288void 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