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 "rsScriptC.h" 19#include "utils/Timers.h" 20#include "utils/StopWatch.h" 21 22using namespace android; 23using namespace android::renderscript; 24 25#define GET_TLS() Context::ScriptTLSStruct * tls = \ 26 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 27 Context * rsc = tls->mContext; \ 28 ScriptC * sc = (ScriptC *) tls->mScript 29 30ScriptC::ScriptC(Context *rsc) : Script(rsc) { 31} 32 33ScriptC::~ScriptC() { 34 if (mInitialized) { 35 mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this); 36 mRSC->mHal.funcs.script.destroy(mRSC, this); 37 } 38} 39 40void ScriptC::setupScript(Context *rsc) { 41 mEnviroment.mStartTimeMillis 42 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 43 44 for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) { 45 if (mSlots[ct].get() && !mTypes[ct].get()) { 46 mTypes[ct].set(mSlots[ct]->getType()); 47 } 48 49 if (!mTypes[ct].get()) 50 continue; 51 rsc->mHal.funcs.script.setGlobalBind(rsc, this, ct, mSlots[ct].get()); 52 } 53} 54 55void ScriptC::setupGLState(Context *rsc) { 56} 57 58uint32_t ScriptC::run(Context *rsc) { 59 if (mHal.info.root == NULL) { 60 rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script"); 61 return 0; 62 } 63 64 setupGLState(rsc); 65 setupScript(rsc); 66 67 uint32_t ret = 0; 68 69 if (rsc->props.mLogScripts) { 70 ALOGV("%p ScriptC::run invoking root, ptr %p", rsc, mHal.info.root); 71 } 72 73 ret = rsc->mHal.funcs.script.invokeRoot(rsc, this); 74 75 if (rsc->props.mLogScripts) { 76 ALOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret); 77 } 78 79 return ret; 80} 81 82 83void ScriptC::runForEach(Context *rsc, 84 uint32_t slot, 85 const Allocation * ain, 86 Allocation * aout, 87 const void * usr, 88 size_t usrBytes, 89 const RsScriptCall *sc) { 90 91 Context::PushState ps(rsc); 92 93 setupGLState(rsc); 94 setupScript(rsc); 95 rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc); 96} 97 98void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) { 99 if (slot >= mHal.info.exportedFunctionCount) { 100 rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script"); 101 return; 102 } 103 setupScript(rsc); 104 105 if (rsc->props.mLogScripts) { 106 ALOGV("%p ScriptC::Invoke invoking slot %i, ptr %p", rsc, slot, this); 107 } 108 rsc->mHal.funcs.script.invokeFunction(rsc, this, slot, data, len); 109} 110 111ScriptCState::ScriptCState() { 112} 113 114ScriptCState::~ScriptCState() { 115} 116 117/* 118static void* symbolLookup(void* pContext, char const* name) { 119 const ScriptCState::SymbolTable_t *sym; 120 ScriptC *s = (ScriptC *)pContext; 121 if (!strcmp(name, "__isThreadable")) { 122 return (void*) s->mHal.info.isThreadable; 123 } else if (!strcmp(name, "__clearThreadable")) { 124 s->mHal.info.isThreadable = false; 125 return NULL; 126 } 127 sym = ScriptCState::lookupSymbol(name); 128 if (!sym) { 129 sym = ScriptCState::lookupSymbolCL(name); 130 } 131 if (!sym) { 132 sym = ScriptCState::lookupSymbolGL(name); 133 } 134 if (sym) { 135 s->mHal.info.isThreadable &= sym->threadable; 136 return sym->mPtr; 137 } 138 ALOGE("ScriptC sym lookup failed for %s", name); 139 return NULL; 140} 141*/ 142 143#if 0 144extern const char rs_runtime_lib_bc[]; 145extern unsigned rs_runtime_lib_bc_size; 146#endif 147 148bool ScriptC::runCompiler(Context *rsc, 149 const char *resName, 150 const char *cacheDir, 151 const uint8_t *bitcode, 152 size_t bitcodeLen) { 153 154 //ALOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen); 155 156 if (!rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0)) { 157 return false; 158 } 159 160 mInitialized = true; 161 162 rsc->mHal.funcs.script.invokeInit(rsc, this); 163 164 for (size_t i=0; i < mHal.info.exportedPragmaCount; ++i) { 165 const char * key = mHal.info.exportedPragmaKeyList[i]; 166 const char * value = mHal.info.exportedPragmaValueList[i]; 167 //ALOGE("pragma %s %s", keys[i], values[i]); 168 if (!strcmp(key, "version")) { 169 if (!strcmp(value, "1")) { 170 continue; 171 } 172 ALOGE("Invalid version pragma value: %s\n", value); 173 return false; 174 } 175 } 176 177 mSlots = new ObjectBaseRef<Allocation>[mHal.info.exportedVariableCount]; 178 mTypes = new ObjectBaseRef<const Type>[mHal.info.exportedVariableCount]; 179 180 return true; 181} 182 183namespace android { 184namespace renderscript { 185 186RsScript rsi_ScriptCCreate(Context *rsc, 187 const char *resName, size_t resName_length, 188 const char *cacheDir, size_t cacheDir_length, 189 const char *text, size_t text_length) 190{ 191 ScriptC *s = new ScriptC(rsc); 192 193 if (!s->runCompiler(rsc, resName, cacheDir, (uint8_t *)text, text_length)) { 194 // Error during compile, destroy s and return null. 195 ObjectBase::checkDelete(s); 196 return NULL; 197 } 198 199 s->incUserRef(); 200 return s; 201} 202 203} 204} 205