rsScriptC.cpp revision 9c4e4ca9ff75a7fe18544c83fcf782e46c9b6ac2
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/String8.h" 23#include "utils/Timers.h" 24 25#include <GLES/gl.h> 26#include <GLES/glext.h> 27 28using namespace android; 29using namespace android::renderscript; 30 31#define GET_TLS() Context::ScriptTLSStruct * tls = \ 32 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 33 Context * rsc = tls->mContext; \ 34 ScriptC * sc = (ScriptC *) tls->mScript 35 36 37ScriptC::ScriptC() 38{ 39 mAccScript = NULL; 40 memset(&mProgram, 0, sizeof(mProgram)); 41} 42 43ScriptC::~ScriptC() 44{ 45 if (mAccScript) { 46 accDeleteScript(mAccScript); 47 } 48} 49 50 51bool ScriptC::run(Context *rsc, uint32_t launchIndex) 52{ 53 Context::ScriptTLSStruct * tls = 54 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); 55 56 if (mEnviroment.mFragmentStore.get()) { 57 rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); 58 } 59 if (mEnviroment.mFragment.get()) { 60 rsc->setFragment(mEnviroment.mFragment.get()); 61 } 62 if (mEnviroment.mVertex.get()) { 63 rsc->setVertex(mEnviroment.mVertex.get()); 64 } 65 66 if (launchIndex == 0) { 67 mEnviroment.mStartTimeMillis 68 = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 69 } 70 71 bool ret = false; 72 tls->mScript = this; 73 ret = mProgram.mScript(launchIndex) != 0; 74 tls->mScript = NULL; 75 return ret; 76} 77 78ScriptCState::ScriptCState() 79{ 80 clear(); 81} 82 83ScriptCState::~ScriptCState() 84{ 85 if (mAccScript) { 86 accDeleteScript(mAccScript); 87 } 88} 89 90void ScriptCState::clear() 91{ 92 memset(&mProgram, 0, sizeof(mProgram)); 93 94 mConstantBufferTypes.clear(); 95 96 memset(&mEnviroment, 0, sizeof(mEnviroment)); 97 mEnviroment.mClearColor[0] = 0; 98 mEnviroment.mClearColor[1] = 0; 99 mEnviroment.mClearColor[2] = 0; 100 mEnviroment.mClearColor[3] = 1; 101 mEnviroment.mClearDepth = 1; 102 mEnviroment.mClearStencil = 0; 103 mEnviroment.mIsRoot = false; 104 105 mAccScript = NULL; 106 107} 108 109static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) 110{ 111 const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name); 112 if (sym) { 113 return sym->mPtr; 114 } 115 LOGE("ScriptC sym lookup failed for %s", name); 116 return NULL; 117} 118 119void ScriptCState::runCompiler(Context *rsc) 120{ 121 mAccScript = accCreateScript(); 122 String8 tmp; 123 124 rsc->appendNameDefines(&tmp); 125 appendDecls(&tmp); 126 tmp.append("#line 1\n"); 127 128 const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; 129 int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; 130 accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); 131 accRegisterSymbolCallback(mAccScript, symbolLookup, NULL); 132 accCompileScript(mAccScript); 133 accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); 134 rsAssert(mProgram.mScript); 135 136 if (!mProgram.mScript) { 137 ACCchar buf[4096]; 138 ACCsizei len; 139 accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf); 140 LOGE(buf); 141 142 } 143 144 mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); 145 mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); 146 mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); 147 148 if (mProgram.mScript) { 149 const static int pragmaMax = 16; 150 ACCsizei pragmaCount; 151 ACCchar * str[pragmaMax]; 152 accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]); 153 154 for (int ct=0; ct < pragmaCount; ct+=2) { 155 if (!strcmp(str[ct], "version")) { 156 continue; 157 } 158 159 if (!strcmp(str[ct], "stateVertex")) { 160 if (!strcmp(str[ct+1], "default")) { 161 continue; 162 } 163 if (!strcmp(str[ct+1], "parent")) { 164 mEnviroment.mVertex.clear(); 165 continue; 166 } 167 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); 168 if (pv != NULL) { 169 mEnviroment.mVertex.set(pv); 170 continue; 171 } 172 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); 173 } 174 175 if (!strcmp(str[ct], "stateRaster")) { 176 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); 177 } 178 179 if (!strcmp(str[ct], "stateFragment")) { 180 if (!strcmp(str[ct+1], "default")) { 181 continue; 182 } 183 if (!strcmp(str[ct+1], "parent")) { 184 mEnviroment.mFragment.clear(); 185 continue; 186 } 187 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); 188 if (pf != NULL) { 189 mEnviroment.mFragment.set(pf); 190 continue; 191 } 192 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); 193 } 194 195 if (!strcmp(str[ct], "stateFragmentStore")) { 196 if (!strcmp(str[ct+1], "default")) { 197 continue; 198 } 199 if (!strcmp(str[ct+1], "parent")) { 200 mEnviroment.mFragmentStore.clear(); 201 continue; 202 } 203 ProgramFragmentStore * pfs = 204 (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); 205 if (pfs != NULL) { 206 mEnviroment.mFragmentStore.set(pfs); 207 continue; 208 } 209 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]); 210 } 211 212 } 213 214 215 } else { 216 // Deal with an error. 217 } 218 219} 220 221namespace android { 222namespace renderscript { 223 224void rsi_ScriptCBegin(Context * rsc) 225{ 226 ScriptCState *ss = &rsc->mScriptC; 227 ss->clear(); 228} 229 230void rsi_ScriptCAddType(Context * rsc, RsType vt) 231{ 232 ScriptCState *ss = &rsc->mScriptC; 233 ss->mConstantBufferTypes.add(static_cast<const Type *>(vt)); 234} 235 236void rsi_ScriptCSetScript(Context * rsc, void *vp) 237{ 238 ScriptCState *ss = &rsc->mScriptC; 239 ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp); 240} 241 242void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) 243{ 244 ScriptCState *ss = &rsc->mScriptC; 245 ss->mEnviroment.mIsRoot = isRoot; 246} 247 248void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) 249{ 250 ScriptCState *ss = &rsc->mScriptC; 251 ss->mProgram.mScriptText = text; 252 ss->mProgram.mScriptTextLength = len; 253} 254 255 256RsScript rsi_ScriptCCreate(Context * rsc) 257{ 258 ScriptCState *ss = &rsc->mScriptC; 259 260 ss->runCompiler(rsc); 261 262 ScriptC *s = new ScriptC(); 263 s->incRef(); 264 s->mAccScript = ss->mAccScript; 265 ss->mAccScript = NULL; 266 s->mEnviroment = ss->mEnviroment; 267 s->mProgram = ss->mProgram; 268 ss->clear(); 269 270 return s; 271} 272 273} 274} 275 276 277