| /* |
| * 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 "acc/acc.h" |
| #include "utils/Timers.h" |
| |
| #include <time.h> |
| |
| 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 |
| |
| |
| |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Non-Updated code below |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| typedef struct { |
| float x; |
| float y; |
| float z; |
| } vec3_t; |
| |
| typedef struct { |
| float x; |
| float y; |
| float z; |
| float w; |
| } vec4_t; |
| |
| typedef struct { |
| float x; |
| float y; |
| } vec2_t; |
| |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Vec3 routines |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| static void SC_vec3Norm(vec3_t *v) |
| { |
| float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); |
| len = 1 / len; |
| v->x *= len; |
| v->y *= len; |
| v->z *= len; |
| } |
| |
| static float SC_vec3Length(const vec3_t *v) |
| { |
| return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); |
| } |
| |
| static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs) |
| { |
| dest->x = lhs->x + rhs->x; |
| dest->y = lhs->y + rhs->y; |
| dest->z = lhs->z + rhs->z; |
| } |
| |
| static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs) |
| { |
| dest->x = lhs->x - rhs->x; |
| dest->y = lhs->y - rhs->y; |
| dest->z = lhs->z - rhs->z; |
| } |
| |
| static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs) |
| { |
| float x = lhs->y * rhs->z - lhs->z * rhs->y; |
| float y = lhs->z * rhs->x - lhs->x * rhs->z; |
| float z = lhs->x * rhs->y - lhs->y * rhs->x; |
| dest->x = x; |
| dest->y = y; |
| dest->z = z; |
| } |
| |
| static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs) |
| { |
| return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z; |
| } |
| |
| static void SC_vec3Scale(vec3_t *lhs, float scale) |
| { |
| lhs->x *= scale; |
| lhs->y *= scale; |
| lhs->z *= scale; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Vec4 routines |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| static void SC_vec4Norm(vec4_t *v) |
| { |
| float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w); |
| len = 1 / len; |
| v->x *= len; |
| v->y *= len; |
| v->z *= len; |
| v->w *= len; |
| } |
| |
| static float SC_vec4Length(const vec4_t *v) |
| { |
| return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w); |
| } |
| |
| static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs) |
| { |
| dest->x = lhs->x + rhs->x; |
| dest->y = lhs->y + rhs->y; |
| dest->z = lhs->z + rhs->z; |
| dest->w = lhs->w + rhs->w; |
| } |
| |
| static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs) |
| { |
| dest->x = lhs->x - rhs->x; |
| dest->y = lhs->y - rhs->y; |
| dest->z = lhs->z - rhs->z; |
| dest->w = lhs->w - rhs->w; |
| } |
| |
| static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs) |
| { |
| return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w; |
| } |
| |
| static void SC_vec4Scale(vec4_t *lhs, float scale) |
| { |
| lhs->x *= scale; |
| lhs->y *= scale; |
| lhs->z *= scale; |
| lhs->w *= scale; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // 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 int SC_clamp(int amount, int low, int high) |
| { |
| return amount < low ? low : (amount > high ? high : amount); |
| } |
| |
| static float SC_roundf(float v) |
| { |
| return floorf(v + 0.4999999999); |
| } |
| |
| static float SC_distf2(float x1, float y1, float x2, float y2) |
| { |
| float x = x2 - x1; |
| float y = y2 - y1; |
| return sqrtf(x * x + y * y); |
| } |
| |
| static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2) |
| { |
| float x = x2 - x1; |
| float y = y2 - y1; |
| float z = z2 - z1; |
| return sqrtf(x * x + y * y + z * z); |
| } |
| |
| static float SC_magf2(float a, float b) |
| { |
| return sqrtf(a * a + b * b); |
| } |
| |
| static float SC_magf3(float a, float b, float c) |
| { |
| return sqrtf(a * a + b * b + c * c); |
| } |
| |
| 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_uptimeMillis2() |
| { |
| return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); |
| } |
| |
| static int64_t SC_startTimeMillis2() |
| { |
| GET_TLS(); |
| return sc->mEnviroment.mStartTimeMillis; |
| } |
| |
| static int64_t SC_elapsedTimeMillis2() |
| { |
| GET_TLS(); |
| return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)) |
| - sc->mEnviroment.mStartTimeMillis; |
| } |
| |
| static int32_t SC_uptimeMillis() |
| { |
| return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); |
| } |
| |
| static int32_t SC_startTimeMillis() |
| { |
| GET_TLS(); |
| return sc->mEnviroment.mStartTimeMillis; |
| } |
| |
| static int32_t SC_elapsedTimeMillis() |
| { |
| GET_TLS(); |
| return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)) |
| - sc->mEnviroment.mStartTimeMillis; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Matrix routines |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| |
| static void SC_matrixLoadIdentity(rsc_Matrix *mat) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->loadIdentity(); |
| } |
| |
| static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->load(f); |
| } |
| |
| static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->load(reinterpret_cast<const Matrix *>(newmat)); |
| } |
| |
| static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->loadRotate(rot, x, y, z); |
| } |
| |
| static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->loadScale(x, y, z); |
| } |
| |
| static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->loadTranslate(x, y, z); |
| } |
| |
| static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->loadMultiply(reinterpret_cast<const Matrix *>(lhs), |
| reinterpret_cast<const Matrix *>(rhs)); |
| } |
| |
| static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->multiply(reinterpret_cast<const Matrix *>(rhs)); |
| } |
| |
| static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->rotate(rot, x, y, z); |
| } |
| |
| static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->scale(x, y, z); |
| } |
| |
| static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z) |
| { |
| Matrix *m = reinterpret_cast<Matrix *>(mat); |
| m->translate(x, y, z); |
| } |
| |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| static uint32_t SC_allocGetDimX(RsAllocation va) |
| { |
| GET_TLS(); |
| const Allocation *a = static_cast<const Allocation *>(va); |
| //LOGE("SC_allocGetDimX a=%p", a); |
| //LOGE(" type=%p", a->getType()); |
| return a->getType()->getDimX(); |
| } |
| |
| static uint32_t SC_allocGetDimY(RsAllocation va) |
| { |
| GET_TLS(); |
| const Allocation *a = static_cast<const Allocation *>(va); |
| return a->getType()->getDimY(); |
| } |
| |
| static uint32_t SC_allocGetDimZ(RsAllocation va) |
| { |
| GET_TLS(); |
| const Allocation *a = static_cast<const Allocation *>(va); |
| return a->getType()->getDimZ(); |
| } |
| |
| static uint32_t SC_allocGetDimLOD(RsAllocation va) |
| { |
| GET_TLS(); |
| const Allocation *a = static_cast<const Allocation *>(va); |
| return a->getType()->getDimLOD(); |
| } |
| |
| static uint32_t SC_allocGetDimFaces(RsAllocation va) |
| { |
| GET_TLS(); |
| const Allocation *a = static_cast<const Allocation *>(va); |
| return a->getType()->getDimFaces(); |
| } |
| |
| |
| |
| 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, rsvF_2 fv) { |
| float *f = (float *)&fv; |
| LOGE("%s {%f, %f}", s, f[0], f[1]); |
| } |
| static void SC_debugFv3(const char *s, rsvF_4 fv) { |
| float *f = (float *)&fv; |
| LOGE("%s {%f, %f, %f}", s, f[0], f[1], f[2]); |
| } |
| static void SC_debugFv4(const char *s, rsvF_4 fv) { |
| float *f = (float *)&fv; |
| LOGE("%s {%f, %f, %f, %f}", s, f[0], f[1], f[2], f[3]); |
| } |
| static void SC_debugI32(const char *s, int32_t i) { |
| LOGE("%s %i 0x%x", s, i, i); |
| } |
| |
| static uchar4 SC_convertColorTo8888_f3(float r, float g, float b) { |
| uchar4 t; |
| t.f[0] = (uint8_t)(r * 255.f); |
| t.f[1] = (uint8_t)(g * 255.f); |
| t.f[2] = (uint8_t)(b * 255.f); |
| t.f[3] = 0xff; |
| return t; |
| } |
| |
| static uchar4 SC_convertColorTo8888_f4(float r, float g, float b, float a) { |
| uchar4 t; |
| t.f[0] = (uint8_t)(r * 255.f); |
| t.f[1] = (uint8_t)(g * 255.f); |
| t.f[2] = (uint8_t)(b * 255.f); |
| t.f[3] = (uint8_t)(a * 255.f); |
| return t; |
| } |
| |
| static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace) |
| { |
| GET_TLS(); |
| //LOGE("SC_toClient %i %i %i", cmdID, len, waitForSpace); |
| return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0); |
| } |
| |
| static void SC_scriptCall(int scriptID) |
| { |
| GET_TLS(); |
| rsc->runScript((Script *)scriptID, 0); |
| } |
| |
| 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; |
| } |
| |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Class implementation |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| // llvm name mangling ref |
| // <builtin-type> ::= v # void |
| // ::= b # bool |
| // ::= c # char |
| // ::= a # signed char |
| // ::= h # unsigned char |
| // ::= s # short |
| // ::= t # unsigned short |
| // ::= i # int |
| // ::= j # unsigned int |
| // ::= l # long |
| // ::= m # unsigned long |
| // ::= x # long long, __int64 |
| // ::= y # unsigned long long, __int64 |
| // ::= f # float |
| // ::= d # double |
| |
| static ScriptCState::SymbolTable_t gSyms[] = { |
| { "__divsi3", (void *)&SC_divsi3 }, |
| |
| // allocation |
| { "rsAllocationGetDimX", (void *)&SC_allocGetDimX }, |
| { "rsAllocationGetDimY", (void *)&SC_allocGetDimY }, |
| { "rsAllocationGetDimZ", (void *)&SC_allocGetDimZ }, |
| { "rsAllocationGetDimLOD", (void *)&SC_allocGetDimLOD }, |
| { "rsAllocationGetDimFaces", (void *)&SC_allocGetDimFaces }, |
| { "rsGetAllocation", (void *)&SC_getAllocation }, |
| |
| // color |
| { "_Z17rsPackColorTo8888fff", (void *)&SC_convertColorTo8888_f3 }, |
| { "_Z17rsPackColorTo8888ffff", (void *)&SC_convertColorTo8888_f4 }, |
| //extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3); |
| //extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4); |
| //extern float4 rsUnpackColor8888(uchar4); |
| //extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float r, float g, float b); |
| //extern uchar4 __attribute__((overloadable)) rsPackColorTo565(float3); |
| //extern float4 rsUnpackColor565(uchar4); |
| |
| // Debug |
| { "_Z7rsDebugPKcf", (void *)&SC_debugF }, |
| { "_Z7rsDebugPKcDv2_f", (void *)&SC_debugFv2 }, |
| { "_Z7rsDebugPKcDv3_f", (void *)&SC_debugFv3 }, |
| { "_Z7rsDebugPKcDv4_f", (void *)&SC_debugFv4 }, |
| { "_Z7rsDebugPKci", (void *)&SC_debugI32 }, |
| //extern void __attribute__((overloadable))rsDebug(const char *, const void *); |
| |
| |
| // RS Math |
| { "_Z6rsRandi", (void *)&SC_randi }, |
| { "_Z6rsRandii", (void *)&SC_randi2 }, |
| { "_Z6rsRandf", (void *)&SC_randf }, |
| { "_Z6rsRandff", (void *)&SC_randf2 }, |
| { "_Z6rsFracf", (void *)&SC_frac }, |
| |
| // time |
| { "rsSecond", (void *)&SC_second }, |
| { "rsMinute", (void *)&SC_minute }, |
| { "rsHour", (void *)&SC_hour }, |
| { "rsDay", (void *)&SC_day }, |
| { "rsMonth", (void *)&SC_month }, |
| { "rsYear", (void *)&SC_year }, |
| { "rsUptimeMillis", (void*)&SC_uptimeMillis2 }, |
| { "rsStartTimeMillis", (void*)&SC_startTimeMillis2 }, |
| { "rsElapsedTimeMillis", (void*)&SC_elapsedTimeMillis2 }, |
| |
| { "rsSendToClient", (void *)&SC_toClient }, |
| |
| // matrix |
| { "rsMatrixLoadIdentity", (void *)&SC_matrixLoadIdentity }, |
| { "rsMatrixLoadFloat", (void *)&SC_matrixLoadFloat }, |
| { "rsMatrixLoadMat", (void *)&SC_matrixLoadMat }, |
| { "rsMatrixLoadRotate", (void *)&SC_matrixLoadRotate }, |
| { "rsMatrixLoadScale", (void *)&SC_matrixLoadScale }, |
| { "rsMatrixLoadTranslate", (void *)&SC_matrixLoadTranslate }, |
| { "rsMatrixLoadMultiply", (void *)&SC_matrixLoadMultiply }, |
| { "rsMatrixMultiply", (void *)&SC_matrixMultiply }, |
| { "rsMatrixRotate", (void *)&SC_matrixRotate }, |
| { "rsMatrixScale", (void *)&SC_matrixScale }, |
| { "rsMatrixTranslate", (void *)&SC_matrixTranslate }, |
| |
| |
| //////////////////////////////////////////////////////////////////// |
| |
| //{ "sinf_fast", (void *)&SC_sinf_fast }, |
| //{ "cosf_fast", (void *)&SC_cosf_fast }, |
| //{ "clamp", (void *)&SC_clamp }, |
| //{ "distf2", (void *)&SC_distf2 }, |
| //{ "distf3", (void *)&SC_distf3 }, |
| //{ "magf2", (void *)&SC_magf2 }, |
| //{ "magf3", (void *)&SC_magf3 }, |
| //{ "mapf", (void *)&SC_mapf }, |
| |
| { "scriptCall", (void *)&SC_scriptCall }, |
| |
| |
| { NULL, NULL } |
| }; |
| |
| const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym) |
| { |
| ScriptCState::SymbolTable_t *syms = gSyms; |
| |
| while (syms->mPtr) { |
| if (!strcmp(syms->mName, sym)) { |
| return syms; |
| } |
| syms++; |
| } |
| return NULL; |
| } |
| |