rsScriptC.cpp revision 57b79ceb1126e3797fa42367b97dd7bcfcda1ed9
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 mInt32Defines.clear(); 108 mFloatDefines.clear(); 109} 110 111static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) 112{ 113 const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name); 114 if (sym) { 115 return sym->mPtr; 116 } 117 LOGE("ScriptC sym lookup failed for %s", name); 118 return NULL; 119} 120 121void ScriptCState::runCompiler(Context *rsc) 122{ 123 mAccScript = accCreateScript(); 124 String8 tmp; 125 126 rsc->appendNameDefines(&tmp); 127 appendDecls(&tmp); 128 rsc->appendVarDefines(&tmp); 129 appendVarDefines(&tmp); 130 tmp.append("#line 1\n"); 131 132 const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; 133 int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; 134 accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); 135 accRegisterSymbolCallback(mAccScript, symbolLookup, NULL); 136 accCompileScript(mAccScript); 137 accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); 138 rsAssert(mProgram.mScript); 139 140 if (!mProgram.mScript) { 141 ACCchar buf[4096]; 142 ACCsizei len; 143 accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf); 144 LOGE(buf); 145 } 146 147 mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); 148 mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); 149 mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); 150 151 if (mProgram.mScript) { 152 const static int pragmaMax = 16; 153 ACCsizei pragmaCount; 154 ACCchar * str[pragmaMax]; 155 accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]); 156 157 for (int ct=0; ct < pragmaCount; ct+=2) { 158 if (!strcmp(str[ct], "version")) { 159 continue; 160 } 161 162 if (!strcmp(str[ct], "stateVertex")) { 163 if (!strcmp(str[ct+1], "default")) { 164 continue; 165 } 166 if (!strcmp(str[ct+1], "parent")) { 167 mEnviroment.mVertex.clear(); 168 continue; 169 } 170 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); 171 if (pv != NULL) { 172 mEnviroment.mVertex.set(pv); 173 continue; 174 } 175 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); 176 } 177 178 if (!strcmp(str[ct], "stateRaster")) { 179 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); 180 } 181 182 if (!strcmp(str[ct], "stateFragment")) { 183 if (!strcmp(str[ct+1], "default")) { 184 continue; 185 } 186 if (!strcmp(str[ct+1], "parent")) { 187 mEnviroment.mFragment.clear(); 188 continue; 189 } 190 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); 191 if (pf != NULL) { 192 mEnviroment.mFragment.set(pf); 193 continue; 194 } 195 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); 196 } 197 198 if (!strcmp(str[ct], "stateFragmentStore")) { 199 if (!strcmp(str[ct+1], "default")) { 200 continue; 201 } 202 if (!strcmp(str[ct+1], "parent")) { 203 mEnviroment.mFragmentStore.clear(); 204 continue; 205 } 206 ProgramFragmentStore * pfs = 207 (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); 208 if (pfs != NULL) { 209 mEnviroment.mFragmentStore.set(pfs); 210 continue; 211 } 212 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]); 213 } 214 215 } 216 217 218 } else { 219 // Deal with an error. 220 } 221} 222 223 224void ScriptCState::appendVarDefines(String8 *str) 225{ 226 char buf[256]; 227 LOGD("appendVarDefines mInt32Defines.size()=%d mFloatDefines.size()=%d\n", 228 mInt32Defines.size(), mFloatDefines.size()); 229 for (size_t ct=0; ct < mInt32Defines.size(); ct++) { 230 str->append("#define "); 231 str->append(mInt32Defines.keyAt(ct)); 232 str->append(" "); 233 sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); 234 str->append(buf); 235 } 236 for (size_t ct=0; ct < mFloatDefines.size(); ct++) { 237 str->append("#define "); 238 str->append(mFloatDefines.keyAt(ct)); 239 str->append(" "); 240 sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); 241 str->append(buf); 242 } 243} 244 245 246namespace android { 247namespace renderscript { 248 249void rsi_ScriptCBegin(Context * rsc) 250{ 251 ScriptCState *ss = &rsc->mScriptC; 252 ss->clear(); 253} 254 255void rsi_ScriptCAddType(Context * rsc, RsType vt) 256{ 257 ScriptCState *ss = &rsc->mScriptC; 258 ss->mConstantBufferTypes.add(static_cast<const Type *>(vt)); 259} 260 261void rsi_ScriptCSetScript(Context * rsc, void *vp) 262{ 263 ScriptCState *ss = &rsc->mScriptC; 264 ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp); 265} 266 267void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) 268{ 269 ScriptCState *ss = &rsc->mScriptC; 270 ss->mEnviroment.mIsRoot = isRoot; 271} 272 273void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) 274{ 275 ScriptCState *ss = &rsc->mScriptC; 276 ss->mProgram.mScriptText = text; 277 ss->mProgram.mScriptTextLength = len; 278} 279 280 281RsScript rsi_ScriptCCreate(Context * rsc) 282{ 283 ScriptCState *ss = &rsc->mScriptC; 284 285 ss->runCompiler(rsc); 286 287 ScriptC *s = new ScriptC(); 288 s->incRef(); 289 s->mAccScript = ss->mAccScript; 290 ss->mAccScript = NULL; 291 s->mEnviroment = ss->mEnviroment; 292 s->mProgram = ss->mProgram; 293 ss->clear(); 294 295 return s; 296} 297 298void rsi_ScriptCSetDefineF(Context *rsc, const char* name, float value) 299{ 300 ScriptCState *ss = &rsc->mScriptC; 301 ss->mFloatDefines.add(String8(name), value); 302} 303 304void rsi_ScriptCSetDefineI32(Context *rsc, const char* name, int32_t value) 305{ 306 ScriptCState *ss = &rsc->mScriptC; 307 ss->mInt32Defines.add(String8(name), value); 308} 309 310} 311} 312 313 314