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