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