rsScriptC_Lib.cpp revision 5192f45b1ab8dc49d5ec7c3f235e769180cdb55b
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 GET_TLS(); 207 const Allocation *a = static_cast<const Allocation *>(va); 208 //LOGE("SC_allocGetDimX a=%p", a); 209 //LOGE(" type=%p", a->getType()); 210 return a->getType()->getDimX(); 211} 212 213static uint32_t SC_allocGetDimY(RsAllocation va) 214{ 215 GET_TLS(); 216 const Allocation *a = static_cast<const Allocation *>(va); 217 return a->getType()->getDimY(); 218} 219 220static uint32_t SC_allocGetDimZ(RsAllocation va) 221{ 222 GET_TLS(); 223 const Allocation *a = static_cast<const Allocation *>(va); 224 return a->getType()->getDimZ(); 225} 226 227static uint32_t SC_allocGetDimLOD(RsAllocation va) 228{ 229 GET_TLS(); 230 const Allocation *a = static_cast<const Allocation *>(va); 231 return a->getType()->getDimLOD(); 232} 233 234static uint32_t SC_allocGetDimFaces(RsAllocation va) 235{ 236 GET_TLS(); 237 const Allocation *a = static_cast<const Allocation *>(va); 238 return a->getType()->getDimFaces(); 239} 240 241static const void * SC_getElementAtX(RsAllocation va, uint32_t x) 242{ 243 const Allocation *a = static_cast<const Allocation *>(va); 244 const Type *t = a->getType(); 245 const uint8_t *p = (const uint8_t *)a->getPtr(); 246 return &p[t->getElementSizeBytes() * x]; 247} 248 249static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) 250{ 251 const Allocation *a = static_cast<const Allocation *>(va); 252 const Type *t = a->getType(); 253 const uint8_t *p = (const uint8_t *)a->getPtr(); 254 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 255} 256 257static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) 258{ 259 const Allocation *a = static_cast<const Allocation *>(va); 260 const Type *t = a->getType(); 261 const uint8_t *p = (const uint8_t *)a->getPtr(); 262 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 263} 264 265static void SC_setObject(void **vdst, void * vsrc) { 266 static_cast<ObjectBase *>(vsrc)->incSysRef(); 267 static_cast<ObjectBase *>(vdst[0])->decSysRef(); 268 *vdst = vsrc; 269} 270static void SC_clearObject(void **vdst) { 271 static_cast<ObjectBase *>(vdst[0])->decSysRef(); 272 *vdst = NULL; 273} 274static bool SC_isObject(RsAllocation vsrc) { 275 return vsrc != NULL; 276} 277 278 279 280static void SC_debugF(const char *s, float f) { 281 LOGE("%s %f, 0x%08x", s, f, *((int *) (&f))); 282} 283static void SC_debugFv2(const char *s, float f1, float f2) { 284 LOGE("%s {%f, %f}", s, f1, f2); 285} 286static void SC_debugFv3(const char *s, float f1, float f2, float f3) { 287 LOGE("%s {%f, %f, %f}", s, f1, f2, f3); 288} 289static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) { 290 LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); 291} 292static void SC_debugFM4v4(const char *s, const float *f) { 293 LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); 294 LOGE("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); 295 LOGE("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); 296 LOGE("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); 297} 298static void SC_debugFM3v3(const char *s, const float *f) { 299 LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]); 300 LOGE("%s %f, %f, %f", s, f[1], f[4], f[7]); 301 LOGE("%s %f, %f, %f}",s, f[2], f[5], f[8]); 302} 303static void SC_debugFM2v2(const char *s, const float *f) { 304 LOGE("%s {%f, %f", s, f[0], f[2]); 305 LOGE("%s %f, %f}",s, f[1], f[3]); 306} 307 308static void SC_debugI32(const char *s, int32_t i) { 309 LOGE("%s %i 0x%x", s, i, i); 310} 311static void SC_debugU32(const char *s, uint32_t i) { 312 LOGE("%s %i 0x%x", s, i, i); 313} 314 315static void SC_debugP(const char *s, const void *p) { 316 LOGE("%s %p", s, p); 317} 318 319static uint32_t SC_toClient2(int cmdID, void *data, int len) 320{ 321 GET_TLS(); 322 //LOGE("SC_toClient %i %i %i", cmdID, len); 323 return rsc->sendMessageToClient(data, cmdID, len, false); 324} 325 326static uint32_t SC_toClient(int cmdID) 327{ 328 GET_TLS(); 329 //LOGE("SC_toClient %i", cmdID); 330 return rsc->sendMessageToClient(NULL, cmdID, 0, false); 331} 332 333static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) 334{ 335 GET_TLS(); 336 //LOGE("SC_toClientBlocking %i %i", cmdID, len); 337 return rsc->sendMessageToClient(data, cmdID, len, true); 338} 339 340static uint32_t SC_toClientBlocking(int cmdID) 341{ 342 GET_TLS(); 343 //LOGE("SC_toClientBlocking %i", cmdID); 344 return rsc->sendMessageToClient(NULL, cmdID, 0, true); 345} 346 347int SC_divsi3(int a, int b) 348{ 349 return a / b; 350} 351 352int SC_getAllocation(const void *ptr) 353{ 354 GET_TLS(); 355 const Allocation *alloc = sc->ptrToAllocation(ptr); 356 return (int)alloc; 357} 358 359 360void SC_ForEach(RsScript vs, 361 RsAllocation vin, 362 RsAllocation vout, 363 const void *usr) 364{ 365 GET_TLS(); 366 const Allocation *ain = static_cast<const Allocation *>(vin); 367 Allocation *aout = static_cast<Allocation *>(vout); 368 Script *s = static_cast<Script *>(vs); 369 s->runForEach(rsc, ain, aout, usr); 370} 371 372void SC_ForEach2(RsScript vs, 373 RsAllocation vin, 374 RsAllocation vout, 375 const void *usr, 376 const RsScriptCall *call) 377{ 378 GET_TLS(); 379 const Allocation *ain = static_cast<const Allocation *>(vin); 380 Allocation *aout = static_cast<Allocation *>(vout); 381 Script *s = static_cast<Script *>(vs); 382 s->runForEach(rsc, ain, aout, usr, call); 383} 384 385////////////////////////////////////////////////////////////////////////////// 386// Class implementation 387////////////////////////////////////////////////////////////////////////////// 388 389// llvm name mangling ref 390// <builtin-type> ::= v # void 391// ::= b # bool 392// ::= c # char 393// ::= a # signed char 394// ::= h # unsigned char 395// ::= s # short 396// ::= t # unsigned short 397// ::= i # int 398// ::= j # unsigned int 399// ::= l # long 400// ::= m # unsigned long 401// ::= x # long long, __int64 402// ::= y # unsigned long long, __int64 403// ::= f # float 404// ::= d # double 405 406static ScriptCState::SymbolTable_t gSyms[] = { 407 { "__divsi3", (void *)&SC_divsi3 }, 408 409 // allocation 410 { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX }, 411 { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY }, 412 { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ }, 413 { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD }, 414 { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces }, 415 { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation }, 416 417 { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX }, 418 { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY }, 419 { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ }, 420 421 { "_Z11rsSetObjectP13rs_allocation13rs_allocation", (void *)&SC_setObject }, 422 { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_clearObject }, 423 { "_Z10rsIsObject13rs_allocation", (void *)&SC_isObject }, 424 425 426 // Debug 427 { "_Z7rsDebugPKcf", (void *)&SC_debugF }, 428 { "_Z7rsDebugPKcff", (void *)&SC_debugFv2 }, 429 { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3 }, 430 { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4 }, 431 { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4 }, 432 { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3 }, 433 { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2 }, 434 { "_Z7rsDebugPKci", (void *)&SC_debugI32 }, 435 { "_Z7rsDebugPKcj", (void *)&SC_debugU32 }, 436 { "_Z7rsDebugPKcPKv", (void *)&SC_debugP }, 437 438 // RS Math 439 { "_Z6rsRandi", (void *)&SC_randi }, 440 { "_Z6rsRandii", (void *)&SC_randi2 }, 441 { "_Z6rsRandf", (void *)&SC_randf }, 442 { "_Z6rsRandff", (void *)&SC_randf2 }, 443 { "_Z6rsFracf", (void *)&SC_frac }, 444 445 // time 446 { "_Z8rsSecondv", (void *)&SC_second }, 447 { "_Z8rsMinutev", (void *)&SC_minute }, 448 { "_Z6rsHourv", (void *)&SC_hour }, 449 { "_Z5rsDayv", (void *)&SC_day }, 450 { "_Z7rsMonthv", (void *)&SC_month }, 451 { "_Z6rsYearv", (void *)&SC_year }, 452 { "_Z14rsUptimeMillisv", (void*)&SC_uptimeMillis }, 453 { "_Z13rsUptimeNanosv", (void*)&SC_uptimeNanos }, 454 { "_Z7rsGetDtv", (void*)&SC_getDt }, 455 456 { "_Z14rsSendToClienti", (void *)&SC_toClient }, 457 { "_Z14rsSendToClientiPKvj", (void *)&SC_toClient2 }, 458 { "_Z22rsSendToClientBlockingi", (void *)&SC_toClientBlocking }, 459 { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2 }, 460 461 { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach }, 462 //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2 }, 463 464//////////////////////////////////////////////////////////////////// 465 466 //{ "sinf_fast", (void *)&SC_sinf_fast }, 467 //{ "cosf_fast", (void *)&SC_cosf_fast }, 468 469 { NULL, NULL } 470}; 471 472const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) 473{ 474 ScriptCState::SymbolTable_t *syms = gSyms; 475 476 while (syms->mPtr) { 477 if (!strcmp(syms->mName, sym)) { 478 return syms; 479 } 480 syms++; 481 } 482 return NULL; 483} 484 485