rsdRuntimeStubs.cpp revision 87fe59a2f4d4c74539bfa0bff5f9a7e320e99415
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 "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(Context::gThreadTLSKey); \
36    Context * rsc = tls->mContext; \
37    ScriptC * sc = (ScriptC *) tls->mScript
38
39
40
41//////////////////////////////////////////////////////////////////////////////
42// Allocation
43//////////////////////////////////////////////////////////////////////////////
44
45static uint32_t SC_allocGetDimX(Allocation *a) {
46    LOGE("SC_allocGetDimX %p", a);
47    return a->mHal.state.dimensionX;
48}
49
50static uint32_t SC_allocGetDimY(Allocation *a) {
51    return a->mHal.state.dimensionY;
52}
53
54static uint32_t SC_allocGetDimZ(Allocation *a) {
55    return a->mHal.state.dimensionZ;
56}
57
58static uint32_t SC_allocGetDimLOD(Allocation *a) {
59    return a->mHal.state.hasMipmaps;
60}
61
62static uint32_t SC_allocGetDimFaces(Allocation *a) {
63    return a->mHal.state.hasFaces;
64}
65
66static const void * SC_getElementAtX(Allocation *a, uint32_t x) {
67    const uint8_t *p = (const uint8_t *)a->getPtr();
68    return &p[a->mHal.state.elementSizeBytes * x];
69}
70
71static const void * SC_getElementAtXY(Allocation *a, uint32_t x, uint32_t y) {
72    const uint8_t *p = (const uint8_t *)a->getPtr();
73    return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX)];
74}
75
76static const void * SC_getElementAtXYZ(Allocation *a, uint32_t x, uint32_t y, uint32_t z) {
77    const uint8_t *p = (const uint8_t *)a->getPtr();
78    return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX +
79              z * a->mHal.state.dimensionX * a->mHal.state.dimensionY)];
80}
81
82static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
83    GET_TLS();
84    rsrAllocationSyncAll(rsc, sc, a, source);
85}
86
87static void SC_AllocationSyncAll(Allocation *a) {
88    GET_TLS();
89    rsrAllocationSyncAll(rsc, sc, a, RS_ALLOCATION_USAGE_SCRIPT);
90}
91
92const Allocation * SC_getAllocation(const void *ptr) {
93    GET_TLS();
94    return rsrGetAllocation(rsc, sc, ptr);
95}
96
97
98//////////////////////////////////////////////////////////////////////////////
99// Context
100//////////////////////////////////////////////////////////////////////////////
101
102static void SC_BindTexture(ProgramFragment *pf, uint32_t slot, Allocation *a) {
103    GET_TLS();
104    rsrBindTexture(rsc, sc, pf, slot, a);
105}
106
107static void SC_BindSampler(ProgramFragment *pf, uint32_t slot, Sampler *s) {
108    GET_TLS();
109    rsrBindSampler(rsc, sc, pf, slot, s);
110}
111
112static void SC_BindProgramStore(ProgramStore *ps) {
113    GET_TLS();
114    rsrBindProgramStore(rsc, sc, ps);
115}
116
117static void SC_BindProgramFragment(ProgramFragment *pf) {
118    GET_TLS();
119    rsrBindProgramFragment(rsc, sc, pf);
120}
121
122static void SC_BindProgramVertex(ProgramVertex *pv) {
123    GET_TLS();
124    rsrBindProgramVertex(rsc, sc, pv);
125}
126
127static void SC_BindProgramRaster(ProgramRaster *pr) {
128    GET_TLS();
129    rsrBindProgramRaster(rsc, sc, pr);
130}
131
132static void SC_BindFrameBufferObjectColorTarget(Allocation *a, uint32_t slot) {
133    GET_TLS();
134    rsrBindFrameBufferObjectColorTarget(rsc, sc, a, slot);
135}
136
137static void SC_BindFrameBufferObjectDepthTarget(Allocation *a) {
138    GET_TLS();
139    rsrBindFrameBufferObjectDepthTarget(rsc, sc, a);
140}
141
142static void SC_ClearFrameBufferObjectColorTarget(uint32_t slot) {
143    GET_TLS();
144    rsrClearFrameBufferObjectColorTarget(rsc, sc, slot);
145}
146
147static void SC_ClearFrameBufferObjectDepthTarget(Context *, Script *) {
148    GET_TLS();
149    rsrClearFrameBufferObjectDepthTarget(rsc, sc);
150}
151
152static void SC_ClearFrameBufferObjectTargets(Context *, Script *) {
153    GET_TLS();
154    rsrClearFrameBufferObjectTargets(rsc, sc);
155}
156
157
158//////////////////////////////////////////////////////////////////////////////
159// VP
160//////////////////////////////////////////////////////////////////////////////
161
162static void SC_VpLoadProjectionMatrix(const rsc_Matrix *m) {
163    GET_TLS();
164    rsrVpLoadProjectionMatrix(rsc, sc, m);
165}
166
167static void SC_VpLoadModelMatrix(const rsc_Matrix *m) {
168    GET_TLS();
169    rsrVpLoadModelMatrix(rsc, sc, m);
170}
171
172static void SC_VpLoadTextureMatrix(const rsc_Matrix *m) {
173    GET_TLS();
174    rsrVpLoadTextureMatrix(rsc, sc, m);
175}
176
177static void SC_PfConstantColor(ProgramFragment *pf, float r, float g, float b, float a) {
178    GET_TLS();
179    rsrPfConstantColor(rsc, sc, pf, r, g, b, a);
180}
181
182static void SC_VpGetProjectionMatrix(rsc_Matrix *m) {
183    GET_TLS();
184    rsrVpGetProjectionMatrix(rsc, sc, m);
185}
186
187
188//////////////////////////////////////////////////////////////////////////////
189// Drawing
190//////////////////////////////////////////////////////////////////////////////
191
192static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
193                                 float x2, float y2, float z2, float u2, float v2,
194                                 float x3, float y3, float z3, float u3, float v3,
195                                 float x4, float y4, float z4, float u4, float v4) {
196    GET_TLS();
197    rsrDrawQuadTexCoords(rsc, sc,
198                         x1, y1, z1, u1, v1,
199                         x2, y2, z2, u2, v2,
200                         x3, y3, z3, u3, v3,
201                         x4, y4, z4, u4, v4);
202}
203
204static void SC_DrawQuad(float x1, float y1, float z1,
205                        float x2, float y2, float z2,
206                        float x3, float y3, float z3,
207                        float x4, float y4, float z4) {
208    GET_TLS();
209    rsrDrawQuad(rsc, sc, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4);
210}
211
212static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) {
213    GET_TLS();
214    rsrDrawSpriteScreenspace(rsc, sc, x, y, z, w, h);
215}
216
217static void SC_DrawRect(float x1, float y1, float x2, float y2, float z) {
218    GET_TLS();
219    rsrDrawRect(rsc, sc, x1, y1, x2, y2, z);
220}
221
222static void SC_DrawMesh(Mesh *m) {
223    GET_TLS();
224    rsrDrawMesh(rsc, sc, m);
225}
226
227static void SC_DrawMeshPrimitive(Mesh *m, uint32_t primIndex) {
228    GET_TLS();
229    rsrDrawMeshPrimitive(rsc, sc, m, primIndex);
230}
231
232static void SC_DrawMeshPrimitiveRange(Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
233    GET_TLS();
234    rsrDrawMeshPrimitiveRange(rsc, sc, m, primIndex, start, len);
235}
236
237static void SC_MeshComputeBoundingBox(Mesh *m,
238                               float *minX, float *minY, float *minZ,
239                               float *maxX, float *maxY, float *maxZ) {
240    GET_TLS();
241    rsrMeshComputeBoundingBox(rsc, sc, m, minX, minY, minZ, maxX, maxY, maxZ);
242}
243
244
245
246//////////////////////////////////////////////////////////////////////////////
247//
248//////////////////////////////////////////////////////////////////////////////
249
250
251static void SC_Color(float r, float g, float b, float a) {
252    GET_TLS();
253    rsrColor(rsc, sc, r, g, b, a);
254}
255
256static void SC_Finish() {
257    GET_TLS();
258    rsrFinish(rsc, sc);
259}
260
261static void SC_ClearColor(float r, float g, float b, float a) {
262    GET_TLS();
263    rsrClearColor(rsc, sc, r, g, b, a);
264}
265
266static void SC_ClearDepth(float v) {
267    GET_TLS();
268    rsrClearDepth(rsc, sc, v);
269}
270
271static uint32_t SC_GetWidth() {
272    GET_TLS();
273    return rsrGetWidth(rsc, sc);
274}
275
276static uint32_t SC_GetHeight() {
277    GET_TLS();
278    return rsrGetHeight(rsc, sc);
279}
280
281static void SC_DrawTextAlloc(Allocation *a, int x, int y) {
282    GET_TLS();
283    rsrDrawTextAlloc(rsc, sc, a, x, y);
284}
285
286static void SC_DrawText(const char *text, int x, int y) {
287    GET_TLS();
288    rsrDrawText(rsc, sc, text, x, y);
289}
290
291static void SC_MeasureTextAlloc(Allocation *a,
292                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
293    GET_TLS();
294    rsrMeasureTextAlloc(rsc, sc, a, left, right, top, bottom);
295}
296
297static void SC_MeasureText(const char *text,
298                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
299    GET_TLS();
300    rsrMeasureText(rsc, sc, text, left, right, top, bottom);
301}
302
303static void SC_BindFont(Font *f) {
304    GET_TLS();
305    rsrBindFont(rsc, sc, f);
306}
307
308static void SC_FontColor(float r, float g, float b, float a) {
309    GET_TLS();
310    rsrFontColor(rsc, sc, r, g, b, a);
311}
312
313
314
315//////////////////////////////////////////////////////////////////////////////
316//
317//////////////////////////////////////////////////////////////////////////////
318
319static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
320    GET_TLS();
321    rsrSetObject(rsc, sc, dst, src);
322}
323
324static void SC_ClearObject(ObjectBase **dst) {
325    GET_TLS();
326    rsrClearObject(rsc, sc, dst);
327}
328
329static bool SC_IsObject(const ObjectBase *src) {
330    GET_TLS();
331    return rsrIsObject(rsc, sc, src);
332}
333
334
335
336
337static const Allocation * SC_GetAllocation(const void *ptr) {
338    GET_TLS();
339    return rsrGetAllocation(rsc, sc, ptr);
340}
341
342static void SC_ForEach(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, NULL);
349}
350
351static void SC_ForEach2(Script *target,
352                 Allocation *in,
353                 Allocation *out,
354                 const void *usr,
355                 const RsScriptCall *call) {
356    GET_TLS();
357    rsrForEach(rsc, sc, target, in, out, usr, 0, call);
358}
359
360
361
362//////////////////////////////////////////////////////////////////////////////
363// Time routines
364//////////////////////////////////////////////////////////////////////////////
365
366static float SC_GetDt() {
367    GET_TLS();
368    return rsrGetDt(rsc, sc);
369}
370
371time_t SC_Time(time_t *timer) {
372    GET_TLS();
373    return rsrTime(rsc, sc, timer);
374}
375
376tm* SC_LocalTime(tm *local, time_t *timer) {
377    GET_TLS();
378    return rsrLocalTime(rsc, sc, local, timer);
379}
380
381int64_t SC_UptimeMillis() {
382    GET_TLS();
383    return rsrUptimeMillis(rsc, sc);
384}
385
386int64_t SC_UptimeNanos() {
387    GET_TLS();
388    return rsrUptimeNanos(rsc, sc);
389}
390
391//////////////////////////////////////////////////////////////////////////////
392// Message routines
393//////////////////////////////////////////////////////////////////////////////
394
395static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
396    GET_TLS();
397    return rsrToClient(rsc, sc, cmdID, data, len);
398}
399
400static uint32_t SC_ToClient(int cmdID) {
401    GET_TLS();
402    return rsrToClient(rsc, sc, cmdID, NULL, 0);
403}
404
405static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
406    GET_TLS();
407    return rsrToClientBlocking(rsc, sc, cmdID, data, len);
408}
409
410static uint32_t SC_ToClientBlocking(int cmdID) {
411    GET_TLS();
412    return rsrToClientBlocking(rsc, sc, cmdID, NULL, 0);
413}
414
415int SC_divsi3(int a, int b) {
416    return a / b;
417}
418
419int SC_modsi3(int a, int b) {
420    return a % b;
421}
422
423unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
424    return a / b;
425}
426
427unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
428    return a % b;
429}
430
431static void SC_debugF(const char *s, float f) {
432    LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
433}
434static void SC_debugFv2(const char *s, float f1, float f2) {
435    LOGD("%s {%f, %f}", s, f1, f2);
436}
437static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
438    LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
439}
440static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
441    LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
442}
443static void SC_debugD(const char *s, double d) {
444    LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
445}
446static void SC_debugFM4v4(const char *s, const float *f) {
447    LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
448    LOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
449    LOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
450    LOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
451}
452static void SC_debugFM3v3(const char *s, const float *f) {
453    LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
454    LOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
455    LOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
456}
457static void SC_debugFM2v2(const char *s, const float *f) {
458    LOGD("%s {%f, %f", s, f[0], f[2]);
459    LOGD("%s  %f, %f}",s, f[1], f[3]);
460}
461
462static void SC_debugI32(const char *s, int32_t i) {
463    LOGD("%s %i  0x%x", s, i, i);
464}
465static void SC_debugU32(const char *s, uint32_t i) {
466    LOGD("%s %u  0x%x", s, i, i);
467}
468static void SC_debugLL64(const char *s, long long ll) {
469    LOGD("%s %lld  0x%llx", s, ll, ll);
470}
471static void SC_debugULL64(const char *s, unsigned long long ll) {
472    LOGD("%s %llu  0x%llx", s, ll, ll);
473}
474
475static void SC_debugP(const char *s, const void *p) {
476    LOGD("%s %p", s, p);
477}
478
479
480//////////////////////////////////////////////////////////////////////////////
481// Stub implementation
482//////////////////////////////////////////////////////////////////////////////
483
484// llvm name mangling ref
485//  <builtin-type> ::= v  # void
486//                 ::= b  # bool
487//                 ::= c  # char
488//                 ::= a  # signed char
489//                 ::= h  # unsigned char
490//                 ::= s  # short
491//                 ::= t  # unsigned short
492//                 ::= i  # int
493//                 ::= j  # unsigned int
494//                 ::= l  # long
495//                 ::= m  # unsigned long
496//                 ::= x  # long long, __int64
497//                 ::= y  # unsigned long long, __int64
498//                 ::= f  # float
499//                 ::= d  # double
500
501static RsdSymbolTable gSyms[] = {
502    { "__divsi3", (void *)&SC_divsi3, true },
503    { "__modsi3", (void *)&SC_modsi3, true },
504    { "__udivsi3", (void *)&SC_udivsi3, true },
505    { "__umodsi3", (void *)&SC_umodsi3, true },
506    { "memset", (void *)&memset, true },
507    { "memcpy", (void *)&memcpy, true },
508
509    // Refcounting
510    { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_SetObject, true },
511    { "_Z13rsClearObjectP10rs_element", (void *)&SC_ClearObject, true },
512    { "_Z10rsIsObject10rs_element", (void *)&SC_IsObject, true },
513
514    { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_SetObject, true },
515    { "_Z13rsClearObjectP7rs_type", (void *)&SC_ClearObject, true },
516    { "_Z10rsIsObject7rs_type", (void *)&SC_IsObject, true },
517
518    { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_SetObject, true },
519    { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_ClearObject, true },
520    { "_Z10rsIsObject13rs_allocation", (void *)&SC_IsObject, true },
521
522    { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_SetObject, true },
523    { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_ClearObject, true },
524    { "_Z10rsIsObject10rs_sampler", (void *)&SC_IsObject, true },
525
526    { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_SetObject, true },
527    { "_Z13rsClearObjectP9rs_script", (void *)&SC_ClearObject, true },
528    { "_Z10rsIsObject9rs_script", (void *)&SC_IsObject, true },
529
530    { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_SetObject, true },
531    { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_ClearObject, true },
532    { "_Z10rsIsObject7rs_mesh", (void *)&SC_IsObject, true },
533
534    { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_SetObject, true },
535    { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_ClearObject, true },
536    { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_IsObject, true },
537
538    { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_SetObject, true },
539    { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_ClearObject, true },
540    { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_IsObject, true },
541
542    { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_SetObject, true },
543    { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_ClearObject, true },
544    { "_Z10rsIsObject17rs_program_raster", (void *)&SC_IsObject, true },
545
546    { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_SetObject, true },
547    { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_ClearObject, true },
548    { "_Z10rsIsObject16rs_program_store", (void *)&SC_IsObject, true },
549
550    { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_SetObject, true },
551    { "_Z13rsClearObjectP7rs_font", (void *)&SC_ClearObject, true },
552    { "_Z10rsIsObject7rs_font", (void *)&SC_IsObject, true },
553
554    // Allocation ops
555    { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
556    { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY, true },
557    { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ, true },
558    { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD, true },
559    { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces, true },
560
561    { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX, true },
562    { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true },
563    { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true },
564
565    { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation, true },
566
567    { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_AllocationSyncAll, true },
568    { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_AllocationSyncAll, false },
569    { "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
570    { "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
571
572
573    // Messaging
574
575    { "_Z14rsSendToClienti", (void *)&SC_ToClient, false },
576    { "_Z14rsSendToClientiPKvj", (void *)&SC_ToClient2, false },
577    { "_Z22rsSendToClientBlockingi", (void *)&SC_ToClientBlocking, false },
578    { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_ToClientBlocking2, false },
579
580    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_BindProgramFragment, false },
581    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_BindProgramStore, false },
582    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_BindProgramVertex, false },
583    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_BindProgramRaster, false },
584    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_BindSampler, false },
585    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_BindTexture, false },
586
587    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadProjectionMatrix, false },
588    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadModelMatrix, false },
589    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadTextureMatrix, false },
590
591    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_VpGetProjectionMatrix, false },
592
593    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_PfConstantColor, false },
594
595    { "_Z11rsgGetWidthv", (void *)&SC_GetWidth, false },
596    { "_Z12rsgGetHeightv", (void *)&SC_GetHeight, false },
597
598
599    { "_Z11rsgDrawRectfffff", (void *)&SC_DrawRect, false },
600    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_DrawQuad, false },
601    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_DrawQuadTexCoords, false },
602    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_DrawSpriteScreenspace, false },
603
604    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_DrawMesh, false },
605    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_DrawMeshPrimitive, false },
606    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_DrawMeshPrimitiveRange, false },
607    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_MeshComputeBoundingBox, false },
608
609    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
610    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
611
612    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
613    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
614    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
615    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
616
617    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
618    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
619
620    { "_Z18rsgBindColorTarget13rs_allocationj", (void *)&SC_BindFrameBufferObjectColorTarget, false },
621    { "_Z18rsgBindDepthTarget13rs_allocation", (void *)&SC_BindFrameBufferObjectDepthTarget, false },
622    { "_Z19rsgClearColorTargetj", (void *)&SC_ClearFrameBufferObjectColorTarget, false },
623    { "_Z19rsgClearDepthTargetv", (void *)&SC_ClearFrameBufferObjectDepthTarget, false },
624    { "_Z24rsgClearAllRenderTargetsv", (void *)&SC_ClearFrameBufferObjectTargets, false },
625
626    { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false },
627    { "_Z9rsForEach9rs_script13rs_allocationS0_PKvj", (void *)&SC_ForEach2, 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