• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 using namespace android;
23 using 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 
ScriptC(Context * rsc)30 ScriptC::ScriptC(Context *rsc) : Script(rsc) {
31 }
32 
~ScriptC()33 ScriptC::~ScriptC() {
34     if (mInitialized) {
35         mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
36         mRSC->mHal.funcs.script.destroy(mRSC, this);
37     }
38 }
39 
setupScript(Context * rsc)40 void 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 
setupGLState(Context * rsc)55 void ScriptC::setupGLState(Context *rsc) {
56 }
57 
run(Context * rsc)58 uint32_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 
runForEach(Context * rsc,uint32_t slot,const Allocation * ain,Allocation * aout,const void * usr,size_t usrBytes,const RsScriptCall * sc)83 void 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 
Invoke(Context * rsc,uint32_t slot,const void * data,size_t len)98 void 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 
ScriptCState()111 ScriptCState::ScriptCState() {
112 }
113 
~ScriptCState()114 ScriptCState::~ScriptCState() {
115 }
116 
117 /*
118 static 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
144 extern const char rs_runtime_lib_bc[];
145 extern unsigned rs_runtime_lib_bc_size;
146 #endif
147 
runCompiler(Context * rsc,const char * resName,const char * cacheDir,const uint8_t * bitcode,size_t bitcodeLen)148 bool 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 
183 namespace android {
184 namespace renderscript {
185 
rsi_ScriptCCreate(Context * rsc,const char * resName,size_t resName_length,const char * cacheDir,size_t cacheDir_length,const char * text,size_t text_length)186 RsScript 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