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