rsScriptC_Lib.cpp revision aeb094b520d8ea49b74129927578f18f758c873e
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#include "rsNoise.h"
21
22#include "acc/acc.h"
23#include "utils/Timers.h"
24
25#include <time.h>
26
27using namespace android;
28using namespace android::renderscript;
29
30#define GET_TLS()  Context::ScriptTLSStruct * tls = \
31    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
32    Context * rsc = tls->mContext; \
33    ScriptC * sc = (ScriptC *) tls->mScript
34
35
36
37
38//////////////////////////////////////////////////////////////////////////////
39// Non-Updated code below
40//////////////////////////////////////////////////////////////////////////////
41
42typedef struct {
43    float x;
44    float y;
45    float z;
46} vec3_t;
47
48typedef struct {
49    float x;
50    float y;
51    float z;
52    float w;
53} vec4_t;
54
55typedef struct {
56    float x;
57    float y;
58} vec2_t;
59
60
61//////////////////////////////////////////////////////////////////////////////
62// Vec3 routines
63//////////////////////////////////////////////////////////////////////////////
64
65static void SC_vec3Norm(vec3_t *v)
66{
67    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
68    len = 1 / len;
69    v->x *= len;
70    v->y *= len;
71    v->z *= len;
72}
73
74static float SC_vec3Length(const vec3_t *v)
75{
76    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
77}
78
79static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
80{
81    dest->x = lhs->x + rhs->x;
82    dest->y = lhs->y + rhs->y;
83    dest->z = lhs->z + rhs->z;
84}
85
86static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
87{
88    dest->x = lhs->x - rhs->x;
89    dest->y = lhs->y - rhs->y;
90    dest->z = lhs->z - rhs->z;
91}
92
93static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
94{
95    float x = lhs->y * rhs->z  - lhs->z * rhs->y;
96    float y = lhs->z * rhs->x  - lhs->x * rhs->z;
97    float z = lhs->x * rhs->y  - lhs->y * rhs->x;
98    dest->x = x;
99    dest->y = y;
100    dest->z = z;
101}
102
103static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs)
104{
105    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z;
106}
107
108static void SC_vec3Scale(vec3_t *lhs, float scale)
109{
110    lhs->x *= scale;
111    lhs->y *= scale;
112    lhs->z *= scale;
113}
114
115//////////////////////////////////////////////////////////////////////////////
116// Vec4 routines
117//////////////////////////////////////////////////////////////////////////////
118
119static void SC_vec4Norm(vec4_t *v)
120{
121    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
122    len = 1 / len;
123    v->x *= len;
124    v->y *= len;
125    v->z *= len;
126    v->w *= len;
127}
128
129static float SC_vec4Length(const vec4_t *v)
130{
131    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z + v->w * v->w);
132}
133
134static void SC_vec4Add(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
135{
136    dest->x = lhs->x + rhs->x;
137    dest->y = lhs->y + rhs->y;
138    dest->z = lhs->z + rhs->z;
139    dest->w = lhs->w + rhs->w;
140}
141
142static void SC_vec4Sub(vec4_t *dest, const vec4_t *lhs, const vec4_t *rhs)
143{
144    dest->x = lhs->x - rhs->x;
145    dest->y = lhs->y - rhs->y;
146    dest->z = lhs->z - rhs->z;
147    dest->w = lhs->w - rhs->w;
148}
149
150static float SC_vec4Dot(const vec4_t *lhs, const vec4_t *rhs)
151{
152    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z + lhs->w * rhs->w;
153}
154
155static void SC_vec4Scale(vec4_t *lhs, float scale)
156{
157    lhs->x *= scale;
158    lhs->y *= scale;
159    lhs->z *= scale;
160    lhs->w *= scale;
161}
162
163//////////////////////////////////////////////////////////////////////////////
164// Math routines
165//////////////////////////////////////////////////////////////////////////////
166
167static float SC_sinf_fast(float x)
168{
169    const float A =   1.0f / (2.0f * M_PI);
170    const float B = -16.0f;
171    const float C =   8.0f;
172
173    // scale angle for easy argument reduction
174    x *= A;
175
176    if (fabsf(x) >= 0.5f) {
177        // argument reduction
178        x = x - ceilf(x + 0.5f) + 1.0f;
179    }
180
181    const float y = B * x * fabsf(x) + C * x;
182    return 0.2215f * (y * fabsf(y) - y) + y;
183}
184
185static float SC_cosf_fast(float x)
186{
187    x += float(M_PI / 2);
188
189    const float A =   1.0f / (2.0f * M_PI);
190    const float B = -16.0f;
191    const float C =   8.0f;
192
193    // scale angle for easy argument reduction
194    x *= A;
195
196    if (fabsf(x) >= 0.5f) {
197        // argument reduction
198        x = x - ceilf(x + 0.5f) + 1.0f;
199    }
200
201    const float y = B * x * fabsf(x) + C * x;
202    return 0.2215f * (y * fabsf(y) - y) + y;
203}
204
205static float SC_randf(float max)
206{
207    //LOGE("max %f", max);
208    float r = (float)rand();
209    return r / RAND_MAX * max;
210}
211
212static float SC_randf2(float min, float max)
213{
214    float r = (float)rand();
215    return r / RAND_MAX * (max - min) + min;
216}
217
218static int SC_sign(int value)
219{
220    return (value > 0) - (value < 0);
221}
222
223static int SC_clamp(int amount, int low, int high)
224{
225    return amount < low ? low : (amount > high ? high : amount);
226}
227
228static float SC_roundf(float v)
229{
230    return floorf(v + 0.4999999999);
231}
232
233static float SC_distf2(float x1, float y1, float x2, float y2)
234{
235    float x = x2 - x1;
236    float y = y2 - y1;
237    return sqrtf(x * x + y * y);
238}
239
240static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
241{
242    float x = x2 - x1;
243    float y = y2 - y1;
244    float z = z2 - z1;
245    return sqrtf(x * x + y * y + z * z);
246}
247
248static float SC_magf2(float a, float b)
249{
250    return sqrtf(a * a + b * b);
251}
252
253static float SC_magf3(float a, float b, float c)
254{
255    return sqrtf(a * a + b * b + c * c);
256}
257
258static float SC_normf(float start, float stop, float value)
259{
260    return (value - start) / (stop - start);
261}
262
263static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
264{
265    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
266}
267
268static float SC_frac(float v)
269{
270    int i = (int)floor(v);
271    return fmin(v - i, 0x1.fffffep-1f);
272}
273
274//////////////////////////////////////////////////////////////////////////////
275// Time routines
276//////////////////////////////////////////////////////////////////////////////
277
278static int32_t SC_second()
279{
280    GET_TLS();
281
282    time_t rawtime;
283    time(&rawtime);
284
285    struct tm *timeinfo;
286    timeinfo = localtime(&rawtime);
287    return timeinfo->tm_sec;
288}
289
290static int32_t SC_minute()
291{
292    GET_TLS();
293
294    time_t rawtime;
295    time(&rawtime);
296
297    struct tm *timeinfo;
298    timeinfo = localtime(&rawtime);
299    return timeinfo->tm_min;
300}
301
302static int32_t SC_hour()
303{
304    GET_TLS();
305
306    time_t rawtime;
307    time(&rawtime);
308
309    struct tm *timeinfo;
310    timeinfo = localtime(&rawtime);
311    return timeinfo->tm_hour;
312}
313
314static int32_t SC_day()
315{
316    GET_TLS();
317
318    time_t rawtime;
319    time(&rawtime);
320
321    struct tm *timeinfo;
322    timeinfo = localtime(&rawtime);
323    return timeinfo->tm_mday;
324}
325
326static int32_t SC_month()
327{
328    GET_TLS();
329
330    time_t rawtime;
331    time(&rawtime);
332
333    struct tm *timeinfo;
334    timeinfo = localtime(&rawtime);
335    return timeinfo->tm_mon;
336}
337
338static int32_t SC_year()
339{
340    GET_TLS();
341
342    time_t rawtime;
343    time(&rawtime);
344
345    struct tm *timeinfo;
346    timeinfo = localtime(&rawtime);
347    return timeinfo->tm_year;
348}
349
350static int32_t SC_uptimeMillis()
351{
352    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
353}
354
355static int32_t SC_startTimeMillis()
356{
357    GET_TLS();
358    return sc->mEnviroment.mStartTimeMillis;
359}
360
361static int32_t SC_elapsedTimeMillis()
362{
363    GET_TLS();
364    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC))
365            - sc->mEnviroment.mStartTimeMillis;
366}
367
368//////////////////////////////////////////////////////////////////////////////
369// Matrix routines
370//////////////////////////////////////////////////////////////////////////////
371
372
373static void SC_matrixLoadIdentity(rsc_Matrix *mat)
374{
375    Matrix *m = reinterpret_cast<Matrix *>(mat);
376    m->loadIdentity();
377}
378
379static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
380{
381    Matrix *m = reinterpret_cast<Matrix *>(mat);
382    m->load(f);
383}
384
385static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
386{
387    Matrix *m = reinterpret_cast<Matrix *>(mat);
388    m->load(reinterpret_cast<const Matrix *>(newmat));
389}
390
391static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
392{
393    Matrix *m = reinterpret_cast<Matrix *>(mat);
394    m->loadRotate(rot, x, y, z);
395}
396
397static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
398{
399    Matrix *m = reinterpret_cast<Matrix *>(mat);
400    m->loadScale(x, y, z);
401}
402
403static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
404{
405    Matrix *m = reinterpret_cast<Matrix *>(mat);
406    m->loadTranslate(x, y, z);
407}
408
409static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
410{
411    Matrix *m = reinterpret_cast<Matrix *>(mat);
412    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
413                    reinterpret_cast<const Matrix *>(rhs));
414}
415
416static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
417{
418    Matrix *m = reinterpret_cast<Matrix *>(mat);
419    m->multiply(reinterpret_cast<const Matrix *>(rhs));
420}
421
422static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
423{
424    Matrix *m = reinterpret_cast<Matrix *>(mat);
425    m->rotate(rot, x, y, z);
426}
427
428static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z)
429{
430    Matrix *m = reinterpret_cast<Matrix *>(mat);
431    m->scale(x, y, z);
432}
433
434static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
435{
436    Matrix *m = reinterpret_cast<Matrix *>(mat);
437    m->translate(x, y, z);
438}
439
440
441static rsvF_2 SC_vec2Rand(float maxLen)
442{
443    float2 t;
444    float angle = SC_randf(M_PI * 2);
445    float len = SC_randf(maxLen);
446    t.f[0] = len * sinf(angle);
447    t.f[1] = len * cosf(angle);
448    return t.v;
449}
450
451
452//////////////////////////////////////////////////////////////////////////////
453//
454//////////////////////////////////////////////////////////////////////////////
455
456static uint32_t SC_allocGetDimX(RsAllocation va)
457{
458    GET_TLS();
459    const Allocation *a = static_cast<const Allocation *>(va);
460    //LOGE("SC_allocGetDimX a=%p", a);
461    //LOGE(" type=%p", a->getType());
462    return a->getType()->getDimX();
463}
464
465static uint32_t SC_allocGetDimY(RsAllocation va)
466{
467    GET_TLS();
468    const Allocation *a = static_cast<const Allocation *>(va);
469    return a->getType()->getDimY();
470}
471
472static uint32_t SC_allocGetDimZ(RsAllocation va)
473{
474    GET_TLS();
475    const Allocation *a = static_cast<const Allocation *>(va);
476    return a->getType()->getDimZ();
477}
478
479static uint32_t SC_allocGetDimLOD(RsAllocation va)
480{
481    GET_TLS();
482    const Allocation *a = static_cast<const Allocation *>(va);
483    return a->getType()->getDimLOD();
484}
485
486static uint32_t SC_allocGetDimFaces(RsAllocation va)
487{
488    GET_TLS();
489    const Allocation *a = static_cast<const Allocation *>(va);
490    return a->getType()->getDimFaces();
491}
492
493
494
495static void SC_debugF(const char *s, float f)
496{
497    LOGE("%s %f", s, f);
498}
499
500static void SC_debugHexF(const char *s, float f)
501{
502    LOGE("%s 0x%x", s, *((int *) (&f)));
503}
504
505static void SC_debugI32(const char *s, int32_t i)
506{
507    LOGE("%s %i", s, i);
508}
509
510static void SC_debugHexI32(const char *s, int32_t i)
511{
512    LOGE("%s 0x%x", s, i);
513}
514
515static uchar4 SC_convertColorTo8888_f3(float r, float g, float b) {
516    uchar4 t;
517    t.f[0] = (uint8_t)(r * 255.f);
518    t.f[1] = (uint8_t)(g * 255.f);
519    t.f[2] = (uint8_t)(b * 255.f);
520    t.f[3] = 0xff;
521    return t;
522}
523
524static uchar4 SC_convertColorTo8888_f4(float r, float g, float b, float a) {
525    uchar4 t;
526    t.f[0] = (uint8_t)(r * 255.f);
527    t.f[1] = (uint8_t)(g * 255.f);
528    t.f[2] = (uint8_t)(b * 255.f);
529    t.f[3] = (uint8_t)(a * 255.f);
530    return t;
531}
532
533static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
534{
535    GET_TLS();
536    //LOGE("SC_toClient %i %i %i", cmdID, len, waitForSpace);
537    return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
538}
539
540static void SC_scriptCall(int scriptID)
541{
542    GET_TLS();
543    rsc->runScript((Script *)scriptID, 0);
544}
545
546static void SC_debugP(int i, void *p)
547{
548    LOGE("debug P  %i  %p, %i", i, p, (int)p);
549}
550
551static void SC_debugPi(int i, int p)
552{
553    LOGE("debug Pi %i  0x%08x, %i", i, p, (int)p);
554}
555
556static void SC_debugPf(int i, float p)
557{
558    LOGE("debug Pf  %i  %f,   0x%08x", i, p, reinterpret_cast<uint32_t *>(&p)[0]);
559}
560
561int SC_divsi3(int a, int b)
562{
563    return a / b;
564}
565
566int SC_getAllocation(const void *ptr)
567{
568    GET_TLS();
569    const Allocation *alloc = sc->ptrToAllocation(ptr);
570    return (int)alloc;
571}
572
573
574//////////////////////////////////////////////////////////////////////////////
575// Class implementation
576//////////////////////////////////////////////////////////////////////////////
577
578// llvm name mangling ref
579//  <builtin-type> ::= v  # void
580//                 ::= b  # bool
581//                 ::= c  # char
582//                 ::= a  # signed char
583//                 ::= h  # unsigned char
584//                 ::= s  # short
585//                 ::= t  # unsigned short
586//                 ::= i  # int
587//                 ::= j  # unsigned int
588//                 ::= l  # long
589//                 ::= m  # unsigned long
590//                 ::= x  # long long, __int64
591//                 ::= y  # unsigned long long, __int64
592//                 ::= f  # float
593//                 ::= d  # double
594
595static ScriptCState::SymbolTable_t gSyms[] = {
596    { "__divsi3", (void *)&SC_divsi3 },
597
598    { "modf", (void *)&fmod },
599    { "_Z4fracf", (void *)&SC_frac },
600    //{ "sinf_fast", (void *)&SC_sinf_fast },
601    //{ "cosf_fast", (void *)&SC_cosf_fast },
602    { "randf", (void *)&SC_randf },
603    { "randf2", (void *)&SC_randf2 },
604    { "sign", (void *)&SC_sign },
605    { "clamp", (void *)&SC_clamp },
606    { "distf2", (void *)&SC_distf2 },
607    { "distf3", (void *)&SC_distf3 },
608    { "magf2", (void *)&SC_magf2 },
609    { "magf3", (void *)&SC_magf3 },
610    { "normf", (void *)&SC_normf },
611    { "mapf", (void *)&SC_mapf },
612    { "noisef", (void *)&SC_noisef },
613    { "noisef2", (void *)&SC_noisef2 },
614    { "noisef3", (void *)&SC_noisef3 },
615    { "turbulencef2", (void *)&SC_turbulencef2 },
616    { "turbulencef3", (void *)&SC_turbulencef3 },
617
618    // time
619    { "second", (void *)&SC_second },
620    { "minute", (void *)&SC_minute },
621    { "hour", (void *)&SC_hour },
622    { "day", (void *)&SC_day },
623    { "month", (void *)&SC_month },
624    { "year", (void *)&SC_year },
625    { "uptimeMillis", (void*)&SC_uptimeMillis },      // TODO: use long instead
626    { "startTimeMillis", (void*)&SC_startTimeMillis },      // TODO: use long instead
627    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis },      // TODO: use long instead
628
629    // matrix
630    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity },
631    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat },
632    { "matrixLoadMat", (void *)&SC_matrixLoadMat },
633    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate },
634    { "matrixLoadScale", (void *)&SC_matrixLoadScale },
635    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate },
636    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply },
637    { "matrixMultiply", (void *)&SC_matrixMultiply },
638    { "matrixRotate", (void *)&SC_matrixRotate },
639    { "matrixScale", (void *)&SC_matrixScale },
640    { "matrixTranslate", (void *)&SC_matrixTranslate },
641
642    // vector
643    { "vec2Rand", (void *)&SC_vec2Rand },
644
645    // vec3
646    { "vec3Norm", (void *)&SC_vec3Norm },
647    { "vec3Length", (void *)&SC_vec3Length },
648    { "vec3Add", (void *)&SC_vec3Add },
649    { "vec3Sub", (void *)&SC_vec3Sub },
650    { "vec3Cross", (void *)&SC_vec3Cross },
651    { "vec3Dot", (void *)&SC_vec3Dot },
652    { "vec3Scale", (void *)&SC_vec3Scale },
653
654    // vec4
655    { "vec4Norm", (void *)&SC_vec4Norm },
656    { "vec4Length", (void *)&SC_vec4Length },
657    { "vec4Add", (void *)&SC_vec4Add },
658    { "vec4Sub", (void *)&SC_vec4Sub },
659    { "vec4Dot", (void *)&SC_vec4Dot },
660    { "vec4Scale", (void *)&SC_vec4Scale },
661
662    // allocation
663    { "allocGetDimX", (void *)&SC_allocGetDimX },
664    { "allocGetDimY", (void *)&SC_allocGetDimY },
665    { "allocGetDimZ", (void *)&SC_allocGetDimZ },
666    { "allocGetDimLOD", (void *)&SC_allocGetDimLOD },
667    { "allocGetDimFaces", (void *)&SC_allocGetDimFaces },
668
669
670    // misc
671    { "sendToClient", (void *)&SC_toClient },
672
673    { "_Z18convertColorTo8888fff", (void *)&SC_convertColorTo8888_f3 },
674    { "_Z18convertColorTo8888ffff", (void *)&SC_convertColorTo8888_f4 },
675
676    { "debugF", (void *)&SC_debugF },
677    { "debugI32", (void *)&SC_debugI32 },
678    { "debugHexF", (void *)&SC_debugHexF },
679    { "debugHexI32", (void *)&SC_debugHexI32 },
680    { "debugP", (void *)&SC_debugP },
681    { "debugPf", (void *)&SC_debugPf },
682    { "debugPi", (void *)&SC_debugPi },
683
684    { "scriptCall", (void *)&SC_scriptCall },
685    { "rsGetAllocation", (void *)&SC_getAllocation },
686
687
688    { NULL, NULL }
689};
690
691const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
692{
693    ScriptCState::SymbolTable_t *syms = gSyms;
694
695    while (syms->mPtr) {
696        if (!strcmp(syms->mName, sym)) {
697            return syms;
698        }
699        syms++;
700    }
701    return NULL;
702}
703
704