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