PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/rs/rsScriptC.cpp

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