/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rsContext.h" #include "rsScriptC.h" #include "rsMatrix.h" #include "utils/Timers.h" #include using namespace android; using namespace android::renderscript; #define GET_TLS() Context::ScriptTLSStruct * tls = \ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ Context * rsc = tls->mContext; \ ScriptC * sc = (ScriptC *) tls->mScript ////////////////////////////////////////////////////////////////////////////// // Math routines ////////////////////////////////////////////////////////////////////////////// static float SC_sinf_fast(float x) { const float A = 1.0f / (2.0f * M_PI); const float B = -16.0f; const float C = 8.0f; // scale angle for easy argument reduction x *= A; if (fabsf(x) >= 0.5f) { // argument reduction x = x - ceilf(x + 0.5f) + 1.0f; } const float y = B * x * fabsf(x) + C * x; return 0.2215f * (y * fabsf(y) - y) + y; } static float SC_cosf_fast(float x) { x += float(M_PI / 2); const float A = 1.0f / (2.0f * M_PI); const float B = -16.0f; const float C = 8.0f; // scale angle for easy argument reduction x *= A; if (fabsf(x) >= 0.5f) { // argument reduction x = x - ceilf(x + 0.5f) + 1.0f; } const float y = B * x * fabsf(x) + C * x; return 0.2215f * (y * fabsf(y) - y) + y; } static float SC_randf(float max) { float r = (float)rand(); return r / RAND_MAX * max; } static float SC_randf2(float min, float max) { float r = (float)rand(); return r / RAND_MAX * (max - min) + min; } static int SC_randi(int max) { return (int)SC_randf(max); } static int SC_randi2(int min, int max) { return (int)SC_randf2(min, max); } static float SC_frac(float v) { int i = (int)floor(v); return fmin(v - i, 0x1.fffffep-1f); } ////////////////////////////////////////////////////////////////////////////// // Time routines ////////////////////////////////////////////////////////////////////////////// static int32_t SC_second() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_sec; } static int32_t SC_minute() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_min; } static int32_t SC_hour() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_hour; } static int32_t SC_day() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_mday; } static int32_t SC_month() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_mon; } static int32_t SC_year() { GET_TLS(); time_t rawtime; time(&rawtime); struct tm *timeinfo; timeinfo = localtime(&rawtime); return timeinfo->tm_year; } static int64_t SC_uptimeMillis() { return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); } static int64_t SC_uptimeNanos() { return systemTime(SYSTEM_TIME_MONOTONIC); } static float SC_getDt() { GET_TLS(); int64_t l = sc->mEnviroment.mLastDtTime; sc->mEnviroment.mLastDtTime = systemTime(SYSTEM_TIME_MONOTONIC); return ((float)(sc->mEnviroment.mLastDtTime - l)) / 1.0e9; } ////////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////////// static uint32_t SC_allocGetDimX(RsAllocation va) { const Allocation *a = static_cast(va); CHECK_OBJ(a); //LOGE("SC_allocGetDimX a=%p type=%p", a, a->getType()); return a->getType()->getDimX(); } static uint32_t SC_allocGetDimY(RsAllocation va) { const Allocation *a = static_cast(va); CHECK_OBJ(a); return a->getType()->getDimY(); } static uint32_t SC_allocGetDimZ(RsAllocation va) { const Allocation *a = static_cast(va); CHECK_OBJ(a); return a->getType()->getDimZ(); } static uint32_t SC_allocGetDimLOD(RsAllocation va) { const Allocation *a = static_cast(va); CHECK_OBJ(a); return a->getType()->getDimLOD(); } static uint32_t SC_allocGetDimFaces(RsAllocation va) { const Allocation *a = static_cast(va); CHECK_OBJ(a); return a->getType()->getDimFaces(); } static const void * SC_getElementAtX(RsAllocation va, uint32_t x) { const Allocation *a = static_cast(va); CHECK_OBJ(a); const Type *t = a->getType(); CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * x]; } static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) { const Allocation *a = static_cast(va); CHECK_OBJ(a); const Type *t = a->getType(); CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; } static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) { const Allocation *a = static_cast(va); CHECK_OBJ(a); const Type *t = a->getType(); CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; } static void SC_setObject(void **vdst, void * vsrc) { //LOGE("SC_setObject %p,%p %p", vdst, *vdst, vsrc); if (vsrc) { CHECK_OBJ(vsrc); static_cast(vsrc)->incSysRef(); } if (vdst[0]) { CHECK_OBJ(vdst[0]); static_cast(vdst[0])->decSysRef(); } *vdst = vsrc; //LOGE("SC_setObject *"); } static void SC_clearObject(void **vdst) { //LOGE("SC_clearObject %p,%p", vdst, *vdst); if (vdst[0]) { CHECK_OBJ(vdst[0]); static_cast(vdst[0])->decSysRef(); } *vdst = NULL; //LOGE("SC_clearObject *"); } static bool SC_isObject(RsAllocation vsrc) { return vsrc != NULL; } static void SC_debugF(const char *s, float f) { LOGE("%s %f, 0x%08x", s, f, *((int *) (&f))); } static void SC_debugFv2(const char *s, float f1, float f2) { LOGE("%s {%f, %f}", s, f1, f2); } static void SC_debugFv3(const char *s, float f1, float f2, float f3) { LOGE("%s {%f, %f, %f}", s, f1, f2, f3); } static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) { LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); } static void SC_debugFM4v4(const char *s, const float *f) { LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); LOGE("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); LOGE("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); LOGE("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); } static void SC_debugFM3v3(const char *s, const float *f) { LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]); LOGE("%s %f, %f, %f", s, f[1], f[4], f[7]); LOGE("%s %f, %f, %f}",s, f[2], f[5], f[8]); } static void SC_debugFM2v2(const char *s, const float *f) { LOGE("%s {%f, %f", s, f[0], f[2]); LOGE("%s %f, %f}",s, f[1], f[3]); } static void SC_debugI32(const char *s, int32_t i) { LOGE("%s %i 0x%x", s, i, i); } static void SC_debugU32(const char *s, uint32_t i) { LOGE("%s %i 0x%x", s, i, i); } static void SC_debugP(const char *s, const void *p) { LOGE("%s %p", s, p); } static uint32_t SC_toClient2(int cmdID, void *data, int len) { GET_TLS(); //LOGE("SC_toClient %i %i %i", cmdID, len); return rsc->sendMessageToClient(data, cmdID, len, false); } static uint32_t SC_toClient(int cmdID) { GET_TLS(); //LOGE("SC_toClient %i", cmdID); return rsc->sendMessageToClient(NULL, cmdID, 0, false); } static uint32_t SC_toClientBlocking2(int cmdID, void *data, int len) { GET_TLS(); //LOGE("SC_toClientBlocking %i %i", cmdID, len); return rsc->sendMessageToClient(data, cmdID, len, true); } static uint32_t SC_toClientBlocking(int cmdID) { GET_TLS(); //LOGE("SC_toClientBlocking %i", cmdID); return rsc->sendMessageToClient(NULL, cmdID, 0, true); } int SC_divsi3(int a, int b) { return a / b; } int SC_getAllocation(const void *ptr) { GET_TLS(); const Allocation *alloc = sc->ptrToAllocation(ptr); return (int)alloc; } void SC_allocationMarkDirty(RsAllocation a) { Allocation *alloc = static_cast(a); alloc->sendDirty(); } void SC_ForEach(RsScript vs, RsAllocation vin, RsAllocation vout, const void *usr) { GET_TLS(); const Allocation *ain = static_cast(vin); Allocation *aout = static_cast(vout); Script *s = static_cast