Home | History | Annotate | Download | only in rs
      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