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