rsScriptC_Lib.cpp revision a2b54c4ccae78fdd9afefd524037dc53ed28e2d8
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 <GLES/gl.h>
26#include <GLES/glext.h>
27
28#include <time.h>
29#include <cutils/tztime.h>
30
31using namespace android;
32using namespace android::renderscript;
33
34#define GET_TLS()  Context::ScriptTLSStruct * tls = \
35    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
36    Context * rsc = tls->mContext; \
37    ScriptC * sc = (ScriptC *) tls->mScript
38
39typedef struct {
40    float x;
41    float y;
42    float z;
43} vec3_t;
44
45typedef struct {
46    float x;
47    float y;
48    float z;
49    float w;
50} vec4_t;
51
52typedef struct {
53    float x;
54    float y;
55} vec2_t;
56
57//////////////////////////////////////////////////////////////////////////////
58// IO routines
59//////////////////////////////////////////////////////////////////////////////
60
61static float SC_loadF(uint32_t bank, uint32_t offset)
62{
63    GET_TLS();
64    const void *vp = sc->mSlots[bank]->getPtr();
65    const float *f = static_cast<const float *>(vp);
66    //LOGE("loadF %i %i = %f %x", bank, offset, f, ((int *)&f)[0]);
67    return f[offset];
68}
69
70static int32_t SC_loadI32(uint32_t bank, uint32_t offset)
71{
72    GET_TLS();
73    const void *vp = sc->mSlots[bank]->getPtr();
74    const int32_t *i = static_cast<const int32_t *>(vp);
75    //LOGE("loadI32 %i %i = %i", bank, offset, t);
76    return i[offset];
77}
78
79static float* SC_loadArrayF(uint32_t bank, uint32_t offset)
80{
81    GET_TLS();
82    void *vp = sc->mSlots[bank]->getPtr();
83    float *f = static_cast<float *>(vp);
84    return f + offset;
85}
86
87static int32_t* SC_loadArrayI32(uint32_t bank, uint32_t offset)
88{
89    GET_TLS();
90    void *vp = sc->mSlots[bank]->getPtr();
91    int32_t *i = static_cast<int32_t *>(vp);
92    return i + offset;
93}
94
95static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx)
96{
97    SimpleMesh *tm = static_cast<SimpleMesh *>(mesh);
98    void *vp = tm->mVertexBuffers[idx]->getPtr();;
99    return static_cast<float *>(vp);
100}
101
102static void SC_updateSimpleMesh(RsSimpleMesh mesh)
103{
104    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
105    sm->uploadAll();
106}
107
108static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
109{
110    GET_TLS();
111    const void *vp = sc->mSlots[bank]->getPtr();
112    const uint32_t *i = static_cast<const uint32_t *>(vp);
113    return i[offset];
114}
115
116static void SC_loadVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v)
117{
118    GET_TLS();
119    const void *vp = sc->mSlots[bank]->getPtr();
120    const float *f = static_cast<const float *>(vp);
121    memcpy(v, &f[offset], sizeof(rsc_Vector4));
122}
123
124static void SC_loadMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m)
125{
126    GET_TLS();
127    const void *vp = sc->mSlots[bank]->getPtr();
128    const float *f = static_cast<const float *>(vp);
129    memcpy(m, &f[offset], sizeof(rsc_Matrix));
130}
131
132
133static void SC_storeF(uint32_t bank, uint32_t offset, float v)
134{
135    //LOGE("storeF %i %i %f", bank, offset, v);
136    GET_TLS();
137    void *vp = sc->mSlots[bank]->getPtr();
138    float *f = static_cast<float *>(vp);
139    f[offset] = v;
140}
141
142static void SC_storeI32(uint32_t bank, uint32_t offset, int32_t v)
143{
144    GET_TLS();
145    void *vp = sc->mSlots[bank]->getPtr();
146    int32_t *f = static_cast<int32_t *>(vp);
147    static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
148}
149
150static void SC_storeU32(uint32_t bank, uint32_t offset, uint32_t v)
151{
152    GET_TLS();
153    void *vp = sc->mSlots[bank]->getPtr();
154    uint32_t *f = static_cast<uint32_t *>(vp);
155    static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
156}
157
158static void SC_storeVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
159{
160    GET_TLS();
161    void *vp = sc->mSlots[bank]->getPtr();
162    float *f = static_cast<float *>(vp);
163    memcpy(&f[offset], v, sizeof(rsc_Vector4));
164}
165
166static void SC_storeMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m)
167{
168    GET_TLS();
169    void *vp = sc->mSlots[bank]->getPtr();
170    float *f = static_cast<float *>(vp);
171    memcpy(&f[offset], m, sizeof(rsc_Matrix));
172}
173
174//////////////////////////////////////////////////////////////////////////////
175// Vec3 routines
176//////////////////////////////////////////////////////////////////////////////
177
178static void SC_vec3Norm(vec3_t *v)
179{
180    float len = sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
181    len = 1 / len;
182    v->x *= len;
183    v->y *= len;
184    v->z *= len;
185}
186
187static float SC_vec3Length(const vec3_t *v)
188{
189    return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
190}
191
192static void SC_vec3Add(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
193{
194    dest->x = lhs->x + rhs->x;
195    dest->y = lhs->y + rhs->y;
196    dest->z = lhs->z + rhs->z;
197}
198
199static void SC_vec3Sub(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
200{
201    dest->x = lhs->x - rhs->x;
202    dest->y = lhs->y - rhs->y;
203    dest->z = lhs->z - rhs->z;
204}
205
206static void SC_vec3Cross(vec3_t *dest, const vec3_t *lhs, const vec3_t *rhs)
207{
208    float x = lhs->y * rhs->z  - lhs->z * rhs->y;
209    float y = lhs->z * rhs->x  - lhs->x * rhs->z;
210    float z = lhs->x * rhs->y  - lhs->y * rhs->x;
211    dest->x = x;
212    dest->y = y;
213    dest->z = z;
214}
215
216static float SC_vec3Dot(const vec3_t *lhs, const vec3_t *rhs)
217{
218    return lhs->x * rhs->x + lhs->y * rhs->y + lhs->z * rhs->z;
219}
220
221static void SC_vec3Scale(vec3_t *lhs, float scale)
222{
223    lhs->x *= scale;
224    lhs->y *= scale;
225    lhs->z *= scale;
226}
227
228
229//////////////////////////////////////////////////////////////////////////////
230// Math routines
231//////////////////////////////////////////////////////////////////////////////
232
233#define PI 3.1415926f
234#define DEG_TO_RAD PI / 180.0f
235#define RAD_TO_DEG 180.0f / PI
236
237static float SC_sinf_fast(float x)
238{
239    const float A =   1.0f / (2.0f * M_PI);
240    const float B = -16.0f;
241    const float C =   8.0f;
242
243    // scale angle for easy argument reduction
244    x *= A;
245
246    if (fabsf(x) >= 0.5f) {
247        // argument reduction
248        x = x - ceilf(x + 0.5f) + 1.0f;
249    }
250
251    const float y = B * x * fabsf(x) + C * x;
252    return 0.2215f * (y * fabsf(y) - y) + y;
253}
254
255static float SC_cosf_fast(float x)
256{
257    x += float(M_PI / 2);
258
259    const float A =   1.0f / (2.0f * M_PI);
260    const float B = -16.0f;
261    const float C =   8.0f;
262
263    // scale angle for easy argument reduction
264    x *= A;
265
266    if (fabsf(x) >= 0.5f) {
267        // argument reduction
268        x = x - ceilf(x + 0.5f) + 1.0f;
269    }
270
271    const float y = B * x * fabsf(x) + C * x;
272    return 0.2215f * (y * fabsf(y) - y) + y;
273}
274
275static float SC_randf(float max)
276{
277    float r = (float)rand();
278    return r / RAND_MAX * max;
279}
280
281static float SC_randf2(float min, float max)
282{
283    float r = (float)rand();
284    return r / RAND_MAX * (max - min) + min;
285}
286
287static float SC_clampf(float amount, float low, float high)
288{
289    return amount < low ? low : (amount > high ? high : amount);
290}
291
292static int SC_clamp(int amount, int low, int high)
293{
294    return amount < low ? low : (amount > high ? high : amount);
295}
296
297static float SC_maxf(float a, float b)
298{
299    return a > b ? a : b;
300}
301
302static float SC_minf(float a, float b)
303{
304    return a < b ? a : b;
305}
306
307static float SC_sqrf(float v)
308{
309    return v * v;
310}
311
312static int SC_sqr(int v)
313{
314    return v * v;
315}
316
317static float SC_fracf(float v)
318{
319    return v - floorf(v);
320}
321
322static float SC_roundf(float v)
323{
324    return floorf(v + 0.4999999999);
325}
326
327static float SC_distf2(float x1, float y1, float x2, float y2)
328{
329    float x = x2 - x1;
330    float y = y2 - y1;
331    return sqrtf(x * x + y * y);
332}
333
334static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
335{
336    float x = x2 - x1;
337    float y = y2 - y1;
338    float z = z2 - z1;
339    return sqrtf(x * x + y * y + z * z);
340}
341
342static float SC_magf2(float a, float b)
343{
344    return sqrtf(a * a + b * b);
345}
346
347static float SC_magf3(float a, float b, float c)
348{
349    return sqrtf(a * a + b * b + c * c);
350}
351
352static float SC_radf(float degrees)
353{
354    return degrees * DEG_TO_RAD;
355}
356
357static float SC_degf(float radians)
358{
359    return radians * RAD_TO_DEG;
360}
361
362static float SC_lerpf(float start, float stop, float amount)
363{
364    return start + (stop - start) * amount;
365}
366
367static float SC_normf(float start, float stop, float value)
368{
369    return (value - start) / (stop - start);
370}
371
372static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
373{
374    return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
375}
376
377//////////////////////////////////////////////////////////////////////////////
378// Time routines
379//////////////////////////////////////////////////////////////////////////////
380
381static int32_t SC_second()
382{
383    GET_TLS();
384
385    time_t rawtime;
386    time(&rawtime);
387
388    if (sc->mEnviroment.mTimeZone) {
389        struct tm timeinfo;
390        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
391        return timeinfo.tm_sec;
392    } else {
393        struct tm *timeinfo;
394        timeinfo = localtime(&rawtime);
395        return timeinfo->tm_sec;
396    }
397}
398
399static int32_t SC_minute()
400{
401    GET_TLS();
402
403    time_t rawtime;
404    time(&rawtime);
405
406    if (sc->mEnviroment.mTimeZone) {
407        struct tm timeinfo;
408        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
409        return timeinfo.tm_min;
410    } else {
411        struct tm *timeinfo;
412        timeinfo = localtime(&rawtime);
413        return timeinfo->tm_min;
414    }
415}
416
417static int32_t SC_hour()
418{
419    GET_TLS();
420
421    time_t rawtime;
422    time(&rawtime);
423
424    if (sc->mEnviroment.mTimeZone) {
425        struct tm timeinfo;
426        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
427        return timeinfo.tm_hour;
428    } else {
429        struct tm *timeinfo;
430        timeinfo = localtime(&rawtime);
431        return timeinfo->tm_hour;
432    }
433}
434
435static int32_t SC_day()
436{
437    GET_TLS();
438
439    time_t rawtime;
440    time(&rawtime);
441
442    if (sc->mEnviroment.mTimeZone) {
443        struct tm timeinfo;
444        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
445        return timeinfo.tm_mday;
446    } else {
447        struct tm *timeinfo;
448        timeinfo = localtime(&rawtime);
449        return timeinfo->tm_mday;
450    }
451}
452
453static int32_t SC_month()
454{
455    GET_TLS();
456
457    time_t rawtime;
458    time(&rawtime);
459
460    if (sc->mEnviroment.mTimeZone) {
461        struct tm timeinfo;
462        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
463        return timeinfo.tm_mon;
464    } else {
465        struct tm *timeinfo;
466        timeinfo = localtime(&rawtime);
467        return timeinfo->tm_mon;
468    }
469}
470
471static int32_t SC_year()
472{
473    GET_TLS();
474
475    time_t rawtime;
476    time(&rawtime);
477
478    if (sc->mEnviroment.mTimeZone) {
479        struct tm timeinfo;
480        localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
481        return timeinfo.tm_year;
482    } else {
483        struct tm *timeinfo;
484        timeinfo = localtime(&rawtime);
485        return timeinfo->tm_year;
486    }
487}
488
489static int32_t SC_uptimeMillis()
490{
491    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
492}
493
494static int32_t SC_startTimeMillis()
495{
496    GET_TLS();
497    return sc->mEnviroment.mStartTimeMillis;
498}
499
500static int32_t SC_elapsedTimeMillis()
501{
502    GET_TLS();
503    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC))
504            - sc->mEnviroment.mStartTimeMillis;
505}
506
507//////////////////////////////////////////////////////////////////////////////
508// Matrix routines
509//////////////////////////////////////////////////////////////////////////////
510
511
512static void SC_matrixLoadIdentity(rsc_Matrix *mat)
513{
514    Matrix *m = reinterpret_cast<Matrix *>(mat);
515    m->loadIdentity();
516}
517
518static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
519{
520    Matrix *m = reinterpret_cast<Matrix *>(mat);
521    m->load(f);
522}
523
524static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
525{
526    Matrix *m = reinterpret_cast<Matrix *>(mat);
527    m->load(reinterpret_cast<const Matrix *>(newmat));
528}
529
530static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
531{
532    Matrix *m = reinterpret_cast<Matrix *>(mat);
533    m->loadRotate(rot, x, y, z);
534}
535
536static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
537{
538    Matrix *m = reinterpret_cast<Matrix *>(mat);
539    m->loadScale(x, y, z);
540}
541
542static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
543{
544    Matrix *m = reinterpret_cast<Matrix *>(mat);
545    m->loadTranslate(x, y, z);
546}
547
548static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
549{
550    Matrix *m = reinterpret_cast<Matrix *>(mat);
551    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
552                    reinterpret_cast<const Matrix *>(rhs));
553}
554
555static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
556{
557    Matrix *m = reinterpret_cast<Matrix *>(mat);
558    m->multiply(reinterpret_cast<const Matrix *>(rhs));
559}
560
561static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
562{
563    Matrix *m = reinterpret_cast<Matrix *>(mat);
564    m->rotate(rot, x, y, z);
565}
566
567static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z)
568{
569    Matrix *m = reinterpret_cast<Matrix *>(mat);
570    m->scale(x, y, z);
571}
572
573static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
574{
575    Matrix *m = reinterpret_cast<Matrix *>(mat);
576    m->translate(x, y, z);
577}
578
579
580static void SC_vec2Rand(float *vec, float maxLen)
581{
582    float angle = SC_randf(PI * 2);
583    float len = SC_randf(maxLen);
584    vec[0] = len * sinf(angle);
585    vec[1] = len * cosf(angle);
586}
587
588
589
590//////////////////////////////////////////////////////////////////////////////
591// Context
592//////////////////////////////////////////////////////////////////////////////
593
594static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
595{
596    GET_TLS();
597    rsi_ProgramFragmentBindTexture(rsc,
598                                   static_cast<ProgramFragment *>(vpf),
599                                   slot,
600                                   static_cast<Allocation *>(va));
601
602}
603
604static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
605{
606    GET_TLS();
607    rsi_ProgramFragmentBindSampler(rsc,
608                                   static_cast<ProgramFragment *>(vpf),
609                                   slot,
610                                   static_cast<Sampler *>(vs));
611
612}
613
614static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
615{
616    GET_TLS();
617    rsi_ContextBindProgramFragmentStore(rsc, pfs);
618
619}
620
621static void SC_bindProgramFragment(RsProgramFragment pf)
622{
623    GET_TLS();
624    rsi_ContextBindProgramFragment(rsc, pf);
625
626}
627
628static void SC_bindProgramVertex(RsProgramVertex pv)
629{
630    GET_TLS();
631    rsi_ContextBindProgramVertex(rsc, pv);
632
633}
634
635//////////////////////////////////////////////////////////////////////////////
636// VP
637//////////////////////////////////////////////////////////////////////////////
638
639static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
640{
641    GET_TLS();
642    rsc->getVertex()->setModelviewMatrix(m);
643}
644
645static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
646{
647    GET_TLS();
648    rsc->getVertex()->setTextureMatrix(m);
649}
650
651
652
653//////////////////////////////////////////////////////////////////////////////
654// Drawing
655//////////////////////////////////////////////////////////////////////////////
656
657static void SC_drawLine(float x1, float y1, float z1,
658                        float x2, float y2, float z2)
659{
660    GET_TLS();
661    rsc->setupCheck();
662
663    float vtx[] = { x1, y1, z1, x2, y2, z2 };
664
665    glBindBuffer(GL_ARRAY_BUFFER, 0);
666    glEnableClientState(GL_VERTEX_ARRAY);
667    glVertexPointer(3, GL_FLOAT, 0, vtx);
668
669    glDisableClientState(GL_NORMAL_ARRAY);
670    glDisableClientState(GL_COLOR_ARRAY);
671
672    glDrawArrays(GL_LINES, 0, 2);
673}
674
675static void SC_drawQuadTexCoords(float x1, float y1, float z1,
676                                 float u1, float v1,
677                                 float x2, float y2, float z2,
678                                 float u2, float v2,
679                                 float x3, float y3, float z3,
680                                 float u3, float v3,
681                                 float x4, float y4, float z4,
682                                 float u4, float v4)
683{
684    GET_TLS();
685
686    //LOGE("Quad");
687    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
688    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
689    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
690    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
691
692    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
693    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
694
695    rsc->setupCheck();
696
697    glBindBuffer(GL_ARRAY_BUFFER, 0);
698    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
699
700    glEnableClientState(GL_VERTEX_ARRAY);
701    glVertexPointer(3, GL_FLOAT, 0, vtx);
702
703    glClientActiveTexture(GL_TEXTURE0);
704    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
705    glTexCoordPointer(2, GL_FLOAT, 0, tex);
706    glClientActiveTexture(GL_TEXTURE1);
707    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
708    glTexCoordPointer(2, GL_FLOAT, 0, tex);
709    glClientActiveTexture(GL_TEXTURE0);
710
711    glDisableClientState(GL_NORMAL_ARRAY);
712    glDisableClientState(GL_COLOR_ARRAY);
713
714    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
715
716    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
717}
718
719static void SC_drawQuad(float x1, float y1, float z1,
720                        float x2, float y2, float z2,
721                        float x3, float y3, float z3,
722                        float x4, float y4, float z4)
723{
724    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
725                         x2, y2, z2, 1, 1,
726                         x3, y3, z3, 1, 0,
727                         x4, y4, z4, 0, 0);
728}
729
730static void SC_drawRect(float x1, float y1,
731                        float x2, float y2, float z)
732{
733    SC_drawQuad(x1, y2, z,
734                x2, y2, z,
735                x2, y1, z,
736                x1, y1, z);
737}
738
739static void SC_drawSimpleMesh(RsSimpleMesh vsm)
740{
741    GET_TLS();
742    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
743    rsc->setupCheck();
744    sm->render();
745}
746
747static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
748{
749    GET_TLS();
750    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
751    rsc->setupCheck();
752    sm->renderRange(start, len);
753}
754
755
756//////////////////////////////////////////////////////////////////////////////
757//
758//////////////////////////////////////////////////////////////////////////////
759
760static void SC_color(float r, float g, float b, float a)
761{
762    glColor4f(r, g, b, a);
763}
764
765static void SC_ambient(float r, float g, float b, float a)
766{
767    GLfloat params[] = { r, g, b, a };
768    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
769}
770
771static void SC_diffuse(float r, float g, float b, float a)
772{
773    GLfloat params[] = { r, g, b, a };
774    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
775}
776
777static void SC_specular(float r, float g, float b, float a)
778{
779    GLfloat params[] = { r, g, b, a };
780    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
781}
782
783static void SC_emission(float r, float g, float b, float a)
784{
785    GLfloat params[] = { r, g, b, a };
786    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
787}
788
789static void SC_shininess(float s)
790{
791    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
792}
793
794static void SC_pointAttenuation(float a, float b, float c)
795{
796    GLfloat params[] = { a, b, c };
797    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
798}
799
800static void SC_hsbToRgb(float h, float s, float b, float* rgb)
801{
802    float red = 0.0f;
803    float green = 0.0f;
804    float blue = 0.0f;
805
806    float x = h;
807    float y = s;
808    float z = b;
809
810    float hf = (x - (int) x) * 6.0f;
811    int ihf = (int) hf;
812    float f = hf - ihf;
813    float pv = z * (1.0f - y);
814    float qv = z * (1.0f - y * f);
815    float tv = z * (1.0f - y * (1.0f - f));
816
817    switch (ihf) {
818        case 0:         // Red is the dominant color
819            red = z;
820            green = tv;
821            blue = pv;
822            break;
823        case 1:         // Green is the dominant color
824            red = qv;
825            green = z;
826            blue = pv;
827            break;
828        case 2:
829            red = pv;
830            green = z;
831            blue = tv;
832            break;
833        case 3:         // Blue is the dominant color
834            red = pv;
835            green = qv;
836            blue = z;
837            break;
838        case 4:
839            red = tv;
840            green = pv;
841            blue = z;
842            break;
843        case 5:         // Red is the dominant color
844            red = z;
845            green = pv;
846            blue = qv;
847            break;
848    }
849
850    rgb[0] = red;
851    rgb[1] = green;
852    rgb[2] = blue;
853}
854
855static int SC_hsbToAbgr(float h, float s, float b, float a)
856{
857    float rgb[3];
858    SC_hsbToRgb(h, s, b, rgb);
859    return int(a      * 255.0f) << 24 |
860           int(rgb[2] * 255.0f) << 16 |
861           int(rgb[1] * 255.0f) <<  8 |
862           int(rgb[0] * 255.0f);
863}
864
865static void SC_hsb(float h, float s, float b, float a)
866{
867    float rgb[3];
868    SC_hsbToRgb(h, s, b, rgb);
869    glColor4f(rgb[0], rgb[1], rgb[2], a);
870}
871
872static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
873{
874    GET_TLS();
875    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
876}
877
878static void SC_uploadToBufferObject(RsAllocation va)
879{
880    GET_TLS();
881    rsi_AllocationUploadToBufferObject(rsc, va);
882}
883
884static void SC_ClearColor(float r, float g, float b, float a)
885{
886    //LOGE("c %f %f %f %f", r, g, b, a);
887    GET_TLS();
888    sc->mEnviroment.mClearColor[0] = r;
889    sc->mEnviroment.mClearColor[1] = g;
890    sc->mEnviroment.mClearColor[2] = b;
891    sc->mEnviroment.mClearColor[3] = a;
892}
893
894static void SC_debugF(const char *s, float f)
895{
896    LOGE("%s %f", s, f);
897}
898
899static void SC_debugHexF(const char *s, float f)
900{
901    LOGE("%s 0x%x", s, *((int *) (&f)));
902}
903
904static void SC_debugI32(const char *s, int32_t i)
905{
906    LOGE("%s %i", s, i);
907}
908
909static void SC_debugHexI32(const char *s, int32_t i)
910{
911    LOGE("%s 0x%x", s, i);
912}
913
914static uint32_t SC_getWidth()
915{
916    GET_TLS();
917    return rsc->getWidth();
918}
919
920static uint32_t SC_getHeight()
921{
922    GET_TLS();
923    return rsc->getHeight();
924}
925
926static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
927{
928    uint32_t c = 0;
929    c |= (uint32_t)(r * 255.f + 0.5f);
930    c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
931    c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
932    c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
933    return c;
934}
935
936static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
937{
938    uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
939    uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
940    uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
941    return rs888to565(ir, ig, ib);
942}
943
944//////////////////////////////////////////////////////////////////////////////
945// Class implementation
946//////////////////////////////////////////////////////////////////////////////
947
948ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
949    // IO
950    { "loadI32", (void *)&SC_loadI32,
951        "int", "(int, int)" },
952    //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
953    { "loadF", (void *)&SC_loadF,
954        "float", "(int, int)" },
955    { "loadArrayF", (void *)&SC_loadArrayF,
956        "float*", "(int, int)" },
957    { "loadArrayI32", (void *)&SC_loadArrayI32,
958        "int*", "(int, int)" },
959    { "loadVec4", (void *)&SC_loadVec4,
960        "void", "(int, int, float *)" },
961    { "loadMatrix", (void *)&SC_loadMatrix,
962        "void", "(int, int, float *)" },
963    { "storeI32", (void *)&SC_storeI32,
964        "void", "(int, int, int)" },
965    //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
966    { "storeF", (void *)&SC_storeF,
967        "void", "(int, int, float)" },
968    { "storeVec4", (void *)&SC_storeVec4,
969        "void", "(int, int, float *)" },
970    { "storeMatrix", (void *)&SC_storeMatrix,
971        "void", "(int, int, float *)" },
972    { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
973        "float*", "(int, int)" },
974    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
975        "void", "(int)" },
976
977    // math
978    { "modf", (void *)&fmod,
979        "float", "(float, float)" },
980    { "abs", (void *)&abs,
981        "int", "(int)" },
982    { "absf", (void *)&fabs,
983        "float", "(float)" },
984    { "sinf_fast", (void *)&SC_sinf_fast,
985        "float", "(float)" },
986    { "cosf_fast", (void *)&SC_cosf_fast,
987        "float", "(float)" },
988    { "sinf", (void *)&sinf,
989        "float", "(float)" },
990    { "cosf", (void *)&cosf,
991        "float", "(float)" },
992    { "asinf", (void *)&asinf,
993        "float", "(float)" },
994    { "acosf", (void *)&acosf,
995        "float", "(float)" },
996    { "atanf", (void *)&atanf,
997        "float", "(float)" },
998    { "atan2f", (void *)&atan2f,
999        "float", "(float, float)" },
1000    { "fabsf", (void *)&fabsf,
1001        "float", "(float)" },
1002    { "randf", (void *)&SC_randf,
1003        "float", "(float)" },
1004    { "randf2", (void *)&SC_randf2,
1005        "float", "(float, float)" },
1006    { "floorf", (void *)&floorf,
1007        "float", "(float)" },
1008    { "fracf", (void *)&SC_fracf,
1009        "float", "(float)" },
1010    { "ceilf", (void *)&ceilf,
1011        "float", "(float)" },
1012    { "roundf", (void *)&SC_roundf,
1013        "float", "(float)" },
1014    { "expf", (void *)&expf,
1015        "float", "(float)" },
1016    { "logf", (void *)&logf,
1017        "float", "(float)" },
1018    { "powf", (void *)&powf,
1019        "float", "(float, float)" },
1020    { "maxf", (void *)&SC_maxf,
1021        "float", "(float, float)" },
1022    { "minf", (void *)&SC_minf,
1023        "float", "(float, float)" },
1024    { "sqrt", (void *)&sqrt,
1025        "int", "(int)" },
1026    { "sqrtf", (void *)&sqrtf,
1027        "float", "(float)" },
1028    { "sqr", (void *)&SC_sqr,
1029        "int", "(int)" },
1030    { "sqrf", (void *)&SC_sqrf,
1031        "float", "(float)" },
1032    { "clamp", (void *)&SC_clamp,
1033        "int", "(int, int, int)" },
1034    { "clampf", (void *)&SC_clampf,
1035        "float", "(float, float, float)" },
1036    { "distf2", (void *)&SC_distf2,
1037        "float", "(float, float, float, float)" },
1038    { "distf3", (void *)&SC_distf3,
1039        "float", "(float, float, float, float, float, float)" },
1040    { "magf2", (void *)&SC_magf2,
1041        "float", "(float, float)" },
1042    { "magf3", (void *)&SC_magf3,
1043        "float", "(float, float, float)" },
1044    { "radf", (void *)&SC_radf,
1045        "float", "(float)" },
1046    { "degf", (void *)&SC_degf,
1047        "float", "(float)" },
1048    { "lerpf", (void *)&SC_lerpf,
1049        "float", "(float, float, float)" },
1050    { "normf", (void *)&SC_normf,
1051        "float", "(float, float, float)" },
1052    { "mapf", (void *)&SC_mapf,
1053        "float", "(float, float, float, float, float)" },
1054    { "noisef", (void *)&SC_noisef,
1055        "float", "(float)" },
1056    { "noisef2", (void *)&SC_noisef2,
1057        "float", "(float, float)" },
1058    { "noisef3", (void *)&SC_noisef3,
1059        "float", "(float, float, float)" },
1060    { "turbulencef2", (void *)&SC_turbulencef2,
1061        "float", "(float, float, float)" },
1062    { "turbulencef3", (void *)&SC_turbulencef3,
1063        "float", "(float, float, float, float)" },
1064
1065    // time
1066    { "second", (void *)&SC_second,
1067        "int", "()" },
1068    { "minute", (void *)&SC_minute,
1069        "int", "()" },
1070    { "hour", (void *)&SC_hour,
1071        "int", "()" },
1072    { "day", (void *)&SC_day,
1073        "int", "()" },
1074    { "month", (void *)&SC_month,
1075        "int", "()" },
1076    { "year", (void *)&SC_year,
1077        "int", "()" },
1078    { "uptimeMillis", (void*)&SC_uptimeMillis,
1079        "int", "()" },      // TODO: use long instead
1080    { "startTimeMillis", (void*)&SC_startTimeMillis,
1081        "int", "()" },      // TODO: use long instead
1082    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
1083        "int", "()" },      // TODO: use long instead
1084
1085    // matrix
1086    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
1087        "void", "(float *mat)" },
1088    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
1089        "void", "(float *mat, float *f)" },
1090    { "matrixLoadMat", (void *)&SC_matrixLoadMat,
1091        "void", "(float *mat, float *newmat)" },
1092    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
1093        "void", "(float *mat, float rot, float x, float y, float z)" },
1094    { "matrixLoadScale", (void *)&SC_matrixLoadScale,
1095        "void", "(float *mat, float x, float y, float z)" },
1096    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
1097        "void", "(float *mat, float x, float y, float z)" },
1098    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
1099        "void", "(float *mat, float *lhs, float *rhs)" },
1100    { "matrixMultiply", (void *)&SC_matrixMultiply,
1101        "void", "(float *mat, float *rhs)" },
1102    { "matrixRotate", (void *)&SC_matrixRotate,
1103        "void", "(float *mat, float rot, float x, float y, float z)" },
1104    { "matrixScale", (void *)&SC_matrixScale,
1105        "void", "(float *mat, float x, float y, float z)" },
1106    { "matrixTranslate", (void *)&SC_matrixTranslate,
1107        "void", "(float *mat, float x, float y, float z)" },
1108
1109    // vector
1110    { "vec2Rand", (void *)&SC_vec2Rand,
1111        "void", "(float *vec, float maxLen)" },
1112
1113    // vec3
1114    { "vec3Norm", (void *)&SC_vec3Norm,
1115        "void", "(struct vec3_s *)" },
1116    { "vec3Length", (void *)&SC_vec3Length,
1117        "float", "(struct vec3_s *)" },
1118    { "vec3Add", (void *)&SC_vec3Add,
1119        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1120    { "vec3Sub", (void *)&SC_vec3Sub,
1121        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1122    { "vec3Cross", (void *)&SC_vec3Cross,
1123        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1124    { "vec3Dot", (void *)&SC_vec3Dot,
1125        "float", "(struct vec3_s *lhs, struct vec3_s *rhs)" },
1126    { "vec3Scale", (void *)&SC_vec3Scale,
1127        "void", "(struct vec3_s *lhs, float scale)" },
1128
1129    // context
1130    { "bindProgramFragment", (void *)&SC_bindProgramFragment,
1131        "void", "(int)" },
1132    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
1133        "void", "(int)" },
1134    { "bindProgramVertex", (void *)&SC_bindProgramVertex,
1135        "void", "(int)" },
1136    { "bindSampler", (void *)&SC_bindSampler,
1137        "void", "(int, int, int)" },
1138    { "bindTexture", (void *)&SC_bindTexture,
1139        "void", "(int, int, int)" },
1140
1141    // vp
1142    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
1143        "void", "(void *)" },
1144    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
1145        "void", "(void *)" },
1146
1147
1148
1149    // drawing
1150    { "drawRect", (void *)&SC_drawRect,
1151        "void", "(float x1, float y1, float x2, float y2, float z)" },
1152    { "drawQuad", (void *)&SC_drawQuad,
1153        "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" },
1154    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
1155        "void", "(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4)" },
1156    { "drawLine", (void *)&SC_drawLine,
1157        "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
1158    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
1159        "void", "(int ism)" },
1160    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
1161        "void", "(int ism, int start, int len)" },
1162
1163
1164    // misc
1165    { "pfClearColor", (void *)&SC_ClearColor,
1166        "void", "(float, float, float, float)" },
1167    { "color", (void *)&SC_color,
1168        "void", "(float, float, float, float)" },
1169    { "hsb", (void *)&SC_hsb,
1170        "void", "(float, float, float, float)" },
1171    { "hsbToRgb", (void *)&SC_hsbToRgb,
1172        "void", "(float, float, float, float*)" },
1173    { "hsbToAbgr", (void *)&SC_hsbToAbgr,
1174        "int", "(float, float, float, float)" },
1175    { "ambient", (void *)&SC_ambient,
1176        "void", "(float, float, float, float)" },
1177    { "diffuse", (void *)&SC_diffuse,
1178        "void", "(float, float, float, float)" },
1179    { "specular", (void *)&SC_specular,
1180        "void", "(float, float, float, float)" },
1181    { "emission", (void *)&SC_emission,
1182        "void", "(float, float, float, float)" },
1183    { "shininess", (void *)&SC_shininess,
1184        "void", "(float)" },
1185    { "pointAttenuation", (void *)&SC_pointAttenuation,
1186        "void", "(float, float, float)" },
1187
1188    { "uploadToTexture", (void *)&SC_uploadToTexture,
1189        "void", "(int, int)" },
1190    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
1191        "void", "(int)" },
1192
1193    { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
1194        "int", "(float, float, float, float)" },
1195    { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
1196        "int", "(float, float, float)" },
1197
1198
1199    { "getWidth", (void *)&SC_getWidth,
1200        "int", "()" },
1201    { "getHeight", (void *)&SC_getHeight,
1202        "int", "()" },
1203
1204
1205
1206    { "debugF", (void *)&SC_debugF,
1207        "void", "(void *, float)" },
1208    { "debugI32", (void *)&SC_debugI32,
1209        "void", "(void *, int)" },
1210    { "debugHexF", (void *)&SC_debugHexF,
1211        "void", "(void *, float)" },
1212    { "debugHexI32", (void *)&SC_debugHexI32,
1213        "void", "(void *, int)" },
1214
1215
1216    { NULL, NULL, NULL, NULL }
1217};
1218
1219const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
1220{
1221    ScriptCState::SymbolTable_t *syms = gSyms;
1222
1223    while (syms->mPtr) {
1224        if (!strcmp(syms->mName, sym)) {
1225            return syms;
1226        }
1227        syms++;
1228    }
1229    return NULL;
1230}
1231
1232void ScriptCState::appendDecls(String8 *str)
1233{
1234    ScriptCState::SymbolTable_t *syms = gSyms;
1235    while (syms->mPtr) {
1236        str->append(syms->mRet);
1237        str->append(" ");
1238        str->append(syms->mName);
1239        str->append(syms->mParam);
1240        str->append(";\n");
1241        syms++;
1242    }
1243}
1244
1245
1246