Home | History | Annotate | Download | only in rs
      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 
     34 using namespace android;
     35 using 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 
     42 typedef struct {
     43     float x;
     44     float y;
     45     float z;
     46 } vec3_t;
     47 
     48 typedef struct {
     49     float x;
     50     float y;
     51     float z;
     52     float w;
     53 } vec4_t;
     54 
     55 typedef struct {
     56     float x;
     57     float y;
     58 } vec2_t;
     59 
     60 //////////////////////////////////////////////////////////////////////////////
     61 // IO routines
     62 //////////////////////////////////////////////////////////////////////////////
     63 
     64 static 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 
     73 static 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 
     82 static 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 
     90 static 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 
     98 static 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 
    105 static void SC_updateSimpleMesh(RsSimpleMesh mesh)
    106 {
    107     GET_TLS();
    108     SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
    109     sm->uploadAll(rsc);
    110 }
    111 
    112 static 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 
    120 static 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 
    128 static 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 
    137 static 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 
    146 static 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 
    154 static 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 
    162 static 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 
    170 static 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 
    182 static 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 
    191 static 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 
    196 static 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 
    203 static 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 
    210 static 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 
    220 static 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 
    225 static 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 
    236 static 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 
    246 static 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 
    251 static 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 
    259 static 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 
    267 static 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 
    272 static 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 
    288 static 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 
    306 static 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 
    326 static float SC_randf(float max)
    327 {
    328     float r = (float)rand();
    329     return r / RAND_MAX * max;
    330 }
    331 
    332 static float SC_randf2(float min, float max)
    333 {
    334     float r = (float)rand();
    335     return r / RAND_MAX * (max - min) + min;
    336 }
    337 
    338 static int SC_sign(int value)
    339 {
    340     return (value > 0) - (value < 0);
    341 }
    342 
    343 static float SC_signf(float value)
    344 {
    345     return (value > 0) - (value < 0);
    346 }
    347 
    348 static float SC_clampf(float amount, float low, float high)
    349 {
    350     return amount < low ? low : (amount > high ? high : amount);
    351 }
    352 
    353 static int SC_clamp(int amount, int low, int high)
    354 {
    355     return amount < low ? low : (amount > high ? high : amount);
    356 }
    357 
    358 static float SC_maxf(float a, float b)
    359 {
    360     return a > b ? a : b;
    361 }
    362 
    363 static float SC_minf(float a, float b)
    364 {
    365     return a < b ? a : b;
    366 }
    367 
    368 static float SC_sqrf(float v)
    369 {
    370     return v * v;
    371 }
    372 
    373 static int SC_sqr(int v)
    374 {
    375     return v * v;
    376 }
    377 
    378 static float SC_fracf(float v)
    379 {
    380     return v - floorf(v);
    381 }
    382 
    383 static float SC_roundf(float v)
    384 {
    385     return floorf(v + 0.4999999999);
    386 }
    387 
    388 static 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 
    395 static 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 
    403 static float SC_magf2(float a, float b)
    404 {
    405     return sqrtf(a * a + b * b);
    406 }
    407 
    408 static float SC_magf3(float a, float b, float c)
    409 {
    410     return sqrtf(a * a + b * b + c * c);
    411 }
    412 
    413 static float SC_radf(float degrees)
    414 {
    415     return degrees * DEG_TO_RAD;
    416 }
    417 
    418 static float SC_degf(float radians)
    419 {
    420     return radians * RAD_TO_DEG;
    421 }
    422 
    423 static float SC_lerpf(float start, float stop, float amount)
    424 {
    425     return start + (stop - start) * amount;
    426 }
    427 
    428 static float SC_normf(float start, float stop, float value)
    429 {
    430     return (value - start) / (stop - start);
    431 }
    432 
    433 static 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 
    442 static 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 
    454 static 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 
    466 static 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 
    478 static 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 
    490 static 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 
    502 static 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 
    514 static int32_t SC_uptimeMillis()
    515 {
    516     return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
    517 }
    518 
    519 static int32_t SC_startTimeMillis()
    520 {
    521     GET_TLS();
    522     return sc->mEnviroment.mStartTimeMillis;
    523 }
    524 
    525 static 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 
    537 static void SC_matrixLoadIdentity(rsc_Matrix *mat)
    538 {
    539     Matrix *m = reinterpret_cast<Matrix *>(mat);
    540     m->loadIdentity();
    541 }
    542 
    543 static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
    544 {
    545     Matrix *m = reinterpret_cast<Matrix *>(mat);
    546     m->load(f);
    547 }
    548 
    549 static 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 
    555 static 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 
    561 static 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 
    567 static 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 
    573 static 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 
    580 static 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 
    586 static 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 
    592 static 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 
    598 static 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 
    605 static 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 
    619 static 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 
    629 static 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 
    639 static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
    640 {
    641     GET_TLS();
    642     rsi_ContextBindProgramFragmentStore(rsc, pfs);
    643 
    644 }
    645 
    646 static void SC_bindProgramFragment(RsProgramFragment pf)
    647 {
    648     GET_TLS();
    649     rsi_ContextBindProgramFragment(rsc, pf);
    650 
    651 }
    652 
    653 static void SC_bindProgramVertex(RsProgramVertex pv)
    654 {
    655     GET_TLS();
    656     rsi_ContextBindProgramVertex(rsc, pv);
    657 
    658 }
    659 
    660 //////////////////////////////////////////////////////////////////////////////
    661 // VP
    662 //////////////////////////////////////////////////////////////////////////////
    663 
    664 static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
    665 {
    666     GET_TLS();
    667     rsc->getVertex()->setModelviewMatrix(m);
    668 }
    669 
    670 static 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 
    682 static void SC_drawLine(float x1, float y1, float z1,
    683                         float x2, float y2, float z2)
    684 {
    685     GET_TLS();
    686     if (!rsc->setupCheck()) {
    687         return;
    688     }
    689 
    690     float vtx[] = { x1, y1, z1, x2, y2, z2 };
    691     VertexArray va;
    692     va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
    693     if (rsc->checkVersion2_0()) {
    694         va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
    695     } else {
    696         va.setupGL(rsc, &rsc->mStateVertexArray);
    697     }
    698 
    699     glDrawArrays(GL_LINES, 0, 2);
    700 }
    701 
    702 static void SC_drawPoint(float x, float y, float z)
    703 {
    704     GET_TLS();
    705     if (!rsc->setupCheck()) {
    706         return;
    707     }
    708 
    709     float vtx[] = { x, y, z };
    710 
    711     VertexArray va;
    712     va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
    713     if (rsc->checkVersion2_0()) {
    714         va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
    715     } else {
    716         va.setupGL(rsc, &rsc->mStateVertexArray);
    717     }
    718 
    719     glDrawArrays(GL_POINTS, 0, 1);
    720 }
    721 
    722 static void SC_drawQuadTexCoords(float x1, float y1, float z1,
    723                                  float u1, float v1,
    724                                  float x2, float y2, float z2,
    725                                  float u2, float v2,
    726                                  float x3, float y3, float z3,
    727                                  float u3, float v3,
    728                                  float x4, float y4, float z4,
    729                                  float u4, float v4)
    730 {
    731     GET_TLS();
    732     if (!rsc->setupCheck()) {
    733         return;
    734     }
    735 
    736     //LOGE("Quad");
    737     //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
    738     //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
    739     //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
    740     //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
    741 
    742     float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
    743     const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
    744 
    745     VertexArray va;
    746     va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
    747     va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
    748     if (rsc->checkVersion2_0()) {
    749         va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
    750     } else {
    751         va.setupGL(rsc, &rsc->mStateVertexArray);
    752     }
    753 
    754 
    755     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    756 }
    757 
    758 static void SC_drawQuad(float x1, float y1, float z1,
    759                         float x2, float y2, float z2,
    760                         float x3, float y3, float z3,
    761                         float x4, float y4, float z4)
    762 {
    763     SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
    764                          x2, y2, z2, 1, 1,
    765                          x3, y3, z3, 1, 0,
    766                          x4, y4, z4, 0, 0);
    767 }
    768 
    769 static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
    770 {
    771     GET_TLS();
    772     ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
    773     rsc->setVertex(rsc->getDefaultProgramVertex());
    774     //rsc->setupCheck();
    775 
    776     //GLint crop[4] = {0, h, w, -h};
    777 
    778     float sh = rsc->getHeight();
    779 
    780     SC_drawQuad(x,   sh - y,     z,
    781                 x+w, sh - y,     z,
    782                 x+w, sh - (y+h), z,
    783                 x,   sh - (y+h), z);
    784     rsc->setVertex((ProgramVertex *)tmp.get());
    785 }
    786 
    787 static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
    788         float cx0, float cy0, float cx1, float cy1)
    789 {
    790     GET_TLS();
    791     if (!rsc->setupCheck()) {
    792         return;
    793     }
    794 
    795     GLint crop[4] = {cx0, cy0, cx1, cy1};
    796     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
    797     glDrawTexfOES(x, y, z, w, h);
    798 }
    799 
    800 static void SC_drawSprite(float x, float y, float z, float w, float h)
    801 {
    802     GET_TLS();
    803     float vin[3] = {x, y, z};
    804     float vout[4];
    805 
    806     //LOGE("ds  in %f %f %f", x, y, z);
    807     rsc->getVertex()->transformToScreen(rsc, vout, vin);
    808     //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
    809     vout[0] /= vout[3];
    810     vout[1] /= vout[3];
    811     vout[2] /= vout[3];
    812 
    813     vout[0] *= rsc->getWidth() / 2;
    814     vout[1] *= rsc->getHeight() / 2;
    815     vout[0] += rsc->getWidth() / 2;
    816     vout[1] += rsc->getHeight() / 2;
    817 
    818     vout[0] -= w/2;
    819     vout[1] -= h/2;
    820 
    821     //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
    822 
    823     // U, V, W, H
    824     SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
    825     //rsc->setupCheck();
    826 }
    827 
    828 
    829 static void SC_drawRect(float x1, float y1,
    830                         float x2, float y2, float z)
    831 {
    832     SC_drawQuad(x1, y2, z,
    833                 x2, y2, z,
    834                 x2, y1, z,
    835                 x1, y1, z);
    836 }
    837 
    838 static void SC_drawSimpleMesh(RsSimpleMesh vsm)
    839 {
    840     GET_TLS();
    841     SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
    842     if (!rsc->setupCheck()) {
    843         return;
    844     }
    845     sm->render(rsc);
    846 }
    847 
    848 static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
    849 {
    850     GET_TLS();
    851     SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
    852     if (!rsc->setupCheck()) {
    853         return;
    854     }
    855     sm->renderRange(rsc, start, len);
    856 }
    857 
    858 
    859 //////////////////////////////////////////////////////////////////////////////
    860 //
    861 //////////////////////////////////////////////////////////////////////////////
    862 
    863 static void SC_color(float r, float g, float b, float a)
    864 {
    865     GET_TLS();
    866     rsc->mStateVertex.color[0] = r;
    867     rsc->mStateVertex.color[1] = g;
    868     rsc->mStateVertex.color[2] = b;
    869     rsc->mStateVertex.color[3] = a;
    870     if (!rsc->checkVersion2_0()) {
    871         glColor4f(r, g, b, a);
    872     }
    873 }
    874 
    875 static void SC_ambient(float r, float g, float b, float a)
    876 {
    877     GLfloat params[] = { r, g, b, a };
    878     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, params);
    879 }
    880 
    881 static void SC_diffuse(float r, float g, float b, float a)
    882 {
    883     GLfloat params[] = { r, g, b, a };
    884     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, params);
    885 }
    886 
    887 static void SC_specular(float r, float g, float b, float a)
    888 {
    889     GLfloat params[] = { r, g, b, a };
    890     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, params);
    891 }
    892 
    893 static void SC_emission(float r, float g, float b, float a)
    894 {
    895     GLfloat params[] = { r, g, b, a };
    896     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, params);
    897 }
    898 
    899 static void SC_shininess(float s)
    900 {
    901     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
    902 }
    903 
    904 static void SC_pointAttenuation(float a, float b, float c)
    905 {
    906     GLfloat params[] = { a, b, c };
    907     glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
    908 }
    909 
    910 static void SC_hsbToRgb(float h, float s, float b, float* rgb)
    911 {
    912     float red = 0.0f;
    913     float green = 0.0f;
    914     float blue = 0.0f;
    915 
    916     float x = h;
    917     float y = s;
    918     float z = b;
    919 
    920     float hf = (x - (int) x) * 6.0f;
    921     int ihf = (int) hf;
    922     float f = hf - ihf;
    923     float pv = z * (1.0f - y);
    924     float qv = z * (1.0f - y * f);
    925     float tv = z * (1.0f - y * (1.0f - f));
    926 
    927     switch (ihf) {
    928         case 0:         // Red is the dominant color
    929             red = z;
    930             green = tv;
    931             blue = pv;
    932             break;
    933         case 1:         // Green is the dominant color
    934             red = qv;
    935             green = z;
    936             blue = pv;
    937             break;
    938         case 2:
    939             red = pv;
    940             green = z;
    941             blue = tv;
    942             break;
    943         case 3:         // Blue is the dominant color
    944             red = pv;
    945             green = qv;
    946             blue = z;
    947             break;
    948         case 4:
    949             red = tv;
    950             green = pv;
    951             blue = z;
    952             break;
    953         case 5:         // Red is the dominant color
    954             red = z;
    955             green = pv;
    956             blue = qv;
    957             break;
    958     }
    959 
    960     rgb[0] = red;
    961     rgb[1] = green;
    962     rgb[2] = blue;
    963 }
    964 
    965 static int SC_hsbToAbgr(float h, float s, float b, float a)
    966 {
    967     float rgb[3];
    968     SC_hsbToRgb(h, s, b, rgb);
    969     return int(a      * 255.0f) << 24 |
    970            int(rgb[2] * 255.0f) << 16 |
    971            int(rgb[1] * 255.0f) <<  8 |
    972            int(rgb[0] * 255.0f);
    973 }
    974 
    975 static void SC_hsb(float h, float s, float b, float a)
    976 {
    977     GET_TLS();
    978     float rgb[3];
    979     SC_hsbToRgb(h, s, b, rgb);
    980     if (rsc->checkVersion2_0()) {
    981         glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
    982     } else {
    983         glColor4f(rgb[0], rgb[1], rgb[2], a);
    984     }
    985 }
    986 
    987 static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
    988 {
    989     GET_TLS();
    990     rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
    991 }
    992 
    993 static void SC_uploadToBufferObject(RsAllocation va)
    994 {
    995     GET_TLS();
    996     rsi_AllocationUploadToBufferObject(rsc, va);
    997 }
    998 
    999 static void SC_syncToGL(RsAllocation va)
   1000 {
   1001     GET_TLS();
   1002     Allocation *a = static_cast<Allocation *>(va);
   1003 
   1004 }
   1005 
   1006 static void SC_ClearColor(float r, float g, float b, float a)
   1007 {
   1008     //LOGE("c %f %f %f %f", r, g, b, a);
   1009     GET_TLS();
   1010     sc->mEnviroment.mClearColor[0] = r;
   1011     sc->mEnviroment.mClearColor[1] = g;
   1012     sc->mEnviroment.mClearColor[2] = b;
   1013     sc->mEnviroment.mClearColor[3] = a;
   1014 }
   1015 
   1016 static void SC_debugF(const char *s, float f)
   1017 {
   1018     LOGE("%s %f", s, f);
   1019 }
   1020 
   1021 static void SC_debugHexF(const char *s, float f)
   1022 {
   1023     LOGE("%s 0x%x", s, *((int *) (&f)));
   1024 }
   1025 
   1026 static void SC_debugI32(const char *s, int32_t i)
   1027 {
   1028     LOGE("%s %i", s, i);
   1029 }
   1030 
   1031 static void SC_debugHexI32(const char *s, int32_t i)
   1032 {
   1033     LOGE("%s 0x%x", s, i);
   1034 }
   1035 
   1036 static uint32_t SC_getWidth()
   1037 {
   1038     GET_TLS();
   1039     return rsc->getWidth();
   1040 }
   1041 
   1042 static uint32_t SC_getHeight()
   1043 {
   1044     GET_TLS();
   1045     return rsc->getHeight();
   1046 }
   1047 
   1048 static uint32_t SC_colorFloatRGBAtoUNorm8(float r, float g, float b, float a)
   1049 {
   1050     uint32_t c = 0;
   1051     c |= (uint32_t)(r * 255.f + 0.5f);
   1052     c |= ((uint32_t)(g * 255.f + 0.5f)) << 8;
   1053     c |= ((uint32_t)(b * 255.f + 0.5f)) << 16;
   1054     c |= ((uint32_t)(a * 255.f + 0.5f)) << 24;
   1055     return c;
   1056 }
   1057 
   1058 static uint32_t SC_colorFloatRGBAto565(float r, float g, float b)
   1059 {
   1060     uint32_t ir = (uint32_t)(r * 255.f + 0.5f);
   1061     uint32_t ig = (uint32_t)(g * 255.f + 0.5f);
   1062     uint32_t ib = (uint32_t)(b * 255.f + 0.5f);
   1063     return rs888to565(ir, ig, ib);
   1064 }
   1065 
   1066 static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace)
   1067 {
   1068     GET_TLS();
   1069     return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
   1070 }
   1071 
   1072 static void SC_scriptCall(int scriptID)
   1073 {
   1074     GET_TLS();
   1075     rsc->runScript((Script *)scriptID, 0);
   1076 }
   1077 
   1078 
   1079 //////////////////////////////////////////////////////////////////////////////
   1080 // Class implementation
   1081 //////////////////////////////////////////////////////////////////////////////
   1082 
   1083 ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
   1084     // IO
   1085     { "loadI32", (void *)&SC_loadI32,
   1086         "int", "(int, int)" },
   1087     //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
   1088     { "loadF", (void *)&SC_loadF,
   1089         "float", "(int, int)" },
   1090     { "loadArrayF", (void *)&SC_loadArrayF,
   1091         "float*", "(int, int)" },
   1092     { "loadArrayI32", (void *)&SC_loadArrayI32,
   1093         "int*", "(int, int)" },
   1094     { "loadVec4", (void *)&SC_loadVec4,
   1095         "void", "(int, int, float *)" },
   1096     { "loadMatrix", (void *)&SC_loadMatrix,
   1097         "void", "(int, int, float *)" },
   1098     { "storeI32", (void *)&SC_storeI32,
   1099         "void", "(int, int, int)" },
   1100     //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
   1101     { "storeF", (void *)&SC_storeF,
   1102         "void", "(int, int, float)" },
   1103     { "storeVec4", (void *)&SC_storeVec4,
   1104         "void", "(int, int, float *)" },
   1105     { "storeMatrix", (void *)&SC_storeMatrix,
   1106         "void", "(int, int, float *)" },
   1107     { "loadSimpleMeshVerticesF", (void *)&SC_loadSimpleMeshVerticesF,
   1108         "float*", "(int, int)" },
   1109     { "updateSimpleMesh", (void *)&SC_updateSimpleMesh,
   1110         "void", "(int)" },
   1111 
   1112     // math
   1113     { "modf", (void *)&fmod,
   1114         "float", "(float, float)" },
   1115     { "abs", (void *)&abs,
   1116         "int", "(int)" },
   1117     { "absf", (void *)&fabsf,
   1118         "float", "(float)" },
   1119     { "sinf_fast", (void *)&SC_sinf_fast,
   1120         "float", "(float)" },
   1121     { "cosf_fast", (void *)&SC_cosf_fast,
   1122         "float", "(float)" },
   1123     { "sinf", (void *)&sinf,
   1124         "float", "(float)" },
   1125     { "cosf", (void *)&cosf,
   1126         "float", "(float)" },
   1127     { "asinf", (void *)&asinf,
   1128         "float", "(float)" },
   1129     { "acosf", (void *)&acosf,
   1130         "float", "(float)" },
   1131     { "atanf", (void *)&atanf,
   1132         "float", "(float)" },
   1133     { "atan2f", (void *)&atan2f,
   1134         "float", "(float, float)" },
   1135     { "fabsf", (void *)&fabsf,
   1136         "float", "(float)" },
   1137     { "randf", (void *)&SC_randf,
   1138         "float", "(float)" },
   1139     { "randf2", (void *)&SC_randf2,
   1140         "float", "(float, float)" },
   1141     { "floorf", (void *)&floorf,
   1142         "float", "(float)" },
   1143     { "fracf", (void *)&SC_fracf,
   1144         "float", "(float)" },
   1145     { "ceilf", (void *)&ceilf,
   1146         "float", "(float)" },
   1147     { "roundf", (void *)&SC_roundf,
   1148         "float", "(float)" },
   1149     { "expf", (void *)&expf,
   1150         "float", "(float)" },
   1151     { "logf", (void *)&logf,
   1152         "float", "(float)" },
   1153     { "powf", (void *)&powf,
   1154         "float", "(float, float)" },
   1155     { "maxf", (void *)&SC_maxf,
   1156         "float", "(float, float)" },
   1157     { "minf", (void *)&SC_minf,
   1158         "float", "(float, float)" },
   1159     { "sqrt", (void *)&sqrt,
   1160         "int", "(int)" },
   1161     { "sqrtf", (void *)&sqrtf,
   1162         "float", "(float)" },
   1163     { "sqr", (void *)&SC_sqr,
   1164         "int", "(int)" },
   1165     { "sqrf", (void *)&SC_sqrf,
   1166         "float", "(float)" },
   1167     { "sign", (void *)&SC_sign,
   1168         "int", "(int)" },
   1169     { "signf", (void *)&SC_signf,
   1170         "float", "(float)" },
   1171     { "clamp", (void *)&SC_clamp,
   1172         "int", "(int, int, int)" },
   1173     { "clampf", (void *)&SC_clampf,
   1174         "float", "(float, float, float)" },
   1175     { "distf2", (void *)&SC_distf2,
   1176         "float", "(float, float, float, float)" },
   1177     { "distf3", (void *)&SC_distf3,
   1178         "float", "(float, float, float, float, float, float)" },
   1179     { "magf2", (void *)&SC_magf2,
   1180         "float", "(float, float)" },
   1181     { "magf3", (void *)&SC_magf3,
   1182         "float", "(float, float, float)" },
   1183     { "radf", (void *)&SC_radf,
   1184         "float", "(float)" },
   1185     { "degf", (void *)&SC_degf,
   1186         "float", "(float)" },
   1187     { "lerpf", (void *)&SC_lerpf,
   1188         "float", "(float, float, float)" },
   1189     { "normf", (void *)&SC_normf,
   1190         "float", "(float, float, float)" },
   1191     { "mapf", (void *)&SC_mapf,
   1192         "float", "(float, float, float, float, float)" },
   1193     { "noisef", (void *)&SC_noisef,
   1194         "float", "(float)" },
   1195     { "noisef2", (void *)&SC_noisef2,
   1196         "float", "(float, float)" },
   1197     { "noisef3", (void *)&SC_noisef3,
   1198         "float", "(float, float, float)" },
   1199     { "turbulencef2", (void *)&SC_turbulencef2,
   1200         "float", "(float, float, float)" },
   1201     { "turbulencef3", (void *)&SC_turbulencef3,
   1202         "float", "(float, float, float, float)" },
   1203 
   1204     // time
   1205     { "second", (void *)&SC_second,
   1206         "int", "()" },
   1207     { "minute", (void *)&SC_minute,
   1208         "int", "()" },
   1209     { "hour", (void *)&SC_hour,
   1210         "int", "()" },
   1211     { "day", (void *)&SC_day,
   1212         "int", "()" },
   1213     { "month", (void *)&SC_month,
   1214         "int", "()" },
   1215     { "year", (void *)&SC_year,
   1216         "int", "()" },
   1217     { "uptimeMillis", (void*)&SC_uptimeMillis,
   1218         "int", "()" },      // TODO: use long instead
   1219     { "startTimeMillis", (void*)&SC_startTimeMillis,
   1220         "int", "()" },      // TODO: use long instead
   1221     { "elapsedTimeMillis", (void*)&SC_elapsedTimeMillis,
   1222         "int", "()" },      // TODO: use long instead
   1223 
   1224     // matrix
   1225     { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
   1226         "void", "(float *mat)" },
   1227     { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
   1228         "void", "(float *mat, float *f)" },
   1229     { "matrixLoadMat", (void *)&SC_matrixLoadMat,
   1230         "void", "(float *mat, float *newmat)" },
   1231     { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
   1232         "void", "(float *mat, float rot, float x, float y, float z)" },
   1233     { "matrixLoadScale", (void *)&SC_matrixLoadScale,
   1234         "void", "(float *mat, float x, float y, float z)" },
   1235     { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
   1236         "void", "(float *mat, float x, float y, float z)" },
   1237     { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
   1238         "void", "(float *mat, float *lhs, float *rhs)" },
   1239     { "matrixMultiply", (void *)&SC_matrixMultiply,
   1240         "void", "(float *mat, float *rhs)" },
   1241     { "matrixRotate", (void *)&SC_matrixRotate,
   1242         "void", "(float *mat, float rot, float x, float y, float z)" },
   1243     { "matrixScale", (void *)&SC_matrixScale,
   1244         "void", "(float *mat, float x, float y, float z)" },
   1245     { "matrixTranslate", (void *)&SC_matrixTranslate,
   1246         "void", "(float *mat, float x, float y, float z)" },
   1247 
   1248     // vector
   1249     { "vec2Rand", (void *)&SC_vec2Rand,
   1250         "void", "(float *vec, float maxLen)" },
   1251 
   1252     // vec3
   1253     { "vec3Norm", (void *)&SC_vec3Norm,
   1254         "void", "(struct vecF32_3_s *)" },
   1255     { "vec3Length", (void *)&SC_vec3Length,
   1256         "float", "(struct vecF32_3_s *)" },
   1257     { "vec3Add", (void *)&SC_vec3Add,
   1258         "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
   1259     { "vec3Sub", (void *)&SC_vec3Sub,
   1260         "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
   1261     { "vec3Cross", (void *)&SC_vec3Cross,
   1262         "void", "(struct vecF32_3_s *dest, struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
   1263     { "vec3Dot", (void *)&SC_vec3Dot,
   1264         "float", "(struct vecF32_3_s *lhs, struct vecF32_3_s *rhs)" },
   1265     { "vec3Scale", (void *)&SC_vec3Scale,
   1266         "void", "(struct vecF32_3_s *lhs, float scale)" },
   1267 
   1268     // vec4
   1269     { "vec4Norm", (void *)&SC_vec4Norm,
   1270         "void", "(struct vecF32_4_s *)" },
   1271     { "vec4Length", (void *)&SC_vec4Length,
   1272         "float", "(struct vecF32_4_s *)" },
   1273     { "vec4Add", (void *)&SC_vec4Add,
   1274         "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
   1275     { "vec4Sub", (void *)&SC_vec4Sub,
   1276         "void", "(struct vecF32_4_s *dest, struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
   1277     { "vec4Dot", (void *)&SC_vec4Dot,
   1278         "float", "(struct vecF32_4_s *lhs, struct vecF32_4_s *rhs)" },
   1279     { "vec4Scale", (void *)&SC_vec4Scale,
   1280         "void", "(struct vecF32_4_s *lhs, float scale)" },
   1281 
   1282     // context
   1283     { "bindProgramFragment", (void *)&SC_bindProgramFragment,
   1284         "void", "(int)" },
   1285     { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
   1286         "void", "(int)" },
   1287     { "bindProgramStore", (void *)&SC_bindProgramFragmentStore,
   1288         "void", "(int)" },
   1289     { "bindProgramVertex", (void *)&SC_bindProgramVertex,
   1290         "void", "(int)" },
   1291     { "bindSampler", (void *)&SC_bindSampler,
   1292         "void", "(int, int, int)" },
   1293     { "bindTexture", (void *)&SC_bindTexture,
   1294         "void", "(int, int, int)" },
   1295 
   1296     // vp
   1297     { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix,
   1298         "void", "(void *)" },
   1299     { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix,
   1300         "void", "(void *)" },
   1301 
   1302 
   1303 
   1304     // drawing
   1305     { "drawRect", (void *)&SC_drawRect,
   1306         "void", "(float x1, float y1, float x2, float y2, float z)" },
   1307     { "drawQuad", (void *)&SC_drawQuad,
   1308         "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)" },
   1309     { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords,
   1310         "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)" },
   1311     { "drawSprite", (void *)&SC_drawSprite,
   1312         "void", "(float x, float y, float z, float w, float h)" },
   1313     { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace,
   1314         "void", "(float x, float y, float z, float w, float h)" },
   1315     { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped,
   1316         "void", "(float x, float y, float z, float w, float h, float cx0, float cy0, float cx1, float cy1)" },
   1317     { "drawLine", (void *)&SC_drawLine,
   1318         "void", "(float x1, float y1, float z1, float x2, float y2, float z2)" },
   1319     { "drawPoint", (void *)&SC_drawPoint,
   1320         "void", "(float x1, float y1, float z1)" },
   1321     { "drawSimpleMesh", (void *)&SC_drawSimpleMesh,
   1322         "void", "(int ism)" },
   1323     { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange,
   1324         "void", "(int ism, int start, int len)" },
   1325 
   1326 
   1327     // misc
   1328     { "pfClearColor", (void *)&SC_ClearColor,
   1329         "void", "(float, float, float, float)" },
   1330     { "color", (void *)&SC_color,
   1331         "void", "(float, float, float, float)" },
   1332     { "hsb", (void *)&SC_hsb,
   1333         "void", "(float, float, float, float)" },
   1334     { "hsbToRgb", (void *)&SC_hsbToRgb,
   1335         "void", "(float, float, float, float*)" },
   1336     { "hsbToAbgr", (void *)&SC_hsbToAbgr,
   1337         "int", "(float, float, float, float)" },
   1338     { "ambient", (void *)&SC_ambient,
   1339         "void", "(float, float, float, float)" },
   1340     { "diffuse", (void *)&SC_diffuse,
   1341         "void", "(float, float, float, float)" },
   1342     { "specular", (void *)&SC_specular,
   1343         "void", "(float, float, float, float)" },
   1344     { "emission", (void *)&SC_emission,
   1345         "void", "(float, float, float, float)" },
   1346     { "shininess", (void *)&SC_shininess,
   1347         "void", "(float)" },
   1348     { "pointAttenuation", (void *)&SC_pointAttenuation,
   1349         "void", "(float, float, float)" },
   1350 
   1351     { "uploadToTexture", (void *)&SC_uploadToTexture,
   1352         "void", "(int, int)" },
   1353     { "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
   1354         "void", "(int)" },
   1355 
   1356     { "syncToGL", (void *)&SC_syncToGL,
   1357         "void", "(int)" },
   1358 
   1359     { "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
   1360         "int", "(float, float, float, float)" },
   1361     { "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
   1362         "int", "(float, float, float)" },
   1363 
   1364 
   1365     { "getWidth", (void *)&SC_getWidth,
   1366         "int", "()" },
   1367     { "getHeight", (void *)&SC_getHeight,
   1368         "int", "()" },
   1369 
   1370     { "sendToClient", (void *)&SC_toClient,
   1371         "int", "(void *data, int cmdID, int len, int waitForSpace)" },
   1372 
   1373 
   1374     { "debugF", (void *)&SC_debugF,
   1375         "void", "(void *, float)" },
   1376     { "debugI32", (void *)&SC_debugI32,
   1377         "void", "(void *, int)" },
   1378     { "debugHexF", (void *)&SC_debugHexF,
   1379         "void", "(void *, float)" },
   1380     { "debugHexI32", (void *)&SC_debugHexI32,
   1381         "void", "(void *, int)" },
   1382 
   1383     { "scriptCall", (void *)&SC_scriptCall,
   1384         "void", "(int)" },
   1385 
   1386 
   1387     { NULL, NULL, NULL, NULL }
   1388 };
   1389 
   1390 const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
   1391 {
   1392     ScriptCState::SymbolTable_t *syms = gSyms;
   1393 
   1394     while (syms->mPtr) {
   1395         if (!strcmp(syms->mName, sym)) {
   1396             return syms;
   1397         }
   1398         syms++;
   1399     }
   1400     return NULL;
   1401 }
   1402 
   1403 void ScriptCState::appendDecls(String8 *str)
   1404 {
   1405     ScriptCState::SymbolTable_t *syms = gSyms;
   1406     while (syms->mPtr) {
   1407         str->append(syms->mRet);
   1408         str->append(" ");
   1409         str->append(syms->mName);
   1410         str->append(syms->mParam);
   1411         str->append(";\n");
   1412         syms++;
   1413     }
   1414 }
   1415 
   1416 
   1417