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