rsScriptC_Lib.cpp revision cdfdb8f2cdf4668c476cac842212892b2505ff3f
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 "utils/Timers.h" 22 23#include <time.h> 24 25using namespace android; 26using namespace android::renderscript; 27 28#define GET_TLS() ScriptTLSStruct * tls = \ 29 (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 30 Context * rsc = tls->mContext; \ 31 ScriptC * sc = (ScriptC *) tls->mScript 32 33 34////////////////////////////////////////////////////////////////////////////// 35// Math routines 36////////////////////////////////////////////////////////////////////////////// 37 38#if 0 39static float SC_sinf_fast(float x) { 40 const float A = 1.0f / (2.0f * M_PI); 41 const float B = -16.0f; 42 const float C = 8.0f; 43 44 // scale angle for easy argument reduction 45 x *= A; 46 47 if (fabsf(x) >= 0.5f) { 48 // argument reduction 49 x = x - ceilf(x + 0.5f) + 1.0f; 50 } 51 52 const float y = B * x * fabsf(x) + C * x; 53 return 0.2215f * (y * fabsf(y) - y) + y; 54} 55 56static float SC_cosf_fast(float x) { 57 x += float(M_PI / 2); 58 59 const float A = 1.0f / (2.0f * M_PI); 60 const float B = -16.0f; 61 const float C = 8.0f; 62 63 // scale angle for easy argument reduction 64 x *= A; 65 66 if (fabsf(x) >= 0.5f) { 67 // argument reduction 68 x = x - ceilf(x + 0.5f) + 1.0f; 69 } 70 71 const float y = B * x * fabsf(x) + C * x; 72 return 0.2215f * (y * fabsf(y) - y) + y; 73} 74#endif 75 76static float SC_randf(float max) { 77 float r = (float)rand(); 78 r *= max; 79 return r / RAND_MAX; 80} 81 82static float SC_randf2(float min, float max) { 83 float r = (float)rand(); 84 r = r * (max - min) + min; 85 return r / RAND_MAX; 86} 87 88static int SC_randi(int max) { 89 return (int)SC_randf(max); 90} 91 92static int SC_randi2(int min, int max) { 93 return (int)SC_randf2(min, max); 94} 95 96static float SC_frac(float v) { 97 int i = (int)floor(v); 98 return fmin(v - i, 0x1.fffffep-1f); 99} 100 101////////////////////////////////////////////////////////////////////////////// 102// Time routines 103////////////////////////////////////////////////////////////////////////////// 104 105static time_t SC_time(time_t *timer) { 106 GET_TLS(); 107 return time(timer); 108} 109 110static tm* SC_localtime(tm *local, time_t *timer) { 111 GET_TLS(); 112 if (!local) { 113 return NULL; 114 } 115 116 // The native localtime function is not thread-safe, so we 117 // have to apply locking for proper behavior in RenderScript. 118 pthread_mutex_lock(&rsc->gLibMutex); 119 tm *tmp = localtime(timer); 120 memcpy(local, tmp, sizeof(*tmp)); 121 pthread_mutex_unlock(&rsc->gLibMutex); 122 return local; 123} 124 125static int64_t SC_uptimeMillis() { 126 return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 127} 128 129static int64_t SC_uptimeNanos() { 130 return systemTime(SYSTEM_TIME_MONOTONIC); 131} 132 133static float SC_getDt() { 134 GET_TLS(); 135 int64_t l = sc->mEnviroment.mLastDtTime; 136 sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC); 137 return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9; 138} 139 140////////////////////////////////////////////////////////////////////////////// 141// 142////////////////////////////////////////////////////////////////////////////// 143 144static uint32_t SC_allocGetDimX(Allocation *a) { 145 CHECK_OBJ(a); 146 return a->mHal.state.dimensionX; 147} 148 149static uint32_t SC_allocGetDimY(Allocation *a) { 150 CHECK_OBJ(a); 151 return a->mHal.state.dimensionY; 152} 153 154static uint32_t SC_allocGetDimZ(Allocation *a) { 155 CHECK_OBJ(a); 156 return a->mHal.state.dimensionZ; 157} 158 159static uint32_t SC_allocGetDimLOD(Allocation *a) { 160 CHECK_OBJ(a); 161 return a->mHal.state.hasMipmaps; 162} 163 164static uint32_t SC_allocGetDimFaces(Allocation *a) { 165 CHECK_OBJ(a); 166 return a->mHal.state.hasFaces; 167} 168 169static const void * SC_getElementAtX(Allocation *a, uint32_t x) { 170 CHECK_OBJ(a); 171 const uint8_t *p = (const uint8_t *)a->getPtr(); 172 return &p[a->mHal.state.elementSizeBytes * x]; 173} 174 175static const void * SC_getElementAtXY(Allocation *a, uint32_t x, uint32_t y) { 176 CHECK_OBJ(a); 177 const uint8_t *p = (const uint8_t *)a->getPtr(); 178 return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX)]; 179} 180 181static const void * SC_getElementAtXYZ(Allocation *a, uint32_t x, uint32_t y, uint32_t z) { 182 CHECK_OBJ(a); 183 const uint8_t *p = (const uint8_t *)a->getPtr(); 184 return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX + 185 z * a->mHal.state.dimensionX * a->mHal.state.dimensionY)]; 186} 187 188void android::renderscript::rsiSetObject(ObjectBase **dst, ObjectBase * src) { 189 //LOGE("rsiSetObject %p,%p %p", vdst, *vdst, vsrc); 190 if (src) { 191 CHECK_OBJ(src); 192 src->incSysRef(); 193 } 194 if (dst[0]) { 195 CHECK_OBJ(dst[0]); 196 dst[0]->decSysRef(); 197 } 198 *dst = src; 199} 200 201void android::renderscript::rsiClearObject(ObjectBase **dst) { 202 //LOGE("rsiClearObject %p,%p", vdst, *vdst); 203 if (dst[0]) { 204 CHECK_OBJ(dst[0]); 205 dst[0]->decSysRef(); 206 } 207 *dst = NULL; 208} 209 210bool android::renderscript::rsiIsObject(const ObjectBase *src) { 211 return src != NULL; 212} 213 214static void SC_debugF(const char *s, float f) { 215 LOGD("%s %f, 0x%08x", s, f, *((int *) (&f))); 216} 217static void SC_debugFv2(const char *s, float f1, float f2) { 218 LOGD("%s {%f, %f}", s, f1, f2); 219} 220static void SC_debugFv3(const char *s, float f1, float f2, float f3) { 221 LOGD("%s {%f, %f, %f}", s, f1, f2, f3); 222} 223static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) { 224 LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); 225} 226static void SC_debugD(const char *s, double d) { 227 LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d))); 228} 229static void SC_debugFM4v4(const char *s, const float *f) { 230 LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); 231 LOGD("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); 232 LOGD("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); 233 LOGD("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); 234} 235static void SC_debugFM3v3(const char *s, const float *f) { 236 LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]); 237 LOGD("%s %f, %f, %f", s, f[1], f[4], f[7]); 238 LOGD("%s %f, %f, %f}",s, f[2], f[5], f[8]); 239} 240static void SC_debugFM2v2(const char *s, const float *f) { 241 LOGD("%s {%f, %f", s, f[0], f[2]); 242 LOGD("%s %f, %f}",s, f[1], f[3]); 243} 244 245static void SC_debugI32(const char *s, int32_t i) { 246 LOGD("%s %i 0x%x", s, i, i); 247} 248static void SC_debugU32(const char *s, uint32_t i) { 249 LOGD("%s %u 0x%x", s, i, i); 250} 251static void SC_debugLL64(const char *s, long long ll) { 252 LOGD("%s %lld 0x%llx", s, ll, ll); 253} 254static void SC_debugULL64(const char *s, unsigned long long ll) { 255 LOGD("%s %llu 0x%llx", s, ll, ll); 256} 257 258static void SC_debugP(const char *s, const void *p) { 259 LOGD("%s %p", s, p); 260} 261 262static uint32_t SC_toClient2(int cmdID, void *data, int len) { 263 GET_TLS(); 264 //LOGE("SC_toClient %i %i %i", cmdID, len); 265 return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, false); 266} 267 268static uint32_t SC_toClient(int cmdID) { 269 GET_TLS(); 270 //LOGE("SC_toClient %i", cmdID); 271 return rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_USER, cmdID, 0, false); 272} 273 274static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) { 275 GET_TLS(); 276 //LOGE("SC_toClientBlocking %i %i", cmdID, len); 277 return rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, cmdID, len, true); 278} 279 280static uint32_t SC_toClientBlocking(int cmdID) { 281 GET_TLS(); 282 //LOGE("SC_toClientBlocking %i", cmdID); 283 return rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_USER, cmdID, 0, true); 284} 285 286int SC_divsi3(int a, int b) { 287 return a / b; 288} 289 290int SC_modsi3(int a, int b) { 291 return a % b; 292} 293 294unsigned int SC_udivsi3(unsigned int a, unsigned int b) { 295 return a / b; 296} 297 298unsigned int SC_umodsi3(unsigned int a, unsigned int b) { 299 return a % b; 300} 301 302int SC_getAllocation(const void *ptr) { 303 GET_TLS(); 304 const Allocation *alloc = sc->ptrToAllocation(ptr); 305 return (int)alloc; 306} 307 308void SC_allocationMarkDirty(RsAllocation a) { 309 Allocation *alloc = static_cast<Allocation *>(a); 310 alloc->sendDirty(); 311} 312 313void SC_ForEach(RsScript vs, 314 RsAllocation vin, 315 RsAllocation vout, 316 const void *usr) { 317 GET_TLS(); 318 const Allocation *ain = static_cast<const Allocation *>(vin); 319 Allocation *aout = static_cast<Allocation *>(vout); 320 Script *s = static_cast<Script *>(vs); 321 s->runForEach(rsc, ain, aout, usr); 322} 323 324void SC_ForEach2(RsScript vs, 325 RsAllocation vin, 326 RsAllocation vout, 327 const void *usr, 328 const RsScriptCall *call) { 329 GET_TLS(); 330 const Allocation *ain = static_cast<const Allocation *>(vin); 331 Allocation *aout = static_cast<Allocation *>(vout); 332 Script *s = static_cast<Script *>(vs); 333 s->runForEach(rsc, ain, aout, usr, call); 334} 335 336 337////////////////////////////////////////////////////////////////////////////// 338// Heavy math functions 339////////////////////////////////////////////////////////////////////////////// 340 341typedef struct { 342 float m[16]; 343} rs_matrix4x4; 344 345typedef struct { 346 float m[9]; 347} rs_matrix3x3; 348 349typedef struct { 350 float m[4]; 351} rs_matrix2x2; 352 353static inline void 354rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) { 355 m->m[row * 4 + col] = v; 356} 357 358static inline float 359rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) { 360 return m->m[row * 4 + col]; 361} 362 363static inline void 364rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) { 365 m->m[row * 3 + col] = v; 366} 367 368static inline float 369rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) { 370 return m->m[row * 3 + col]; 371} 372 373static inline void 374rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) { 375 m->m[row * 2 + col] = v; 376} 377 378static inline float 379rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) { 380 return m->m[row * 2 + col]; 381} 382 383 384static void SC_MatrixLoadIdentity_4x4(rs_matrix4x4 *m) { 385 m->m[0] = 1.f; 386 m->m[1] = 0.f; 387 m->m[2] = 0.f; 388 m->m[3] = 0.f; 389 m->m[4] = 0.f; 390 m->m[5] = 1.f; 391 m->m[6] = 0.f; 392 m->m[7] = 0.f; 393 m->m[8] = 0.f; 394 m->m[9] = 0.f; 395 m->m[10] = 1.f; 396 m->m[11] = 0.f; 397 m->m[12] = 0.f; 398 m->m[13] = 0.f; 399 m->m[14] = 0.f; 400 m->m[15] = 1.f; 401} 402 403static void SC_MatrixLoadIdentity_3x3(rs_matrix3x3 *m) { 404 m->m[0] = 1.f; 405 m->m[1] = 0.f; 406 m->m[2] = 0.f; 407 m->m[3] = 0.f; 408 m->m[4] = 1.f; 409 m->m[5] = 0.f; 410 m->m[6] = 0.f; 411 m->m[7] = 0.f; 412 m->m[8] = 1.f; 413} 414 415static void SC_MatrixLoadIdentity_2x2(rs_matrix2x2 *m) { 416 m->m[0] = 1.f; 417 m->m[1] = 0.f; 418 m->m[2] = 0.f; 419 m->m[3] = 1.f; 420} 421 422static void SC_MatrixLoad_4x4_f(rs_matrix4x4 *m, const float *v) { 423 m->m[0] = v[0]; 424 m->m[1] = v[1]; 425 m->m[2] = v[2]; 426 m->m[3] = v[3]; 427 m->m[4] = v[4]; 428 m->m[5] = v[5]; 429 m->m[6] = v[6]; 430 m->m[7] = v[7]; 431 m->m[8] = v[8]; 432 m->m[9] = v[9]; 433 m->m[10] = v[10]; 434 m->m[11] = v[11]; 435 m->m[12] = v[12]; 436 m->m[13] = v[13]; 437 m->m[14] = v[14]; 438 m->m[15] = v[15]; 439} 440 441static void SC_MatrixLoad_3x3_f(rs_matrix3x3 *m, const float *v) { 442 m->m[0] = v[0]; 443 m->m[1] = v[1]; 444 m->m[2] = v[2]; 445 m->m[3] = v[3]; 446 m->m[4] = v[4]; 447 m->m[5] = v[5]; 448 m->m[6] = v[6]; 449 m->m[7] = v[7]; 450 m->m[8] = v[8]; 451} 452 453static void SC_MatrixLoad_2x2_f(rs_matrix2x2 *m, const float *v) { 454 m->m[0] = v[0]; 455 m->m[1] = v[1]; 456 m->m[2] = v[2]; 457 m->m[3] = v[3]; 458} 459 460static void SC_MatrixLoad_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *v) { 461 m->m[0] = v->m[0]; 462 m->m[1] = v->m[1]; 463 m->m[2] = v->m[2]; 464 m->m[3] = v->m[3]; 465 m->m[4] = v->m[4]; 466 m->m[5] = v->m[5]; 467 m->m[6] = v->m[6]; 468 m->m[7] = v->m[7]; 469 m->m[8] = v->m[8]; 470 m->m[9] = v->m[9]; 471 m->m[10] = v->m[10]; 472 m->m[11] = v->m[11]; 473 m->m[12] = v->m[12]; 474 m->m[13] = v->m[13]; 475 m->m[14] = v->m[14]; 476 m->m[15] = v->m[15]; 477} 478 479static void SC_MatrixLoad_4x4_3x3(rs_matrix4x4 *m, const rs_matrix3x3 *v) { 480 m->m[0] = v->m[0]; 481 m->m[1] = v->m[1]; 482 m->m[2] = v->m[2]; 483 m->m[3] = 0.f; 484 m->m[4] = v->m[3]; 485 m->m[5] = v->m[4]; 486 m->m[6] = v->m[5]; 487 m->m[7] = 0.f; 488 m->m[8] = v->m[6]; 489 m->m[9] = v->m[7]; 490 m->m[10] = v->m[8]; 491 m->m[11] = 0.f; 492 m->m[12] = 0.f; 493 m->m[13] = 0.f; 494 m->m[14] = 0.f; 495 m->m[15] = 1.f; 496} 497 498static void SC_MatrixLoad_4x4_2x2(rs_matrix4x4 *m, const rs_matrix2x2 *v) { 499 m->m[0] = v->m[0]; 500 m->m[1] = v->m[1]; 501 m->m[2] = 0.f; 502 m->m[3] = 0.f; 503 m->m[4] = v->m[2]; 504 m->m[5] = v->m[3]; 505 m->m[6] = 0.f; 506 m->m[7] = 0.f; 507 m->m[8] = 0.f; 508 m->m[9] = 0.f; 509 m->m[10] = 1.f; 510 m->m[11] = 0.f; 511 m->m[12] = 0.f; 512 m->m[13] = 0.f; 513 m->m[14] = 0.f; 514 m->m[15] = 1.f; 515} 516 517static void SC_MatrixLoad_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *v) { 518 m->m[0] = v->m[0]; 519 m->m[1] = v->m[1]; 520 m->m[2] = v->m[2]; 521 m->m[3] = v->m[3]; 522 m->m[4] = v->m[4]; 523 m->m[5] = v->m[5]; 524 m->m[6] = v->m[6]; 525 m->m[7] = v->m[7]; 526 m->m[8] = v->m[8]; 527} 528 529static void SC_MatrixLoad_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *v) { 530 m->m[0] = v->m[0]; 531 m->m[1] = v->m[1]; 532 m->m[2] = v->m[2]; 533 m->m[3] = v->m[3]; 534} 535 536static void SC_MatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 537 float c, s; 538 m->m[3] = 0; 539 m->m[7] = 0; 540 m->m[11]= 0; 541 m->m[12]= 0; 542 m->m[13]= 0; 543 m->m[14]= 0; 544 m->m[15]= 1; 545 rot *= (float)(M_PI / 180.0f); 546 c = cos(rot); 547 s = sin(rot); 548 549 const float len = x*x + y*y + z*z; 550 if (len != 1) { 551 const float recipLen = 1.f / sqrt(len); 552 x *= recipLen; 553 y *= recipLen; 554 z *= recipLen; 555 } 556 const float nc = 1.0f - c; 557 const float xy = x * y; 558 const float yz = y * z; 559 const float zx = z * x; 560 const float xs = x * s; 561 const float ys = y * s; 562 const float zs = z * s; 563 m->m[ 0] = x*x*nc + c; 564 m->m[ 4] = xy*nc - zs; 565 m->m[ 8] = zx*nc + ys; 566 m->m[ 1] = xy*nc + zs; 567 m->m[ 5] = y*y*nc + c; 568 m->m[ 9] = yz*nc - xs; 569 m->m[ 2] = zx*nc - ys; 570 m->m[ 6] = yz*nc + xs; 571 m->m[10] = z*z*nc + c; 572} 573 574static void SC_MatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) { 575 SC_MatrixLoadIdentity_4x4(m); 576 m->m[0] = x; 577 m->m[5] = y; 578 m->m[10] = z; 579} 580 581static void SC_MatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) { 582 SC_MatrixLoadIdentity_4x4(m); 583 m->m[12] = x; 584 m->m[13] = y; 585 m->m[14] = z; 586} 587 588static void SC_MatrixLoadMultiply_4x4_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) { 589 for (int i=0 ; i<4 ; i++) { 590 float ri0 = 0; 591 float ri1 = 0; 592 float ri2 = 0; 593 float ri3 = 0; 594 for (int j=0 ; j<4 ; j++) { 595 const float rhs_ij = rsMatrixGet(rhs, i,j); 596 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 597 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 598 ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 599 ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij; 600 } 601 rsMatrixSet(m, i, 0, ri0); 602 rsMatrixSet(m, i, 1, ri1); 603 rsMatrixSet(m, i, 2, ri2); 604 rsMatrixSet(m, i, 3, ri3); 605 } 606} 607 608static void SC_MatrixMultiply_4x4_4x4(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) { 609 rs_matrix4x4 mt; 610 SC_MatrixLoadMultiply_4x4_4x4_4x4(&mt, m, rhs); 611 SC_MatrixLoad_4x4_4x4(m, &mt); 612} 613 614static void SC_MatrixLoadMultiply_3x3_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) { 615 for (int i=0 ; i<3 ; i++) { 616 float ri0 = 0; 617 float ri1 = 0; 618 float ri2 = 0; 619 for (int j=0 ; j<3 ; j++) { 620 const float rhs_ij = rsMatrixGet(rhs, i,j); 621 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 622 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 623 ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij; 624 } 625 rsMatrixSet(m, i, 0, ri0); 626 rsMatrixSet(m, i, 1, ri1); 627 rsMatrixSet(m, i, 2, ri2); 628 } 629} 630 631static void SC_MatrixMultiply_3x3_3x3(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) { 632 rs_matrix3x3 mt; 633 SC_MatrixLoadMultiply_3x3_3x3_3x3(&mt, m, rhs); 634 SC_MatrixLoad_3x3_3x3(m, &mt); 635} 636 637static void SC_MatrixLoadMultiply_2x2_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) { 638 for (int i=0 ; i<2 ; i++) { 639 float ri0 = 0; 640 float ri1 = 0; 641 for (int j=0 ; j<2 ; j++) { 642 const float rhs_ij = rsMatrixGet(rhs, i,j); 643 ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij; 644 ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij; 645 } 646 rsMatrixSet(m, i, 0, ri0); 647 rsMatrixSet(m, i, 1, ri1); 648 } 649} 650 651static void SC_MatrixMultiply_2x2_2x2(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) { 652 rs_matrix2x2 mt; 653 SC_MatrixLoadMultiply_2x2_2x2_2x2(&mt, m, rhs); 654 SC_MatrixLoad_2x2_2x2(m, &mt); 655} 656 657static void SC_MatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) { 658 rs_matrix4x4 m1; 659 SC_MatrixLoadRotate(&m1, rot, x, y, z); 660 SC_MatrixMultiply_4x4_4x4(m, &m1); 661} 662 663static void SC_MatrixScale(rs_matrix4x4 *m, float x, float y, float z) { 664 rs_matrix4x4 m1; 665 SC_MatrixLoadScale(&m1, x, y, z); 666 SC_MatrixMultiply_4x4_4x4(m, &m1); 667} 668 669static void SC_MatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) { 670 rs_matrix4x4 m1; 671 SC_MatrixLoadTranslate(&m1, x, y, z); 672 SC_MatrixMultiply_4x4_4x4(m, &m1); 673} 674 675static void SC_MatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 676 SC_MatrixLoadIdentity_4x4(m); 677 m->m[0] = 2.f / (right - left); 678 m->m[5] = 2.f / (top - bottom); 679 m->m[10]= -2.f / (far - near); 680 m->m[12]= -(right + left) / (right - left); 681 m->m[13]= -(top + bottom) / (top - bottom); 682 m->m[14]= -(far + near) / (far - near); 683} 684 685static void SC_MatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) { 686 SC_MatrixLoadIdentity_4x4(m); 687 m->m[0] = 2.f * near / (right - left); 688 m->m[5] = 2.f * near / (top - bottom); 689 m->m[8] = (right + left) / (right - left); 690 m->m[9] = (top + bottom) / (top - bottom); 691 m->m[10]= -(far + near) / (far - near); 692 m->m[11]= -1.f; 693 m->m[14]= -2.f * far * near / (far - near); 694 m->m[15]= 0.f; 695} 696 697static void SC_MatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far) { 698 float top = near * tan((float) (fovy * M_PI / 360.0f)); 699 float bottom = -top; 700 float left = bottom * aspect; 701 float right = top * aspect; 702 SC_MatrixLoadFrustum(m, left, right, bottom, top, near, far); 703} 704 705 706// Returns true if the matrix was successfully inversed 707static bool SC_MatrixInverse_4x4(rs_matrix4x4 *m) { 708 rs_matrix4x4 result; 709 710 int i, j; 711 for (i = 0; i < 4; ++i) { 712 for (j = 0; j < 4; ++j) { 713 // computeCofactor for int i, int j 714 int c0 = (i+1) % 4; 715 int c1 = (i+2) % 4; 716 int c2 = (i+3) % 4; 717 int r0 = (j+1) % 4; 718 int r1 = (j+2) % 4; 719 int r2 = (j+3) % 4; 720 721 float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1])) 722 - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0])) 723 + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0])); 724 725 float cofactor = (i+j) & 1 ? -minor : minor; 726 727 result.m[4*i + j] = cofactor; 728 } 729 } 730 731 // Dot product of 0th column of source and 0th row of result 732 float det = m->m[0]*result.m[0] + m->m[4]*result.m[1] + 733 m->m[8]*result.m[2] + m->m[12]*result.m[3]; 734 735 if (fabs(det) < 1e-6) { 736 return false; 737 } 738 739 det = 1.0f / det; 740 for (i = 0; i < 16; ++i) { 741 m->m[i] = result.m[i] * det; 742 } 743 744 return true; 745} 746 747// Returns true if the matrix was successfully inversed 748static bool SC_MatrixInverseTranspose_4x4(rs_matrix4x4 *m) { 749 rs_matrix4x4 result; 750 751 int i, j; 752 for (i = 0; i < 4; ++i) { 753 for (j = 0; j < 4; ++j) { 754 // computeCofactor for int i, int j 755 int c0 = (i+1) % 4; 756 int c1 = (i+2) % 4; 757 int c2 = (i+3) % 4; 758 int r0 = (j+1) % 4; 759 int r1 = (j+2) % 4; 760 int r2 = (j+3) % 4; 761 762 float minor = (m->m[c0 + 4*r0] * (m->m[c1 + 4*r1] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r1])) 763 - (m->m[c0 + 4*r1] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r2] - m->m[c1 + 4*r2] * m->m[c2 + 4*r0])) 764 + (m->m[c0 + 4*r2] * (m->m[c1 + 4*r0] * m->m[c2 + 4*r1] - m->m[c1 + 4*r1] * m->m[c2 + 4*r0])); 765 766 float cofactor = (i+j) & 1 ? -minor : minor; 767 768 result.m[4*j + i] = cofactor; 769 } 770 } 771 772 // Dot product of 0th column of source and 0th column of result 773 float det = m->m[0]*result.m[0] + m->m[4]*result.m[4] + 774 m->m[8]*result.m[8] + m->m[12]*result.m[12]; 775 776 if (fabs(det) < 1e-6) { 777 return false; 778 } 779 780 det = 1.0f / det; 781 for (i = 0; i < 16; ++i) { 782 m->m[i] = result.m[i] * det; 783 } 784 785 return true; 786} 787 788static void SC_MatrixTranspose_4x4(rs_matrix4x4 *m) { 789 int i, j; 790 float temp; 791 for (i = 0; i < 3; ++i) { 792 for (j = i + 1; j < 4; ++j) { 793 temp = m->m[i*4 + j]; 794 m->m[i*4 + j] = m->m[j*4 + i]; 795 m->m[j*4 + i] = temp; 796 } 797 } 798} 799 800static void SC_MatrixTranspose_3x3(rs_matrix3x3 *m) { 801 int i, j; 802 float temp; 803 for (i = 0; i < 2; ++i) { 804 for (j = i + 1; j < 3; ++j) { 805 temp = m->m[i*3 + j]; 806 m->m[i*3 + j] = m->m[j*4 + i]; 807 m->m[j*3 + i] = temp; 808 } 809 } 810} 811 812static void SC_MatrixTranspose_2x2(rs_matrix2x2 *m) { 813 float temp = m->m[1]; 814 m->m[1] = m->m[2]; 815 m->m[2] = temp; 816} 817 818 819////////////////////////////////////////////////////////////////////////////// 820// Class implementation 821////////////////////////////////////////////////////////////////////////////// 822 823// llvm name mangling ref 824// <builtin-type> ::= v # void 825// ::= b # bool 826// ::= c # char 827// ::= a # signed char 828// ::= h # unsigned char 829// ::= s # short 830// ::= t # unsigned short 831// ::= i # int 832// ::= j # unsigned int 833// ::= l # long 834// ::= m # unsigned long 835// ::= x # long long, __int64 836// ::= y # unsigned long long, __int64 837// ::= f # float 838// ::= d # double 839 840static ScriptCState::SymbolTable_t gSyms[] = { 841 { "__divsi3", (void *)&SC_divsi3, true }, 842 { "__modsi3", (void *)&SC_modsi3, true }, 843 { "__udivsi3", (void *)&SC_udivsi3, true }, 844 { "__umodsi3", (void *)&SC_umodsi3, true }, 845 { "memset", (void *)&memset, true }, 846 { "memcpy", (void *)&memcpy, true }, 847 848 // allocation 849 { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true }, 850 { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY, true }, 851 { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ, true }, 852 { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD, true }, 853 { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces, true }, 854 { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation, true }, 855 856 { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX, true }, 857 { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true }, 858 { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true }, 859 860 { "_Z11rsSetObjectP10rs_elementS_", (void *)&rsiSetObject, true }, 861 { "_Z13rsClearObjectP10rs_element", (void *)&rsiClearObject, true }, 862 { "_Z10rsIsObject10rs_element", (void *)&rsiIsObject, true }, 863 864 { "_Z11rsSetObjectP7rs_typeS_", (void *)&rsiSetObject, true }, 865 { "_Z13rsClearObjectP7rs_type", (void *)&rsiClearObject, true }, 866 { "_Z10rsIsObject7rs_type", (void *)&rsiIsObject, true }, 867 868 { "_Z11rsSetObjectP13rs_allocationS_", (void *)&rsiSetObject, true }, 869 { "_Z13rsClearObjectP13rs_allocation", (void *)&rsiClearObject, true }, 870 { "_Z10rsIsObject13rs_allocation", (void *)&rsiIsObject, true }, 871 872 { "_Z11rsSetObjectP10rs_samplerS_", (void *)&rsiSetObject, true }, 873 { "_Z13rsClearObjectP10rs_sampler", (void *)&rsiClearObject, true }, 874 { "_Z10rsIsObject10rs_sampler", (void *)&rsiIsObject, true }, 875 876 { "_Z11rsSetObjectP9rs_scriptS_", (void *)&rsiSetObject, true }, 877 { "_Z13rsClearObjectP9rs_script", (void *)&rsiClearObject, true }, 878 { "_Z10rsIsObject9rs_script", (void *)&rsiIsObject, true }, 879 880 { "_Z11rsSetObjectP7rs_meshS_", (void *)&rsiSetObject, true }, 881 { "_Z13rsClearObjectP7rs_mesh", (void *)&rsiClearObject, true }, 882 { "_Z10rsIsObject7rs_mesh", (void *)&rsiIsObject, true }, 883 884 { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&rsiSetObject, true }, 885 { "_Z13rsClearObjectP19rs_program_fragment", (void *)&rsiClearObject, true }, 886 { "_Z10rsIsObject19rs_program_fragment", (void *)&rsiIsObject, true }, 887 888 { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&rsiSetObject, true }, 889 { "_Z13rsClearObjectP17rs_program_vertex", (void *)&rsiClearObject, true }, 890 { "_Z10rsIsObject17rs_program_vertex", (void *)&rsiIsObject, true }, 891 892 { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&rsiSetObject, true }, 893 { "_Z13rsClearObjectP17rs_program_raster", (void *)&rsiClearObject, true }, 894 { "_Z10rsIsObject17rs_program_raster", (void *)&rsiIsObject, true }, 895 896 { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&rsiSetObject, true }, 897 { "_Z13rsClearObjectP16rs_program_store", (void *)&rsiClearObject, true }, 898 { "_Z10rsIsObject16rs_program_store", (void *)&rsiIsObject, true }, 899 900 { "_Z11rsSetObjectP7rs_fontS_", (void *)&rsiSetObject, true }, 901 { "_Z13rsClearObjectP7rs_font", (void *)&rsiClearObject, true }, 902 { "_Z10rsIsObject7rs_font", (void *)&rsiIsObject, true }, 903 904 905 { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_allocationMarkDirty, true }, 906 907 908 // Debug 909 { "_Z7rsDebugPKcf", (void *)&SC_debugF, true }, 910 { "_Z7rsDebugPKcff", (void *)&SC_debugFv2, true }, 911 { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3, true }, 912 { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4, true }, 913 { "_Z7rsDebugPKcd", (void *)&SC_debugD, true }, 914 { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4, true }, 915 { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3, true }, 916 { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2, true }, 917 { "_Z7rsDebugPKci", (void *)&SC_debugI32, true }, 918 { "_Z7rsDebugPKcj", (void *)&SC_debugU32, true }, 919 // Both "long" and "unsigned long" need to be redirected to their 920 // 64-bit counterparts, since we have hacked Slang to use 64-bit 921 // for "long" on Arm (to be similar to Java). 922 { "_Z7rsDebugPKcl", (void *)&SC_debugLL64, true }, 923 { "_Z7rsDebugPKcm", (void *)&SC_debugULL64, true }, 924 { "_Z7rsDebugPKcx", (void *)&SC_debugLL64, true }, 925 { "_Z7rsDebugPKcy", (void *)&SC_debugULL64, true }, 926 { "_Z7rsDebugPKcPKv", (void *)&SC_debugP, true }, 927 928 // RS Math 929 { "_Z6rsRandi", (void *)&SC_randi, true }, 930 { "_Z6rsRandii", (void *)&SC_randi2, true }, 931 { "_Z6rsRandf", (void *)&SC_randf, true }, 932 { "_Z6rsRandff", (void *)&SC_randf2, true }, 933 { "_Z6rsFracf", (void *)&SC_frac, true }, 934 935 // time 936 { "_Z6rsTimePi", (void *)&SC_time, true }, 937 { "_Z11rsLocaltimeP5rs_tmPKi", (void *)&SC_localtime, true }, 938 { "_Z14rsUptimeMillisv", (void*)&SC_uptimeMillis, true }, 939 { "_Z13rsUptimeNanosv", (void*)&SC_uptimeNanos, true }, 940 { "_Z7rsGetDtv", (void*)&SC_getDt, false }, 941 942 { "_Z14rsSendToClienti", (void *)&SC_toClient, false }, 943 { "_Z14rsSendToClientiPKvj", (void *)&SC_toClient2, false }, 944 { "_Z22rsSendToClientBlockingi", (void *)&SC_toClientBlocking, false }, 945 { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2, false }, 946 947 // matrix 948 { "_Z20rsMatrixLoadIdentityP12rs_matrix4x4", (void *)&SC_MatrixLoadIdentity_4x4, true }, 949 { "_Z20rsMatrixLoadIdentityP12rs_matrix3x3", (void *)&SC_MatrixLoadIdentity_3x3, true }, 950 { "_Z20rsMatrixLoadIdentityP12rs_matrix2x2", (void *)&SC_MatrixLoadIdentity_2x2, true }, 951 952 { "_Z12rsMatrixLoadP12rs_matrix4x4PKf", (void *)&SC_MatrixLoad_4x4_f, true }, 953 { "_Z12rsMatrixLoadP12rs_matrix3x3PKf", (void *)&SC_MatrixLoad_3x3_f, true }, 954 { "_Z12rsMatrixLoadP12rs_matrix2x2PKf", (void *)&SC_MatrixLoad_2x2_f, true }, 955 956 { "_Z12rsMatrixLoadP12rs_matrix4x4PKS_", (void *)&SC_MatrixLoad_4x4_4x4, true }, 957 { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix3x3", (void *)&SC_MatrixLoad_4x4_3x3, true }, 958 { "_Z12rsMatrixLoadP12rs_matrix4x4PK12rs_matrix2x2", (void *)&SC_MatrixLoad_4x4_2x2, true }, 959 { "_Z12rsMatrixLoadP12rs_matrix3x3PKS_", (void *)&SC_MatrixLoad_3x3_3x3, true }, 960 { "_Z12rsMatrixLoadP12rs_matrix2x2PKS_", (void *)&SC_MatrixLoad_2x2_2x2, true }, 961 962 { "_Z18rsMatrixLoadRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadRotate, true }, 963 { "_Z17rsMatrixLoadScaleP12rs_matrix4x4fff", (void *)&SC_MatrixLoadScale, true }, 964 { "_Z21rsMatrixLoadTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixLoadTranslate, true }, 965 { "_Z14rsMatrixRotateP12rs_matrix4x4ffff", (void *)&SC_MatrixRotate, true }, 966 { "_Z13rsMatrixScaleP12rs_matrix4x4fff", (void *)&SC_MatrixScale, true }, 967 { "_Z17rsMatrixTranslateP12rs_matrix4x4fff", (void *)&SC_MatrixTranslate, true }, 968 969 { "_Z20rsMatrixLoadMultiplyP12rs_matrix4x4PKS_S2_", (void *)&SC_MatrixLoadMultiply_4x4_4x4_4x4, true }, 970 { "_Z16rsMatrixMultiplyP12rs_matrix4x4PKS_", (void *)&SC_MatrixMultiply_4x4_4x4, true }, 971 { "_Z20rsMatrixLoadMultiplyP12rs_matrix3x3PKS_S2_", (void *)&SC_MatrixLoadMultiply_3x3_3x3_3x3, true }, 972 { "_Z16rsMatrixMultiplyP12rs_matrix3x3PKS_", (void *)&SC_MatrixMultiply_3x3_3x3, true }, 973 { "_Z20rsMatrixLoadMultiplyP12rs_matrix2x2PKS_S2_", (void *)&SC_MatrixLoadMultiply_2x2_2x2_2x2, true }, 974 { "_Z16rsMatrixMultiplyP12rs_matrix2x2PKS_", (void *)&SC_MatrixMultiply_2x2_2x2, true }, 975 976 { "_Z17rsMatrixLoadOrthoP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadOrtho, true }, 977 { "_Z19rsMatrixLoadFrustumP12rs_matrix4x4ffffff", (void *)&SC_MatrixLoadFrustum, true }, 978 { "_Z23rsMatrixLoadPerspectiveP12rs_matrix4x4ffff", (void *)&SC_MatrixLoadPerspective, true }, 979 980 { "_Z15rsMatrixInverseP12rs_matrix4x4", (void *)&SC_MatrixInverse_4x4, true }, 981 { "_Z24rsMatrixInverseTransposeP12rs_matrix4x4", (void *)&SC_MatrixInverseTranspose_4x4, true }, 982 { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_4x4, true }, 983 { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_3x3, true }, 984 { "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, true }, 985 986 { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false }, 987 //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2, false }, 988 989//////////////////////////////////////////////////////////////////// 990 991 //{ "sinf_fast", (void *)&SC_sinf_fast, true }, 992 //{ "cosf_fast", (void *)&SC_cosf_fast, true }, 993 994 { NULL, NULL, false } 995}; 996 997const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) { 998 ScriptCState::SymbolTable_t *syms = gSyms; 999 1000 while (syms->mPtr) { 1001 if (!strcmp(syms->mName, sym)) { 1002 return syms; 1003 } 1004 syms++; 1005 } 1006 return NULL; 1007} 1008 1009