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