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