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