rsdRuntimeStubs.cpp revision 9479e5bf0152ecff022cd374e2e80905f88b1a5d
1/*
2 * Copyright (C) 2011-2012 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 "rsdCore.h"
25#include "rsdBcc.h"
26
27#include "rsdAllocation.h"
28#include "rsdShaderCache.h"
29#include "rsdVertexArray.h"
30
31#include <time.h>
32
33using namespace android;
34using namespace android::renderscript;
35
36typedef float float2 __attribute__((ext_vector_type(2)));
37typedef float float3 __attribute__((ext_vector_type(3)));
38typedef float float4 __attribute__((ext_vector_type(4)));
39typedef double double2 __attribute__((ext_vector_type(2)));
40typedef double double3 __attribute__((ext_vector_type(3)));
41typedef double double4 __attribute__((ext_vector_type(4)));
42typedef char char2 __attribute__((ext_vector_type(2)));
43typedef char char3 __attribute__((ext_vector_type(3)));
44typedef char char4 __attribute__((ext_vector_type(4)));
45typedef unsigned char uchar2 __attribute__((ext_vector_type(2)));
46typedef unsigned char uchar3 __attribute__((ext_vector_type(3)));
47typedef unsigned char uchar4 __attribute__((ext_vector_type(4)));
48typedef int16_t short2 __attribute__((ext_vector_type(2)));
49typedef int16_t short3 __attribute__((ext_vector_type(3)));
50typedef int16_t short4 __attribute__((ext_vector_type(4)));
51typedef uint16_t ushort2 __attribute__((ext_vector_type(2)));
52typedef uint16_t ushort3 __attribute__((ext_vector_type(3)));
53typedef uint16_t ushort4 __attribute__((ext_vector_type(4)));
54typedef int32_t int2 __attribute__((ext_vector_type(2)));
55typedef int32_t int3 __attribute__((ext_vector_type(3)));
56typedef int32_t int4 __attribute__((ext_vector_type(4)));
57typedef uint32_t uint2 __attribute__((ext_vector_type(2)));
58typedef uint32_t uint3 __attribute__((ext_vector_type(3)));
59typedef uint32_t uint4 __attribute__((ext_vector_type(4)));
60typedef int64_t long2 __attribute__((ext_vector_type(2)));
61typedef int64_t long3 __attribute__((ext_vector_type(3)));
62typedef int64_t long4 __attribute__((ext_vector_type(4)));
63typedef uint64_t ulong2 __attribute__((ext_vector_type(2)));
64typedef uint64_t ulong3 __attribute__((ext_vector_type(3)));
65typedef uint64_t ulong4 __attribute__((ext_vector_type(4)));
66
67typedef uint8_t uchar;
68typedef uint16_t ushort;
69typedef uint32_t uint;
70#ifndef RS_SERVER
71typedef uint64_t ulong;
72#endif
73
74#ifndef __LP64__
75#define OPAQUETYPE(t) \
76    typedef struct { const int* const p; } __attribute__((packed, aligned(4))) t;
77#else
78#define OPAQUETYPE(t) \
79    typedef struct { const void* p; const void* r; const void* v1; const void* v2; } t;
80#endif
81
82OPAQUETYPE(rs_element)
83OPAQUETYPE(rs_type)
84OPAQUETYPE(rs_allocation)
85OPAQUETYPE(rs_sampler)
86OPAQUETYPE(rs_script)
87OPAQUETYPE(rs_script_call)
88
89OPAQUETYPE(rs_program_fragment);
90OPAQUETYPE(rs_program_store);
91OPAQUETYPE(rs_program_vertex);
92OPAQUETYPE(rs_program_raster);
93OPAQUETYPE(rs_mesh);
94OPAQUETYPE(rs_font);
95
96#undef OPAQUETYPE
97
98typedef enum {
99    // Empty to avoid conflicting definitions with RsAllocationCubemapFace
100} rs_allocation_cubemap_face;
101
102typedef struct { unsigned int val; } rs_allocation_usage_type;
103
104typedef struct {
105    int tm_sec;     ///< seconds
106    int tm_min;     ///< minutes
107    int tm_hour;    ///< hours
108    int tm_mday;    ///< day of the month
109    int tm_mon;     ///< month
110    int tm_year;    ///< year
111    int tm_wday;    ///< day of the week
112    int tm_yday;    ///< day of the year
113    int tm_isdst;   ///< daylight savings time
114} rs_tm;
115
116// Some RS functions are not threadsafe but can be called from an invoke
117// function.  Instead of summarily marking scripts that call these functions as
118// not-threadable we detect calls to them in the driver and sends a fatal error
119// message.
120static bool failIfInKernel(Context *rsc, const char *funcName) {
121    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
122    RsdCpuReference *impl = (RsdCpuReference *) dc->mCpuRef;
123
124    if (impl->getInForEach()) {
125        char buf[256];
126        sprintf(buf, "Error: Call to unsupported function %s "
127                         "in kernel", funcName);
128        rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
129        return true;
130    }
131    return false;
132}
133
134//////////////////////////////////////////////////////////////////////////////
135// Allocation routines
136//////////////////////////////////////////////////////////////////////////////
137#ifdef __i386__
138// i386 has different struct return passing to ARM; emulate with a pointer
139const Allocation * rsGetAllocation(const void *ptr) {
140    Context *rsc = RsdCpuReference::getTlsContext();
141    const Script *sc = RsdCpuReference::getTlsScript();
142    Allocation* alloc = rsdScriptGetAllocationForPointer(rsc, sc, ptr);
143    android::renderscript::rs_allocation obj = {0};
144    alloc->callUpdateCacheObject(rsc, &obj);
145    return (Allocation *)obj.p;
146}
147#else
148const android::renderscript::rs_allocation rsGetAllocation(const void *ptr) {
149    Context *rsc = RsdCpuReference::getTlsContext();
150    const Script *sc = RsdCpuReference::getTlsScript();
151    Allocation* alloc = rsdScriptGetAllocationForPointer(rsc, sc, ptr);
152
153#ifndef __LP64__ // ARMv7/MIPS
154    android::renderscript::rs_allocation obj = {0};
155#else // AArch64/x86_64/MIPS64
156    android::renderscript::rs_allocation obj = {0, 0, 0, 0};
157#endif
158    alloc->callUpdateCacheObject(rsc, &obj);
159    return obj;
160}
161#endif
162
163void __attribute__((overloadable)) rsAllocationIoSend(::rs_allocation a) {
164    Context *rsc = RsdCpuReference::getTlsContext();
165    if (failIfInKernel(rsc, "rsAllocationIoSend"))
166        return;
167    rsrAllocationIoSend(rsc, (Allocation *)a.p);
168}
169
170void __attribute__((overloadable)) rsAllocationIoReceive(::rs_allocation a) {
171    Context *rsc = RsdCpuReference::getTlsContext();
172    if (failIfInKernel(rsc, "rsAllocationIoReceive"))
173        return;
174    rsrAllocationIoReceive(rsc, (Allocation *)a.p);
175}
176
177void __attribute__((overloadable)) rsAllocationCopy1DRange(
178        ::rs_allocation dstAlloc,
179        uint32_t dstOff, uint32_t dstMip, uint32_t count,
180        ::rs_allocation srcAlloc,
181        uint32_t srcOff, uint32_t srcMip) {
182    Context *rsc = RsdCpuReference::getTlsContext();
183    if (failIfInKernel(rsc, "rsAllocationCopy1DRange"))
184        return;
185    rsrAllocationCopy1DRange(rsc, (Allocation *)dstAlloc.p, dstOff, dstMip,
186                             count, (Allocation *)srcAlloc.p, srcOff, srcMip);
187}
188
189void __attribute__((overloadable)) rsAllocationCopy2DRange(
190        ::rs_allocation dstAlloc,
191        uint32_t dstXoff, uint32_t dstYoff,
192        uint32_t dstMip, rs_allocation_cubemap_face dstFace,
193        uint32_t width, uint32_t height,
194        ::rs_allocation srcAlloc,
195        uint32_t srcXoff, uint32_t srcYoff,
196        uint32_t srcMip, rs_allocation_cubemap_face srcFace) {
197    Context *rsc = RsdCpuReference::getTlsContext();
198    if (failIfInKernel(rsc, "rsAllocationCopy2DRange"))
199        return;
200    rsrAllocationCopy2DRange(rsc, (Allocation *)dstAlloc.p,
201                             dstXoff, dstYoff, dstMip, dstFace,
202                             width, height, (Allocation *)srcAlloc.p,
203                             srcXoff, srcYoff, srcMip, srcFace);
204}
205
206//////////////////////////////////////////////////////////////////////////////
207// Object routines
208//////////////////////////////////////////////////////////////////////////////
209#define IS_CLEAR_SET_OBJ(t) \
210    bool rsIsObject(t src) { \
211        return src.p != nullptr; \
212    } \
213    void __attribute__((overloadable)) rsClearObject(t *dst) { \
214        Context *rsc = RsdCpuReference::getTlsContext(); \
215        rsrClearObject(rsc, reinterpret_cast<rs_object_base *>(dst)); \
216    } \
217    void __attribute__((overloadable)) rsSetObject(t *dst, t src) { \
218        Context *rsc = RsdCpuReference::getTlsContext(); \
219        rsrSetObject(rsc, reinterpret_cast<rs_object_base *>(dst), (ObjectBase*)src.p); \
220    }
221
222IS_CLEAR_SET_OBJ(::rs_element)
223IS_CLEAR_SET_OBJ(::rs_type)
224IS_CLEAR_SET_OBJ(::rs_allocation)
225IS_CLEAR_SET_OBJ(::rs_sampler)
226IS_CLEAR_SET_OBJ(::rs_script)
227
228IS_CLEAR_SET_OBJ(::rs_mesh)
229IS_CLEAR_SET_OBJ(::rs_program_fragment)
230IS_CLEAR_SET_OBJ(::rs_program_vertex)
231IS_CLEAR_SET_OBJ(::rs_program_raster)
232IS_CLEAR_SET_OBJ(::rs_program_store)
233IS_CLEAR_SET_OBJ(::rs_font)
234
235#undef IS_CLEAR_SET_OBJ
236
237//////////////////////////////////////////////////////////////////////////////
238// Element routines
239//////////////////////////////////////////////////////////////////////////////
240static void * ElementAt(Allocation *a, RsDataType dt, uint32_t vecSize,
241                        uint32_t x, uint32_t y, uint32_t z) {
242    Context *rsc = RsdCpuReference::getTlsContext();
243    const Type *t = a->getType();
244    const Element *e = t->getElement();
245
246    char buf[256];
247    if (x && (x >= t->getLODDimX(0))) {
248        sprintf(buf, "Out range ElementAt X %i of %i", x, t->getLODDimX(0));
249        rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
250        return nullptr;
251    }
252
253    if (y && (y >= t->getLODDimY(0))) {
254        sprintf(buf, "Out range ElementAt Y %i of %i", y, t->getLODDimY(0));
255        rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
256        return nullptr;
257    }
258
259    if (z && (z >= t->getLODDimZ(0))) {
260        sprintf(buf, "Out range ElementAt Z %i of %i", z, t->getLODDimZ(0));
261        rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
262        return nullptr;
263    }
264
265    if (vecSize > 0) {
266        if (vecSize != e->getVectorSize()) {
267            sprintf(buf, "Vector size mismatch for ElementAt %i of %i", vecSize, e->getVectorSize());
268            rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
269            return nullptr;
270        }
271
272        if (dt != e->getType()) {
273            sprintf(buf, "Data type mismatch for ElementAt %i of %i", dt, e->getType());
274            rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
275            return nullptr;
276        }
277    }
278
279    uint8_t *p = (uint8_t *)a->mHal.drvState.lod[0].mallocPtr;
280    const uint32_t eSize = e->getSizeBytes();
281    const uint32_t stride = a->mHal.drvState.lod[0].stride;
282    const uint32_t dimY = a->mHal.drvState.lod[0].dimY;
283    return &p[(x * eSize) + (y * stride) + (z * stride * dimY)];
284}
285
286void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y, uint32_t z) {
287    const Type *t = const_cast<Allocation*>((Allocation*)a.p)->getType();
288    const Element *e = t->getElement();
289    void *tmp = ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
290    if (tmp != nullptr)
291        memcpy(tmp, ptr, e->getSizeBytes());
292}
293
294void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y) {
295    rsSetElementAt(a, ptr, x, y, 0);
296}
297
298void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x) {
299    rsSetElementAt(a, ptr, x, 0, 0);
300}
301
302const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
303    return ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
304}
305
306const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y) {
307    return rsGetElementAt(a, x, y ,0);
308}
309
310const void *rsGetElementAt(::rs_allocation a, uint32_t x) {
311    return rsGetElementAt(a, x, 0, 0);
312}
313
314#define ELEMENT_AT(T, DT, VS) \
315    void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, uint32_t y, uint32_t z) { \
316        void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \
317        if (r != nullptr) ((T *)r)[0] = *val; \
318        else ALOGE("Error from %s", __PRETTY_FUNCTION__); \
319    } \
320    void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, uint32_t y) { \
321        rsSetElementAt_##T(a, val, x, y, 0); \
322    } \
323    void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x) { \
324        rsSetElementAt_##T(a, val, x, 0, 0); \
325    } \
326    void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y, uint32_t z) { \
327        void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \
328        if (r != nullptr) *val = ((T *)r)[0]; \
329        else ALOGE("Error from %s", __PRETTY_FUNCTION__); \
330    } \
331    void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y) { \
332        rsGetElementAt_##T(a, val, x, y, 0); \
333    } \
334    void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x) { \
335        rsGetElementAt_##T(a, val, x, 0, 0); \
336    }
337
338ELEMENT_AT(char, RS_TYPE_SIGNED_8, 1)
339ELEMENT_AT(char2, RS_TYPE_SIGNED_8, 2)
340ELEMENT_AT(char3, RS_TYPE_SIGNED_8, 3)
341ELEMENT_AT(char4, RS_TYPE_SIGNED_8, 4)
342ELEMENT_AT(uchar, RS_TYPE_UNSIGNED_8, 1)
343ELEMENT_AT(uchar2, RS_TYPE_UNSIGNED_8, 2)
344ELEMENT_AT(uchar3, RS_TYPE_UNSIGNED_8, 3)
345ELEMENT_AT(uchar4, RS_TYPE_UNSIGNED_8, 4)
346ELEMENT_AT(short, RS_TYPE_SIGNED_16, 1)
347ELEMENT_AT(short2, RS_TYPE_SIGNED_16, 2)
348ELEMENT_AT(short3, RS_TYPE_SIGNED_16, 3)
349ELEMENT_AT(short4, RS_TYPE_SIGNED_16, 4)
350ELEMENT_AT(ushort, RS_TYPE_UNSIGNED_16, 1)
351ELEMENT_AT(ushort2, RS_TYPE_UNSIGNED_16, 2)
352ELEMENT_AT(ushort3, RS_TYPE_UNSIGNED_16, 3)
353ELEMENT_AT(ushort4, RS_TYPE_UNSIGNED_16, 4)
354ELEMENT_AT(int, RS_TYPE_SIGNED_32, 1)
355ELEMENT_AT(int2, RS_TYPE_SIGNED_32, 2)
356ELEMENT_AT(int3, RS_TYPE_SIGNED_32, 3)
357ELEMENT_AT(int4, RS_TYPE_SIGNED_32, 4)
358ELEMENT_AT(uint, RS_TYPE_UNSIGNED_32, 1)
359ELEMENT_AT(uint2, RS_TYPE_UNSIGNED_32, 2)
360ELEMENT_AT(uint3, RS_TYPE_UNSIGNED_32, 3)
361ELEMENT_AT(uint4, RS_TYPE_UNSIGNED_32, 4)
362ELEMENT_AT(long, RS_TYPE_SIGNED_64, 1)
363ELEMENT_AT(long2, RS_TYPE_SIGNED_64, 2)
364ELEMENT_AT(long3, RS_TYPE_SIGNED_64, 3)
365ELEMENT_AT(long4, RS_TYPE_SIGNED_64, 4)
366ELEMENT_AT(ulong, RS_TYPE_UNSIGNED_64, 1)
367ELEMENT_AT(ulong2, RS_TYPE_UNSIGNED_64, 2)
368ELEMENT_AT(ulong3, RS_TYPE_UNSIGNED_64, 3)
369ELEMENT_AT(ulong4, RS_TYPE_UNSIGNED_64, 4)
370ELEMENT_AT(float, RS_TYPE_FLOAT_32, 1)
371ELEMENT_AT(float2, RS_TYPE_FLOAT_32, 2)
372ELEMENT_AT(float3, RS_TYPE_FLOAT_32, 3)
373ELEMENT_AT(float4, RS_TYPE_FLOAT_32, 4)
374ELEMENT_AT(double, RS_TYPE_FLOAT_64, 1)
375ELEMENT_AT(double2, RS_TYPE_FLOAT_64, 2)
376ELEMENT_AT(double3, RS_TYPE_FLOAT_64, 3)
377ELEMENT_AT(double4, RS_TYPE_FLOAT_64, 4)
378
379#undef ELEMENT_AT
380
381#ifndef __LP64__
382/*
383 * We miss some symbols for rs{Get,Set}Element_long,ulong variants because 64
384 * bit integer values are 'long' in RS-land but might be 'long long' in the
385 * driver.  Define native_long* and native_ulong* types to be vectors of
386 * 'long' as seen by the driver and define overloaded versions of
387 * rsSetElementAt_* and rsGetElementAt_*.  This should get us the correct
388 * mangled names in the driver.
389 */
390
391typedef long native_long2 __attribute__((ext_vector_type(2)));
392typedef long native_long3 __attribute__((ext_vector_type(3)));
393typedef long native_long4 __attribute__((ext_vector_type(4)));
394typedef unsigned long native_ulong2 __attribute__((ext_vector_type(2)));
395typedef unsigned long native_ulong3 __attribute__((ext_vector_type(3)));
396typedef unsigned long native_ulong4 __attribute__((ext_vector_type(4)));
397
398#define ELEMENT_AT_OVERLOADS(T, U) \
399    void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, uint32_t y, uint32_t z) { \
400        rsSetElementAt_##T(a, (T *) val, x, y, z); \
401    } \
402    void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, uint32_t y) { \
403        rsSetElementAt_##T(a, (T *) val, x, y, 0); \
404    } \
405    void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x) { \
406        rsSetElementAt_##T(a, (T *) val, x, 0, 0); \
407    } \
408    void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y, uint32_t z) { \
409        rsGetElementAt_##T(a, (T *) val, x, y, z); \
410    } \
411    void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y) { \
412        rsGetElementAt_##T(a, (T *) val, x, y, 0); \
413    } \
414    void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x) { \
415        rsGetElementAt_##T(a, (T *) val, x, 0, 0); \
416    } \
417
418ELEMENT_AT_OVERLOADS(long2, native_long2)
419ELEMENT_AT_OVERLOADS(long3, native_long3)
420ELEMENT_AT_OVERLOADS(long4, native_long4)
421ELEMENT_AT_OVERLOADS(ulong, unsigned long)
422ELEMENT_AT_OVERLOADS(ulong2, native_ulong2)
423ELEMENT_AT_OVERLOADS(ulong3, native_ulong3)
424ELEMENT_AT_OVERLOADS(ulong4, native_ulong4)
425
426// We also need variants of rs{Get,Set}ElementAt_long that take 'long long *' as
427// we might have this overloaded variant in old APKs.
428ELEMENT_AT_OVERLOADS(long, long long)
429
430#undef ELEMENT_AT_OVERLOADS
431#endif
432
433//////////////////////////////////////////////////////////////////////////////
434// ForEach routines
435//////////////////////////////////////////////////////////////////////////////
436void __attribute__((overloadable)) rsForEach(::rs_script script,
437                                             ::rs_allocation in,
438                                             ::rs_allocation out,
439                                             const void *usr,
440                                             const rs_script_call *call) {
441    Context *rsc = RsdCpuReference::getTlsContext();
442    rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p,
443               (Allocation *)out.p, usr, 0, (RsScriptCall *)call);
444}
445
446void __attribute__((overloadable)) rsForEach(::rs_script script,
447                                             ::rs_allocation in,
448                                             ::rs_allocation out,
449                                             const void *usr) {
450    Context *rsc = RsdCpuReference::getTlsContext();
451    rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
452               usr, 0, nullptr);
453}
454
455void __attribute__((overloadable)) rsForEach(::rs_script script,
456                                             ::rs_allocation in,
457                                             ::rs_allocation out) {
458    Context *rsc = RsdCpuReference::getTlsContext();
459    rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
460               nullptr, 0, nullptr);
461}
462
463// These functions are only supported in 32-bit.
464#ifndef __LP64__
465void __attribute__((overloadable)) rsForEach(::rs_script script,
466                                             ::rs_allocation in,
467                                             ::rs_allocation out,
468                                             const void *usr,
469                                             uint32_t usrLen) {
470    Context *rsc = RsdCpuReference::getTlsContext();
471    rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
472               usr, usrLen, nullptr);
473}
474
475void __attribute__((overloadable)) rsForEach(::rs_script script,
476                                             ::rs_allocation in,
477                                             ::rs_allocation out,
478                                             const void *usr,
479                                             uint32_t usrLen,
480                                             const rs_script_call *call) {
481    Context *rsc = RsdCpuReference::getTlsContext();
482    rsrForEach(rsc, (Script *)script.p, (Allocation *)in.p, (Allocation *)out.p,
483               usr, usrLen, (RsScriptCall *)call);
484}
485#endif
486
487//////////////////////////////////////////////////////////////////////////////
488// Message routines
489//////////////////////////////////////////////////////////////////////////////
490uint32_t rsSendToClient(int cmdID) {
491    Context *rsc = RsdCpuReference::getTlsContext();
492    return rsrToClient(rsc, cmdID, (const void *)nullptr, 0);
493}
494
495uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) {
496    Context *rsc = RsdCpuReference::getTlsContext();
497    return rsrToClient(rsc, cmdID, data, len);
498}
499
500uint32_t rsSendToClientBlocking(int cmdID) {
501    Context *rsc = RsdCpuReference::getTlsContext();
502    return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0);
503}
504
505uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) {
506    Context *rsc = RsdCpuReference::getTlsContext();
507    return rsrToClientBlocking(rsc, cmdID, data, len);
508}
509
510//////////////////////////////////////////////////////////////////////////////
511// Time routines
512//////////////////////////////////////////////////////////////////////////////
513
514// time_t is int in 32-bit RenderScript.  time_t is long in bionic.  rsTime and
515// rsLocaltime are set to explicitly take 'const int *' so we generate the
516// correct mangled names.
517#ifndef __LP64__
518int rsTime(int *timer) {
519#else
520time_t rsTime(time_t * timer) {
521#endif
522    Context *rsc = RsdCpuReference::getTlsContext();
523    return rsrTime(rsc, (time_t *)timer);
524}
525
526#ifndef __LP64__
527rs_tm* rsLocaltime(rs_tm* local, const int *timer) {
528#else
529rs_tm* rsLocaltime(rs_tm* local, const time_t *timer) {
530#endif
531    Context *rsc = RsdCpuReference::getTlsContext();
532    return (rs_tm*)rsrLocalTime(rsc, (tm*)local, (time_t *)timer);
533}
534
535int64_t rsUptimeMillis() {
536    Context *rsc = RsdCpuReference::getTlsContext();
537    return rsrUptimeMillis(rsc);
538}
539
540int64_t rsUptimeNanos() {
541    Context *rsc = RsdCpuReference::getTlsContext();
542    return rsrUptimeNanos(rsc);
543}
544
545float rsGetDt() {
546    Context *rsc = RsdCpuReference::getTlsContext();
547    const Script *sc = RsdCpuReference::getTlsScript();
548    return rsrGetDt(rsc, sc);
549}
550
551//////////////////////////////////////////////////////////////////////////////
552// Graphics routines
553//////////////////////////////////////////////////////////////////////////////
554#ifndef RS_COMPATIBILITY_LIB
555static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
556                                 float x2, float y2, float z2, float u2, float v2,
557                                 float x3, float y3, float z3, float u3, float v3,
558                                 float x4, float y4, float z4, float u4, float v4) {
559    Context *rsc = RsdCpuReference::getTlsContext();
560
561    if (!rsc->setupCheck()) {
562        return;
563    }
564
565    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
566    if (!dc->gl.shaderCache->setup(rsc)) {
567        return;
568    }
569
570    //ALOGE("Quad");
571    //ALOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
572    //ALOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
573    //ALOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
574    //ALOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
575
576    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
577    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
578
579    RsdVertexArray::Attrib attribs[2];
580    attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position");
581    attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0");
582
583    RsdVertexArray va(attribs, 2);
584    va.setup(rsc);
585
586    RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
587}
588
589static void SC_DrawQuad(float x1, float y1, float z1,
590                        float x2, float y2, float z2,
591                        float x3, float y3, float z3,
592                        float x4, float y4, float z4) {
593    SC_DrawQuadTexCoords(x1, y1, z1, 0, 1,
594                         x2, y2, z2, 1, 1,
595                         x3, y3, z3, 1, 0,
596                         x4, y4, z4, 0, 0);
597}
598
599static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) {
600    Context *rsc = RsdCpuReference::getTlsContext();
601
602    ObjectBaseRef<const ProgramVertex> tmp(rsc->getProgramVertex());
603    rsc->setProgramVertex(rsc->getDefaultProgramVertex());
604    //rsc->setupCheck();
605
606    //GLint crop[4] = {0, h, w, -h};
607
608    float sh = rsc->getHeight();
609
610    SC_DrawQuad(x,   sh - y,     z,
611                x+w, sh - y,     z,
612                x+w, sh - (y+h), z,
613                x,   sh - (y+h), z);
614    rsc->setProgramVertex((ProgramVertex *)tmp.get());
615}
616
617void rsAllocationMarkDirty(::rs_allocation a) {
618    Context *rsc = RsdCpuReference::getTlsContext();
619    rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT);
620}
621
622void rsgAllocationSyncAll(::rs_allocation a) {
623    Context *rsc = RsdCpuReference::getTlsContext();
624    rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT);
625}
626
627void rsgAllocationSyncAll(::rs_allocation a,
628                          unsigned int usage) {
629    Context *rsc = RsdCpuReference::getTlsContext();
630    rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)usage);
631}
632
633
634void rsgAllocationSyncAll(::rs_allocation a,
635                          rs_allocation_usage_type source) {
636    Context *rsc = RsdCpuReference::getTlsContext();
637    rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)source.val);
638}
639
640void rsgBindProgramFragment(::rs_program_fragment pf) {
641    Context *rsc = RsdCpuReference::getTlsContext();
642    rsrBindProgramFragment(rsc, (ProgramFragment *)pf.p);
643}
644
645void rsgBindProgramStore(::rs_program_store ps) {
646    Context *rsc = RsdCpuReference::getTlsContext();
647    rsrBindProgramStore(rsc, (ProgramStore *)ps.p);
648}
649
650void rsgBindProgramVertex(::rs_program_vertex pv) {
651    Context *rsc = RsdCpuReference::getTlsContext();
652    rsrBindProgramVertex(rsc, (ProgramVertex *)pv.p);
653}
654
655void rsgBindProgramRaster(::rs_program_raster pr) {
656    Context *rsc = RsdCpuReference::getTlsContext();
657    rsrBindProgramRaster(rsc, (ProgramRaster *)pr.p);
658}
659
660void rsgBindSampler(::rs_program_fragment pf,
661                    uint32_t slot, ::rs_sampler s) {
662    Context *rsc = RsdCpuReference::getTlsContext();
663    rsrBindSampler(rsc, (ProgramFragment *)pf.p, slot, (Sampler *)s.p);
664}
665
666void rsgBindTexture(::rs_program_fragment pf,
667                    uint32_t slot, ::rs_allocation a) {
668    Context *rsc = RsdCpuReference::getTlsContext();
669    rsrBindTexture(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p);
670}
671
672void rsgBindConstant(::rs_program_fragment pf,
673                     uint32_t slot, ::rs_allocation a) {
674    Context *rsc = RsdCpuReference::getTlsContext();
675    rsrBindConstant(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p);
676}
677
678void rsgBindConstant(::rs_program_vertex pv,
679                     uint32_t slot, ::rs_allocation a) {
680    Context *rsc = RsdCpuReference::getTlsContext();
681    rsrBindConstant(rsc, (ProgramVertex *)pv.p, slot, (Allocation *)a.p);
682}
683
684void rsgProgramVertexLoadProjectionMatrix(const rs_matrix4x4 *m) {
685    Context *rsc = RsdCpuReference::getTlsContext();
686    rsrVpLoadProjectionMatrix(rsc, (const rsc_Matrix *)m);
687}
688
689void rsgProgramVertexLoadModelMatrix(const rs_matrix4x4 *m) {
690    Context *rsc = RsdCpuReference::getTlsContext();
691    rsrVpLoadModelMatrix(rsc, (const rsc_Matrix *)m);
692}
693
694void rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *m) {
695    Context *rsc = RsdCpuReference::getTlsContext();
696    rsrVpLoadTextureMatrix(rsc, (const rsc_Matrix *)m);
697}
698
699void rsgProgramVertexGetProjectionMatrix(rs_matrix4x4 *m) {
700    Context *rsc = RsdCpuReference::getTlsContext();
701    rsrVpGetProjectionMatrix(rsc, (rsc_Matrix *)m);
702}
703
704void rsgProgramFragmentConstantColor(::rs_program_fragment pf,
705                                     float r, float g, float b, float a) {
706    Context *rsc = RsdCpuReference::getTlsContext();
707    rsrPfConstantColor(rsc, (ProgramFragment *)pf.p, r, g, b, a);
708}
709
710uint32_t rsgGetWidth(void) {
711    Context *rsc = RsdCpuReference::getTlsContext();
712    return rsrGetWidth(rsc);
713}
714
715uint32_t rsgGetHeight(void) {
716    Context *rsc = RsdCpuReference::getTlsContext();
717    return rsrGetHeight(rsc);
718}
719
720void rsgDrawRect(float x1, float y1, float x2, float y2, float z) {
721    SC_DrawQuad(x1, y2, z,
722                x2, y2, z,
723                x2, y1, z,
724                x1, y1, z);
725}
726
727void rsgDrawQuad(float x1, float y1, float z1,
728                 float x2, float y2, float z2,
729                 float x3, float y3, float z3,
730                 float x4, float y4, float z4) {
731    SC_DrawQuad(x1, y1, z1,
732                x2, y2, z2,
733                x3, y3, z3,
734                x4, y4, z4);
735}
736
737void rsgDrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
738                          float x2, float y2, float z2, float u2, float v2,
739                          float x3, float y3, float z3, float u3, float v3,
740                          float x4, float y4, float z4, float u4, float v4) {
741    SC_DrawQuadTexCoords(x1, y1, z1, u1, v1,
742                         x2, y2, z2, u2, v2,
743                         x3, y3, z3, u3, v3,
744                         x4, y4, z4, u4, v4);
745}
746
747void rsgDrawSpriteScreenspace(float x, float y, float z, float w, float h) {
748    SC_DrawSpriteScreenspace(x, y, z, w, h);
749}
750
751void rsgDrawMesh(::rs_mesh ism) {
752    Context *rsc = RsdCpuReference::getTlsContext();
753    rsrDrawMesh(rsc, (Mesh *)ism.p);
754}
755
756void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex) {
757    Context *rsc = RsdCpuReference::getTlsContext();
758    rsrDrawMeshPrimitive(rsc, (Mesh *)ism.p, primitiveIndex);
759}
760
761void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex, uint start, uint len) {
762    Context *rsc = RsdCpuReference::getTlsContext();
763    rsrDrawMeshPrimitiveRange(rsc, (Mesh *)ism.p, primitiveIndex, start, len);
764}
765
766void  rsgMeshComputeBoundingBox(::rs_mesh mesh,
767                                float *minX, float *minY, float *minZ,
768                                float *maxX, float *maxY, float *maxZ) {
769    Context *rsc = RsdCpuReference::getTlsContext();
770    rsrMeshComputeBoundingBox(rsc, (Mesh *)mesh.p, minX, minY, minZ, maxX, maxY, maxZ);
771}
772
773void rsgClearColor(float r, float g, float b, float a) {
774    Context *rsc = RsdCpuReference::getTlsContext();
775    rsrPrepareClear(rsc);
776    rsdGLClearColor(rsc, r, g, b, a);
777}
778
779void rsgClearDepth(float value) {
780    Context *rsc = RsdCpuReference::getTlsContext();
781    rsrPrepareClear(rsc);
782    rsdGLClearDepth(rsc, value);
783}
784
785void rsgDrawText(const char *text, int x, int y) {
786    Context *rsc = RsdCpuReference::getTlsContext();
787    rsrDrawText(rsc, text, x, y);
788}
789
790void rsgDrawText(::rs_allocation a, int x, int y) {
791    Context *rsc = RsdCpuReference::getTlsContext();
792    rsrDrawTextAlloc(rsc, (Allocation *)a.p, x, y);
793}
794
795void rsgMeasureText(const char *text, int *left, int *right,
796                    int *top, int *bottom) {
797    Context *rsc = RsdCpuReference::getTlsContext();
798    rsrMeasureText(rsc, text, left, right, top, bottom);
799}
800
801void rsgMeasureText(::rs_allocation a, int *left, int *right,
802                    int *top, int *bottom) {
803    Context *rsc = RsdCpuReference::getTlsContext();
804    rsrMeasureTextAlloc(rsc, (Allocation *)a.p, left, right, top, bottom);
805}
806
807void rsgBindFont(::rs_font font) {
808    Context *rsc = RsdCpuReference::getTlsContext();
809    rsrBindFont(rsc, (Font *)font.p);
810}
811
812void rsgFontColor(float r, float g, float b, float a) {
813    Context *rsc = RsdCpuReference::getTlsContext();
814    rsrFontColor(rsc, r, g, b, a);
815}
816
817void rsgBindColorTarget(::rs_allocation a, uint slot) {
818    Context *rsc = RsdCpuReference::getTlsContext();
819    rsrBindFrameBufferObjectColorTarget(rsc, (Allocation *)a.p, slot);
820}
821
822void rsgBindDepthTarget(::rs_allocation a) {
823    Context *rsc = RsdCpuReference::getTlsContext();
824    rsrBindFrameBufferObjectDepthTarget(rsc, (Allocation *)a.p);
825}
826
827void rsgClearColorTarget(uint slot) {
828    Context *rsc = RsdCpuReference::getTlsContext();
829    rsrClearFrameBufferObjectColorTarget(rsc, slot);
830}
831
832void rsgClearDepthTarget(void) {
833    Context *rsc = RsdCpuReference::getTlsContext();
834    rsrClearFrameBufferObjectDepthTarget(rsc);
835}
836
837void rsgClearAllRenderTargets(void) {
838    Context *rsc = RsdCpuReference::getTlsContext();
839    rsrClearFrameBufferObjectTargets(rsc);
840}
841
842void color(float r, float g, float b, float a) {
843    Context *rsc = RsdCpuReference::getTlsContext();
844    rsrColor(rsc, r, g, b, a);
845}
846
847void rsgFinish(void) {
848    Context *rsc = RsdCpuReference::getTlsContext();
849    rsdGLFinish(rsc);
850}
851#endif
852
853//////////////////////////////////////////////////////////////////////////////
854// Debug routines
855//////////////////////////////////////////////////////////////////////////////
856void rsDebug(const char *s, float f) {
857    ALOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
858}
859
860void rsDebug(const char *s, float f1, float f2) {
861    ALOGD("%s {%f, %f}", s, f1, f2);
862}
863
864void rsDebug(const char *s, float f1, float f2, float f3) {
865    ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
866}
867
868void rsDebug(const char *s, float f1, float f2, float f3, float f4) {
869    ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
870}
871
872void rsDebug(const char *s, const float2 *f2) {
873    float2 f = *f2;
874    ALOGD("%s {%f, %f}", s, f.x, f.y);
875}
876
877void rsDebug(const char *s, const float3 *f3) {
878    float3 f = *f3;
879    ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
880}
881
882void rsDebug(const char *s, const float4 *f4) {
883    float4 f = *f4;
884    ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
885}
886
887void rsDebug(const char *s, double d) {
888    ALOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
889}
890
891void rsDebug(const char *s, const double2 *d2) {
892    double2 d = *d2;
893    ALOGD("%s {%f, %f}", s, d.x, d.y);
894}
895
896void rsDebug(const char *s, const double3 *d3) {
897    double3 d = *d3;
898    ALOGD("%s {%f, %f, %f}", s, d.x, d.y, d.z);
899}
900
901void rsDebug(const char *s, const double4 *d4) {
902    double4 d = *d4;
903    ALOGD("%s {%f, %f, %f, %f}", s, d.x, d.y, d.z, d.w);
904}
905
906void rsDebug(const char *s, const rs_matrix4x4 *m) {
907    float *f = (float *)m;
908    ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
909    ALOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
910    ALOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
911    ALOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
912}
913
914void rsDebug(const char *s, const rs_matrix3x3 *m) {
915    float *f = (float *)m;
916    ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
917    ALOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
918    ALOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
919}
920
921void rsDebug(const char *s, const rs_matrix2x2 *m) {
922    float *f = (float *)m;
923    ALOGD("%s {%f, %f", s, f[0], f[2]);
924    ALOGD("%s  %f, %f}",s, f[1], f[3]);
925}
926
927void rsDebug(const char *s, char c) {
928    ALOGD("%s %hhd  0x%hhx", s, c, (unsigned char)c);
929}
930
931void rsDebug(const char *s, const char2 *c2) {
932    char2 c = *c2;
933    ALOGD("%s {%hhd, %hhd}  0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x, (unsigned char)c.y);
934}
935
936void rsDebug(const char *s, const char3 *c3) {
937    char3 c = *c3;
938    ALOGD("%s {%hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z);
939}
940
941void rsDebug(const char *s, const char4 *c4) {
942    char4 c = *c4;
943    ALOGD("%s {%hhd, %hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z, (unsigned char)c.w);
944}
945
946void rsDebug(const char *s, unsigned char c) {
947    ALOGD("%s %hhu  0x%hhx", s, c, c);
948}
949
950void rsDebug(const char *s, const uchar2 *c2) {
951    uchar2 c = *c2;
952    ALOGD("%s {%hhu, %hhu}  0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
953}
954
955void rsDebug(const char *s, const uchar3 *c3) {
956    uchar3 c = *c3;
957    ALOGD("%s {%hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x, c.y, c.z);
958}
959
960void rsDebug(const char *s, const uchar4 *c4) {
961    uchar4 c = *c4;
962    ALOGD("%s {%hhu, %hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
963}
964
965void rsDebug(const char *s, short c) {
966    ALOGD("%s %hd  0x%hx", s, c, c);
967}
968
969void rsDebug(const char *s, const short2 *c2) {
970    short2 c = *c2;
971    ALOGD("%s {%hd, %hd}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
972}
973
974void rsDebug(const char *s, const short3 *c3) {
975    short3 c = *c3;
976    ALOGD("%s {%hd, %hd, %hd}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
977}
978
979void rsDebug(const char *s, const short4 *c4) {
980    short4 c = *c4;
981    ALOGD("%s {%hd, %hd, %hd, %hd}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
982}
983
984void rsDebug(const char *s, unsigned short c) {
985    ALOGD("%s %hu  0x%hx", s, c, c);
986}
987
988void rsDebug(const char *s, const ushort2 *c2) {
989    ushort2 c = *c2;
990    ALOGD("%s {%hu, %hu}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
991}
992
993void rsDebug(const char *s, const ushort3 *c3) {
994    ushort3 c = *c3;
995    ALOGD("%s {%hu, %hu, %hu}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
996}
997
998void rsDebug(const char *s, const ushort4 *c4) {
999    ushort4 c = *c4;
1000    ALOGD("%s {%hu, %hu, %hu, %hu}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
1001}
1002
1003void rsDebug(const char *s, int i) {
1004    ALOGD("%s %d  0x%x", s, i, i);
1005}
1006
1007void rsDebug(const char *s, const int2 *i2) {
1008    int2 i = *i2;
1009    ALOGD("%s {%d, %d}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
1010}
1011
1012void rsDebug(const char *s, const int3 *i3) {
1013    int3 i = *i3;
1014    ALOGD("%s {%d, %d, %d}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
1015}
1016
1017void rsDebug(const char *s, const int4 *i4) {
1018    int4 i = *i4;
1019    ALOGD("%s {%d, %d, %d, %d}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
1020}
1021
1022void rsDebug(const char *s, unsigned int i) {
1023    ALOGD("%s %u  0x%x", s, i, i);
1024}
1025
1026void rsDebug(const char *s, const uint2 *i2) {
1027    uint2 i = *i2;
1028    ALOGD("%s {%u, %u}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
1029}
1030
1031void rsDebug(const char *s, const uint3 *i3) {
1032    uint3 i = *i3;
1033    ALOGD("%s {%u, %u, %u}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
1034}
1035
1036void rsDebug(const char *s, const uint4 *i4) {
1037    uint4 i = *i4;
1038    ALOGD("%s {%u, %u, %u, %u}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
1039}
1040
1041template <typename T>
1042static inline long long LL(const T &x) {
1043    return static_cast<long long>(x);
1044}
1045
1046template <typename T>
1047static inline unsigned long long LLu(const T &x) {
1048    return static_cast<unsigned long long>(x);
1049}
1050
1051void rsDebug(const char *s, long l) {
1052    ALOGD("%s %lld  0x%llx", s, LL(l), LL(l));
1053}
1054
1055void rsDebug(const char *s, long long ll) {
1056    ALOGD("%s %lld  0x%llx", s, LL(ll), LL(ll));
1057}
1058
1059void rsDebug(const char *s, const long2 *c) {
1060    long2 ll = *c;
1061    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1062}
1063
1064void rsDebug(const char *s, const long3 *c) {
1065    long3 ll = *c;
1066    ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
1067}
1068
1069void rsDebug(const char *s, const long4 *c) {
1070    long4 ll = *c;
1071    ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
1072}
1073
1074void rsDebug(const char *s, unsigned long l) {
1075    unsigned long long ll = l;
1076    ALOGD("%s %llu  0x%llx", s, ll, ll);
1077}
1078
1079void rsDebug(const char *s, unsigned long long ll) {
1080    ALOGD("%s %llu  0x%llx", s, ll, ll);
1081}
1082
1083void rsDebug(const char *s, const ulong2 *c) {
1084    ulong2 ll = *c;
1085    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y));
1086}
1087
1088void rsDebug(const char *s, const ulong3 *c) {
1089    ulong3 ll = *c;
1090    ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
1091}
1092
1093void rsDebug(const char *s, const ulong4 *c) {
1094    ulong4 ll = *c;
1095    ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w));
1096}
1097
1098// FIXME: We need to export these function signatures for the compatibility
1099// library. The C++ name mangling that LLVM uses for ext_vector_type requires
1100// different versions for "long" vs. "long long". Note that the called
1101// functions are still using the appropriate 64-bit sizes.
1102
1103#ifndef __LP64__
1104typedef long l2 __attribute__((ext_vector_type(2)));
1105typedef long l3 __attribute__((ext_vector_type(3)));
1106typedef long l4 __attribute__((ext_vector_type(4)));
1107typedef unsigned long ul2 __attribute__((ext_vector_type(2)));
1108typedef unsigned long ul3 __attribute__((ext_vector_type(3)));
1109typedef unsigned long ul4 __attribute__((ext_vector_type(4)));
1110
1111void rsDebug(const char *s, const l2 *c) {
1112    long2 ll = *(const long2 *)c;
1113    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1114}
1115
1116void rsDebug(const char *s, const l3 *c) {
1117    long3 ll = *(const long3 *)c;
1118    ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
1119}
1120
1121void rsDebug(const char *s, const l4 *c) {
1122    long4 ll = *(const long4 *)c;
1123    ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
1124}
1125
1126void rsDebug(const char *s, const ul2 *c) {
1127    ulong2 ll = *(const ulong2 *)c;
1128    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y));
1129}
1130
1131void rsDebug(const char *s, const ul3 *c) {
1132    ulong3 ll = *(const ulong3 *)c;
1133    ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
1134}
1135
1136void rsDebug(const char *s, const ul4 *c) {
1137    ulong4 ll = *(const ulong4 *)c;
1138    ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w));
1139}
1140#endif
1141
1142void rsDebug(const char *s, const long2 ll) {
1143    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1144}
1145
1146void rsDebug(const char *s, const long3 ll) {
1147    ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
1148}
1149
1150void rsDebug(const char *s, const long4 ll) {
1151    ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
1152}
1153
1154void rsDebug(const char *s, const ulong2 ll) {
1155    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y));
1156}
1157
1158void rsDebug(const char *s, const ulong3 ll) {
1159    ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
1160}
1161
1162void rsDebug(const char *s, const ulong4 ll) {
1163    ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w));
1164}
1165
1166void rsDebug(const char *s, const void *p) {
1167    ALOGD("%s %p", s, p);
1168}
1169
1170extern const RsdCpuReference::CpuSymbol * rsdLookupRuntimeStub(Context * pContext, char const* name) {
1171// TODO: remove
1172    return nullptr;
1173}
1174