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