rsdRuntimeStubs.cpp revision dda5cb5b59ae02ec03001ea12c374413714f3d38
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#if defined(__i386__) || (defined(__mips__) && __mips==32)
138// i386 and MIPS32 have 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
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 rsForEachInternal(int slot,
437                       rs_script_call *call,
438                       int hasOutput,
439                       int numIn,
440                       ...) {
441    Context *rsc = RsdCpuReference::getTlsContext();
442    Script *s = const_cast<Script*>(RsdCpuReference::getTlsScript());
443    std::unique_ptr<Allocation*> inputs(numIn > 0 ? new Allocation*[numIn] : nullptr);
444    if (numIn > 0 && inputs == nullptr) {
445        ALOGE("rsForEachInternal: out of memory for %u inputs.", numIn);
446        return;
447    }
448    Allocation* out = nullptr;
449    va_list argp;
450    va_start(argp, numIn);
451    for (int i = 0; i < numIn; i++) {
452        ::rs_allocation alloc = va_arg(argp, ::rs_allocation);
453        inputs.get()[i] = reinterpret_cast<Allocation*>(const_cast<int*>(alloc.p));
454    }
455    if (hasOutput) {
456        ::rs_allocation outAlloc = va_arg(argp, ::rs_allocation);
457        out = reinterpret_cast<Allocation*>(const_cast<int*>(outAlloc.p));
458    }
459    va_end(argp);
460    rsrForEach(rsc, s, slot, numIn, inputs.get(), out, nullptr, 0, (RsScriptCall*)call);
461}
462
463void __attribute__((overloadable)) rsForEach(::rs_script script,
464                                             ::rs_allocation in,
465                                             ::rs_allocation out,
466                                             const void *usr,
467                                             const rs_script_call *call) {
468    Context *rsc = RsdCpuReference::getTlsContext();
469    rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
470               (Allocation *)out.p, usr, 0, (RsScriptCall *)call);
471}
472
473void __attribute__((overloadable)) rsForEach(::rs_script script,
474                                             ::rs_allocation in,
475                                             ::rs_allocation out,
476                                             const void *usr) {
477    Context *rsc = RsdCpuReference::getTlsContext();
478    rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p,
479               usr, 0, nullptr);
480}
481
482void __attribute__((overloadable)) rsForEach(::rs_script script,
483                                             ::rs_allocation in,
484                                             ::rs_allocation out) {
485    Context *rsc = RsdCpuReference::getTlsContext();
486    rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p,
487               nullptr, 0, nullptr);
488}
489
490// These functions are only supported in 32-bit.
491#ifndef __LP64__
492void __attribute__((overloadable)) rsForEach(::rs_script script,
493                                             ::rs_allocation in,
494                                             ::rs_allocation out,
495                                             const void *usr,
496                                             uint32_t usrLen) {
497    Context *rsc = RsdCpuReference::getTlsContext();
498    rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p,
499               usr, usrLen, nullptr);
500}
501
502void __attribute__((overloadable)) rsForEach(::rs_script script,
503                                             ::rs_allocation in,
504                                             ::rs_allocation out,
505                                             const void *usr,
506                                             uint32_t usrLen,
507                                             const rs_script_call *call) {
508    Context *rsc = RsdCpuReference::getTlsContext();
509    rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p,
510               usr, usrLen, (RsScriptCall *)call);
511}
512#endif
513
514//////////////////////////////////////////////////////////////////////////////
515// Message routines
516//////////////////////////////////////////////////////////////////////////////
517uint32_t rsSendToClient(int cmdID) {
518    Context *rsc = RsdCpuReference::getTlsContext();
519    return rsrToClient(rsc, cmdID, (const void *)nullptr, 0);
520}
521
522uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) {
523    Context *rsc = RsdCpuReference::getTlsContext();
524    return rsrToClient(rsc, cmdID, data, len);
525}
526
527uint32_t rsSendToClientBlocking(int cmdID) {
528    Context *rsc = RsdCpuReference::getTlsContext();
529    return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0);
530}
531
532uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) {
533    Context *rsc = RsdCpuReference::getTlsContext();
534    return rsrToClientBlocking(rsc, cmdID, data, len);
535}
536
537//////////////////////////////////////////////////////////////////////////////
538// Time routines
539//////////////////////////////////////////////////////////////////////////////
540
541// time_t is int in 32-bit RenderScript.  time_t is long in bionic.  rsTime and
542// rsLocaltime are set to explicitly take 'const int *' so we generate the
543// correct mangled names.
544#ifndef __LP64__
545int rsTime(int *timer) {
546#else
547time_t rsTime(time_t * timer) {
548#endif
549    Context *rsc = RsdCpuReference::getTlsContext();
550    return rsrTime(rsc, (time_t *)timer);
551}
552
553#ifndef __LP64__
554rs_tm* rsLocaltime(rs_tm* local, const int *timer) {
555#else
556rs_tm* rsLocaltime(rs_tm* local, const time_t *timer) {
557#endif
558    Context *rsc = RsdCpuReference::getTlsContext();
559    return (rs_tm*)rsrLocalTime(rsc, (tm*)local, (time_t *)timer);
560}
561
562int64_t rsUptimeMillis() {
563    Context *rsc = RsdCpuReference::getTlsContext();
564    return rsrUptimeMillis(rsc);
565}
566
567int64_t rsUptimeNanos() {
568    Context *rsc = RsdCpuReference::getTlsContext();
569    return rsrUptimeNanos(rsc);
570}
571
572float rsGetDt() {
573    Context *rsc = RsdCpuReference::getTlsContext();
574    const Script *sc = RsdCpuReference::getTlsScript();
575    return rsrGetDt(rsc, sc);
576}
577
578//////////////////////////////////////////////////////////////////////////////
579// Graphics routines
580//////////////////////////////////////////////////////////////////////////////
581#ifndef RS_COMPATIBILITY_LIB
582static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
583                                 float x2, float y2, float z2, float u2, float v2,
584                                 float x3, float y3, float z3, float u3, float v3,
585                                 float x4, float y4, float z4, float u4, float v4) {
586    Context *rsc = RsdCpuReference::getTlsContext();
587
588    if (!rsc->setupCheck()) {
589        return;
590    }
591
592    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
593    if (!dc->gl.shaderCache->setup(rsc)) {
594        return;
595    }
596
597    //ALOGE("Quad");
598    //ALOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
599    //ALOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
600    //ALOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
601    //ALOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
602
603    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
604    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
605
606    RsdVertexArray::Attrib attribs[2];
607    attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position");
608    attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0");
609
610    RsdVertexArray va(attribs, 2);
611    va.setup(rsc);
612
613    RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
614}
615
616static void SC_DrawQuad(float x1, float y1, float z1,
617                        float x2, float y2, float z2,
618                        float x3, float y3, float z3,
619                        float x4, float y4, float z4) {
620    SC_DrawQuadTexCoords(x1, y1, z1, 0, 1,
621                         x2, y2, z2, 1, 1,
622                         x3, y3, z3, 1, 0,
623                         x4, y4, z4, 0, 0);
624}
625
626static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) {
627    Context *rsc = RsdCpuReference::getTlsContext();
628
629    ObjectBaseRef<const ProgramVertex> tmp(rsc->getProgramVertex());
630    rsc->setProgramVertex(rsc->getDefaultProgramVertex());
631    //rsc->setupCheck();
632
633    //GLint crop[4] = {0, h, w, -h};
634
635    float sh = rsc->getHeight();
636
637    SC_DrawQuad(x,   sh - y,     z,
638                x+w, sh - y,     z,
639                x+w, sh - (y+h), z,
640                x,   sh - (y+h), z);
641    rsc->setProgramVertex((ProgramVertex *)tmp.get());
642}
643
644void rsAllocationMarkDirty(::rs_allocation a) {
645    Context *rsc = RsdCpuReference::getTlsContext();
646    rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT);
647}
648
649void rsgAllocationSyncAll(::rs_allocation a) {
650    Context *rsc = RsdCpuReference::getTlsContext();
651    rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT);
652}
653
654void rsgAllocationSyncAll(::rs_allocation a,
655                          unsigned int usage) {
656    Context *rsc = RsdCpuReference::getTlsContext();
657    rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)usage);
658}
659
660
661void rsgAllocationSyncAll(::rs_allocation a,
662                          rs_allocation_usage_type source) {
663    Context *rsc = RsdCpuReference::getTlsContext();
664    rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)source.val);
665}
666
667void rsgBindProgramFragment(::rs_program_fragment pf) {
668    Context *rsc = RsdCpuReference::getTlsContext();
669    rsrBindProgramFragment(rsc, (ProgramFragment *)pf.p);
670}
671
672void rsgBindProgramStore(::rs_program_store ps) {
673    Context *rsc = RsdCpuReference::getTlsContext();
674    rsrBindProgramStore(rsc, (ProgramStore *)ps.p);
675}
676
677void rsgBindProgramVertex(::rs_program_vertex pv) {
678    Context *rsc = RsdCpuReference::getTlsContext();
679    rsrBindProgramVertex(rsc, (ProgramVertex *)pv.p);
680}
681
682void rsgBindProgramRaster(::rs_program_raster pr) {
683    Context *rsc = RsdCpuReference::getTlsContext();
684    rsrBindProgramRaster(rsc, (ProgramRaster *)pr.p);
685}
686
687void rsgBindSampler(::rs_program_fragment pf,
688                    uint32_t slot, ::rs_sampler s) {
689    Context *rsc = RsdCpuReference::getTlsContext();
690    rsrBindSampler(rsc, (ProgramFragment *)pf.p, slot, (Sampler *)s.p);
691}
692
693void rsgBindTexture(::rs_program_fragment pf,
694                    uint32_t slot, ::rs_allocation a) {
695    Context *rsc = RsdCpuReference::getTlsContext();
696    rsrBindTexture(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p);
697}
698
699void rsgBindConstant(::rs_program_fragment pf,
700                     uint32_t slot, ::rs_allocation a) {
701    Context *rsc = RsdCpuReference::getTlsContext();
702    rsrBindConstant(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p);
703}
704
705void rsgBindConstant(::rs_program_vertex pv,
706                     uint32_t slot, ::rs_allocation a) {
707    Context *rsc = RsdCpuReference::getTlsContext();
708    rsrBindConstant(rsc, (ProgramVertex *)pv.p, slot, (Allocation *)a.p);
709}
710
711void rsgProgramVertexLoadProjectionMatrix(const rs_matrix4x4 *m) {
712    Context *rsc = RsdCpuReference::getTlsContext();
713    rsrVpLoadProjectionMatrix(rsc, (const rsc_Matrix *)m);
714}
715
716void rsgProgramVertexLoadModelMatrix(const rs_matrix4x4 *m) {
717    Context *rsc = RsdCpuReference::getTlsContext();
718    rsrVpLoadModelMatrix(rsc, (const rsc_Matrix *)m);
719}
720
721void rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *m) {
722    Context *rsc = RsdCpuReference::getTlsContext();
723    rsrVpLoadTextureMatrix(rsc, (const rsc_Matrix *)m);
724}
725
726void rsgProgramVertexGetProjectionMatrix(rs_matrix4x4 *m) {
727    Context *rsc = RsdCpuReference::getTlsContext();
728    rsrVpGetProjectionMatrix(rsc, (rsc_Matrix *)m);
729}
730
731void rsgProgramFragmentConstantColor(::rs_program_fragment pf,
732                                     float r, float g, float b, float a) {
733    Context *rsc = RsdCpuReference::getTlsContext();
734    rsrPfConstantColor(rsc, (ProgramFragment *)pf.p, r, g, b, a);
735}
736
737uint32_t rsgGetWidth(void) {
738    Context *rsc = RsdCpuReference::getTlsContext();
739    return rsrGetWidth(rsc);
740}
741
742uint32_t rsgGetHeight(void) {
743    Context *rsc = RsdCpuReference::getTlsContext();
744    return rsrGetHeight(rsc);
745}
746
747void rsgDrawRect(float x1, float y1, float x2, float y2, float z) {
748    SC_DrawQuad(x1, y2, z,
749                x2, y2, z,
750                x2, y1, z,
751                x1, y1, z);
752}
753
754void rsgDrawQuad(float x1, float y1, float z1,
755                 float x2, float y2, float z2,
756                 float x3, float y3, float z3,
757                 float x4, float y4, float z4) {
758    SC_DrawQuad(x1, y1, z1,
759                x2, y2, z2,
760                x3, y3, z3,
761                x4, y4, z4);
762}
763
764void rsgDrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1,
765                          float x2, float y2, float z2, float u2, float v2,
766                          float x3, float y3, float z3, float u3, float v3,
767                          float x4, float y4, float z4, float u4, float v4) {
768    SC_DrawQuadTexCoords(x1, y1, z1, u1, v1,
769                         x2, y2, z2, u2, v2,
770                         x3, y3, z3, u3, v3,
771                         x4, y4, z4, u4, v4);
772}
773
774void rsgDrawSpriteScreenspace(float x, float y, float z, float w, float h) {
775    SC_DrawSpriteScreenspace(x, y, z, w, h);
776}
777
778void rsgDrawMesh(::rs_mesh ism) {
779    Context *rsc = RsdCpuReference::getTlsContext();
780    rsrDrawMesh(rsc, (Mesh *)ism.p);
781}
782
783void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex) {
784    Context *rsc = RsdCpuReference::getTlsContext();
785    rsrDrawMeshPrimitive(rsc, (Mesh *)ism.p, primitiveIndex);
786}
787
788void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex, uint start, uint len) {
789    Context *rsc = RsdCpuReference::getTlsContext();
790    rsrDrawMeshPrimitiveRange(rsc, (Mesh *)ism.p, primitiveIndex, start, len);
791}
792
793void  rsgMeshComputeBoundingBox(::rs_mesh mesh,
794                                float *minX, float *minY, float *minZ,
795                                float *maxX, float *maxY, float *maxZ) {
796    Context *rsc = RsdCpuReference::getTlsContext();
797    rsrMeshComputeBoundingBox(rsc, (Mesh *)mesh.p, minX, minY, minZ, maxX, maxY, maxZ);
798}
799
800void rsgClearColor(float r, float g, float b, float a) {
801    Context *rsc = RsdCpuReference::getTlsContext();
802    rsrPrepareClear(rsc);
803    rsdGLClearColor(rsc, r, g, b, a);
804}
805
806void rsgClearDepth(float value) {
807    Context *rsc = RsdCpuReference::getTlsContext();
808    rsrPrepareClear(rsc);
809    rsdGLClearDepth(rsc, value);
810}
811
812void rsgDrawText(const char *text, int x, int y) {
813    Context *rsc = RsdCpuReference::getTlsContext();
814    rsrDrawText(rsc, text, x, y);
815}
816
817void rsgDrawText(::rs_allocation a, int x, int y) {
818    Context *rsc = RsdCpuReference::getTlsContext();
819    rsrDrawTextAlloc(rsc, (Allocation *)a.p, x, y);
820}
821
822void rsgMeasureText(const char *text, int *left, int *right,
823                    int *top, int *bottom) {
824    Context *rsc = RsdCpuReference::getTlsContext();
825    rsrMeasureText(rsc, text, left, right, top, bottom);
826}
827
828void rsgMeasureText(::rs_allocation a, int *left, int *right,
829                    int *top, int *bottom) {
830    Context *rsc = RsdCpuReference::getTlsContext();
831    rsrMeasureTextAlloc(rsc, (Allocation *)a.p, left, right, top, bottom);
832}
833
834void rsgBindFont(::rs_font font) {
835    Context *rsc = RsdCpuReference::getTlsContext();
836    rsrBindFont(rsc, (Font *)font.p);
837}
838
839void rsgFontColor(float r, float g, float b, float a) {
840    Context *rsc = RsdCpuReference::getTlsContext();
841    rsrFontColor(rsc, r, g, b, a);
842}
843
844void rsgBindColorTarget(::rs_allocation a, uint slot) {
845    Context *rsc = RsdCpuReference::getTlsContext();
846    rsrBindFrameBufferObjectColorTarget(rsc, (Allocation *)a.p, slot);
847}
848
849void rsgBindDepthTarget(::rs_allocation a) {
850    Context *rsc = RsdCpuReference::getTlsContext();
851    rsrBindFrameBufferObjectDepthTarget(rsc, (Allocation *)a.p);
852}
853
854void rsgClearColorTarget(uint slot) {
855    Context *rsc = RsdCpuReference::getTlsContext();
856    rsrClearFrameBufferObjectColorTarget(rsc, slot);
857}
858
859void rsgClearDepthTarget(void) {
860    Context *rsc = RsdCpuReference::getTlsContext();
861    rsrClearFrameBufferObjectDepthTarget(rsc);
862}
863
864void rsgClearAllRenderTargets(void) {
865    Context *rsc = RsdCpuReference::getTlsContext();
866    rsrClearFrameBufferObjectTargets(rsc);
867}
868
869void color(float r, float g, float b, float a) {
870    Context *rsc = RsdCpuReference::getTlsContext();
871    rsrColor(rsc, r, g, b, a);
872}
873
874void rsgFinish(void) {
875    Context *rsc = RsdCpuReference::getTlsContext();
876    rsdGLFinish(rsc);
877}
878#endif
879
880//////////////////////////////////////////////////////////////////////////////
881// Debug routines
882//////////////////////////////////////////////////////////////////////////////
883void rsDebug(const char *s, float f) {
884    ALOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
885}
886
887void rsDebug(const char *s, float f1, float f2) {
888    ALOGD("%s {%f, %f}", s, f1, f2);
889}
890
891void rsDebug(const char *s, float f1, float f2, float f3) {
892    ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
893}
894
895void rsDebug(const char *s, float f1, float f2, float f3, float f4) {
896    ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
897}
898
899void rsDebug(const char *s, const float2 *f2) {
900    float2 f = *f2;
901    ALOGD("%s {%f, %f}", s, f.x, f.y);
902}
903
904void rsDebug(const char *s, const float3 *f3) {
905    float3 f = *f3;
906    ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
907}
908
909void rsDebug(const char *s, const float4 *f4) {
910    float4 f = *f4;
911    ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
912}
913
914void rsDebug(const char *s, double d) {
915    ALOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
916}
917
918void rsDebug(const char *s, const double2 *d2) {
919    double2 d = *d2;
920    ALOGD("%s {%f, %f}", s, d.x, d.y);
921}
922
923void rsDebug(const char *s, const double3 *d3) {
924    double3 d = *d3;
925    ALOGD("%s {%f, %f, %f}", s, d.x, d.y, d.z);
926}
927
928void rsDebug(const char *s, const double4 *d4) {
929    double4 d = *d4;
930    ALOGD("%s {%f, %f, %f, %f}", s, d.x, d.y, d.z, d.w);
931}
932
933void rsDebug(const char *s, const rs_matrix4x4 *m) {
934    float *f = (float *)m;
935    ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
936    ALOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
937    ALOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
938    ALOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
939}
940
941void rsDebug(const char *s, const rs_matrix3x3 *m) {
942    float *f = (float *)m;
943    ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
944    ALOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
945    ALOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
946}
947
948void rsDebug(const char *s, const rs_matrix2x2 *m) {
949    float *f = (float *)m;
950    ALOGD("%s {%f, %f", s, f[0], f[2]);
951    ALOGD("%s  %f, %f}",s, f[1], f[3]);
952}
953
954void rsDebug(const char *s, char c) {
955    ALOGD("%s %hhd  0x%hhx", s, c, (unsigned char)c);
956}
957
958void rsDebug(const char *s, const char2 *c2) {
959    char2 c = *c2;
960    ALOGD("%s {%hhd, %hhd}  0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x, (unsigned char)c.y);
961}
962
963void rsDebug(const char *s, const char3 *c3) {
964    char3 c = *c3;
965    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);
966}
967
968void rsDebug(const char *s, const char4 *c4) {
969    char4 c = *c4;
970    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);
971}
972
973void rsDebug(const char *s, unsigned char c) {
974    ALOGD("%s %hhu  0x%hhx", s, c, c);
975}
976
977void rsDebug(const char *s, const uchar2 *c2) {
978    uchar2 c = *c2;
979    ALOGD("%s {%hhu, %hhu}  0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
980}
981
982void rsDebug(const char *s, const uchar3 *c3) {
983    uchar3 c = *c3;
984    ALOGD("%s {%hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x, c.y, c.z);
985}
986
987void rsDebug(const char *s, const uchar4 *c4) {
988    uchar4 c = *c4;
989    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);
990}
991
992void rsDebug(const char *s, short c) {
993    ALOGD("%s %hd  0x%hx", s, c, c);
994}
995
996void rsDebug(const char *s, const short2 *c2) {
997    short2 c = *c2;
998    ALOGD("%s {%hd, %hd}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
999}
1000
1001void rsDebug(const char *s, const short3 *c3) {
1002    short3 c = *c3;
1003    ALOGD("%s {%hd, %hd, %hd}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
1004}
1005
1006void rsDebug(const char *s, const short4 *c4) {
1007    short4 c = *c4;
1008    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);
1009}
1010
1011void rsDebug(const char *s, unsigned short c) {
1012    ALOGD("%s %hu  0x%hx", s, c, c);
1013}
1014
1015void rsDebug(const char *s, const ushort2 *c2) {
1016    ushort2 c = *c2;
1017    ALOGD("%s {%hu, %hu}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
1018}
1019
1020void rsDebug(const char *s, const ushort3 *c3) {
1021    ushort3 c = *c3;
1022    ALOGD("%s {%hu, %hu, %hu}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
1023}
1024
1025void rsDebug(const char *s, const ushort4 *c4) {
1026    ushort4 c = *c4;
1027    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);
1028}
1029
1030void rsDebug(const char *s, int i) {
1031    ALOGD("%s %d  0x%x", s, i, i);
1032}
1033
1034void rsDebug(const char *s, const int2 *i2) {
1035    int2 i = *i2;
1036    ALOGD("%s {%d, %d}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
1037}
1038
1039void rsDebug(const char *s, const int3 *i3) {
1040    int3 i = *i3;
1041    ALOGD("%s {%d, %d, %d}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
1042}
1043
1044void rsDebug(const char *s, const int4 *i4) {
1045    int4 i = *i4;
1046    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);
1047}
1048
1049void rsDebug(const char *s, unsigned int i) {
1050    ALOGD("%s %u  0x%x", s, i, i);
1051}
1052
1053void rsDebug(const char *s, const uint2 *i2) {
1054    uint2 i = *i2;
1055    ALOGD("%s {%u, %u}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
1056}
1057
1058void rsDebug(const char *s, const uint3 *i3) {
1059    uint3 i = *i3;
1060    ALOGD("%s {%u, %u, %u}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
1061}
1062
1063void rsDebug(const char *s, const uint4 *i4) {
1064    uint4 i = *i4;
1065    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);
1066}
1067
1068template <typename T>
1069static inline long long LL(const T &x) {
1070    return static_cast<long long>(x);
1071}
1072
1073template <typename T>
1074static inline unsigned long long LLu(const T &x) {
1075    return static_cast<unsigned long long>(x);
1076}
1077
1078void rsDebug(const char *s, long l) {
1079    ALOGD("%s %lld  0x%llx", s, LL(l), LL(l));
1080}
1081
1082void rsDebug(const char *s, long long ll) {
1083    ALOGD("%s %lld  0x%llx", s, LL(ll), LL(ll));
1084}
1085
1086void rsDebug(const char *s, const long2 *c) {
1087    long2 ll = *c;
1088    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1089}
1090
1091void rsDebug(const char *s, const long3 *c) {
1092    long3 ll = *c;
1093    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));
1094}
1095
1096void rsDebug(const char *s, const long4 *c) {
1097    long4 ll = *c;
1098    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));
1099}
1100
1101void rsDebug(const char *s, unsigned long l) {
1102    unsigned long long ll = l;
1103    ALOGD("%s %llu  0x%llx", s, ll, ll);
1104}
1105
1106void rsDebug(const char *s, unsigned long long ll) {
1107    ALOGD("%s %llu  0x%llx", s, ll, ll);
1108}
1109
1110void rsDebug(const char *s, const ulong2 *c) {
1111    ulong2 ll = *c;
1112    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y));
1113}
1114
1115void rsDebug(const char *s, const ulong3 *c) {
1116    ulong3 ll = *c;
1117    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));
1118}
1119
1120void rsDebug(const char *s, const ulong4 *c) {
1121    ulong4 ll = *c;
1122    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));
1123}
1124
1125// FIXME: We need to export these function signatures for the compatibility
1126// library. The C++ name mangling that LLVM uses for ext_vector_type requires
1127// different versions for "long" vs. "long long". Note that the called
1128// functions are still using the appropriate 64-bit sizes.
1129
1130#ifndef __LP64__
1131typedef long l2 __attribute__((ext_vector_type(2)));
1132typedef long l3 __attribute__((ext_vector_type(3)));
1133typedef long l4 __attribute__((ext_vector_type(4)));
1134typedef unsigned long ul2 __attribute__((ext_vector_type(2)));
1135typedef unsigned long ul3 __attribute__((ext_vector_type(3)));
1136typedef unsigned long ul4 __attribute__((ext_vector_type(4)));
1137
1138void rsDebug(const char *s, const l2 *c) {
1139    long2 ll = *(const long2 *)c;
1140    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1141}
1142
1143void rsDebug(const char *s, const l3 *c) {
1144    long3 ll = *(const long3 *)c;
1145    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));
1146}
1147
1148void rsDebug(const char *s, const l4 *c) {
1149    long4 ll = *(const long4 *)c;
1150    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));
1151}
1152
1153void rsDebug(const char *s, const ul2 *c) {
1154    ulong2 ll = *(const ulong2 *)c;
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 ul3 *c) {
1159    ulong3 ll = *(const ulong3 *)c;
1160    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));
1161}
1162
1163void rsDebug(const char *s, const ul4 *c) {
1164    ulong4 ll = *(const ulong4 *)c;
1165    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));
1166}
1167#endif
1168
1169void rsDebug(const char *s, const long2 ll) {
1170    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y));
1171}
1172
1173void rsDebug(const char *s, const long3 ll) {
1174    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));
1175}
1176
1177void rsDebug(const char *s, const long4 ll) {
1178    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));
1179}
1180
1181void rsDebug(const char *s, const ulong2 ll) {
1182    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y));
1183}
1184
1185void rsDebug(const char *s, const ulong3 ll) {
1186    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));
1187}
1188
1189void rsDebug(const char *s, const ulong4 ll) {
1190    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));
1191}
1192
1193void rsDebug(const char *s, const void *p) {
1194    ALOGD("%s %p", s, p);
1195}
1196
1197extern const RsdCpuReference::CpuSymbol * rsdLookupRuntimeStub(Context * pContext, char const* name) {
1198// TODO: remove
1199    return nullptr;
1200}
1201