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