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