OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / libs / rs / rsScriptC.cpp
1 /*
2  * Copyright (C) 2009 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 "rsMatrix.h"
20
21 #include "acc/acc.h"
22 #include "utils/Timers.h"
23
24 #include <GLES/gl.h>
25 #include <GLES/glext.h>
26
27 using namespace android;
28 using namespace android::renderscript;
29
30 #define GET_TLS()  Context::ScriptTLSStruct * tls = \
31     (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
32     Context * rsc = tls->mContext; \
33     ScriptC * sc = (ScriptC *) tls->mScript
34
35
36 ScriptC::ScriptC(Context *rsc) : Script(rsc)
37 {
38     mAllocFile = __FILE__;
39     mAllocLine = __LINE__;
40     mAccScript = NULL;
41     memset(&mProgram, 0, sizeof(mProgram));
42 }
43
44 ScriptC::~ScriptC()
45 {
46     if (mAccScript) {
47         accDeleteScript(mAccScript);
48     }
49     free(mEnviroment.mScriptText);
50     mEnviroment.mScriptText = NULL;
51 }
52
53 void ScriptC::setupScript()
54 {
55     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
56         if (mProgram.mSlotPointers[ct]) {
57             *mProgram.mSlotPointers[ct] = mSlots[ct]->getPtr();
58         }
59     }
60 }
61
62
63 uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex)
64 {
65     if (mProgram.mScript == NULL) {
66         rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script");
67         return 0;
68     }
69
70     Context::ScriptTLSStruct * tls =
71     (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
72     rsAssert(tls);
73
74     if (mEnviroment.mFragmentStore.get()) {
75         rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
76     }
77     if (mEnviroment.mFragment.get()) {
78         rsc->setFragment(mEnviroment.mFragment.get());
79     }
80     if (mEnviroment.mVertex.get()) {
81         rsc->setVertex(mEnviroment.mVertex.get());
82     }
83     if (mEnviroment.mRaster.get()) {
84         rsc->setRaster(mEnviroment.mRaster.get());
85     }
86
87     if (launchIndex == 0) {
88         mEnviroment.mStartTimeMillis
89                 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
90     }
91     setupScript();
92
93     uint32_t ret = 0;
94     tls->mScript = this;
95     ret = mProgram.mScript(launchIndex);
96     tls->mScript = NULL;
97     return ret;
98 }
99
100 ScriptCState::ScriptCState()
101 {
102     mScript = NULL;
103     clear();
104 }
105
106 ScriptCState::~ScriptCState()
107 {
108     delete mScript;
109     mScript = NULL;
110 }
111
112 void ScriptCState::clear()
113 {
114     for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
115         mConstantBufferTypes[ct].clear();
116         mSlotNames[ct].setTo("");
117         mInvokableNames[ct].setTo("");
118         mSlotWritable[ct] = false;
119     }
120
121     delete mScript;
122     mScript = new ScriptC(NULL);
123
124     mInt32Defines.clear();
125     mFloatDefines.clear();
126 }
127
128 static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name)
129 {
130     const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name);
131     if (sym) {
132         return sym->mPtr;
133     }
134     LOGE("ScriptC sym lookup failed for %s", name);
135     return NULL;
136 }
137
138 void ScriptCState::runCompiler(Context *rsc, ScriptC *s)
139 {
140     s->mAccScript = accCreateScript();
141     String8 tmp;
142
143     rsc->appendNameDefines(&tmp);
144     appendDecls(&tmp);
145     appendVarDefines(rsc, &tmp);
146     appendTypes(rsc, &tmp);
147     tmp.append("#line 1\n");
148
149     const char* scriptSource[] = {tmp.string(), s->mEnviroment.mScriptText};
150     int scriptLength[] = {tmp.length(), s->mEnviroment.mScriptTextLength} ;
151     accScriptSource(s->mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
152     accRegisterSymbolCallback(s->mAccScript, symbolLookup, NULL);
153     accCompileScript(s->mAccScript);
154     accGetScriptLabel(s->mAccScript, "main", (ACCvoid**) &s->mProgram.mScript);
155     accGetScriptLabel(s->mAccScript, "init", (ACCvoid**) &s->mProgram.mInit);
156     rsAssert(s->mProgram.mScript);
157
158     if (!s->mProgram.mScript) {
159         ACCchar buf[4096];
160         ACCsizei len;
161         accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf);
162         LOGE("%s", buf);
163         rsc->setError(RS_ERROR_BAD_SCRIPT, "Error compiling user script.");
164         return;
165     }
166
167     if (s->mProgram.mInit) {
168         s->mProgram.mInit();
169     }
170
171     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
172         if (mSlotNames[ct].length() > 0) {
173             accGetScriptLabel(s->mAccScript,
174                               mSlotNames[ct].string(),
175                               (ACCvoid**) &s->mProgram.mSlotPointers[ct]);
176         }
177     }
178
179     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
180         if (mInvokableNames[ct].length() > 0) {
181             accGetScriptLabel(s->mAccScript,
182                               mInvokableNames[ct].string(),
183                               (ACCvoid**) &s->mEnviroment.mInvokables[ct]);
184         }
185     }
186
187     s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
188     s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
189     s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
190     s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
191
192     if (s->mProgram.mScript) {
193         const static int pragmaMax = 16;
194         ACCsizei pragmaCount;
195         ACCchar * str[pragmaMax];
196         accGetPragmas(s->mAccScript, &pragmaCount, pragmaMax, &str[0]);
197
198         for (int ct=0; ct < pragmaCount; ct+=2) {
199             if (!strcmp(str[ct], "version")) {
200                 continue;
201             }
202
203             if (!strcmp(str[ct], "stateVertex")) {
204                 if (!strcmp(str[ct+1], "default")) {
205                     continue;
206                 }
207                 if (!strcmp(str[ct+1], "parent")) {
208                     s->mEnviroment.mVertex.clear();
209                     continue;
210                 }
211                 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
212                 if (pv != NULL) {
213                     s->mEnviroment.mVertex.set(pv);
214                     continue;
215                 }
216                 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
217             }
218
219             if (!strcmp(str[ct], "stateRaster")) {
220                 if (!strcmp(str[ct+1], "default")) {
221                     continue;
222                 }
223                 if (!strcmp(str[ct+1], "parent")) {
224                     s->mEnviroment.mRaster.clear();
225                     continue;
226                 }
227                 ProgramRaster * pr = (ProgramRaster *)rsc->lookupName(str[ct+1]);
228                 if (pr != NULL) {
229                     s->mEnviroment.mRaster.set(pr);
230                     continue;
231                 }
232                 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
233             }
234
235             if (!strcmp(str[ct], "stateFragment")) {
236                 if (!strcmp(str[ct+1], "default")) {
237                     continue;
238                 }
239                 if (!strcmp(str[ct+1], "parent")) {
240                     s->mEnviroment.mFragment.clear();
241                     continue;
242                 }
243                 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
244                 if (pf != NULL) {
245                     s->mEnviroment.mFragment.set(pf);
246                     continue;
247                 }
248                 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
249             }
250
251             if (!strcmp(str[ct], "stateStore")) {
252                 if (!strcmp(str[ct+1], "default")) {
253                     continue;
254                 }
255                 if (!strcmp(str[ct+1], "parent")) {
256                     s->mEnviroment.mFragmentStore.clear();
257                     continue;
258                 }
259                 ProgramFragmentStore * pfs =
260                     (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
261                 if (pfs != NULL) {
262                     s->mEnviroment.mFragmentStore.set(pfs);
263                     continue;
264                 }
265                 LOGE("Unreconized value %s passed to stateStore", str[ct+1]);
266             }
267
268         }
269
270
271     } else {
272         // Deal with an error.
273     }
274 }
275
276 static void appendElementBody(String8 *s, const Element *e)
277 {
278     s->append(" {\n");
279     for (size_t ct2=0; ct2 < e->getFieldCount(); ct2++) {
280         const Element *c = e->getField(ct2);
281         s->append("    ");
282         s->append(c->getCType());
283         s->append(" ");
284         s->append(e->getFieldName(ct2));
285         s->append(";\n");
286     }
287     s->append("}");
288 }
289
290 void ScriptCState::appendVarDefines(const Context *rsc, String8 *str)
291 {
292     char buf[256];
293     if (rsc->props.mLogScripts) {
294         LOGD("appendVarDefines mInt32Defines.size()=%d mFloatDefines.size()=%d\n",
295                 mInt32Defines.size(), mFloatDefines.size());
296     }
297     for (size_t ct=0; ct < mInt32Defines.size(); ct++) {
298         str->append("#define ");
299         str->append(mInt32Defines.keyAt(ct));
300         str->append(" ");
301         sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct));
302         str->append(buf);
303     }
304     for (size_t ct=0; ct < mFloatDefines.size(); ct++) {
305         str->append("#define ");
306         str->append(mFloatDefines.keyAt(ct));
307         str->append(" ");
308         sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct));
309         str->append(buf);
310     }
311 }
312
313
314
315 void ScriptCState::appendTypes(const Context *rsc, String8 *str)
316 {
317     char buf[256];
318     String8 tmp;
319
320     str->append("struct vecF32_2_s {float x; float y;};\n");
321     str->append("struct vecF32_3_s {float x; float y; float z;};\n");
322     str->append("struct vecF32_4_s {float x; float y; float z; float w;};\n");
323     str->append("struct vecU8_4_s {char r; char g; char b; char a;};\n");
324     str->append("#define vecF32_2_t struct vecF32_2_s\n");
325     str->append("#define vecF32_3_t struct vecF32_3_s\n");
326     str->append("#define vecF32_4_t struct vecF32_4_s\n");
327     str->append("#define vecU8_4_t struct vecU8_4_s\n");
328     str->append("#define vecI8_4_t struct vecU8_4_s\n");
329
330     for (size_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
331         const Type *t = mConstantBufferTypes[ct].get();
332         if (!t) {
333             continue;
334         }
335         const Element *e = t->getElement();
336         if (e->getName() && (e->getFieldCount() > 1)) {
337             String8 s("struct struct_");
338             s.append(e->getName());
339             s.append(e->getCStructBody());
340             s.append(";\n");
341
342             s.append("#define ");
343             s.append(e->getName());
344             s.append("_t struct struct_");
345             s.append(e->getName());
346             s.append("\n\n");
347             if (rsc->props.mLogScripts) {
348                 LOGV("%s", static_cast<const char*>(s));
349             }
350             str->append(s);
351         }
352
353         if (mSlotNames[ct].length() > 0) {
354             String8 s;
355             if (e->getName()) {
356                 // Use the named struct
357                 s.setTo(e->getName());
358             } else {
359                 // create an struct named from the slot.
360                 s.setTo("struct ");
361                 s.append(mSlotNames[ct]);
362                 s.append("_s");
363                 s.append(e->getCStructBody());
364                 //appendElementBody(&s, e);
365                 s.append(";\n");
366                 s.append("struct ");
367                 s.append(mSlotNames[ct]);
368                 s.append("_s");
369             }
370
371             s.append(" * ");
372             s.append(mSlotNames[ct]);
373             s.append(";\n");
374             if (rsc->props.mLogScripts) {
375                 LOGV("%s", static_cast<const char*>(s));
376             }
377             str->append(s);
378         }
379     }
380 }
381
382
383 namespace android {
384 namespace renderscript {
385
386 void rsi_ScriptCBegin(Context * rsc)
387 {
388     ScriptCState *ss = &rsc->mScriptC;
389     ss->clear();
390 }
391
392 void rsi_ScriptCSetScript(Context * rsc, void *vp)
393 {
394     rsAssert(0);
395     //ScriptCState *ss = &rsc->mScriptC;
396     //ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
397 }
398
399 void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
400 {
401     ScriptCState *ss = &rsc->mScriptC;
402
403     char *t = (char *)malloc(len + 1);
404     memcpy(t, text, len);
405     t[len] = 0;
406     ss->mScript->mEnviroment.mScriptText = t;
407     ss->mScript->mEnviroment.mScriptTextLength = len;
408 }
409
410
411 RsScript rsi_ScriptCCreate(Context * rsc)
412 {
413     ScriptCState *ss = &rsc->mScriptC;
414
415     ScriptC *s = ss->mScript;
416     ss->mScript = NULL;
417
418     ss->runCompiler(rsc, s);
419     s->incUserRef();
420     s->setContext(rsc);
421     for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
422         s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
423         s->mSlotNames[ct] = ss->mSlotNames[ct];
424         s->mSlotWritable[ct] = ss->mSlotWritable[ct];
425     }
426
427     ss->clear();
428     return s;
429 }
430
431 void rsi_ScriptCSetDefineF(Context *rsc, const char* name, float value)
432 {
433     ScriptCState *ss = &rsc->mScriptC;
434     ss->mFloatDefines.add(String8(name), value);
435 }
436
437 void rsi_ScriptCSetDefineI32(Context *rsc, const char* name, int32_t value)
438 {
439     ScriptCState *ss = &rsc->mScriptC;
440     ss->mInt32Defines.add(String8(name), value);
441 }
442
443 }
444 }
445
446