Home | History | Annotate | Download | only in driver
      1 /*
      2  * Copyright (C) 2011 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 "rsMatrix4x4.h"
     20 #include "rsMatrix3x3.h"
     21 #include "rsMatrix2x2.h"
     22 #include "rsRuntime.h"
     23 
     24 #include "utils/Timers.h"
     25 #include "rsdCore.h"
     26 
     27 #include "rsdRuntime.h"
     28 
     29 #include <time.h>
     30 
     31 using namespace android;
     32 using namespace android::renderscript;
     33 
     34 #define GET_TLS()  ScriptTLSStruct * tls = \
     35     (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey); \
     36     Context * rsc = tls->mContext; \
     37     ScriptC * sc = (ScriptC *) tls->mScript
     38 
     39 
     40 
     41 //////////////////////////////////////////////////////////////////////////////
     42 // Allocation
     43 //////////////////////////////////////////////////////////////////////////////
     44 
     45 
     46 static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
     47     GET_TLS();
     48     rsrAllocationSyncAll(rsc, sc, a, source);
     49 }
     50 
     51 static void SC_AllocationSyncAll(Allocation *a) {
     52     GET_TLS();
     53     rsrAllocationSyncAll(rsc, sc, a, RS_ALLOCATION_USAGE_SCRIPT);
     54 }
     55 
     56 static void SC_AllocationCopy1DRange(Allocation *dstAlloc,
     57                                      uint32_t dstOff,
     58                                      uint32_t dstMip,
     59                                      uint32_t count,
     60                                      Allocation *srcAlloc,
     61                                      uint32_t srcOff, uint32_t srcMip) {
     62     GET_TLS();
     63     rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count,
     64                              srcAlloc, srcOff, srcMip);
     65 }
     66 
     67 static void SC_AllocationCopy2DRange(Allocation *dstAlloc,
     68                                      uint32_t dstXoff, uint32_t dstYoff,
     69                                      uint32_t dstMip, uint32_t dstFace,
     70                                      uint32_t width, uint32_t height,
     71                                      Allocation *srcAlloc,
     72                                      uint32_t srcXoff, uint32_t srcYoff,
     73                                      uint32_t srcMip, uint32_t srcFace) {
     74     GET_TLS();
     75     rsrAllocationCopy2DRange(rsc, dstAlloc,
     76                              dstXoff, dstYoff, dstMip, dstFace,
     77                              width, height,
     78                              srcAlloc,
     79                              srcXoff, srcYoff, srcMip, srcFace);
     80 }
     81 
     82 
     83 //////////////////////////////////////////////////////////////////////////////
     84 // Context
     85 //////////////////////////////////////////////////////////////////////////////
     86 
     87 static void SC_BindTexture(ProgramFragment *pf, uint32_t slot, Allocation *a) {
     88     GET_TLS();
     89     rsrBindTexture(rsc, sc, pf, slot, a);
     90 }
     91 
     92 static void SC_BindSampler(ProgramFragment *pf, uint32_t slot, Sampler *s) {
     93     GET_TLS();
     94     rsrBindSampler(rsc, sc, pf, slot, s);
     95 }
     96 
     97 static void SC_BindProgramStore(ProgramStore *ps) {
     98     GET_TLS();
     99     rsrBindProgramStore(rsc, sc, ps);
    100 }
    101 
    102 static void SC_BindProgramFragment(ProgramFragment *pf) {
    103     GET_TLS();
    104     rsrBindProgramFragment(rsc, sc, pf);
    105 }
    106 
    107 static void SC_BindProgramVertex(ProgramVertex *pv) {
    108     GET_TLS();
    109     rsrBindProgramVertex(rsc, sc, pv);
    110 }
    111 
    112 static void SC_BindProgramRaster(ProgramRaster *pr) {
    113     GET_TLS();
    114     rsrBindProgramRaster(rsc, sc, pr);
    115 }
    116 
    117 static void SC_BindFrameBufferObjectColorTarget(Allocation *a, uint32_t slot) {
    118     GET_TLS();
    119     rsrBindFrameBufferObjectColorTarget(rsc, sc, a, slot);
    120 }
    121 
    122 static void SC_BindFrameBufferObjectDepthTarget(Allocation *a) {
    123     GET_TLS();
    124     rsrBindFrameBufferObjectDepthTarget(rsc, sc, a);
    125 }
    126 
    127 static void SC_ClearFrameBufferObjectColorTarget(uint32_t slot) {
    128     GET_TLS();
    129     rsrClearFrameBufferObjectColorTarget(rsc, sc, slot);
    130 }
    131 
    132 static void SC_ClearFrameBufferObjectDepthTarget(Context *, Script *) {
    133     GET_TLS();
    134     rsrClearFrameBufferObjectDepthTarget(rsc, sc);
    135 }
    136 
    137 static void SC_ClearFrameBufferObjectTargets(Context *, Script *) {
    138     GET_TLS();
    139     rsrClearFrameBufferObjectTargets(rsc, sc);
    140 }
    141 
    142 
    143 //////////////////////////////////////////////////////////////////////////////
    144 // VP
    145 //////////////////////////////////////////////////////////////////////////////
    146 
    147 static void SC_VpLoadProjectionMatrix(const rsc_Matrix *m) {
    148     GET_TLS();
    149     rsrVpLoadProjectionMatrix(rsc, sc, m);
    150 }
    151 
    152 static void SC_VpLoadModelMatrix(const rsc_Matrix *m) {
    153     GET_TLS();
    154     rsrVpLoadModelMatrix(rsc, sc, m);
    155 }
    156 
    157 static void SC_VpLoadTextureMatrix(const rsc_Matrix *m) {
    158     GET_TLS();
    159     rsrVpLoadTextureMatrix(rsc, sc, m);
    160 }
    161 
    162 static void SC_PfConstantColor(ProgramFragment *pf, float r, float g, float b, float a) {
    163     GET_TLS();
    164     rsrPfConstantColor(rsc, sc, pf, r, g, b, a);
    165 }
    166 
    167 static void SC_VpGetProjectionMatrix(rsc_Matrix *m) {
    168     GET_TLS();
    169     rsrVpGetProjectionMatrix(rsc, sc, m);
    170 }
    171 
    172 
    173 //////////////////////////////////////////////////////////////////////////////
    174 // Drawing
    175 //////////////////////////////////////////////////////////////////////////////
    176 
    177 static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
    178                                  float x2, float y2, float z2, float u2, float v2,
    179                                  float x3, float y3, float z3, float u3, float v3,
    180                                  float x4, float y4, float z4, float u4, float v4) {
    181     GET_TLS();
    182     rsrDrawQuadTexCoords(rsc, sc,
    183                          x1, y1, z1, u1, v1,
    184                          x2, y2, z2, u2, v2,
    185                          x3, y3, z3, u3, v3,
    186                          x4, y4, z4, u4, v4);
    187 }
    188 
    189 static void SC_DrawQuad(float x1, float y1, float z1,
    190                         float x2, float y2, float z2,
    191                         float x3, float y3, float z3,
    192                         float x4, float y4, float z4) {
    193     GET_TLS();
    194     rsrDrawQuad(rsc, sc, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4);
    195 }
    196 
    197 static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) {
    198     GET_TLS();
    199     rsrDrawSpriteScreenspace(rsc, sc, x, y, z, w, h);
    200 }
    201 
    202 static void SC_DrawRect(float x1, float y1, float x2, float y2, float z) {
    203     GET_TLS();
    204     rsrDrawRect(rsc, sc, x1, y1, x2, y2, z);
    205 }
    206 
    207 static void SC_DrawMesh(Mesh *m) {
    208     GET_TLS();
    209     rsrDrawMesh(rsc, sc, m);
    210 }
    211 
    212 static void SC_DrawMeshPrimitive(Mesh *m, uint32_t primIndex) {
    213     GET_TLS();
    214     rsrDrawMeshPrimitive(rsc, sc, m, primIndex);
    215 }
    216 
    217 static void SC_DrawMeshPrimitiveRange(Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
    218     GET_TLS();
    219     rsrDrawMeshPrimitiveRange(rsc, sc, m, primIndex, start, len);
    220 }
    221 
    222 static void SC_MeshComputeBoundingBox(Mesh *m,
    223                                float *minX, float *minY, float *minZ,
    224                                float *maxX, float *maxY, float *maxZ) {
    225     GET_TLS();
    226     rsrMeshComputeBoundingBox(rsc, sc, m, minX, minY, minZ, maxX, maxY, maxZ);
    227 }
    228 
    229 
    230 
    231 //////////////////////////////////////////////////////////////////////////////
    232 //
    233 //////////////////////////////////////////////////////////////////////////////
    234 
    235 
    236 static void SC_Color(float r, float g, float b, float a) {
    237     GET_TLS();
    238     rsrColor(rsc, sc, r, g, b, a);
    239 }
    240 
    241 static void SC_Finish() {
    242     GET_TLS();
    243     rsrFinish(rsc, sc);
    244 }
    245 
    246 static void SC_ClearColor(float r, float g, float b, float a) {
    247     GET_TLS();
    248     rsrClearColor(rsc, sc, r, g, b, a);
    249 }
    250 
    251 static void SC_ClearDepth(float v) {
    252     GET_TLS();
    253     rsrClearDepth(rsc, sc, v);
    254 }
    255 
    256 static uint32_t SC_GetWidth() {
    257     GET_TLS();
    258     return rsrGetWidth(rsc, sc);
    259 }
    260 
    261 static uint32_t SC_GetHeight() {
    262     GET_TLS();
    263     return rsrGetHeight(rsc, sc);
    264 }
    265 
    266 static void SC_DrawTextAlloc(Allocation *a, int x, int y) {
    267     GET_TLS();
    268     rsrDrawTextAlloc(rsc, sc, a, x, y);
    269 }
    270 
    271 static void SC_DrawText(const char *text, int x, int y) {
    272     GET_TLS();
    273     rsrDrawText(rsc, sc, text, x, y);
    274 }
    275 
    276 static void SC_MeasureTextAlloc(Allocation *a,
    277                          int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
    278     GET_TLS();
    279     rsrMeasureTextAlloc(rsc, sc, a, left, right, top, bottom);
    280 }
    281 
    282 static void SC_MeasureText(const char *text,
    283                     int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
    284     GET_TLS();
    285     rsrMeasureText(rsc, sc, text, left, right, top, bottom);
    286 }
    287 
    288 static void SC_BindFont(Font *f) {
    289     GET_TLS();
    290     rsrBindFont(rsc, sc, f);
    291 }
    292 
    293 static void SC_FontColor(float r, float g, float b, float a) {
    294     GET_TLS();
    295     rsrFontColor(rsc, sc, r, g, b, a);
    296 }
    297 
    298 
    299 
    300 //////////////////////////////////////////////////////////////////////////////
    301 //
    302 //////////////////////////////////////////////////////////////////////////////
    303 
    304 static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
    305     GET_TLS();
    306     rsrSetObject(rsc, sc, dst, src);
    307 }
    308 
    309 static void SC_ClearObject(ObjectBase **dst) {
    310     GET_TLS();
    311     rsrClearObject(rsc, sc, dst);
    312 }
    313 
    314 static bool SC_IsObject(const ObjectBase *src) {
    315     GET_TLS();
    316     return rsrIsObject(rsc, sc, src);
    317 }
    318 
    319 
    320 
    321 
    322 static const Allocation * SC_GetAllocation(const void *ptr) {
    323     GET_TLS();
    324     return rsrGetAllocation(rsc, sc, ptr);
    325 }
    326 
    327 static void SC_ForEach_SAA(Script *target,
    328                             Allocation *in,
    329                             Allocation *out) {
    330     GET_TLS();
    331     rsrForEach(rsc, sc, target, in, out, NULL, 0, NULL);
    332 }
    333 
    334 static void SC_ForEach_SAAU(Script *target,
    335                             Allocation *in,
    336                             Allocation *out,
    337                             const void *usr) {
    338     GET_TLS();
    339     rsrForEach(rsc, sc, target, in, out, usr, 0, NULL);
    340 }
    341 
    342 static void SC_ForEach_SAAUS(Script *target,
    343                              Allocation *in,
    344                              Allocation *out,
    345                              const void *usr,
    346                              const RsScriptCall *call) {
    347     GET_TLS();
    348     rsrForEach(rsc, sc, target, in, out, usr, 0, call);
    349 }
    350 
    351 static void SC_ForEach_SAAUL(Script *target,
    352                              Allocation *in,
    353                              Allocation *out,
    354                              const void *usr,
    355                              uint32_t usrLen) {
    356     GET_TLS();
    357     rsrForEach(rsc, sc, target, in, out, usr, usrLen, NULL);
    358 }
    359 
    360 static void SC_ForEach_SAAULS(Script *target,
    361                               Allocation *in,
    362                               Allocation *out,
    363                               const void *usr,
    364                               uint32_t usrLen,
    365                               const RsScriptCall *call) {
    366     GET_TLS();
    367     rsrForEach(rsc, sc, target, in, out, usr, usrLen, call);
    368 }
    369 
    370 
    371 
    372 //////////////////////////////////////////////////////////////////////////////
    373 // Time routines
    374 //////////////////////////////////////////////////////////////////////////////
    375 
    376 static float SC_GetDt() {
    377     GET_TLS();
    378     return rsrGetDt(rsc, sc);
    379 }
    380 
    381 time_t SC_Time(time_t *timer) {
    382     GET_TLS();
    383     return rsrTime(rsc, sc, timer);
    384 }
    385 
    386 tm* SC_LocalTime(tm *local, time_t *timer) {
    387     GET_TLS();
    388     return rsrLocalTime(rsc, sc, local, timer);
    389 }
    390 
    391 int64_t SC_UptimeMillis() {
    392     GET_TLS();
    393     return rsrUptimeMillis(rsc, sc);
    394 }
    395 
    396 int64_t SC_UptimeNanos() {
    397     GET_TLS();
    398     return rsrUptimeNanos(rsc, sc);
    399 }
    400 
    401 //////////////////////////////////////////////////////////////////////////////
    402 // Message routines
    403 //////////////////////////////////////////////////////////////////////////////
    404 
    405 static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
    406     GET_TLS();
    407     return rsrToClient(rsc, sc, cmdID, data, len);
    408 }
    409 
    410 static uint32_t SC_ToClient(int cmdID) {
    411     GET_TLS();
    412     return rsrToClient(rsc, sc, cmdID, NULL, 0);
    413 }
    414 
    415 static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
    416     GET_TLS();
    417     return rsrToClientBlocking(rsc, sc, cmdID, data, len);
    418 }
    419 
    420 static uint32_t SC_ToClientBlocking(int cmdID) {
    421     GET_TLS();
    422     return rsrToClientBlocking(rsc, sc, cmdID, NULL, 0);
    423 }
    424 
    425 int SC_divsi3(int a, int b) {
    426     return a / b;
    427 }
    428 
    429 int SC_modsi3(int a, int b) {
    430     return a % b;
    431 }
    432 
    433 unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
    434     return a / b;
    435 }
    436 
    437 unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
    438     return a % b;
    439 }
    440 
    441 static void SC_debugF(const char *s, float f) {
    442     LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
    443 }
    444 static void SC_debugFv2(const char *s, float f1, float f2) {
    445     LOGD("%s {%f, %f}", s, f1, f2);
    446 }
    447 static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
    448     LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
    449 }
    450 static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
    451     LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
    452 }
    453 static void SC_debugD(const char *s, double d) {
    454     LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
    455 }
    456 static void SC_debugFM4v4(const char *s, const float *f) {
    457     LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
    458     LOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
    459     LOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
    460     LOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
    461 }
    462 static void SC_debugFM3v3(const char *s, const float *f) {
    463     LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
    464     LOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
    465     LOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
    466 }
    467 static void SC_debugFM2v2(const char *s, const float *f) {
    468     LOGD("%s {%f, %f", s, f[0], f[2]);
    469     LOGD("%s  %f, %f}",s, f[1], f[3]);
    470 }
    471 
    472 static void SC_debugI32(const char *s, int32_t i) {
    473     LOGD("%s %i  0x%x", s, i, i);
    474 }
    475 static void SC_debugU32(const char *s, uint32_t i) {
    476     LOGD("%s %u  0x%x", s, i, i);
    477 }
    478 static void SC_debugLL64(const char *s, long long ll) {
    479     LOGD("%s %lld  0x%llx", s, ll, ll);
    480 }
    481 static void SC_debugULL64(const char *s, unsigned long long ll) {
    482     LOGD("%s %llu  0x%llx", s, ll, ll);
    483 }
    484 
    485 static void SC_debugP(const char *s, const void *p) {
    486     LOGD("%s %p", s, p);
    487 }
    488 
    489 
    490 //////////////////////////////////////////////////////////////////////////////
    491 // Stub implementation
    492 //////////////////////////////////////////////////////////////////////////////
    493 
    494 // llvm name mangling ref
    495 //  <builtin-type> ::= v  # void
    496 //                 ::= b  # bool
    497 //                 ::= c  # char
    498 //                 ::= a  # signed char
    499 //                 ::= h  # unsigned char
    500 //                 ::= s  # short
    501 //                 ::= t  # unsigned short
    502 //                 ::= i  # int
    503 //                 ::= j  # unsigned int
    504 //                 ::= l  # long
    505 //                 ::= m  # unsigned long
    506 //                 ::= x  # long long, __int64
    507 //                 ::= y  # unsigned long long, __int64
    508 //                 ::= f  # float
    509 //                 ::= d  # double
    510 
    511 static RsdSymbolTable gSyms[] = {
    512     { "memset", (void *)&memset, true },
    513     { "memcpy", (void *)&memcpy, true },
    514 
    515     // Refcounting
    516     { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_SetObject, true },
    517     { "_Z13rsClearObjectP10rs_element", (void *)&SC_ClearObject, true },
    518     { "_Z10rsIsObject10rs_element", (void *)&SC_IsObject, true },
    519 
    520     { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_SetObject, true },
    521     { "_Z13rsClearObjectP7rs_type", (void *)&SC_ClearObject, true },
    522     { "_Z10rsIsObject7rs_type", (void *)&SC_IsObject, true },
    523 
    524     { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_SetObject, true },
    525     { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_ClearObject, true },
    526     { "_Z10rsIsObject13rs_allocation", (void *)&SC_IsObject, true },
    527 
    528     { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_SetObject, true },
    529     { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_ClearObject, true },
    530     { "_Z10rsIsObject10rs_sampler", (void *)&SC_IsObject, true },
    531 
    532     { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_SetObject, true },
    533     { "_Z13rsClearObjectP9rs_script", (void *)&SC_ClearObject, true },
    534     { "_Z10rsIsObject9rs_script", (void *)&SC_IsObject, true },
    535 
    536     { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_SetObject, true },
    537     { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_ClearObject, true },
    538     { "_Z10rsIsObject7rs_mesh", (void *)&SC_IsObject, true },
    539 
    540     { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_SetObject, true },
    541     { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_ClearObject, true },
    542     { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_IsObject, true },
    543 
    544     { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_SetObject, true },
    545     { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_ClearObject, true },
    546     { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_IsObject, true },
    547 
    548     { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_SetObject, true },
    549     { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_ClearObject, true },
    550     { "_Z10rsIsObject17rs_program_raster", (void *)&SC_IsObject, true },
    551 
    552     { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_SetObject, true },
    553     { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_ClearObject, true },
    554     { "_Z10rsIsObject16rs_program_store", (void *)&SC_IsObject, true },
    555 
    556     { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_SetObject, true },
    557     { "_Z13rsClearObjectP7rs_font", (void *)&SC_ClearObject, true },
    558     { "_Z10rsIsObject7rs_font", (void *)&SC_IsObject, true },
    559 
    560     // Allocation ops
    561     { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_AllocationSyncAll, true },
    562     { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_AllocationSyncAll, false },
    563     { "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
    564     { "_Z20rsgAllocationSyncAll13rs_allocation24rs_allocation_usage_type", (void *)&SC_AllocationSyncAll2, false },
    565     { "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
    566 
    567     { "_Z23rsAllocationCopy1DRange13rs_allocationjjjS_jj", (void *)&SC_AllocationCopy1DRange, false },
    568     { "_Z23rsAllocationCopy2DRange13rs_allocationjjj26rs_allocation_cubemap_facejjS_jjjS0_", (void *)&SC_AllocationCopy2DRange, false },
    569 
    570     // Messaging
    571 
    572     { "_Z14rsSendToClienti", (void *)&SC_ToClient, false },
    573     { "_Z14rsSendToClientiPKvj", (void *)&SC_ToClient2, false },
    574     { "_Z22rsSendToClientBlockingi", (void *)&SC_ToClientBlocking, false },
    575     { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_ToClientBlocking2, false },
    576 
    577     { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_BindProgramFragment, false },
    578     { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_BindProgramStore, false },
    579     { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_BindProgramVertex, false },
    580     { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_BindProgramRaster, false },
    581     { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_BindSampler, false },
    582     { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_BindTexture, false },
    583 
    584     { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadProjectionMatrix, false },
    585     { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadModelMatrix, false },
    586     { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadTextureMatrix, false },
    587 
    588     { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_VpGetProjectionMatrix, false },
    589 
    590     { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_PfConstantColor, false },
    591 
    592     { "_Z11rsgGetWidthv", (void *)&SC_GetWidth, false },
    593     { "_Z12rsgGetHeightv", (void *)&SC_GetHeight, false },
    594 
    595 
    596     { "_Z11rsgDrawRectfffff", (void *)&SC_DrawRect, false },
    597     { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_DrawQuad, false },
    598     { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_DrawQuadTexCoords, false },
    599     { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_DrawSpriteScreenspace, false },
    600 
    601     { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_DrawMesh, false },
    602     { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_DrawMeshPrimitive, false },
    603     { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_DrawMeshPrimitiveRange, false },
    604     { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_MeshComputeBoundingBox, false },
    605 
    606     { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
    607     { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
    608 
    609     { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
    610     { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
    611     { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
    612     { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
    613 
    614     { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
    615     { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
    616 
    617     { "_Z18rsgBindColorTarget13rs_allocationj", (void *)&SC_BindFrameBufferObjectColorTarget, false },
    618     { "_Z18rsgBindDepthTarget13rs_allocation", (void *)&SC_BindFrameBufferObjectDepthTarget, false },
    619     { "_Z19rsgClearColorTargetj", (void *)&SC_ClearFrameBufferObjectColorTarget, false },
    620     { "_Z19rsgClearDepthTargetv", (void *)&SC_ClearFrameBufferObjectDepthTarget, false },
    621     { "_Z24rsgClearAllRenderTargetsv", (void *)&SC_ClearFrameBufferObjectTargets, false },
    622 
    623     { "_Z9rsForEach9rs_script13rs_allocationS0_", (void *)&SC_ForEach_SAA, false },
    624     { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach_SAAU, false },
    625     { "_Z9rsForEach9rs_script13rs_allocationS0_PKvPK16rs_script_call_t", (void *)&SC_ForEach_SAAUS, false },
    626     { "_Z9rsForEach9rs_script13rs_allocationS0_PKvj", (void *)&SC_ForEach_SAAUL, false },
    627     { "_Z9rsForEach9rs_script13rs_allocationS0_PKvjPK16rs_script_call_t", (void *)&SC_ForEach_SAAULS, false },
    628 
    629     // time
    630     { "_Z6rsTimePi", (void *)&SC_Time, true },
    631     { "_Z11rsLocaltimeP5rs_tmPKi", (void *)&SC_LocalTime, true },
    632     { "_Z14rsUptimeMillisv", (void*)&SC_UptimeMillis, true },
    633     { "_Z13rsUptimeNanosv", (void*)&SC_UptimeNanos, true },
    634     { "_Z7rsGetDtv", (void*)&SC_GetDt, false },
    635 
    636     // misc
    637     { "_Z5colorffff", (void *)&SC_Color, false },
    638     { "_Z9rsgFinishv", (void *)&SC_Finish, false },
    639 
    640     // Debug
    641     { "_Z7rsDebugPKcf", (void *)&SC_debugF, true },
    642     { "_Z7rsDebugPKcff", (void *)&SC_debugFv2, true },
    643     { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3, true },
    644     { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4, true },
    645     { "_Z7rsDebugPKcd", (void *)&SC_debugD, true },
    646     { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4, true },
    647     { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3, true },
    648     { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2, true },
    649     { "_Z7rsDebugPKci", (void *)&SC_debugI32, true },
    650     { "_Z7rsDebugPKcj", (void *)&SC_debugU32, true },
    651     // Both "long" and "unsigned long" need to be redirected to their
    652     // 64-bit counterparts, since we have hacked Slang to use 64-bit
    653     // for "long" on Arm (to be similar to Java).
    654     { "_Z7rsDebugPKcl", (void *)&SC_debugLL64, true },
    655     { "_Z7rsDebugPKcm", (void *)&SC_debugULL64, true },
    656     { "_Z7rsDebugPKcx", (void *)&SC_debugLL64, true },
    657     { "_Z7rsDebugPKcy", (void *)&SC_debugULL64, true },
    658     { "_Z7rsDebugPKcPKv", (void *)&SC_debugP, true },
    659 
    660     { NULL, NULL, false }
    661 };
    662 
    663 
    664 void* rsdLookupRuntimeStub(void* pContext, char const* name) {
    665     ScriptC *s = (ScriptC *)pContext;
    666     if (!strcmp(name, "__isThreadable")) {
    667       return (void*) s->mHal.info.isThreadable;
    668     } else if (!strcmp(name, "__clearThreadable")) {
    669       s->mHal.info.isThreadable = false;
    670       return NULL;
    671     }
    672 
    673     RsdSymbolTable *syms = gSyms;
    674     const RsdSymbolTable *sym = rsdLookupSymbolMath(name);
    675 
    676     if (!sym) {
    677         while (syms->mPtr) {
    678             if (!strcmp(syms->mName, name)) {
    679                 sym = syms;
    680             }
    681             syms++;
    682         }
    683     }
    684 
    685     if (sym) {
    686         s->mHal.info.isThreadable &= sym->threadable;
    687         return sym->mPtr;
    688     }
    689     LOGE("ScriptC sym lookup failed for %s", name);
    690     return NULL;
    691 }
    692 
    693 
    694