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