rsScriptC_Lib.cpp revision 7dce6bc09126187534ab0297c66b30149643b162
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "rsContext.h" 18#include "rsScriptC.h" 19#include "rsMatrix.h" 20 21#include "acc/acc.h" 22#include "utils/Timers.h" 23 24#include <time.h> 25 26using namespace android; 27using namespace android::renderscript; 28 29#define GET_TLS() Context::ScriptTLSStruct * tls = \ 30 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 31 Context * rsc = tls->mContext; \ 32 ScriptC * sc = (ScriptC *) tls->mScript 33 34 35////////////////////////////////////////////////////////////////////////////// 36// Math routines 37////////////////////////////////////////////////////////////////////////////// 38 39static float SC_sinf_fast(float x) 40{ 41 const float A = 1.0f / (2.0f * M_PI); 42 const float B = -16.0f; 43 const float C = 8.0f; 44 45 // scale angle for easy argument reduction 46 x *= A; 47 48 if (fabsf(x) >= 0.5f) { 49 // argument reduction 50 x = x - ceilf(x + 0.5f) + 1.0f; 51 } 52 53 const float y = B * x * fabsf(x) + C * x; 54 return 0.2215f * (y * fabsf(y) - y) + y; 55} 56 57static float SC_cosf_fast(float x) 58{ 59 x += float(M_PI / 2); 60 61 const float A = 1.0f / (2.0f * M_PI); 62 const float B = -16.0f; 63 const float C = 8.0f; 64 65 // scale angle for easy argument reduction 66 x *= A; 67 68 if (fabsf(x) >= 0.5f) { 69 // argument reduction 70 x = x - ceilf(x + 0.5f) + 1.0f; 71 } 72 73 const float y = B * x * fabsf(x) + C * x; 74 return 0.2215f * (y * fabsf(y) - y) + y; 75} 76 77 78static float SC_randf(float max) 79{ 80 float r = (float)rand(); 81 return r / RAND_MAX * max; 82} 83 84static float SC_randf2(float min, float max) 85{ 86 float r = (float)rand(); 87 return r / RAND_MAX * (max - min) + min; 88} 89 90static int SC_randi(int max) 91{ 92 return (int)SC_randf(max); 93} 94 95static int SC_randi2(int min, int max) 96{ 97 return (int)SC_randf2(min, max); 98} 99 100static float SC_frac(float v) 101{ 102 int i = (int)floor(v); 103 return fmin(v - i, 0x1.fffffep-1f); 104} 105 106////////////////////////////////////////////////////////////////////////////// 107// Time routines 108////////////////////////////////////////////////////////////////////////////// 109 110static int32_t SC_second() 111{ 112 GET_TLS(); 113 114 time_t rawtime; 115 time(&rawtime); 116 117 struct tm *timeinfo; 118 timeinfo = localtime(&rawtime); 119 return timeinfo->tm_sec; 120} 121 122static int32_t SC_minute() 123{ 124 GET_TLS(); 125 126 time_t rawtime; 127 time(&rawtime); 128 129 struct tm *timeinfo; 130 timeinfo = localtime(&rawtime); 131 return timeinfo->tm_min; 132} 133 134static int32_t SC_hour() 135{ 136 GET_TLS(); 137 138 time_t rawtime; 139 time(&rawtime); 140 141 struct tm *timeinfo; 142 timeinfo = localtime(&rawtime); 143 return timeinfo->tm_hour; 144} 145 146static int32_t SC_day() 147{ 148 GET_TLS(); 149 150 time_t rawtime; 151 time(&rawtime); 152 153 struct tm *timeinfo; 154 timeinfo = localtime(&rawtime); 155 return timeinfo->tm_mday; 156} 157 158static int32_t SC_month() 159{ 160 GET_TLS(); 161 162 time_t rawtime; 163 time(&rawtime); 164 165 struct tm *timeinfo; 166 timeinfo = localtime(&rawtime); 167 return timeinfo->tm_mon; 168} 169 170static int32_t SC_year() 171{ 172 GET_TLS(); 173 174 time_t rawtime; 175 time(&rawtime); 176 177 struct tm *timeinfo; 178 timeinfo = localtime(&rawtime); 179 return timeinfo->tm_year; 180} 181 182static int64_t SC_uptimeMillis() 183{ 184 return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); 185} 186 187static int64_t SC_uptimeNanos() 188{ 189 return systemTime(SYSTEM_TIME_MONOTONIC); 190} 191 192static float SC_getDt() 193{ 194 GET_TLS(); 195 int64_t l = sc->mEnviroment.mLastDtTime; 196 sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC); 197 return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9; 198} 199 200 201////////////////////////////////////////////////////////////////////////////// 202// 203////////////////////////////////////////////////////////////////////////////// 204 205static uint32_t SC_allocGetDimX(RsAllocation va) 206{ 207 GET_TLS(); 208 const Allocation *a = static_cast<const Allocation *>(va); 209 //LOGE("SC_allocGetDimX a=%p", a); 210 //LOGE(" type=%p", a->getType()); 211 return a->getType()->getDimX(); 212} 213 214static uint32_t SC_allocGetDimY(RsAllocation va) 215{ 216 GET_TLS(); 217 const Allocation *a = static_cast<const Allocation *>(va); 218 return a->getType()->getDimY(); 219} 220 221static uint32_t SC_allocGetDimZ(RsAllocation va) 222{ 223 GET_TLS(); 224 const Allocation *a = static_cast<const Allocation *>(va); 225 return a->getType()->getDimZ(); 226} 227 228static uint32_t SC_allocGetDimLOD(RsAllocation va) 229{ 230 GET_TLS(); 231 const Allocation *a = static_cast<const Allocation *>(va); 232 return a->getType()->getDimLOD(); 233} 234 235static uint32_t SC_allocGetDimFaces(RsAllocation va) 236{ 237 GET_TLS(); 238 const Allocation *a = static_cast<const Allocation *>(va); 239 return a->getType()->getDimFaces(); 240} 241 242const void * SC_getElementAtX(RsAllocation va, uint32_t x) 243{ 244 const Allocation *a = static_cast<const Allocation *>(va); 245 const Type *t = a->getType(); 246 const uint8_t *p = (const uint8_t *)a->getPtr(); 247 return &p[t->getElementSizeBytes() * x]; 248} 249 250const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) 251{ 252 const Allocation *a = static_cast<const Allocation *>(va); 253 const Type *t = a->getType(); 254 const uint8_t *p = (const uint8_t *)a->getPtr(); 255 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 256} 257 258const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) 259{ 260 const Allocation *a = static_cast<const Allocation *>(va); 261 const Type *t = a->getType(); 262 const uint8_t *p = (const uint8_t *)a->getPtr(); 263 return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; 264} 265 266 267static void SC_debugF(const char *s, float f) { 268 LOGE("%s %f, 0x%08x", s, f, *((int *) (&f))); 269} 270static void SC_debugFv2(const char *s, float f1, float f2) { 271 LOGE("%s {%f, %f}", s, f1, f2); 272} 273static void SC_debugFv3(const char *s, float f1, float f2, float f3) { 274 LOGE("%s {%f, %f, %f}", s, f1, f2, f3); 275} 276static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) { 277 LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); 278} 279static void SC_debugFM4v4(const char *s, const float *f) { 280 LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); 281 LOGE("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); 282 LOGE("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); 283 LOGE("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); 284} 285static void SC_debugFM3v3(const char *s, const float *f) { 286 LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]); 287 LOGE("%s %f, %f, %f", s, f[1], f[4], f[7]); 288 LOGE("%s %f, %f, %f}",s, f[2], f[5], f[8]); 289} 290static void SC_debugFM2v2(const char *s, const float *f) { 291 LOGE("%s {%f, %f", s, f[0], f[2]); 292 LOGE("%s %f, %f}",s, f[1], f[3]); 293} 294 295static void SC_debugI32(const char *s, int32_t i) { 296 LOGE("%s %i 0x%x", s, i, i); 297} 298static void SC_debugU32(const char *s, uint32_t i) { 299 LOGE("%s %i 0x%x", s, i, i); 300} 301 302static void SC_debugP(const char *s, const void *p) { 303 LOGE("%s %p", s, p); 304} 305 306static uint32_t SC_toClient2(int cmdID, void *data, int len) 307{ 308 GET_TLS(); 309 //LOGE("SC_toClient %i %i %i", cmdID, len); 310 return rsc->sendMessageToClient(data, cmdID, len, false); 311} 312 313static uint32_t SC_toClient(int cmdID) 314{ 315 GET_TLS(); 316 //LOGE("SC_toClient %i", cmdID); 317 return rsc->sendMessageToClient(NULL, cmdID, 0, false); 318} 319 320static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) 321{ 322 GET_TLS(); 323 //LOGE("SC_toClientBlocking %i %i", cmdID, len); 324 return rsc->sendMessageToClient(data, cmdID, len, true); 325} 326 327static uint32_t SC_toClientBlocking(int cmdID) 328{ 329 GET_TLS(); 330 //LOGE("SC_toClientBlocking %i", cmdID); 331 return rsc->sendMessageToClient(NULL, cmdID, 0, true); 332} 333 334int SC_divsi3(int a, int b) 335{ 336 return a / b; 337} 338 339int SC_getAllocation(const void *ptr) 340{ 341 GET_TLS(); 342 const Allocation *alloc = sc->ptrToAllocation(ptr); 343 return (int)alloc; 344} 345 346 347void SC_ForEach(RsScript vs, 348 RsAllocation vin, 349 RsAllocation vout, 350 const void *usr) 351{ 352 GET_TLS(); 353 const Allocation *ain = static_cast<const Allocation *>(vin); 354 Allocation *aout = static_cast<Allocation *>(vout); 355 Script *s = static_cast<Script *>(vs); 356 s->runForEach(rsc, ain, aout, usr); 357} 358 359void SC_ForEach2(RsScript vs, 360 RsAllocation vin, 361 RsAllocation vout, 362 const void *usr, 363 const RsScriptCall *call) 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, call); 370} 371 372////////////////////////////////////////////////////////////////////////////// 373// Class implementation 374////////////////////////////////////////////////////////////////////////////// 375 376// llvm name mangling ref 377// <builtin-type> ::= v # void 378// ::= b # bool 379// ::= c # char 380// ::= a # signed char 381// ::= h # unsigned char 382// ::= s # short 383// ::= t # unsigned short 384// ::= i # int 385// ::= j # unsigned int 386// ::= l # long 387// ::= m # unsigned long 388// ::= x # long long, __int64 389// ::= y # unsigned long long, __int64 390// ::= f # float 391// ::= d # double 392 393static ScriptCState::SymbolTable_t gSyms[] = { 394 { "__divsi3", (void *)&SC_divsi3 }, 395 396 // allocation 397 { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX }, 398 { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY }, 399 { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ }, 400 { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD }, 401 { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces }, 402 { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation }, 403 404 { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX }, 405 { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY }, 406 { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ }, 407 408 // Debug 409 { "_Z7rsDebugPKcf", (void *)&SC_debugF }, 410 { "_Z7rsDebugPKcff", (void *)&SC_debugFv2 }, 411 { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3 }, 412 { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4 }, 413 { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4 }, 414 { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3 }, 415 { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2 }, 416 { "_Z7rsDebugPKci", (void *)&SC_debugI32 }, 417 { "_Z7rsDebugPKcj", (void *)&SC_debugU32 }, 418 { "_Z7rsDebugPKcPKv", (void *)&SC_debugP }, 419 420 // RS Math 421 { "_Z6rsRandi", (void *)&SC_randi }, 422 { "_Z6rsRandii", (void *)&SC_randi2 }, 423 { "_Z6rsRandf", (void *)&SC_randf }, 424 { "_Z6rsRandff", (void *)&SC_randf2 }, 425 { "_Z6rsFracf", (void *)&SC_frac }, 426 427 // time 428 { "_Z8rsSecondv", (void *)&SC_second }, 429 { "_Z8rsMinutev", (void *)&SC_minute }, 430 { "_Z6rsHourv", (void *)&SC_hour }, 431 { "_Z5rsDayv", (void *)&SC_day }, 432 { "_Z7rsMonthv", (void *)&SC_month }, 433 { "_Z6rsYearv", (void *)&SC_year }, 434 { "_Z14rsUptimeMillisv", (void*)&SC_uptimeMillis }, 435 { "_Z13rsUptimeNanosv", (void*)&SC_uptimeNanos }, 436 { "_Z7rsGetDtv", (void*)&SC_getDt }, 437 438 { "_Z14rsSendToClienti", (void *)&SC_toClient }, 439 { "_Z14rsSendToClientiPKvj", (void *)&SC_toClient2 }, 440 { "_Z22rsSendToClientBlockingi", (void *)&SC_toClientBlocking }, 441 { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_toClientBlocking2 }, 442 443 { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach }, 444 //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2 }, 445 446//////////////////////////////////////////////////////////////////// 447 448 //{ "sinf_fast", (void *)&SC_sinf_fast }, 449 //{ "cosf_fast", (void *)&SC_cosf_fast }, 450 451 { NULL, NULL } 452}; 453 454const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) 455{ 456 ScriptCState::SymbolTable_t *syms = gSyms; 457 458 while (syms->mPtr) { 459 if (!strcmp(syms->mName, sym)) { 460 return syms; 461 } 462 syms++; 463 } 464 return NULL; 465} 466 467