rsScriptC_Lib.cpp revision d01d970cf5973aa5186cc02c80fb2c143a69b0b1
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, 0);
742    //va.setTexture(2, GL_FLOAT, 8, (uint32_t)&tex, 1);
743    //
744    if (rsc->checkVersion2_0()) {
745        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
746    } else {
747        va.setupGL(rsc, &rsc->mStateVertexArray);
748    }
749
750
751    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
752}
753
754static void SC_drawQuad(float x1, float y1, float z1,
755                        float x2, float y2, float z2,
756                        float x3, float y3, float z3,
757                        float x4, float y4, float z4)
758{
759    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
760                         x2, y2, z2, 1, 1,
761                         x3, y3, z3, 1, 0,
762                         x4, y4, z4, 0, 0);
763}
764
765static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
766{
767    GET_TLS();
768    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
769    rsc->setVertex(rsc->getDefaultProgramVertex());
770    //rsc->setupCheck();
771
772    //GLint crop[4] = {0, h, w, -h};
773
774    float sh = rsc->getHeight();
775
776    SC_drawQuad(x,   sh - y,     z,
777                x+w, sh - y,     z,
778                x+w, sh - (y+h), z,
779                x,   sh - (y+h), z);
780    rsc->setVertex((ProgramVertex *)tmp.get());
781}
782
783static void SC_drawSprite(float x, float y, float z, float w, float h)
784{
785    GET_TLS();
786    float vin[3] = {x, y, z};
787    float vout[4];
788
789    //LOGE("ds  in %f %f %f", x, y, z);
790    rsc->getVertex()->transformToScreen(rsc, vout, vin);
791    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
792    vout[0] /= vout[3];
793    vout[1] /= vout[3];
794    vout[2] /= vout[3];
795
796    vout[0] *= rsc->getWidth() / 2;
797    vout[1] *= rsc->getHeight() / 2;
798    vout[0] += rsc->getWidth() / 2;
799    vout[1] += rsc->getHeight() / 2;
800
801    vout[0] -= w/2;
802    vout[1] -= h/2;
803
804    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
805
806    // U, V, W, H
807    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
808    //rsc->setupCheck();
809}
810
811
812static void SC_drawRect(float x1, float y1,
813                        float x2, float y2, float z)
814{
815    SC_drawQuad(x1, y2, z,
816                x2, y2, z,
817                x2, y1, z,
818                x1, y1, z);
819}
820
821static void SC_drawSimpleMesh(RsSimpleMesh vsm)
822{
823    GET_TLS();
824    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
825    rsc->setupCheck();
826    sm->render(rsc);
827}
828
829static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
830{
831    GET_TLS();
832    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
833    rsc->setupCheck();
834    sm->renderRange(rsc, start, len);
835}
836
837
838//////////////////////////////////////////////////////////////////////////////
839//
840//////////////////////////////////////////////////////////////////////////////
841
842static void SC_color(float r, float g, float b, float a)
843{
844    GET_TLS();
845    rsc->mStateVertex.color[0] = r;
846    rsc->mStateVertex.color[1] = g;
847    rsc->mStateVertex.color[2] = b;
848    rsc->mStateVertex.color[3] = a;
849    if (!rsc->checkVersion2_0()) {
850        glColor4f(r, g, b, a);
851    }
852}
853
854static void SC_ambient(float r, float g, float b, float a)
855{
856    GLfloat params[] = { r, g, b, a };
857    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
858}
859
860static void SC_diffuse(float r, float g, float b, float a)
861{
862    GLfloat params[] = { r, g, b, a };
863    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
864}
865
866static void SC_specular(float r, float g, float b, float a)
867{
868    GLfloat params[] = { r, g, b, a };
869    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
870}
871
872static void SC_emission(float r, float g, float b, float a)
873{
874    GLfloat params[] = { r, g, b, a };
875    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
876}
877
878static void SC_shininess(float s)
879{
880    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
881}
882
883static void SC_pointAttenuation(float a, float b, float c)
884{
885    GLfloat params[] = { a, b, c };
886    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
887}
888
889static void SC_hsbToRgb(float h, float s, float b, float* rgb)
890{
891    float red = 0.0f;
892    float green = 0.0f;
893    float blue = 0.0f;
894
895    float x = h;
896    float y = s;
897    float z = b;
898
899    float hf = (x - (int) x) * 6.0f;
900    int ihf = (int) hf;
901    float f = hf - ihf;
902    float pv = z * (1.0f - y);
903    float qv = z * (1.0f - y * f);
904    float tv = z * (1.0f - y * (1.0f - f));
905
906    switch (ihf) {
907        case 0:         // Red is the dominant color
908            red = z;
909            green = tv;
910            blue = pv;
911            break;
912        case 1:         // Green is the dominant color
913            red = qv;
914            green = z;
915            blue = pv;
916            break;
917        case 2:
918            red = pv;
919            green = z;
920            blue = tv;
921            break;
922        case 3:         // Blue is the dominant color
923            red = pv;
924            green = qv;
925            blue = z;
926            break;
927        case 4:
928            red = tv;
929            green = pv;
930            blue = z;
931            break;
932        case 5:         // Red is the dominant color
933            red = z;
934            green = pv;
935            blue = qv;
936            break;
937    }
938
939    rgb[0] = red;
940    rgb[1] = green;
941    rgb[2] = blue;
942}
943
944static int SC_hsbToAbgr(float h, float s, float b, float a)
945{
946    float rgb[3];
947    SC_hsbToRgb(h, s, b, rgb);
948    return int(a      * 255.0f) << 24 |
949           int(rgb[2] * 255.0f) << 16 |
950           int(rgb[1] * 255.0f) <<  8 |
951           int(rgb[0] * 255.0f);
952}
953
954static void SC_hsb(float h, float s, float b, float a)
955{
956    GET_TLS();
957    float rgb[3];
958    SC_hsbToRgb(h, s, b, rgb);
959    if (rsc->checkVersion2_0()) {
960        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
961    } else {
962        glColor4f(rgb[0], rgb[1], rgb[2], a);
963    }
964}
965
966static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
967{
968    GET_TLS();
969    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
970}
971
972static void SC_uploadToBufferObject(RsAllocation va)
973{
974    GET_TLS();
975    rsi_AllocationUploadToBufferObject(rsc, va);
976}
977
978static void SC_ClearColor(float r, float g, float b, float a)
979{
980    //LOGE("c %f %f %f %f", r, g, b, a);
981    GET_TLS();
982    sc->mEnviroment.mClearColor[0] = r;
983    sc->mEnviroment.mClearColor[1] = g;
984    sc->mEnviroment.mClearColor[2] = b;
985    sc->mEnviroment.mClearColor[3] = a;
986}
987
988static void SC_debugF(const char *s, float f)
989{
990    LOGE("%s %f", s, f);
991}
992
993static void SC_debugHexF(const char *s, float f)
994{
995    LOGE("%s 0x%x", s, *((int *) (&f)));
996}
997
998static void SC_debugI32(const char *s, int32_t i)
999{
1000    LOGE("%s %i", s, i);
1001}
1002
1003static void SC_debugHexI32(const char *s, int32_t i)
1004{
1005    LOGE("%s 0x%x", s, i);
1006}
1007
1008static uint32_t SC_getWidth()
1009{
1010    GET_TLS();
1011    return rsc->getWidth();
1012}
1013
1014static uint32_t SC_getHeight()
1015{
1016    GET_TLS();
1017    return rsc->getHeight();
1018}
1019
1020static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
1021{
1022    uint32_t c = 0;
1023    c |= (uint32_t)(r * 255.f + 0.5f);
1024    c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
1025    c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
1026    c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
1027    return c;
1028}
1029
1030static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
1031{
1032    uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
1033    uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
1034    uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
1035    return rs888to565(ir, ig, ib);
1036}
1037
1038static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
1039{
1040    GET_TLS();
1041    return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
1042}
1043
1044static void SC_scriptCall(int scriptID)
1045{
1046    GET_TLS();
1047    rsc->runScript((Script *)scriptID, 0);
1048}
1049
1050
1051//////////////////////////////////////////////////////////////////////////////
1052// Class implementation
1053//////////////////////////////////////////////////////////////////////////////
1054
1055ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
1056    // IO
1057    { "loadI32", (void *)&SC_loadI32,
1058        "int", "(int, int)" },
1059    //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
1060    { "loadF", (void *)&SC_loadF,
1061        "float", "(int, int)" },
1062    { "loadArrayF", (void *)&SC_loadArrayF,
1063        "float*", "(int, int)" },
1064    { "loadArrayI32", (void *)&SC_loadArrayI32,
1065        "int*", "(int, int)" },
1066    { "loadVec4", (void *)&SC_loadVec4,
1067        "void", "(int, int, float *)" },
1068    { "loadMatrix", (void *)&SC_loadMatrix,
1069        "void", "(int, int, float *)" },
1070    { "storeI32", (void *)&SC_storeI32,
1071        "void", "(int, int, int)" },
1072    //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
1073    { "storeF", (void *)&SC_storeF,
1074        "void", "(int, int, float)" },
1075    { "storeVec4", (void *)&SC_storeVec4,
1076        "void", "(int, int, float *)" },
1077    { "storeMatrix", (void *)&SC_storeMatrix,
1078        "void", "(int, int, float *)" },
1079    { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
1080        "float*", "(int, int)" },
1081    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
1082        "void", "(int)" },
1083
1084    // math
1085    { "modf", (void *)&fmod,
1086        "float", "(float, float)" },
1087    { "abs", (void *)&abs,
1088        "int", "(int)" },
1089    { "absf", (void *)&fabsf,
1090        "float", "(float)" },
1091    { "sinf_fast", (void *)&SC_sinf_fast,
1092        "float", "(float)" },
1093    { "cosf_fast", (void *)&SC_cosf_fast,
1094        "float", "(float)" },
1095    { "sinf", (void *)&sinf,
1096        "float", "(float)" },
1097    { "cosf", (void *)&cosf,
1098        "float", "(float)" },
1099    { "asinf", (void *)&asinf,
1100        "float", "(float)" },
1101    { "acosf", (void *)&acosf,
1102        "float", "(float)" },
1103    { "atanf", (void *)&atanf,
1104        "float", "(float)" },
1105    { "atan2f", (void *)&atan2f,
1106        "float", "(float, float)" },
1107    { "fabsf", (void *)&fabsf,
1108        "float", "(float)" },
1109    { "randf", (void *)&SC_randf,
1110        "float", "(float)" },
1111    { "randf2", (void *)&SC_randf2,
1112        "float", "(float, float)" },
1113    { "floorf", (void *)&floorf,
1114        "float", "(float)" },
1115    { "fracf", (void *)&SC_fracf,
1116        "float", "(float)" },
1117    { "ceilf", (void *)&ceilf,
1118        "float", "(float)" },
1119    { "roundf", (void *)&SC_roundf,
1120        "float", "(float)" },
1121    { "expf", (void *)&expf,
1122        "float", "(float)" },
1123    { "logf", (void *)&logf,
1124        "float", "(float)" },
1125    { "powf", (void *)&powf,
1126        "float", "(float, float)" },
1127    { "maxf", (void *)&SC_maxf,
1128        "float", "(float, float)" },
1129    { "minf", (void *)&SC_minf,
1130        "float", "(float, float)" },
1131    { "sqrt", (void *)&sqrt,
1132        "int", "(int)" },
1133    { "sqrtf", (void *)&sqrtf,
1134        "float", "(float)" },
1135    { "sqr", (void *)&SC_sqr,
1136        "int", "(int)" },
1137    { "sqrf", (void *)&SC_sqrf,
1138        "float", "(float)" },
1139    { "sign", (void *)&SC_sign,
1140        "int", "(int)" },
1141    { "signf", (void *)&SC_signf,
1142        "float", "(float)" },
1143    { "clamp", (void *)&SC_clamp,
1144        "int", "(int, int, int)" },
1145    { "clampf", (void *)&SC_clampf,
1146        "float", "(float, float, float)" },
1147    { "distf2", (void *)&SC_distf2,
1148        "float", "(float, float, float, float)" },
1149    { "distf3", (void *)&SC_distf3,
1150        "float", "(float, float, float, float, float, float)" },
1151    { "magf2", (void *)&SC_magf2,
1152        "float", "(float, float)" },
1153    { "magf3", (void *)&SC_magf3,
1154        "float", "(float, float, float)" },
1155    { "radf", (void *)&SC_radf,
1156        "float", "(float)" },
1157    { "degf", (void *)&SC_degf,
1158        "float", "(float)" },
1159    { "lerpf", (void *)&SC_lerpf,
1160        "float", "(float, float, float)" },
1161    { "normf", (void *)&SC_normf,
1162        "float", "(float, float, float)" },
1163    { "mapf", (void *)&SC_mapf,
1164        "float", "(float, float, float, float, float)" },
1165    { "noisef", (void *)&SC_noisef,
1166        "float", "(float)" },
1167    { "noisef2", (void *)&SC_noisef2,
1168        "float", "(float, float)" },
1169    { "noisef3", (void *)&SC_noisef3,
1170        "float", "(float, float, float)" },
1171    { "turbulencef2", (void *)&SC_turbulencef2,
1172        "float", "(float, float, float)" },
1173    { "turbulencef3", (void *)&SC_turbulencef3,
1174        "float", "(float, float, float, float)" },
1175
1176    // time
1177    { "second", (void *)&SC_second,
1178        "int", "()" },
1179    { "minute", (void *)&SC_minute,
1180        "int", "()" },
1181    { "hour", (void *)&SC_hour,
1182        "int", "()" },
1183    { "day", (void *)&SC_day,
1184        "int", "()" },
1185    { "month", (void *)&SC_month,
1186        "int", "()" },
1187    { "year", (void *)&SC_year,
1188        "int", "()" },
1189    { "uptimeMillis", (void*)&SC_uptimeMillis,
1190        "int", "()" },      // TODO: use long instead
1191    { "startTimeMillis", (void*)&SC_startTimeMillis,
1192        "int", "()" },      // TODO: use long instead
1193    { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
1194        "int", "()" },      // TODO: use long instead
1195
1196    // matrix
1197    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
1198        "void", "(float *mat)" },
1199    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
1200        "void", "(float *mat, float *f)" },
1201    { "matrixLoadMat", (void *)&SC_matrixLoadMat,
1202        "void", "(float *mat, float *newmat)" },
1203    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
1204        "void", "(float *mat, float rot, float x, float y, float z)" },
1205    { "matrixLoadScale", (void *)&SC_matrixLoadScale,
1206        "void", "(float *mat, float x, float y, float z)" },
1207    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
1208        "void", "(float *mat, float x, float y, float z)" },
1209    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
1210        "void", "(float *mat, float *lhs, float *rhs)" },
1211    { "matrixMultiply", (void *)&SC_matrixMultiply,
1212        "void", "(float *mat, float *rhs)" },
1213    { "matrixRotate", (void *)&SC_matrixRotate,
1214        "void", "(float *mat, float rot, float x, float y, float z)" },
1215    { "matrixScale", (void *)&SC_matrixScale,
1216        "void", "(float *mat, float x, float y, float z)" },
1217    { "matrixTranslate", (void *)&SC_matrixTranslate,
1218        "void", "(float *mat, float x, float y, float z)" },
1219
1220    // vector
1221    { "vec2Rand", (void *)&SC_vec2Rand,
1222        "void", "(float *vec, float maxLen)" },
1223
1224    // vec3
1225    { "vec3Norm", (void *)&SC_vec3Norm,
1226        "void", "(struct vecF32_3_s *)" },
1227    { "vec3Length", (void *)&SC_vec3Length,
1228        "float", "(struct vecF32_3_s *)" },
1229    { "vec3Add", (void *)&SC_vec3Add,
1230        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1231    { "vec3Sub", (void *)&SC_vec3Sub,
1232        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1233    { "vec3Cross", (void *)&SC_vec3Cross,
1234        "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1235    { "vec3Dot", (void *)&SC_vec3Dot,
1236        "float", "(struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
1237    { "vec3Scale", (void *)&SC_vec3Scale,
1238        "void", "(struct vecF32_3_s *lhs, float scale)" },
1239
1240    // vec4
1241    { "vec4Norm", (void *)&SC_vec4Norm,
1242        "void", "(struct vecF32_4_s *)" },
1243    { "vec4Length", (void *)&SC_vec4Length,
1244        "float", "(struct vecF32_4_s *)" },
1245    { "vec4Add", (void *)&SC_vec4Add,
1246        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1247    { "vec4Sub", (void *)&SC_vec4Sub,
1248        "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1249    { "vec4Dot", (void *)&SC_vec4Dot,
1250        "float", "(struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
1251    { "vec4Scale", (void *)&SC_vec4Scale,
1252        "void", "(struct vecF32_4_s *lhs, float scale)" },
1253
1254    // context
1255    { "bindProgramFragment", (void *)&SC_bindProgramFragment,
1256        "void", "(int)" },
1257    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
1258        "void", "(int)" },
1259    { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
1260        "void", "(int)" },
1261    { "bindProgramVertex", (void *)&SC_bindProgramVertex,
1262        "void", "(int)" },
1263    { "bindSampler", (void *)&SC_bindSampler,
1264        "void", "(int, int, int)" },
1265    { "bindTexture", (void *)&SC_bindTexture,
1266        "void", "(int, int, int)" },
1267
1268    // vp
1269    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
1270        "void", "(void *)" },
1271    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
1272        "void", "(void *)" },
1273
1274
1275
1276    // drawing
1277    { "drawRect", (void *)&SC_drawRect,
1278        "void", "(float x1, float y1, float x2, float y2, float z)" },
1279    { "drawQuad", (void *)&SC_drawQuad,
1280        "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)" },
1281    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
1282        "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)" },
1283    { "drawSprite", (void *)&SC_drawSprite,
1284        "void", "(float x, float y, float z, float w, float h)" },
1285    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace,
1286        "void", "(float x, float y, float z, float w, float h)" },
1287    { "drawLine", (void *)&SC_drawLine,
1288        "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
1289    { "drawPoint", (void *)&SC_drawPoint,
1290        "void", "(float x1, float y1, float z1)" },
1291    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
1292        "void", "(int ism)" },
1293    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
1294        "void", "(int ism, int start, int len)" },
1295
1296
1297    // misc
1298    { "pfClearColor", (void *)&SC_ClearColor,
1299        "void", "(float, float, float, float)" },
1300    { "color", (void *)&SC_color,
1301        "void", "(float, float, float, float)" },
1302    { "hsb", (void *)&SC_hsb,
1303        "void", "(float, float, float, float)" },
1304    { "hsbToRgb", (void *)&SC_hsbToRgb,
1305        "void", "(float, float, float, float*)" },
1306    { "hsbToAbgr", (void *)&SC_hsbToAbgr,
1307        "int", "(float, float, float, float)" },
1308    { "ambient", (void *)&SC_ambient,
1309        "void", "(float, float, float, float)" },
1310    { "diffuse", (void *)&SC_diffuse,
1311        "void", "(float, float, float, float)" },
1312    { "specular", (void *)&SC_specular,
1313        "void", "(float, float, float, float)" },
1314    { "emission", (void *)&SC_emission,
1315        "void", "(float, float, float, float)" },
1316    { "shininess", (void *)&SC_shininess,
1317        "void", "(float)" },
1318    { "pointAttenuation", (void *)&SC_pointAttenuation,
1319        "void", "(float, float, float)" },
1320
1321    { "uploadToTexture", (void *)&SC_uploadToTexture,
1322        "void", "(int, int)" },
1323    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
1324        "void", "(int)" },
1325
1326    { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
1327        "int", "(float, float, float, float)" },
1328    { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
1329        "int", "(float, float, float)" },
1330
1331
1332    { "getWidth", (void *)&SC_getWidth,
1333        "int", "()" },
1334    { "getHeight", (void *)&SC_getHeight,
1335        "int", "()" },
1336
1337    { "sendToClient", (void *)&SC_toClient,
1338        "int", "(void *data, int cmdID, int len, int waitForSpace)" },
1339
1340
1341    { "debugF", (void *)&SC_debugF,
1342        "void", "(void *, float)" },
1343    { "debugI32", (void *)&SC_debugI32,
1344        "void", "(void *, int)" },
1345    { "debugHexF", (void *)&SC_debugHexF,
1346        "void", "(void *, float)" },
1347    { "debugHexI32", (void *)&SC_debugHexI32,
1348        "void", "(void *, int)" },
1349
1350    { "scriptCall", (void *)&SC_scriptCall,
1351        "void", "(int)" },
1352
1353
1354    { NULL, NULL, NULL, NULL }
1355};
1356
1357const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
1358{
1359    ScriptCState::SymbolTable_t *syms = gSyms;
1360
1361    while (syms->mPtr) {
1362        if (!strcmp(syms->mName, sym)) {
1363            return syms;
1364        }
1365        syms++;
1366    }
1367    return NULL;
1368}
1369
1370void ScriptCState::appendDecls(String8 *str)
1371{
1372    ScriptCState::SymbolTable_t *syms = gSyms;
1373    while (syms->mPtr) {
1374        str->append(syms->mRet);
1375        str->append(" ");
1376        str->append(syms->mName);
1377        str->append(syms->mParam);
1378        str->append(";\n");
1379        syms++;
1380    }
1381}
1382
1383
1384