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