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