rsScriptC_Lib.cpp revision df09719cbeb426a4c8279f2ce226b5874ad7c2c9
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 38static float SC_sinf_fast(float x) 39{ 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{ 58 x += float(M_PI / 2); 59 60 const float A = 1.0f / (2.0f * M_PI); 61 const float B = -16.0f; 62 const float C = 8.0f; 63 64 // scale angle for easy argument reduction 65 x *= A; 66 67 if (fabsf(x) >= 0.5f) { 68 // argument reduction 69 x = x - ceilf(x + 0.5f) + 1.0f; 70 } 71 72 const float y = B * x * fabsf(x) + C * x; 73 return 0.2215f * (y * fabsf(y) - y) + y; 74} 75 76 77static float SC_randf(float max) 78{ 79 float r = (float)rand(); 80 return r / RAND_MAX * max; 81} 82 83static float SC_randf2(float min, float max) 84{ 85 float r = (float)rand(); 86 return r / RAND_MAX * (max - min) + min; 87} 88 89static int SC_randi(int max) 90{ 91 return (int)SC_randf(max); 92} 93 94static int SC_randi2(int min, int max) 95{ 96 return (int)SC_randf2(min, max); 97} 98 99static float SC_frac(float v) 100{ 101 int i = (int)floor(v); 102 return fmin(v - i, 0x1.fffffep-1f); 103} 104 105////////////////////////////////////////////////////////////////////////////// 106// Time routines 107////////////////////////////////////////////////////////////////////////////// 108 109static int32_t SC_second() 110{ 111 GET_TLS(); 112 113 time_t rawtime; 114 time(&rawtime); 115 116 struct tm *timeinfo; 117 timeinfo = localtime(&rawtime); 118 return timeinfo->tm_sec; 119} 120 121static int32_t SC_minute() 122{ 123 GET_TLS(); 124 125 time_t rawtime; 126 time(&rawtime); 127 128 struct tm *timeinfo; 129 timeinfo = localtime(&rawtime); 130 return timeinfo->tm_min; 131} 132 133static int32_t SC_hour() 134{ 135 GET_TLS(); 136 137 time_t rawtime; 138 time(&rawtime); 139 140 struct tm *timeinfo; 141 timeinfo = localtime(&rawtime); 142 return timeinfo->tm_hour; 143} 144 145static int32_t SC_day() 146{ 147 GET_TLS(); 148 149 time_t rawtime; 150 time(&rawtime); 151 152 struct tm *timeinfo; 153 timeinfo = localtime(&rawtime); 154 return timeinfo->tm_mday; 155} 156 157static int32_t SC_month() 158{ 159 GET_TLS(); 160 161 time_t rawtime; 162 time(&rawtime); 163 164 struct tm *timeinfo; 165 timeinfo = localtime(&rawtime); 166 return timeinfo->tm_mon; 167} 168 169static int32_t SC_year() 170{ 171 GET_TLS(); 172 173 time_t rawtime; 174 time(&rawtime); 175 176 struct tm *timeinfo; 177 timeinfo = localtime(&rawtime); 178 return timeinfo->tm_year; 179} 180 181static int64_t SC_uptimeMillis() 182{ 183 return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 184} 185 186static int64_t SC_uptimeNanos() 187{ 188 return systemTime(SYSTEM_TIME_MONOTONIC); 189} 190 191static float SC_getDt() 192{ 193 GET_TLS(); 194 int64_t l = sc->mEnviroment.mLastDtTime; 195 sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC); 196 return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9; 197} 198 199 200////////////////////////////////////////////////////////////////////////////// 201// 202////////////////////////////////////////////////////////////////////////////// 203 204static uint32_t SC_allocGetDimX(RsAllocation va) 205{ 206 const Allocation *a = static_cast<const Allocation *>(va); 207 CHECK_OBJ(a); 208 //LOGE("SC_allocGetDimX a=%p type=%p", a, a->getType()); 209 return a->getType()->getDimX(); 210} 211 212static uint32_t SC_allocGetDimY(RsAllocation va) 213{ 214 const Allocation *a = static_cast<const Allocation *>(va); 215 CHECK_OBJ(a); 216 return a->getType()->getDimY(); 217} 218 219static uint32_t SC_allocGetDimZ(RsAllocation va) 220{ 221 const Allocation *a = static_cast<const Allocation *>(va); 222 CHECK_OBJ(a); 223 return a->getType()->getDimZ(); 224} 225 226static uint32_t SC_allocGetDimLOD(RsAllocation va) 227{ 228 const Allocation *a = static_cast<const Allocation *>(va); 229 CHECK_OBJ(a); 230 return a->getType()->getDimLOD(); 231} 232 233static uint32_t SC_allocGetDimFaces(RsAllocation va) 234{ 235 const Allocation *a = static_cast<const Allocation *>(va); 236 CHECK_OBJ(a); 237 return a->getType()->getDimFaces(); 238} 239 240static const void * SC_getElementAtX(RsAllocation va, uint32_t x) 241{ 242 const Allocation *a = static_cast<const Allocation *>(va); 243 CHECK_OBJ(a); 244 const Type *t = a->getType(); 245 CHECK_OBJ(t); 246 const uint8_t *p = (const uint8_t *)a->getPtr(); 247 return &p[t->getElementSizeBytes() * x]; 248} 249 250static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) 251{ 252 const Allocation *a = static_cast<const Allocation *>(va); 253 CHECK_OBJ(a); 254 const Type *t = a->getType(); 255 CHECK_OBJ(t); 256 const uint8_t *p = (const uint8_t *)a->getPtr(); 257 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 258} 259 260static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) 261{ 262 const Allocation *a = static_cast<const Allocation *>(va); 263 CHECK_OBJ(a); 264 const Type *t = a->getType(); 265 CHECK_OBJ(t); 266 const uint8_t *p = (const uint8_t *)a->getPtr(); 267 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 268} 269 270static void SC_setObject(void **vdst, void * vsrc) { 271 //LOGE("SC_setObject %p,%p %p", vdst, *vdst, vsrc); 272 if (vsrc) { 273 CHECK_OBJ(vsrc); 274 static_cast<ObjectBase *>(vsrc)->incSysRef(); 275 } 276 if (vdst[0]) { 277 CHECK_OBJ(vdst[0]); 278 static_cast<ObjectBase *>(vdst[0])->decSysRef(); 279 } 280 *vdst = vsrc; 281 //LOGE("SC_setObject *"); 282} 283static void SC_clearObject(void **vdst) { 284 //LOGE("SC_clearObject %p,%p", vdst, *vdst); 285 if (vdst[0]) { 286 CHECK_OBJ(vdst[0]); 287 static_cast<ObjectBase *>(vdst[0])->decSysRef(); 288 } 289 *vdst = NULL; 290 //LOGE("SC_clearObject *"); 291} 292static bool SC_isObject(RsAllocation vsrc) { 293 return vsrc != NULL; 294} 295 296 297 298static void SC_debugF(const char *s, float f) { 299 LOGE("%s %f, 0x%08x", s, f, *((int *) (&f))); 300} 301static void SC_debugFv2(const char *s, float f1, float f2) { 302 LOGE("%s {%f, %f}", s, f1, f2); 303} 304static void SC_debugFv3(const char *s, float f1, float f2, float f3) { 305 LOGE("%s {%f, %f, %f}", s, f1, f2, f3); 306} 307static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) { 308 LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); 309} 310static void SC_debugD(const char *s, double d) { 311 LOGE("%s %f, 0x%08llx", s, d, *((long long *) (&d))); 312} 313static void SC_debugFM4v4(const char *s, const float *f) { 314 LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); 315 LOGE("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); 316 LOGE("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); 317 LOGE("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); 318} 319static void SC_debugFM3v3(const char *s, const float *f) { 320 LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]); 321 LOGE("%s %f, %f, %f", s, f[1], f[4], f[7]); 322 LOGE("%s %f, %f, %f}",s, f[2], f[5], f[8]); 323} 324static void SC_debugFM2v2(const char *s, const float *f) { 325 LOGE("%s {%f, %f", s, f[0], f[2]); 326 LOGE("%s %f, %f}",s, f[1], f[3]); 327} 328 329static void SC_debugI32(const char *s, int32_t i) { 330 LOGE("%s %i 0x%x", s, i, i); 331} 332static void SC_debugU32(const char *s, uint32_t i) { 333 LOGE("%s %u 0x%x", s, i, i); 334} 335static void SC_debugLL64(const char *s, long long ll) { 336 LOGE("%s %lld 0x%llx", s, ll, ll); 337} 338static void SC_debugULL64(const char *s, unsigned long long ll) { 339 LOGE("%s %llu 0x%llx", s, ll, ll); 340} 341 342static void SC_debugP(const char *s, const void *p) { 343 LOGE("%s %p", s, p); 344} 345 346static uint32_t SC_toClient2(int cmdID, void *data, int len) 347{ 348 GET_TLS(); 349 //LOGE("SC_toClient %i %i %i", cmdID, len); 350 return rsc->sendMessageToClient(data, cmdID, len, false); 351} 352 353static uint32_t SC_toClient(int cmdID) 354{ 355 GET_TLS(); 356 //LOGE("SC_toClient %i", cmdID); 357 return rsc->sendMessageToClient(NULL, cmdID, 0, false); 358} 359 360static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) 361{ 362 GET_TLS(); 363 //LOGE("SC_toClientBlocking %i %i", cmdID, len); 364 return rsc->sendMessageToClient(data, cmdID, len, true); 365} 366 367static uint32_t SC_toClientBlocking(int cmdID) 368{ 369 GET_TLS(); 370 //LOGE("SC_toClientBlocking %i", cmdID); 371 return rsc->sendMessageToClient(NULL, cmdID, 0, true); 372} 373 374int SC_divsi3(int a, int b) 375{ 376 return a / b; 377} 378 379int SC_getAllocation(const void *ptr) 380{ 381 GET_TLS(); 382 const Allocation *alloc = sc->ptrToAllocation(ptr); 383 return (int)alloc; 384} 385 386void SC_allocationMarkDirty(RsAllocation a) 387{ 388 Allocation *alloc = static_cast<Allocation *>(a); 389 alloc->sendDirty(); 390} 391 392void SC_ForEach(RsScript vs, 393 RsAllocation vin, 394 RsAllocation vout, 395 const void *usr) 396{ 397 GET_TLS(); 398 const Allocation *ain = static_cast<const Allocation *>(vin); 399 Allocation *aout = static_cast<Allocation *>(vout); 400 Script *s = static_cast<Script *>(vs); 401 s->runForEach(rsc, ain, aout, usr); 402} 403 404void SC_ForEach2(RsScript vs, 405 RsAllocation vin, 406 RsAllocation vout, 407 const void *usr, 408 const RsScriptCall *call) 409{ 410 GET_TLS(); 411 const Allocation *ain = static_cast<const Allocation *>(vin); 412 Allocation *aout = static_cast<Allocation *>(vout); 413 Script *s = static_cast<Script *>(vs); 414 s->runForEach(rsc, ain, aout, usr, call); 415} 416 417////////////////////////////////////////////////////////////////////////////// 418// Class implementation 419////////////////////////////////////////////////////////////////////////////// 420 421// llvm name mangling ref 422// <builtin-type> ::= v # void 423// ::= b # bool 424// ::= c # char 425// ::= a # signed char 426// ::= h # unsigned char 427// ::= s # short 428// ::= t # unsigned short 429// ::= i # int 430// ::= j # unsigned int 431// ::= l # long 432// ::= m # unsigned long 433// ::= x # long long, __int64 434// ::= y # unsigned long long, __int64 435// ::= f # float 436// ::= d # double 437 438static ScriptCState::SymbolTable_t gSyms[] = { 439 { "__divsi3", (void *)&SC_divsi3 }, 440 441 // allocation 442 { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX }, 443 { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY }, 444 { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ }, 445 { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD }, 446 { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces }, 447 { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation }, 448 449 { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX }, 450 { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY }, 451 { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ }, 452 453 { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_setObject }, 454 { "_Z13rsClearObjectP10rs_element", (void *)&SC_clearObject }, 455 { "_Z10rsIsObject10rs_element", (void *)&SC_isObject }, 456 457 { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_setObject }, 458 { "_Z13rsClearObjectP7rs_type", (void *)&SC_clearObject }, 459 { "_Z10rsIsObject7rs_type", (void *)&SC_isObject }, 460 461 { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_setObject }, 462 { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_clearObject }, 463 { "_Z10rsIsObject13rs_allocation", (void *)&SC_isObject }, 464 465 { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_setObject }, 466 { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_clearObject }, 467 { "_Z10rsIsObject10rs_sampler", (void *)&SC_isObject }, 468 469 { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_setObject }, 470 { "_Z13rsClearObjectP9rs_script", (void *)&SC_clearObject }, 471 { "_Z10rsIsObject9rs_script", (void *)&SC_isObject }, 472 473 { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_setObject }, 474 { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_clearObject }, 475 { "_Z10rsIsObject7rs_mesh", (void *)&SC_isObject }, 476 477 { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_setObject }, 478 { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_clearObject }, 479 { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_isObject }, 480 481 { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_setObject }, 482 { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_clearObject }, 483 { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_isObject }, 484 485 { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_setObject }, 486 { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_clearObject }, 487 { "_Z10rsIsObject17rs_program_raster", (void *)&SC_isObject }, 488 489 { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_setObject }, 490 { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_clearObject }, 491 { "_Z10rsIsObject16rs_program_store", (void *)&SC_isObject }, 492 493 { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_setObject }, 494 { "_Z13rsClearObjectP7rs_font", (void *)&SC_clearObject }, 495 { "_Z10rsIsObject7rs_font", (void *)&SC_isObject }, 496 497 498 { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_allocationMarkDirty }, 499 500 501 // Debug 502 { "_Z7rsDebugPKcf", (void *)&SC_debugF }, 503 { "_Z7rsDebugPKcff", (void *)&SC_debugFv2 }, 504 { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3 }, 505 { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4 }, 506 { "_Z7rsDebugPKcd", (void *)&SC_debugD }, 507 { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4 }, 508 { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3 }, 509 { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2 }, 510 { "_Z7rsDebugPKci", (void *)&SC_debugI32 }, 511 { "_Z7rsDebugPKcj", (void *)&SC_debugU32 }, 512 // Both "long" and "unsigned long" need to be redirected to their 513 // 64-bit counterparts, since we have hacked Slang to use 64-bit 514 // for "long" on Arm (to be similar to Java). 515 { "_Z7rsDebugPKcl", (void *)&SC_debugLL64 }, 516 { "_Z7rsDebugPKcm", (void *)&SC_debugULL64 }, 517 { "_Z7rsDebugPKcx", (void *)&SC_debugLL64 }, 518 { "_Z7rsDebugPKcy", (void *)&SC_debugULL64 }, 519 { "_Z7rsDebugPKcPKv", (void *)&SC_debugP }, 520 521 // RS Math 522 { "_Z6rsRandi", (void *)&SC_randi }, 523 { "_Z6rsRandii", (void *)&SC_randi2 }, 524 { "_Z6rsRandf", (void *)&SC_randf }, 525 { "_Z6rsRandff", (void *)&SC_randf2 }, 526 { "_Z6rsFracf", (void *)&SC_frac }, 527 528 // time 529 { "_Z8rsSecondv", (void *)&SC_second }, 530 { "_Z8rsMinutev", (void *)&SC_minute }, 531 { "_Z6rsHourv", (void *)&SC_hour }, 532 { "_Z5rsDayv", (void *)&SC_day }, 533 { "_Z7rsMonthv", (void *)&SC_month }, 534 { "_Z6rsYearv", (void *)&SC_year }, 535 { "_Z14rsUptimeMillisv", (void*)&SC_uptimeMillis }, 536 { "_Z13rsUptimeNanosv", (void*)&SC_uptimeNanos }, 537 { "_Z7rsGetDtv", (void*)&SC_getDt }, 538 539 { "_Z14rsSendToClienti", (void *)&SC_toClient }, 540 { "_Z14rsSendToClientiPKvj", (void *)&SC_toClient2 }, 541 { "_Z22rsSendToClientBlockingi", (void *)&SC_toClientBlocking }, 542 { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2 }, 543 544 { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach }, 545 //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2 }, 546 547//////////////////////////////////////////////////////////////////// 548 549 //{ "sinf_fast", (void *)&SC_sinf_fast }, 550 //{ "cosf_fast", (void *)&SC_cosf_fast }, 551 552 { NULL, NULL } 553}; 554 555const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) 556{ 557 ScriptCState::SymbolTable_t *syms = gSyms; 558 559 while (syms->mPtr) { 560 if (!strcmp(syms->mName, sym)) { 561 return syms; 562 } 563 syms++; 564 } 565 return NULL; 566} 567 568