rsScriptC_Lib.cpp revision c5174c72f2a122d939da051eaf571b0ff95f1f8a
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_drawPoint(float x, float y, float z)
676{
677    GET_TLS();
678    rsc->setupCheck();
679
680    float vtx[] = { x, y, z };
681
682    glBindBuffer(GL_ARRAY_BUFFER, 0);
683    glEnableClientState(GL_VERTEX_ARRAY);
684    glVertexPointer(3, GL_FLOAT, 0, vtx);
685
686    glDisableClientState(GL_NORMAL_ARRAY);
687    glDisableClientState(GL_COLOR_ARRAY);
688
689    glDrawArrays(GL_POINTS, 0, 1);
690}
691
692static void SC_drawQuadTexCoords(float x1, float y1, float z1,
693                                 float u1, float v1,
694                                 float x2, float y2, float z2,
695                                 float u2, float v2,
696                                 float x3, float y3, float z3,
697                                 float u3, float v3,
698                                 float x4, float y4, float z4,
699                                 float u4, float v4)
700{
701    GET_TLS();
702
703    //LOGE("Quad");
704    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
705    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
706    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
707    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
708
709    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
710    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
711
712    rsc->setupCheck();
713
714    glBindBuffer(GL_ARRAY_BUFFER, 0);
715    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
716
717    glEnableClientState(GL_VERTEX_ARRAY);
718    glVertexPointer(3, GL_FLOAT, 0, vtx);
719
720    glClientActiveTexture(GL_TEXTURE0);
721    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
722    glTexCoordPointer(2, GL_FLOAT, 0, tex);
723    glClientActiveTexture(GL_TEXTURE1);
724    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
725    glTexCoordPointer(2, GL_FLOAT, 0, tex);
726    glClientActiveTexture(GL_TEXTURE0);
727
728    glDisableClientState(GL_NORMAL_ARRAY);
729    glDisableClientState(GL_COLOR_ARRAY);
730
731    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
732
733    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
734}
735
736static void SC_drawQuad(float x1, float y1, float z1,
737                        float x2, float y2, float z2,
738                        float x3, float y3, float z3,
739                        float x4, float y4, float z4)
740{
741    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
742                         x2, y2, z2, 1, 1,
743                         x3, y3, z3, 1, 0,
744                         x4, y4, z4, 0, 0);
745}
746
747static void SC_drawRect(float x1, float y1,
748                        float x2, float y2, float z)
749{
750    SC_drawQuad(x1, y2, z,
751                x2, y2, z,
752                x2, y1, z,
753                x1, y1, z);
754}
755
756static void SC_drawSimpleMesh(RsSimpleMesh vsm)
757{
758    GET_TLS();
759    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
760    rsc->setupCheck();
761    sm->render();
762}
763
764static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
765{
766    GET_TLS();
767    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
768    rsc->setupCheck();
769    sm->renderRange(start, len);
770}
771
772
773//////////////////////////////////////////////////////////////////////////////
774//
775//////////////////////////////////////////////////////////////////////////////
776
777static void SC_color(float r, float g, float b, float a)
778{
779    glColor4f(r, g, b, a);
780}
781
782static void SC_ambient(float r, float g, float b, float a)
783{
784    GLfloat params[] = { r, g, b, a };
785    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
786}
787
788static void SC_diffuse(float r, float g, float b, float a)
789{
790    GLfloat params[] = { r, g, b, a };
791    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
792}
793
794static void SC_specular(float r, float g, float b, float a)
795{
796    GLfloat params[] = { r, g, b, a };
797    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
798}
799
800static void SC_emission(float r, float g, float b, float a)
801{
802    GLfloat params[] = { r, g, b, a };
803    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
804}
805
806static void SC_shininess(float s)
807{
808    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
809}
810
811static void SC_pointAttenuation(float a, float b, float c)
812{
813    GLfloat params[] = { a, b, c };
814    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
815}
816
817static void SC_hsbToRgb(float h, float s, float b, float* rgb)
818{
819    float red = 0.0f;
820    float green = 0.0f;
821    float blue = 0.0f;
822
823    float x = h;
824    float y = s;
825    float z = b;
826
827    float hf = (x - (int) x) * 6.0f;
828    int ihf = (int) hf;
829    float f = hf - ihf;
830    float pv = z * (1.0f - y);
831    float qv = z * (1.0f - y * f);
832    float tv = z * (1.0f - y * (1.0f - f));
833
834    switch (ihf) {
835        case 0:         // Red is the dominant color
836            red = z;
837            green = tv;
838            blue = pv;
839            break;
840        case 1:         // Green is the dominant color
841            red = qv;
842            green = z;
843            blue = pv;
844            break;
845        case 2:
846            red = pv;
847            green = z;
848            blue = tv;
849            break;
850        case 3:         // Blue is the dominant color
851            red = pv;
852            green = qv;
853            blue = z;
854            break;
855        case 4:
856            red = tv;
857            green = pv;
858            blue = z;
859            break;
860        case 5:         // Red is the dominant color
861            red = z;
862            green = pv;
863            blue = qv;
864            break;
865    }
866
867    rgb[0] = red;
868    rgb[1] = green;
869    rgb[2] = blue;
870}
871
872static int SC_hsbToAbgr(float h, float s, float b, float a)
873{
874    float rgb[3];
875    SC_hsbToRgb(h, s, b, rgb);
876    return int(a      * 255.0f) << 24 |
877           int(rgb[2] * 255.0f) << 16 |
878           int(rgb[1] * 255.0f) <<  8 |
879           int(rgb[0] * 255.0f);
880}
881
882static void SC_hsb(float h, float s, float b, float a)
883{
884    float rgb[3];
885    SC_hsbToRgb(h, s, b, rgb);
886    glColor4f(rgb[0], rgb[1], rgb[2], a);
887}
888
889static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
890{
891    GET_TLS();
892    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
893}
894
895static void SC_uploadToBufferObject(RsAllocation va)
896{
897    GET_TLS();
898    rsi_AllocationUploadToBufferObject(rsc, va);
899}
900
901static void SC_ClearColor(float r, float g, float b, float a)
902{
903    //LOGE("c %f %f %f %f", r, g, b, a);
904    GET_TLS();
905    sc->mEnviroment.mClearColor[0] = r;
906    sc->mEnviroment.mClearColor[1] = g;
907    sc->mEnviroment.mClearColor[2] = b;
908    sc->mEnviroment.mClearColor[3] = a;
909}
910
911static void SC_debugF(const char *s, float f)
912{
913    LOGE("%s %f", s, f);
914}
915
916static void SC_debugHexF(const char *s, float f)
917{
918    LOGE("%s 0x%x", s, *((int *) (&f)));
919}
920
921static void SC_debugI32(const char *s, int32_t i)
922{
923    LOGE("%s %i", s, i);
924}
925
926static void SC_debugHexI32(const char *s, int32_t i)
927{
928    LOGE("%s 0x%x", s, i);
929}
930
931static uint32_t SC_getWidth()
932{
933    GET_TLS();
934    return rsc->getWidth();
935}
936
937static uint32_t SC_getHeight()
938{
939    GET_TLS();
940    return rsc->getHeight();
941}
942
943static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
944{
945    uint32_t c = 0;
946    c |= (uint32_t)(r * 255.f + 0.5f);
947    c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
948    c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
949    c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
950    return c;
951}
952
953static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
954{
955    uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
956    uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
957    uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
958    return rs888to565(ir, ig, ib);
959}
960
961//////////////////////////////////////////////////////////////////////////////
962// Class implementation
963//////////////////////////////////////////////////////////////////////////////
964
965ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
966    // IO
967    { "loadI32", (void *)&SC_loadI32,
968        "int", "(int, int)" },
969    //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
970    { "loadF", (void *)&SC_loadF,
971        "float", "(int, int)" },
972    { "loadArrayF", (void *)&SC_loadArrayF,
973        "float*", "(int, int)" },
974    { "loadArrayI32", (void *)&SC_loadArrayI32,
975        "int*", "(int, int)" },
976    { "loadVec4", (void *)&SC_loadVec4,
977        "void", "(int, int, float *)" },
978    { "loadMatrix", (void *)&SC_loadMatrix,
979        "void", "(int, int, float *)" },
980    { "storeI32", (void *)&SC_storeI32,
981        "void", "(int, int, int)" },
982    //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
983    { "storeF", (void *)&SC_storeF,
984        "void", "(int, int, float)" },
985    { "storeVec4", (void *)&SC_storeVec4,
986        "void", "(int, int, float *)" },
987    { "storeMatrix", (void *)&SC_storeMatrix,
988        "void", "(int, int, float *)" },
989    { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
990        "float*", "(int, int)" },
991    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
992        "void", "(int)" },
993
994    // math
995    { "modf", (void *)&fmod,
996        "float", "(float, float)" },
997    { "abs", (void *)&abs,
998        "int", "(int)" },
999    { "absf", (void *)&fabsf,
1000        "float", "(float)" },
1001    { "sinf_fast", (void *)&SC_sinf_fast,
1002        "float", "(float)" },
1003    { "cosf_fast", (void *)&SC_cosf_fast,
1004        "float", "(float)" },
1005    { "sinf", (void *)&sinf,
1006        "float", "(float)" },
1007    { "cosf", (void *)&cosf,
1008        "float", "(float)" },
1009    { "asinf", (void *)&asinf,
1010        "float", "(float)" },
1011    { "acosf", (void *)&acosf,
1012        "float", "(float)" },
1013    { "atanf", (void *)&atanf,
1014        "float", "(float)" },
1015    { "atan2f", (void *)&atan2f,
1016        "float", "(float, float)" },
1017    { "fabsf", (void *)&fabsf,
1018        "float", "(float)" },
1019    { "randf", (void *)&SC_randf,
1020        "float", "(float)" },
1021    { "randf2", (void *)&SC_randf2,
1022        "float", "(float, float)" },
1023    { "floorf", (void *)&floorf,
1024        "float", "(float)" },
1025    { "fracf", (void *)&SC_fracf,
1026        "float", "(float)" },
1027    { "ceilf", (void *)&ceilf,
1028        "float", "(float)" },
1029    { "roundf", (void *)&SC_roundf,
1030        "float", "(float)" },
1031    { "expf", (void *)&expf,
1032        "float", "(float)" },
1033    { "logf", (void *)&logf,
1034        "float", "(float)" },
1035    { "powf", (void *)&powf,
1036        "float", "(float, float)" },
1037    { "maxf", (void *)&SC_maxf,
1038        "float", "(float, float)" },
1039    { "minf", (void *)&SC_minf,
1040        "float", "(float, float)" },
1041    { "sqrt", (void *)&sqrt,
1042        "int", "(int)" },
1043    { "sqrtf", (void *)&sqrtf,
1044        "float", "(float)" },
1045    { "sqr", (void *)&SC_sqr,
1046        "int", "(int)" },
1047    { "sqrf", (void *)&SC_sqrf,
1048        "float", "(float)" },
1049    { "clamp", (void *)&SC_clamp,
1050        "int", "(int, int, int)" },
1051    { "clampf", (void *)&SC_clampf,
1052        "float", "(float, float, float)" },
1053    { "distf2", (void *)&SC_distf2,
1054        "float", "(float, float, float, float)" },
1055    { "distf3", (void *)&SC_distf3,
1056        "float", "(float, float, float, float, float, float)" },
1057    { "magf2", (void *)&SC_magf2,
1058        "float", "(float, float)" },
1059    { "magf3", (void *)&SC_magf3,
1060        "float", "(float, float, float)" },
1061    { "radf", (void *)&SC_radf,
1062        "float", "(float)" },
1063    { "degf", (void *)&SC_degf,
1064        "float", "(float)" },
1065    { "lerpf", (void *)&SC_lerpf,
1066        "float", "(float, float, float)" },
1067    { "normf", (void *)&SC_normf,
1068        "float", "(float, float, float)" },
1069    { "mapf", (void *)&SC_mapf,
1070        "float", "(float, float, float, float, float)" },
1071    { "noisef", (void *)&SC_noisef,
1072        "float", "(float)" },
1073    { "noisef2", (void *)&SC_noisef2,
1074        "float", "(float, float)" },
1075    { "noisef3", (void *)&SC_noisef3,
1076        "float", "(float, float, float)" },
1077    { "turbulencef2", (void *)&SC_turbulencef2,
1078        "float", "(float, float, float)" },
1079    { "turbulencef3", (void *)&SC_turbulencef3,
1080        "float", "(float, float, float, float)" },
1081
1082    // time
1083    { "second", (void *)&SC_second,
1084        "int", "()" },
1085    { "minute", (void *)&SC_minute,
1086        "int", "()" },
1087    { "hour", (void *)&SC_hour,
1088        "int", "()" },
1089    { "day", (void *)&SC_day,
1090        "int", "()" },
1091    { "month", (void *)&SC_month,
1092        "int", "()" },
1093    { "year", (void *)&SC_year,
1094        "int", "()" },
1095    { "uptimeMillis", (void*)&SC_uptimeMillis,
1096        "int", "()" },      // TODO: use long instead
1097    { "startTimeMillis", (void*)&SC_startTimeMillis,
1098        "int", "()" },      // TODO: use long instead
1099    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
1100        "int", "()" },      // TODO: use long instead
1101
1102    // matrix
1103    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
1104        "void", "(float *mat)" },
1105    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
1106        "void", "(float *mat, float *f)" },
1107    { "matrixLoadMat", (void *)&SC_matrixLoadMat,
1108        "void", "(float *mat, float *newmat)" },
1109    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
1110        "void", "(float *mat, float rot, float x, float y, float z)" },
1111    { "matrixLoadScale", (void *)&SC_matrixLoadScale,
1112        "void", "(float *mat, float x, float y, float z)" },
1113    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
1114        "void", "(float *mat, float x, float y, float z)" },
1115    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
1116        "void", "(float *mat, float *lhs, float *rhs)" },
1117    { "matrixMultiply", (void *)&SC_matrixMultiply,
1118        "void", "(float *mat, float *rhs)" },
1119    { "matrixRotate", (void *)&SC_matrixRotate,
1120        "void", "(float *mat, float rot, float x, float y, float z)" },
1121    { "matrixScale", (void *)&SC_matrixScale,
1122        "void", "(float *mat, float x, float y, float z)" },
1123    { "matrixTranslate", (void *)&SC_matrixTranslate,
1124        "void", "(float *mat, float x, float y, float z)" },
1125
1126    // vector
1127    { "vec2Rand", (void *)&SC_vec2Rand,
1128        "void", "(float *vec, float maxLen)" },
1129
1130    // vec3
1131    { "vec3Norm", (void *)&SC_vec3Norm,
1132        "void", "(struct vec3_s *)" },
1133    { "vec3Length", (void *)&SC_vec3Length,
1134        "float", "(struct vec3_s *)" },
1135    { "vec3Add", (void *)&SC_vec3Add,
1136        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1137    { "vec3Sub", (void *)&SC_vec3Sub,
1138        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1139    { "vec3Cross", (void *)&SC_vec3Cross,
1140        "void", "(struct vec3_s *dest, struct vec3_s *lhs, struct vec3_s *rhs)" },
1141    { "vec3Dot", (void *)&SC_vec3Dot,
1142        "float", "(struct vec3_s *lhs, struct vec3_s *rhs)" },
1143    { "vec3Scale", (void *)&SC_vec3Scale,
1144        "void", "(struct vec3_s *lhs, float scale)" },
1145
1146    // context
1147    { "bindProgramFragment", (void *)&SC_bindProgramFragment,
1148        "void", "(int)" },
1149    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
1150        "void", "(int)" },
1151    { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
1152        "void", "(int)" },
1153    { "bindProgramVertex", (void *)&SC_bindProgramVertex,
1154        "void", "(int)" },
1155    { "bindSampler", (void *)&SC_bindSampler,
1156        "void", "(int, int, int)" },
1157    { "bindTexture", (void *)&SC_bindTexture,
1158        "void", "(int, int, int)" },
1159
1160    // vp
1161    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
1162        "void", "(void *)" },
1163    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
1164        "void", "(void *)" },
1165
1166
1167
1168    // drawing
1169    { "drawRect", (void *)&SC_drawRect,
1170        "void", "(float x1, float y1, float x2, float y2, float z)" },
1171    { "drawQuad", (void *)&SC_drawQuad,
1172        "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)" },
1173    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
1174        "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)" },
1175    { "drawLine", (void *)&SC_drawLine,
1176        "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
1177    { "drawPoint", (void *)&SC_drawPoint,
1178        "void", "(float x1, float y1, float z1)" },
1179    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
1180        "void", "(int ism)" },
1181    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
1182        "void", "(int ism, int start, int len)" },
1183
1184
1185    // misc
1186    { "pfClearColor", (void *)&SC_ClearColor,
1187        "void", "(float, float, float, float)" },
1188    { "color", (void *)&SC_color,
1189        "void", "(float, float, float, float)" },
1190    { "hsb", (void *)&SC_hsb,
1191        "void", "(float, float, float, float)" },
1192    { "hsbToRgb", (void *)&SC_hsbToRgb,
1193        "void", "(float, float, float, float*)" },
1194    { "hsbToAbgr", (void *)&SC_hsbToAbgr,
1195        "int", "(float, float, float, float)" },
1196    { "ambient", (void *)&SC_ambient,
1197        "void", "(float, float, float, float)" },
1198    { "diffuse", (void *)&SC_diffuse,
1199        "void", "(float, float, float, float)" },
1200    { "specular", (void *)&SC_specular,
1201        "void", "(float, float, float, float)" },
1202    { "emission", (void *)&SC_emission,
1203        "void", "(float, float, float, float)" },
1204    { "shininess", (void *)&SC_shininess,
1205        "void", "(float)" },
1206    { "pointAttenuation", (void *)&SC_pointAttenuation,
1207        "void", "(float, float, float)" },
1208
1209    { "uploadToTexture", (void *)&SC_uploadToTexture,
1210        "void", "(int, int)" },
1211    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
1212        "void", "(int)" },
1213
1214    { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
1215        "int", "(float, float, float, float)" },
1216    { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
1217        "int", "(float, float, float)" },
1218
1219
1220    { "getWidth", (void *)&SC_getWidth,
1221        "int", "()" },
1222    { "getHeight", (void *)&SC_getHeight,
1223        "int", "()" },
1224
1225
1226
1227    { "debugF", (void *)&SC_debugF,
1228        "void", "(void *, float)" },
1229    { "debugI32", (void *)&SC_debugI32,
1230        "void", "(void *, int)" },
1231    { "debugHexF", (void *)&SC_debugHexF,
1232        "void", "(void *, float)" },
1233    { "debugHexI32", (void *)&SC_debugHexI32,
1234        "void", "(void *, int)" },
1235
1236
1237    { NULL, NULL, NULL, NULL }
1238};
1239
1240const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
1241{
1242    ScriptCState::SymbolTable_t *syms = gSyms;
1243
1244    while (syms->mPtr) {
1245        if (!strcmp(syms->mName, sym)) {
1246            return syms;
1247        }
1248        syms++;
1249    }
1250    return NULL;
1251}
1252
1253void ScriptCState::appendDecls(String8 *str)
1254{
1255    ScriptCState::SymbolTable_t *syms = gSyms;
1256    while (syms->mPtr) {
1257        str->append(syms->mRet);
1258        str->append(" ");
1259        str->append(syms->mName);
1260        str->append(syms->mParam);
1261        str->append(";\n");
1262        syms++;
1263    }
1264}
1265
1266
1267