rsScriptC.cpp revision 36e0bc403e8166970c71bf4d55423bf39eebea4e
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 24using namespace android; 25using namespace android::renderscript; 26 27#define GET_TLS() Context::ScriptTLSStruct * tls = \ 28 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 29 Context * rsc = tls->mContext; \ 30 ScriptC * sc = (ScriptC *) tls->mScript 31 32 33ScriptC::ScriptC() 34{ 35 mAccScript = NULL; 36 memset(&mProgram, 0, sizeof(mProgram)); 37} 38 39ScriptC::~ScriptC() 40{ 41 if (mAccScript) { 42 accDeleteScript(mAccScript); 43 } 44} 45 46extern "C" float fixedToFloat(int32_t f) 47{ 48 return ((float)f) / 0x10000; 49} 50 51extern "C" float intToFloat(int32_t f) 52{ 53 return (float)f; 54} 55 56extern "C" void matrixLoadIdentity(rsc_Matrix *mat) 57{ 58 Matrix *m = reinterpret_cast<Matrix *>(mat); 59 m->loadIdentity(); 60} 61 62extern "C" void matrixLoadFloat(rsc_Matrix *mat, const float *f) 63{ 64 Matrix *m = reinterpret_cast<Matrix *>(mat); 65 m->load(f); 66} 67 68extern "C" void matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat) 69{ 70 Matrix *m = reinterpret_cast<Matrix *>(mat); 71 m->load(reinterpret_cast<const Matrix *>(newmat)); 72} 73 74extern "C" void matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z) 75{ 76 Matrix *m = reinterpret_cast<Matrix *>(mat); 77 m->loadRotate(rot, x, y, z); 78} 79 80extern "C" void matrixLoadScale(rsc_Matrix *mat, float x, float y, float z) 81{ 82 Matrix *m = reinterpret_cast<Matrix *>(mat); 83 m->loadScale(x, y, z); 84} 85 86extern "C" void matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z) 87{ 88 Matrix *m = reinterpret_cast<Matrix *>(mat); 89 m->loadTranslate(x, y, z); 90} 91 92extern "C" void matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs) 93{ 94 Matrix *m = reinterpret_cast<Matrix *>(mat); 95 m->loadMultiply(reinterpret_cast<const Matrix *>(lhs), 96 reinterpret_cast<const Matrix *>(rhs)); 97} 98 99extern "C" void matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs) 100{ 101 Matrix *m = reinterpret_cast<Matrix *>(mat); 102 m->multiply(reinterpret_cast<const Matrix *>(rhs)); 103} 104 105extern "C" void matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z) 106{ 107 Matrix *m = reinterpret_cast<Matrix *>(mat); 108 m->rotate(rot, x, y, z); 109} 110 111extern "C" void matrixScale(rsc_Matrix *mat, float x, float y, float z) 112{ 113 Matrix *m = reinterpret_cast<Matrix *>(mat); 114 m->scale(x, y, z); 115} 116 117extern "C" void matrixTranslate(rsc_Matrix *mat, float x, float y, float z) 118{ 119 Matrix *m = reinterpret_cast<Matrix *>(mat); 120 m->translate(x, y, z); 121} 122 123 124extern "C" const void * loadVp(uint32_t bank, uint32_t offset) 125{ 126 GET_TLS(); 127 return &static_cast<const uint8_t *>(sc->mSlots[bank]->getPtr())[offset]; 128} 129 130extern "C" float loadF(uint32_t bank, uint32_t offset) 131{ 132 GET_TLS(); 133 return static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset]; 134} 135 136extern "C" int32_t loadI32(uint32_t bank, uint32_t offset) 137{ 138 GET_TLS(); 139 return static_cast<const int32_t *>(sc->mSlots[bank]->getPtr())[offset]; 140} 141 142extern "C" uint32_t loadU32(uint32_t bank, uint32_t offset) 143{ 144 GET_TLS(); 145 return static_cast<const uint32_t *>(sc->mSlots[bank]->getPtr())[offset]; 146} 147 148extern "C" void loadEnvVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v) 149{ 150 GET_TLS(); 151 memcpy(v, &static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset], sizeof(rsc_Vector4)); 152} 153 154extern "C" void loadEnvMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m) 155{ 156 GET_TLS(); 157 memcpy(m, &static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset], sizeof(rsc_Matrix)); 158} 159 160 161extern "C" void storeF(uint32_t bank, uint32_t offset, float v) 162{ 163 GET_TLS(); 164 static_cast<float *>(sc->mSlots[bank]->getPtr())[offset] = v; 165} 166 167extern "C" void storeI32(uint32_t bank, uint32_t offset, int32_t v) 168{ 169 GET_TLS(); 170 static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v; 171} 172 173extern "C" void storeU32(uint32_t bank, uint32_t offset, uint32_t v) 174{ 175 GET_TLS(); 176 static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v; 177} 178 179extern "C" void storeEnvVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v) 180{ 181 GET_TLS(); 182 memcpy(&static_cast<float *>(sc->mSlots[bank]->getPtr())[offset], v, sizeof(rsc_Vector4)); 183} 184 185extern "C" void storeEnvMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m) 186{ 187 GET_TLS(); 188 memcpy(&static_cast<float *>(sc->mSlots[bank]->getPtr())[offset], m, sizeof(rsc_Matrix)); 189} 190 191 192extern "C" void color(float r, float g, float b, float a) 193{ 194 glColor4f(r, g, b, a); 195} 196 197extern "C" void renderTriangleMesh(RsTriangleMesh mesh) 198{ 199 GET_TLS(); 200 rsi_TriangleMeshRender(rsc, mesh); 201} 202 203extern "C" void renderTriangleMeshRange(RsTriangleMesh mesh, uint32_t start, uint32_t count) 204{ 205 GET_TLS(); 206 rsi_TriangleMeshRenderRange(rsc, mesh, start, count); 207} 208 209extern "C" void materialDiffuse(float r, float g, float b, float a) 210{ 211 float v[] = {r, g, b, a}; 212 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v); 213} 214 215extern "C" void materialSpecular(float r, float g, float b, float a) 216{ 217 float v[] = {r, g, b, a}; 218 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v); 219} 220 221extern "C" void lightPosition(float x, float y, float z, float w) 222{ 223 float v[] = {x, y, z, w}; 224 glLightfv(GL_LIGHT0, GL_POSITION, v); 225} 226 227extern "C" void materialShininess(float s) 228{ 229 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s); 230} 231 232extern "C" void uploadToTexture(RsAllocation va, uint32_t baseMipLevel) 233{ 234 GET_TLS(); 235 rsi_AllocationUploadToTexture(rsc, va, baseMipLevel); 236} 237 238extern "C" void enable(uint32_t p) 239{ 240 glEnable(p); 241} 242 243extern "C" void disable(uint32_t p) 244{ 245 glDisable(p); 246} 247 248extern "C" uint32_t scriptRand(uint32_t max) 249{ 250 return (uint32_t)(((float)rand()) * max / RAND_MAX); 251} 252 253// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a 254extern "C" void drawTriangleArray(RsAllocation alloc, uint32_t count) 255{ 256 GET_TLS(); 257 258 const Allocation *a = (const Allocation *)alloc; 259 const uint32_t *ptr = (const uint32_t *)a->getPtr(); 260 261 rsc->setupCheck(); 262 263 glBindBuffer(GL_ARRAY_BUFFER, 0); 264 //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); 265 266 glEnableClientState(GL_VERTEX_ARRAY); 267 glDisableClientState(GL_NORMAL_ARRAY); 268 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 269 glEnableClientState(GL_COLOR_ARRAY); 270 271 glVertexPointer(2, GL_FIXED, 12, ptr + 1); 272 //glTexCoordPointer(2, GL_FIXED, 24, ptr + 1); 273 glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); 274 275 glDrawArrays(GL_TRIANGLES, 0, count * 3); 276} 277 278extern "C" void drawRect(int32_t x1, int32_t x2, int32_t y1, int32_t y2) 279{ 280 GET_TLS(); 281 x1 = (x1 << 16); 282 x2 = (x2 << 16); 283 y1 = (y1 << 16); 284 y2 = (y2 << 16); 285 286 int32_t vtx[] = {x1,y1, x1,y2, x2,y1, x2,y2}; 287 static const int32_t tex[] = {0,0, 0,0x10000, 0x10000,0, 0x10000,0x10000}; 288 289 290 rsc->setupCheck(); 291 292 glBindBuffer(GL_ARRAY_BUFFER, 0); 293 //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); 294 295 glEnableClientState(GL_VERTEX_ARRAY); 296 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 297 glDisableClientState(GL_NORMAL_ARRAY); 298 glDisableClientState(GL_COLOR_ARRAY); 299 300 glVertexPointer(2, GL_FIXED, 8, vtx); 301 glTexCoordPointer(2, GL_FIXED, 8, tex); 302 //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); 303 304 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 305} 306 307extern "C" void pfBindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) 308{ 309 GET_TLS(); 310 rsi_ProgramFragmentBindTexture(rsc, 311 static_cast<ProgramFragment *>(vpf), 312 slot, 313 static_cast<Allocation *>(va)); 314 315} 316 317extern "C" void pfBindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) 318{ 319 GET_TLS(); 320 rsi_ProgramFragmentBindSampler(rsc, 321 static_cast<ProgramFragment *>(vpf), 322 slot, 323 static_cast<Sampler *>(vs)); 324 325} 326 327extern "C" void contextBindProgramFragmentStore(RsProgramFragmentStore pfs) 328{ 329 GET_TLS(); 330 rsi_ContextBindProgramFragmentStore(rsc, pfs); 331 332} 333 334extern "C" void contextBindProgramFragment(RsProgramFragment pf) 335{ 336 GET_TLS(); 337 rsi_ContextBindProgramFragment(rsc, pf); 338 339} 340 341 342static rsc_FunctionTable scriptCPtrTable = { 343 loadVp, 344 loadF, 345 loadI32, 346 loadU32, 347 loadEnvVec4, 348 loadEnvMatrix, 349 350 storeF, 351 storeI32, 352 storeU32, 353 storeEnvVec4, 354 storeEnvMatrix, 355 356 matrixLoadIdentity, 357 matrixLoadFloat, 358 matrixLoadMat, 359 matrixLoadRotate, 360 matrixLoadScale, 361 matrixLoadTranslate, 362 matrixLoadMultiply, 363 matrixMultiply, 364 matrixRotate, 365 matrixScale, 366 matrixTranslate, 367 368 color, 369 370 pfBindTexture, 371 pfBindSampler, 372 373 materialDiffuse, 374 materialSpecular, 375 lightPosition, 376 materialShininess, 377 uploadToTexture, 378 enable, 379 disable, 380 381 scriptRand, 382 contextBindProgramFragment, 383 contextBindProgramFragmentStore, 384 385 386 renderTriangleMesh, 387 renderTriangleMeshRange, 388 389 drawTriangleArray, 390 drawRect 391 392}; 393 394 395bool ScriptC::run(Context *rsc, uint32_t launchIndex) 396{ 397 Context::ScriptTLSStruct * tls = 398 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); 399 400 if (mEnviroment.mFragmentStore.get()) { 401 rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); 402 } 403 if (mEnviroment.mFragment.get()) { 404 rsc->setFragment(mEnviroment.mFragment.get()); 405 } 406 if (mEnviroment.mVertex.get()) { 407 rsc->setVertex(mEnviroment.mVertex.get()); 408 } 409 410 tls->mScript = this; 411 return mProgram.mScript(launchIndex, &scriptCPtrTable) != 0; 412 tls->mScript = NULL; 413} 414 415ScriptCState::ScriptCState() 416{ 417 clear(); 418} 419 420ScriptCState::~ScriptCState() 421{ 422 if (mAccScript) { 423 accDeleteScript(mAccScript); 424 } 425} 426 427void ScriptCState::clear() 428{ 429 memset(&mProgram, 0, sizeof(mProgram)); 430 431 mConstantBufferTypes.clear(); 432 433 memset(&mEnviroment, 0, sizeof(mEnviroment)); 434 mEnviroment.mClearColor[0] = 0; 435 mEnviroment.mClearColor[1] = 0; 436 mEnviroment.mClearColor[2] = 0; 437 mEnviroment.mClearColor[3] = 1; 438 mEnviroment.mClearDepth = 1; 439 mEnviroment.mClearStencil = 0; 440 mEnviroment.mIsRoot = false; 441 442 mAccScript = NULL; 443 444} 445 446 447void ScriptCState::runCompiler(Context *rsc) 448{ 449 mAccScript = accCreateScript(); 450 String8 tmp; 451 452 rsc->appendNameDefines(&tmp); 453 454 const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; 455 int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; 456 accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); 457 accCompileScript(mAccScript); 458 accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); 459 rsAssert(mProgram.mScript); 460 461 mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); 462 mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); 463 mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); 464 465 if (mProgram.mScript) { 466 const static int pragmaMax = 16; 467 ACCsizei pragmaCount; 468 ACCchar * str[pragmaMax]; 469 accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]); 470 471 for (int ct=0; ct < pragmaCount; ct+=2) { 472 LOGE("pragma %i %s %s", ct, str[ct], str[ct+1]); 473 474 if (!strcmp(str[ct], "version")) { 475 continue; 476 477 } 478 479 480 if (!strcmp(str[ct], "stateVertex")) { 481 if (!strcmp(str[ct+1], "default")) { 482 continue; 483 } 484 if (!strcmp(str[ct+1], "parent")) { 485 mEnviroment.mVertex.clear(); 486 continue; 487 } 488 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); 489 if (pv != NULL) { 490 mEnviroment.mVertex.set(pv); 491 continue; 492 } 493 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); 494 } 495 496 if (!strcmp(str[ct], "stateRaster")) { 497 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); 498 } 499 500 if (!strcmp(str[ct], "stateFragment")) { 501 if (!strcmp(str[ct+1], "default")) { 502 continue; 503 } 504 if (!strcmp(str[ct+1], "parent")) { 505 mEnviroment.mFragment.clear(); 506 continue; 507 } 508 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); 509 if (pf != NULL) { 510 mEnviroment.mFragment.set(pf); 511 continue; 512 } 513 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); 514 } 515 516 if (!strcmp(str[ct], "stateFragmentStore")) { 517 if (!strcmp(str[ct+1], "default")) { 518 continue; 519 } 520 if (!strcmp(str[ct+1], "parent")) { 521 mEnviroment.mFragmentStore.clear(); 522 continue; 523 } 524 ProgramFragmentStore * pfs = 525 (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); 526 if (pfs != NULL) { 527 mEnviroment.mFragmentStore.set(pfs); 528 continue; 529 } 530 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]); 531 } 532 533 } 534 535 536 } else { 537 // Deal with an error. 538 } 539 540} 541 542namespace android { 543namespace renderscript { 544 545void rsi_ScriptCBegin(Context * rsc) 546{ 547 ScriptCState *ss = &rsc->mScriptC; 548 ss->clear(); 549} 550 551void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a) 552{ 553 ScriptCState *ss = &rsc->mScriptC; 554 ss->mEnviroment.mClearColor[0] = r; 555 ss->mEnviroment.mClearColor[1] = g; 556 ss->mEnviroment.mClearColor[2] = b; 557 ss->mEnviroment.mClearColor[3] = a; 558} 559 560void rsi_ScriptCSetClearDepth(Context * rsc, float v) 561{ 562 ScriptCState *ss = &rsc->mScriptC; 563 ss->mEnviroment.mClearDepth = v; 564} 565 566void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v) 567{ 568 ScriptCState *ss = &rsc->mScriptC; 569 ss->mEnviroment.mClearStencil = v; 570} 571 572void rsi_ScriptCAddType(Context * rsc, RsType vt) 573{ 574 ScriptCState *ss = &rsc->mScriptC; 575 ss->mConstantBufferTypes.add(static_cast<const Type *>(vt)); 576} 577 578void rsi_ScriptCSetScript(Context * rsc, void *vp) 579{ 580 ScriptCState *ss = &rsc->mScriptC; 581 ss->mProgram.mScript = reinterpret_cast<rsc_RunScript>(vp); 582} 583 584void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) 585{ 586 ScriptCState *ss = &rsc->mScriptC; 587 ss->mEnviroment.mIsRoot = isRoot; 588} 589 590void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) 591{ 592 ScriptCState *ss = &rsc->mScriptC; 593 ss->mProgram.mScriptText = text; 594 ss->mProgram.mScriptTextLength = len; 595} 596 597 598RsScript rsi_ScriptCCreate(Context * rsc) 599{ 600 ScriptCState *ss = &rsc->mScriptC; 601 602 ss->runCompiler(rsc); 603 604 ScriptC *s = new ScriptC(); 605 s->incRef(); 606 s->mAccScript = ss->mAccScript; 607 ss->mAccScript = NULL; 608 s->mEnviroment = ss->mEnviroment; 609 s->mProgram = ss->mProgram; 610 ss->clear(); 611 612 return s; 613} 614 615} 616} 617 618 619