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