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