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