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