rsScriptC.cpp revision 334fd9aeacd4221fc8cd1333b2a34fb3b26b3a0d
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 glVertexPointer(3, GL_FIXED, 0, vtx); 338 339 glClientActiveTexture(GL_TEXTURE0); 340 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 341 glTexCoordPointer(2, GL_FIXED, 0, tex); 342 glClientActiveTexture(GL_TEXTURE1); 343 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 344 glTexCoordPointer(2, GL_FIXED, 0, tex); 345 glClientActiveTexture(GL_TEXTURE0); 346 347 glDisableClientState(GL_NORMAL_ARRAY); 348 glDisableClientState(GL_COLOR_ARRAY); 349 350 //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); 351 352 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 353} 354 355extern "C" int32_t sinx(int32_t angle) 356{ 357 float a = ((float)angle) / 0x10000; 358 a *= 3.14f / 180.f; 359 float s = (float)sin(a); 360 return int32_t(s * 0x10000); 361} 362 363extern "C" int32_t cosx(int32_t angle) 364{ 365 float a = ((float)angle) / 0x10000; 366 a *= 3.14f / 180.f; 367 float s = (float)cos(a); 368 return int32_t(s * 0x10000); 369} 370 371extern "C" void pfBindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) 372{ 373 GET_TLS(); 374 rsi_ProgramFragmentBindTexture(rsc, 375 static_cast<ProgramFragment *>(vpf), 376 slot, 377 static_cast<Allocation *>(va)); 378 379} 380 381extern "C" void pfBindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) 382{ 383 GET_TLS(); 384 rsi_ProgramFragmentBindSampler(rsc, 385 static_cast<ProgramFragment *>(vpf), 386 slot, 387 static_cast<Sampler *>(vs)); 388 389} 390 391extern "C" void contextBindProgramFragmentStore(RsProgramFragmentStore pfs) 392{ 393 GET_TLS(); 394 rsi_ContextBindProgramFragmentStore(rsc, pfs); 395 396} 397 398extern "C" void contextBindProgramFragment(RsProgramFragment pf) 399{ 400 GET_TLS(); 401 rsi_ContextBindProgramFragment(rsc, pf); 402 403} 404 405 406static rsc_FunctionTable scriptCPtrTable = { 407 loadVp, 408 loadF, 409 loadI32, 410 loadU32, 411 loadEnvVec4, 412 loadEnvMatrix, 413 414 storeF, 415 storeI32, 416 storeU32, 417 storeEnvVec4, 418 storeEnvMatrix, 419 420 matrixLoadIdentity, 421 matrixLoadFloat, 422 matrixLoadMat, 423 matrixLoadRotate, 424 matrixLoadScale, 425 matrixLoadTranslate, 426 matrixLoadMultiply, 427 matrixMultiply, 428 matrixRotate, 429 matrixScale, 430 matrixTranslate, 431 432 color, 433 434 pfBindTexture, 435 pfBindSampler, 436 437 materialDiffuse, 438 materialSpecular, 439 lightPosition, 440 materialShininess, 441 uploadToTexture, 442 enable, 443 disable, 444 445 scriptRand, 446 contextBindProgramFragment, 447 contextBindProgramFragmentStore, 448 449 450 renderTriangleMesh, 451 renderTriangleMeshRange, 452 453 drawTriangleArray, 454 drawRect 455 456}; 457 458 459bool ScriptC::run(Context *rsc, uint32_t launchIndex) 460{ 461 Context::ScriptTLSStruct * tls = 462 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); 463 464 if (mEnviroment.mFragmentStore.get()) { 465 rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); 466 } 467 if (mEnviroment.mFragment.get()) { 468 rsc->setFragment(mEnviroment.mFragment.get()); 469 } 470 if (mEnviroment.mVertex.get()) { 471 rsc->setVertex(mEnviroment.mVertex.get()); 472 } 473 474 tls->mScript = this; 475 return mProgram.mScript(launchIndex, &scriptCPtrTable) != 0; 476 tls->mScript = NULL; 477} 478 479ScriptCState::ScriptCState() 480{ 481 clear(); 482} 483 484ScriptCState::~ScriptCState() 485{ 486 if (mAccScript) { 487 accDeleteScript(mAccScript); 488 } 489} 490 491void ScriptCState::clear() 492{ 493 memset(&mProgram, 0, sizeof(mProgram)); 494 495 mConstantBufferTypes.clear(); 496 497 memset(&mEnviroment, 0, sizeof(mEnviroment)); 498 mEnviroment.mClearColor[0] = 0; 499 mEnviroment.mClearColor[1] = 0; 500 mEnviroment.mClearColor[2] = 0; 501 mEnviroment.mClearColor[3] = 1; 502 mEnviroment.mClearDepth = 1; 503 mEnviroment.mClearStencil = 0; 504 mEnviroment.mIsRoot = false; 505 506 mAccScript = NULL; 507 508} 509 510 511void ScriptCState::runCompiler(Context *rsc) 512{ 513 mAccScript = accCreateScript(); 514 String8 tmp; 515 516 rsc->appendNameDefines(&tmp); 517 518 const char* scriptSource[] = {tmp.string(), mProgram.mScriptText}; 519 int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ; 520 accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); 521 accCompileScript(mAccScript); 522 accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript); 523 rsAssert(mProgram.mScript); 524 525 mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); 526 mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); 527 mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); 528 529 if (mProgram.mScript) { 530 const static int pragmaMax = 16; 531 ACCsizei pragmaCount; 532 ACCchar * str[pragmaMax]; 533 accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]); 534 535 for (int ct=0; ct < pragmaCount; ct+=2) { 536 if (!strcmp(str[ct], "version")) { 537 continue; 538 } 539 540 if (!strcmp(str[ct], "stateVertex")) { 541 if (!strcmp(str[ct+1], "default")) { 542 continue; 543 } 544 if (!strcmp(str[ct+1], "parent")) { 545 mEnviroment.mVertex.clear(); 546 continue; 547 } 548 ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); 549 if (pv != NULL) { 550 mEnviroment.mVertex.set(pv); 551 continue; 552 } 553 LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); 554 } 555 556 if (!strcmp(str[ct], "stateRaster")) { 557 LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); 558 } 559 560 if (!strcmp(str[ct], "stateFragment")) { 561 if (!strcmp(str[ct+1], "default")) { 562 continue; 563 } 564 if (!strcmp(str[ct+1], "parent")) { 565 mEnviroment.mFragment.clear(); 566 continue; 567 } 568 ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); 569 if (pf != NULL) { 570 mEnviroment.mFragment.set(pf); 571 continue; 572 } 573 LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); 574 } 575 576 if (!strcmp(str[ct], "stateFragmentStore")) { 577 if (!strcmp(str[ct+1], "default")) { 578 continue; 579 } 580 if (!strcmp(str[ct+1], "parent")) { 581 mEnviroment.mFragmentStore.clear(); 582 continue; 583 } 584 ProgramFragmentStore * pfs = 585 (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); 586 if (pfs != NULL) { 587 mEnviroment.mFragmentStore.set(pfs); 588 continue; 589 } 590 LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]); 591 } 592 593 } 594 595 596 } else { 597 // Deal with an error. 598 } 599 600} 601 602namespace android { 603namespace renderscript { 604 605void rsi_ScriptCBegin(Context * rsc) 606{ 607 ScriptCState *ss = &rsc->mScriptC; 608 ss->clear(); 609} 610 611void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a) 612{ 613 ScriptCState *ss = &rsc->mScriptC; 614 ss->mEnviroment.mClearColor[0] = r; 615 ss->mEnviroment.mClearColor[1] = g; 616 ss->mEnviroment.mClearColor[2] = b; 617 ss->mEnviroment.mClearColor[3] = a; 618} 619 620void rsi_ScriptCSetClearDepth(Context * rsc, float v) 621{ 622 ScriptCState *ss = &rsc->mScriptC; 623 ss->mEnviroment.mClearDepth = v; 624} 625 626void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v) 627{ 628 ScriptCState *ss = &rsc->mScriptC; 629 ss->mEnviroment.mClearStencil = v; 630} 631 632void rsi_ScriptCAddType(Context * rsc, RsType vt) 633{ 634 ScriptCState *ss = &rsc->mScriptC; 635 ss->mConstantBufferTypes.add(static_cast<const Type *>(vt)); 636} 637 638void rsi_ScriptCSetScript(Context * rsc, void *vp) 639{ 640 ScriptCState *ss = &rsc->mScriptC; 641 ss->mProgram.mScript = reinterpret_cast<rsc_RunScript>(vp); 642} 643 644void rsi_ScriptCSetRoot(Context * rsc, bool isRoot) 645{ 646 ScriptCState *ss = &rsc->mScriptC; 647 ss->mEnviroment.mIsRoot = isRoot; 648} 649 650void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) 651{ 652 ScriptCState *ss = &rsc->mScriptC; 653 ss->mProgram.mScriptText = text; 654 ss->mProgram.mScriptTextLength = len; 655} 656 657 658RsScript rsi_ScriptCCreate(Context * rsc) 659{ 660 ScriptCState *ss = &rsc->mScriptC; 661 662 ss->runCompiler(rsc); 663 664 ScriptC *s = new ScriptC(); 665 s->incRef(); 666 s->mAccScript = ss->mAccScript; 667 ss->mAccScript = NULL; 668 s->mEnviroment = ss->mEnviroment; 669 s->mProgram = ss->mProgram; 670 ss->clear(); 671 672 return s; 673} 674 675} 676} 677 678 679