rsdRuntimeStubs.cpp revision 1e5149f5cd3e75a010b58b985b1151d955d227d1
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
31using namespace android;
32using 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
46static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
47    GET_TLS();
48    rsrAllocationSyncAll(rsc, sc, a, source);
49}
50
51static void SC_AllocationSyncAll(Allocation *a) {
52    GET_TLS();
53    rsrAllocationSyncAll(rsc, sc, a, RS_ALLOCATION_USAGE_SCRIPT);
54}
55
56static 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
67static 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
87static void SC_BindTexture(ProgramFragment *pf, uint32_t slot, Allocation *a) {
88    GET_TLS();
89    rsrBindTexture(rsc, sc, pf, slot, a);
90}
91
92static void SC_BindSampler(ProgramFragment *pf, uint32_t slot, Sampler *s) {
93    GET_TLS();
94    rsrBindSampler(rsc, sc, pf, slot, s);
95}
96
97static void SC_BindProgramStore(ProgramStore *ps) {
98    GET_TLS();
99    rsrBindProgramStore(rsc, sc, ps);
100}
101
102static void SC_BindProgramFragment(ProgramFragment *pf) {
103    GET_TLS();
104    rsrBindProgramFragment(rsc, sc, pf);
105}
106
107static void SC_BindProgramVertex(ProgramVertex *pv) {
108    GET_TLS();
109    rsrBindProgramVertex(rsc, sc, pv);
110}
111
112static void SC_BindProgramRaster(ProgramRaster *pr) {
113    GET_TLS();
114    rsrBindProgramRaster(rsc, sc, pr);
115}
116
117static void SC_BindFrameBufferObjectColorTarget(Allocation *a, uint32_t slot) {
118    GET_TLS();
119    rsrBindFrameBufferObjectColorTarget(rsc, sc, a, slot);
120}
121
122static void SC_BindFrameBufferObjectDepthTarget(Allocation *a) {
123    GET_TLS();
124    rsrBindFrameBufferObjectDepthTarget(rsc, sc, a);
125}
126
127static void SC_ClearFrameBufferObjectColorTarget(uint32_t slot) {
128    GET_TLS();
129    rsrClearFrameBufferObjectColorTarget(rsc, sc, slot);
130}
131
132static void SC_ClearFrameBufferObjectDepthTarget(Context *, Script *) {
133    GET_TLS();
134    rsrClearFrameBufferObjectDepthTarget(rsc, sc);
135}
136
137static void SC_ClearFrameBufferObjectTargets(Context *, Script *) {
138    GET_TLS();
139    rsrClearFrameBufferObjectTargets(rsc, sc);
140}
141
142
143//////////////////////////////////////////////////////////////////////////////
144// VP
145//////////////////////////////////////////////////////////////////////////////
146
147static void SC_VpLoadProjectionMatrix(const rsc_Matrix *m) {
148    GET_TLS();
149    rsrVpLoadProjectionMatrix(rsc, sc, m);
150}
151
152static void SC_VpLoadModelMatrix(const rsc_Matrix *m) {
153    GET_TLS();
154    rsrVpLoadModelMatrix(rsc, sc, m);
155}
156
157static void SC_VpLoadTextureMatrix(const rsc_Matrix *m) {
158    GET_TLS();
159    rsrVpLoadTextureMatrix(rsc, sc, m);
160}
161
162static 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
167static void SC_VpGetProjectionMatrix(rsc_Matrix *m) {
168    GET_TLS();
169    rsrVpGetProjectionMatrix(rsc, sc, m);
170}
171
172
173//////////////////////////////////////////////////////////////////////////////
174// Drawing
175//////////////////////////////////////////////////////////////////////////////
176
177static 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
189static 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
197static 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
202static 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
207static void SC_DrawMesh(Mesh *m) {
208    GET_TLS();
209    rsrDrawMesh(rsc, sc, m);
210}
211
212static void SC_DrawMeshPrimitive(Mesh *m, uint32_t primIndex) {
213    GET_TLS();
214    rsrDrawMeshPrimitive(rsc, sc, m, primIndex);
215}
216
217static 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
222static 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
236static void SC_Color(float r, float g, float b, float a) {
237    GET_TLS();
238    rsrColor(rsc, sc, r, g, b, a);
239}
240
241static void SC_Finish() {
242    GET_TLS();
243    rsrFinish(rsc, sc);
244}
245
246static void SC_ClearColor(float r, float g, float b, float a) {
247    GET_TLS();
248    rsrClearColor(rsc, sc, r, g, b, a);
249}
250
251static void SC_ClearDepth(float v) {
252    GET_TLS();
253    rsrClearDepth(rsc, sc, v);
254}
255
256static uint32_t SC_GetWidth() {
257    GET_TLS();
258    return rsrGetWidth(rsc, sc);
259}
260
261static uint32_t SC_GetHeight() {
262    GET_TLS();
263    return rsrGetHeight(rsc, sc);
264}
265
266static void SC_DrawTextAlloc(Allocation *a, int x, int y) {
267    GET_TLS();
268    rsrDrawTextAlloc(rsc, sc, a, x, y);
269}
270
271static void SC_DrawText(const char *text, int x, int y) {
272    GET_TLS();
273    rsrDrawText(rsc, sc, text, x, y);
274}
275
276static 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
282static 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
288static void SC_BindFont(Font *f) {
289    GET_TLS();
290    rsrBindFont(rsc, sc, f);
291}
292
293static 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
304static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
305    GET_TLS();
306    rsrSetObject(rsc, sc, dst, src);
307}
308
309static void SC_ClearObject(ObjectBase **dst) {
310    GET_TLS();
311    rsrClearObject(rsc, sc, dst);
312}
313
314static bool SC_IsObject(const ObjectBase *src) {
315    GET_TLS();
316    return rsrIsObject(rsc, sc, src);
317}
318
319
320
321
322static const Allocation * SC_GetAllocation(const void *ptr) {
323    GET_TLS();
324    return rsrGetAllocation(rsc, sc, ptr);
325}
326
327static 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
334static 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
342static 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
351static 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
360static 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
376static float SC_GetDt() {
377    GET_TLS();
378    return rsrGetDt(rsc, sc);
379}
380
381time_t SC_Time(time_t *timer) {
382    GET_TLS();
383    return rsrTime(rsc, sc, timer);
384}
385
386tm* SC_LocalTime(tm *local, time_t *timer) {
387    GET_TLS();
388    return rsrLocalTime(rsc, sc, local, timer);
389}
390
391int64_t SC_UptimeMillis() {
392    GET_TLS();
393    return rsrUptimeMillis(rsc, sc);
394}
395
396int64_t SC_UptimeNanos() {
397    GET_TLS();
398    return rsrUptimeNanos(rsc, sc);
399}
400
401//////////////////////////////////////////////////////////////////////////////
402// Message routines
403//////////////////////////////////////////////////////////////////////////////
404
405static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
406    GET_TLS();
407    return rsrToClient(rsc, sc, cmdID, data, len);
408}
409
410static uint32_t SC_ToClient(int cmdID) {
411    GET_TLS();
412    return rsrToClient(rsc, sc, cmdID, NULL, 0);
413}
414
415static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
416    GET_TLS();
417    return rsrToClientBlocking(rsc, sc, cmdID, data, len);
418}
419
420static uint32_t SC_ToClientBlocking(int cmdID) {
421    GET_TLS();
422    return rsrToClientBlocking(rsc, sc, cmdID, NULL, 0);
423}
424
425int SC_divsi3(int a, int b) {
426    return a / b;
427}
428
429int SC_modsi3(int a, int b) {
430    return a % b;
431}
432
433unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
434    return a / b;
435}
436
437unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
438    return a % b;
439}
440
441static void SC_debugF(const char *s, float f) {
442    LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
443}
444static void SC_debugFv2(const char *s, float f1, float f2) {
445    LOGD("%s {%f, %f}", s, f1, f2);
446}
447static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
448    LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
449}
450static 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}
453static void SC_debugD(const char *s, double d) {
454    LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
455}
456static 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}
462static 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}
467static 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
472static void SC_debugI32(const char *s, int32_t i) {
473    LOGD("%s %i  0x%x", s, i, i);
474}
475static void SC_debugU32(const char *s, uint32_t i) {
476    LOGD("%s %u  0x%x", s, i, i);
477}
478static void SC_debugLL64(const char *s, long long ll) {
479    LOGD("%s %lld  0x%llx", s, ll, ll);
480}
481static void SC_debugULL64(const char *s, unsigned long long ll) {
482    LOGD("%s %llu  0x%llx", s, ll, ll);
483}
484
485static 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
511static 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
664void* 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