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