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 <time.h>
     18 
     19 #include "rsContext.h"
     20 #include "rsElement.h"
     21 #include "rsMatrix2x2.h"
     22 #include "rsMatrix3x3.h"
     23 #include "rsMatrix4x4.h"
     24 #include "rsRuntime.h"
     25 #include "rsScriptC.h"
     26 #include "rsType.h"
     27 #include "rsovAllocation.h"
     28 #include "rsovCore.h"
     29 #include "rsovScript.h"
     30 
     31 using namespace android;
     32 using namespace android::renderscript;
     33 
     34 typedef __fp16 half;
     35 typedef half half2 __attribute__((ext_vector_type(2)));
     36 typedef half half3 __attribute__((ext_vector_type(3)));
     37 typedef half half4 __attribute__((ext_vector_type(4)));
     38 
     39 typedef float float2 __attribute__((ext_vector_type(2)));
     40 typedef float float3 __attribute__((ext_vector_type(3)));
     41 typedef float float4 __attribute__((ext_vector_type(4)));
     42 typedef double double2 __attribute__((ext_vector_type(2)));
     43 typedef double double3 __attribute__((ext_vector_type(3)));
     44 typedef double double4 __attribute__((ext_vector_type(4)));
     45 typedef char char2 __attribute__((ext_vector_type(2)));
     46 typedef char char3 __attribute__((ext_vector_type(3)));
     47 typedef char char4 __attribute__((ext_vector_type(4)));
     48 typedef unsigned char uchar2 __attribute__((ext_vector_type(2)));
     49 typedef unsigned char uchar3 __attribute__((ext_vector_type(3)));
     50 typedef unsigned char uchar4 __attribute__((ext_vector_type(4)));
     51 typedef int16_t short2 __attribute__((ext_vector_type(2)));
     52 typedef int16_t short3 __attribute__((ext_vector_type(3)));
     53 typedef int16_t short4 __attribute__((ext_vector_type(4)));
     54 typedef uint16_t ushort2 __attribute__((ext_vector_type(2)));
     55 typedef uint16_t ushort3 __attribute__((ext_vector_type(3)));
     56 typedef uint16_t ushort4 __attribute__((ext_vector_type(4)));
     57 typedef int32_t int2 __attribute__((ext_vector_type(2)));
     58 typedef int32_t int3 __attribute__((ext_vector_type(3)));
     59 typedef int32_t int4 __attribute__((ext_vector_type(4)));
     60 typedef uint32_t uint2 __attribute__((ext_vector_type(2)));
     61 typedef uint32_t uint3 __attribute__((ext_vector_type(3)));
     62 typedef uint32_t uint4 __attribute__((ext_vector_type(4)));
     63 typedef int64_t long2 __attribute__((ext_vector_type(2)));
     64 typedef int64_t long3 __attribute__((ext_vector_type(3)));
     65 typedef int64_t long4 __attribute__((ext_vector_type(4)));
     66 typedef uint64_t ulong2 __attribute__((ext_vector_type(2)));
     67 typedef uint64_t ulong3 __attribute__((ext_vector_type(3)));
     68 typedef uint64_t ulong4 __attribute__((ext_vector_type(4)));
     69 
     70 typedef uint8_t uchar;
     71 typedef uint16_t ushort;
     72 typedef uint32_t uint;
     73 typedef uint64_t ulong;
     74 
     75 // Add NOLINT to suppress wrong warnings from clang-tidy.
     76 #ifndef __LP64__
     77 #define OPAQUETYPE(t)   \
     78   typedef struct {      \
     79     const int *const p; \
     80   } __attribute__((packed, aligned(4))) t; /*NOLINT*/
     81 #else
     82 #define OPAQUETYPE(t)     \
     83   typedef struct {        \
     84     const void *p;        \
     85     const void *unused1;  \
     86     const void *unused2;  \
     87     const void *unused3;  \
     88   } t; /*NOLINT*/
     89 #endif
     90 
     91 OPAQUETYPE(rs_element)
     92 OPAQUETYPE(rs_type)
     93 OPAQUETYPE(rs_allocation)
     94 OPAQUETYPE(rs_sampler)
     95 OPAQUETYPE(rs_script)
     96 OPAQUETYPE(rs_script_call)
     97 
     98 OPAQUETYPE(rs_program_fragment);
     99 OPAQUETYPE(rs_program_store);
    100 OPAQUETYPE(rs_program_vertex);
    101 OPAQUETYPE(rs_program_raster);
    102 OPAQUETYPE(rs_mesh);
    103 OPAQUETYPE(rs_font);
    104 
    105 #undef OPAQUETYPE
    106 
    107 typedef enum {
    108   // Empty to avoid conflicting definitions with RsAllocationCubemapFace
    109 } rs_allocation_cubemap_face;
    110 
    111 typedef enum {
    112   // Empty to avoid conflicting definitions with RsYuvFormat
    113 } rs_yuv_format;
    114 
    115 typedef enum {
    116   // Empty to avoid conflicting definitions with RsAllocationMipmapControl
    117 } rs_allocation_mipmap_control;
    118 
    119 typedef struct { unsigned int val; } rs_allocation_usage_type;
    120 
    121 typedef struct {
    122   int tm_sec;    ///< seconds
    123   int tm_min;    ///< minutes
    124   int tm_hour;   ///< hours
    125   int tm_mday;   ///< day of the month
    126   int tm_mon;    ///< month
    127   int tm_year;   ///< year
    128   int tm_wday;   ///< day of the week
    129   int tm_yday;   ///< day of the year
    130   int tm_isdst;  ///< daylight savings time
    131 } rs_tm;
    132 
    133 // Some RS functions are not threadsafe but can be called from an invoke
    134 // function.  Instead of summarily marking scripts that call these functions as
    135 // not-threadable we detect calls to them in the driver and sends a fatal error
    136 // message.
    137 static bool failIfInKernel(Context *rsc, const char *funcName) {
    138   RSoVHal *dc = (RSoVHal *)rsc->mHal.drv;
    139   RsdCpuReference *impl = (RsdCpuReference *)dc->mCpuRef;
    140 
    141   if (impl->getInKernel()) {
    142     char buf[256];
    143     snprintf(buf, sizeof(buf),
    144              "Error: Call to unsupported function %s "
    145              "in kernel",
    146              funcName);
    147     rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
    148     return true;
    149   }
    150   return false;
    151 }
    152 
    153 //////////////////////////////////////////////////////////////////////////////
    154 // Allocation routines
    155 //////////////////////////////////////////////////////////////////////////////
    156 #if defined(__i386__) || (defined(__mips__) && __mips == 32)
    157 // i386 and MIPS32 have different struct return passing to ARM; emulate with a
    158 // pointer
    159 const Allocation *rsGetAllocation(const void *ptr) {
    160   Context *rsc = RsdCpuReference::getTlsContext();
    161   const Script *sc = RsdCpuReference::getTlsScript();
    162   Allocation *alloc = rsovScriptGetAllocationForPointer(rsc, sc, ptr);
    163   android::renderscript::rs_allocation obj = {0};
    164   alloc->callUpdateCacheObject(rsc, &obj);
    165   return (Allocation *)obj.p;
    166 }
    167 #else
    168 const android::renderscript::rs_allocation rsGetAllocation(const void *ptr) {
    169   Context *rsc = RsdCpuReference::getTlsContext();
    170   const Script *sc = RsdCpuReference::getTlsScript();
    171   Allocation *alloc = rsovScriptGetAllocationForPointer(rsc, sc, ptr);
    172 
    173 #ifndef __LP64__  // ARMv7
    174   android::renderscript::rs_allocation obj = {0};
    175 #else             // AArch64/x86_64/MIPS64
    176   android::renderscript::rs_allocation obj = {0, 0, 0, 0};
    177 #endif
    178   alloc->callUpdateCacheObject(rsc, &obj);
    179   return obj;
    180 }
    181 #endif
    182 
    183 void __attribute__((overloadable)) rsAllocationIoSend(::rs_allocation a) {
    184   Context *rsc = RsdCpuReference::getTlsContext();
    185   if (failIfInKernel(rsc, "rsAllocationIoSend")) return;
    186   rsrAllocationIoSend(rsc, (Allocation *)a.p);
    187 }
    188 
    189 void __attribute__((overloadable)) rsAllocationIoReceive(::rs_allocation a) {
    190   Context *rsc = RsdCpuReference::getTlsContext();
    191   if (failIfInKernel(rsc, "rsAllocationIoReceive")) return;
    192   rsrAllocationIoReceive(rsc, (Allocation *)a.p);
    193 }
    194 
    195 void __attribute__((overloadable))
    196 rsAllocationCopy1DRange(::rs_allocation dstAlloc, uint32_t dstOff,
    197                         uint32_t dstMip, uint32_t count,
    198                         ::rs_allocation srcAlloc, uint32_t srcOff,
    199                         uint32_t srcMip) {
    200   Context *rsc = RsdCpuReference::getTlsContext();
    201   if (failIfInKernel(rsc, "rsAllocationCopy1DRange")) return;
    202   rsrAllocationCopy1DRange(rsc, (Allocation *)dstAlloc.p, dstOff, dstMip, count,
    203                            (Allocation *)srcAlloc.p, srcOff, srcMip);
    204 }
    205 
    206 void __attribute__((overloadable))
    207 rsAllocationCopy2DRange(::rs_allocation dstAlloc, uint32_t dstXoff,
    208                         uint32_t dstYoff, uint32_t dstMip,
    209                         rs_allocation_cubemap_face dstFace, uint32_t width,
    210                         uint32_t height, ::rs_allocation srcAlloc,
    211                         uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip,
    212                         rs_allocation_cubemap_face srcFace) {
    213   Context *rsc = RsdCpuReference::getTlsContext();
    214   if (failIfInKernel(rsc, "rsAllocationCopy2DRange")) return;
    215   rsrAllocationCopy2DRange(
    216       rsc, (Allocation *)dstAlloc.p, dstXoff, dstYoff, dstMip, dstFace, width,
    217       height, (Allocation *)srcAlloc.p, srcXoff, srcYoff, srcMip, srcFace);
    218 }
    219 
    220 static android::renderscript::rs_element CreateElement(RsDataType dt,
    221                                                        RsDataKind dk,
    222                                                        bool isNormalized,
    223                                                        uint32_t vecSize) {
    224   Context *rsc = RsdCpuReference::getTlsContext();
    225 
    226   // No need for validation here.  The rsCreateElement overload below is not
    227   // exposed to the Script.  The Element-creation APIs call this function in a
    228   // consistent manner and rsComponent.cpp asserts on any inconsistency.
    229   Element *element =
    230       (Element *)rsrElementCreate(rsc, dt, dk, isNormalized, vecSize);
    231   android::renderscript::rs_element obj = {};
    232   if (element == nullptr) return obj;
    233   element->callUpdateCacheObject(rsc, &obj);
    234 
    235   // Any new rsObject created from inside a script should have the usrRefCount
    236   // initialized to 0 and the sysRefCount initialized to 1.
    237   element->incSysRef();
    238   element->decUserRef();
    239 
    240   return obj;
    241 }
    242 
    243 static android::renderscript::rs_type CreateType(RsElement element,
    244                                                  uint32_t dimX, uint32_t dimY,
    245                                                  uint32_t dimZ, bool mipmaps,
    246                                                  bool faces,
    247                                                  uint32_t yuv_format) {
    248   Context *rsc = RsdCpuReference::getTlsContext();
    249   android::renderscript::rs_type obj = {};
    250 
    251   if (element == nullptr) {
    252     ALOGE("rs_type creation error: Invalid element");
    253     return obj;
    254   }
    255 
    256   // validate yuv_format
    257   RsYuvFormat yuv = (RsYuvFormat)yuv_format;
    258   if (yuv != RS_YUV_NONE && yuv != RS_YUV_YV12 && yuv != RS_YUV_NV21 &&
    259       yuv != RS_YUV_420_888) {
    260     ALOGE("rs_type creation error: Invalid yuv_format %d\n", yuv_format);
    261     return obj;
    262   }
    263 
    264   // validate consistency of shape parameters
    265   if (dimZ > 0) {
    266     if (dimX < 1 || dimY < 1) {
    267       ALOGE(
    268           "rs_type creation error: Both X and Y dimension required "
    269           "when Z is present.");
    270       return obj;
    271     }
    272     if (mipmaps) {
    273       ALOGE("rs_type creation error: mipmap control requires 2D types");
    274       return obj;
    275     }
    276     if (faces) {
    277       ALOGE("rs_type creation error: Cube maps require 2D types");
    278       return obj;
    279     }
    280   }
    281   if (dimY > 0 && dimX < 1) {
    282     ALOGE(
    283         "rs_type creation error: X dimension required when Y is "
    284         "present.");
    285     return obj;
    286   }
    287   if (mipmaps && dimY < 1) {
    288     ALOGE("rs_type creation error: mipmap control require 2D Types.");
    289     return obj;
    290   }
    291   if (faces && dimY < 1) {
    292     ALOGE("rs_type creation error: Cube maps require 2D Types.");
    293     return obj;
    294   }
    295   if (yuv_format != RS_YUV_NONE) {
    296     if (dimZ != 0 || dimY == 0 || faces || mipmaps) {
    297       ALOGE("rs_type creation error: YUV only supports basic 2D.");
    298       return obj;
    299     }
    300   }
    301 
    302   Type *type = (Type *)rsrTypeCreate(rsc, element, dimX, dimY, dimZ, mipmaps,
    303                                      faces, yuv_format);
    304   if (type == nullptr) return obj;
    305   type->callUpdateCacheObject(rsc, &obj);
    306 
    307   // Any new rsObject created from inside a script should have the usrRefCount
    308   // initialized to 0 and the sysRefCount initialized to 1.
    309   type->incSysRef();
    310   type->decUserRef();
    311 
    312   return obj;
    313 }
    314 
    315 static android::renderscript::rs_allocation CreateAllocation(
    316     RsType type, RsAllocationMipmapControl mipmaps, uint32_t usages,
    317     void *ptr) {
    318   Context *rsc = RsdCpuReference::getTlsContext();
    319   android::renderscript::rs_allocation obj = {};
    320 
    321   if (type == nullptr) {
    322     ALOGE("rs_allocation creation error: Invalid type");
    323     return obj;
    324   }
    325 
    326   uint32_t validUsages =
    327       RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
    328   if (usages & ~validUsages) {
    329     ALOGE("rs_allocation creation error: Invalid usage flag");
    330     return obj;
    331   }
    332 
    333   Allocation *alloc = (Allocation *)rsrAllocationCreateTyped(
    334       rsc, type, mipmaps, usages, (uintptr_t)ptr);
    335   if (alloc == nullptr) return obj;
    336   alloc->callUpdateCacheObject(rsc, &obj);
    337 
    338   // Any new rsObject created from inside a script should have the usrRefCount
    339   // initialized to 0 and the sysRefCount initialized to 1.
    340   alloc->incSysRef();
    341   alloc->decUserRef();
    342 
    343   return obj;
    344 }
    345 
    346 // Define rsCreateElement, rsCreateType and rsCreateAllocation entry points
    347 // differently for 32-bit x86 and Mips.  The definitions for ARM32 and all
    348 // 64-bit architectures is further below.
    349 #if defined(__i386__) || (defined(__mips__) && __mips == 32)
    350 
    351 // The calling convention for the driver on 32-bit x86 and Mips returns
    352 // rs_element etc. as a stack-return parameter.  The Script uses ARM32 calling
    353 // conventions that return the structs in a register.  To match this convention,
    354 // emulate the return value using a pointer.
    355 Element *rsCreateElement(int32_t dt, int32_t dk, bool isNormalized,
    356                          uint32_t vecSize) {
    357   android::renderscript::rs_element obj =
    358       CreateElement((RsDataType)dt, (RsDataKind)dk, isNormalized, vecSize);
    359   return (Element *)obj.p;
    360 }
    361 
    362 Type *rsCreateType(::rs_element element, uint32_t dimX, uint32_t dimY,
    363                    uint32_t dimZ, bool mipmaps, bool faces,
    364                    rs_yuv_format yuv_format) {
    365   android::renderscript::rs_type obj =
    366       CreateType((RsElement)element.p, dimX, dimY, dimZ, mipmaps, faces,
    367                  (RsYuvFormat)yuv_format);
    368   return (Type *)obj.p;
    369 }
    370 
    371 Allocation *rsCreateAllocation(::rs_type type,
    372                                rs_allocation_mipmap_control mipmaps,
    373                                uint32_t usages, void *ptr) {
    374   android::renderscript::rs_allocation obj;
    375   obj = CreateAllocation((RsType)type.p, (RsAllocationMipmapControl)mipmaps,
    376                          usages, ptr);
    377   return (Allocation *)obj.p;
    378 }
    379 
    380 #else
    381 android::renderscript::rs_element rsCreateElement(int32_t dt, int32_t dk,
    382                                                   bool isNormalized,
    383                                                   uint32_t vecSize) {
    384   return CreateElement((RsDataType)dt, (RsDataKind)dk, isNormalized, vecSize);
    385 }
    386 
    387 android::renderscript::rs_type rsCreateType(::rs_element element, uint32_t dimX,
    388                                             uint32_t dimY, uint32_t dimZ,
    389                                             bool mipmaps, bool faces,
    390                                             rs_yuv_format yuv_format) {
    391   return CreateType((RsElement)element.p, dimX, dimY, dimZ, mipmaps, faces,
    392                     yuv_format);
    393 }
    394 
    395 android::renderscript::rs_allocation rsCreateAllocation(
    396     ::rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
    397     void *ptr) {
    398   return CreateAllocation((RsType)type.p, (RsAllocationMipmapControl)mipmaps,
    399                           usages, ptr);
    400 }
    401 #endif
    402 
    403 //////////////////////////////////////////////////////////////////////////////
    404 // Object routines
    405 //////////////////////////////////////////////////////////////////////////////
    406 // Add NOLINT to suppress wrong warnings from clang-tidy.
    407 #define IS_CLEAR_SET_OBJ(t)                                                  \
    408   bool rsIsObject(t src) { return src.p != nullptr; }                        \
    409   void __attribute__((overloadable)) rsClearObject(t *dst) { /*NOLINT*/      \
    410     rsrClearObject(reinterpret_cast<rs_object_base *>(dst));                 \
    411   }                                                                          \
    412   void __attribute__((overloadable)) rsSetObject(t *dst, t src) { /*NOLINT*/ \
    413     Context *rsc = RsdCpuReference::getTlsContext();                         \
    414     rsrSetObject(rsc, reinterpret_cast<rs_object_base *>(dst),               \
    415                  (ObjectBase *)src.p);                                       \
    416   }
    417 
    418 IS_CLEAR_SET_OBJ(::rs_element)
    419 IS_CLEAR_SET_OBJ(::rs_type)
    420 IS_CLEAR_SET_OBJ(::rs_allocation)
    421 IS_CLEAR_SET_OBJ(::rs_sampler)
    422 IS_CLEAR_SET_OBJ(::rs_script)
    423 
    424 IS_CLEAR_SET_OBJ(::rs_mesh)
    425 IS_CLEAR_SET_OBJ(::rs_program_fragment)
    426 IS_CLEAR_SET_OBJ(::rs_program_vertex)
    427 IS_CLEAR_SET_OBJ(::rs_program_raster)
    428 IS_CLEAR_SET_OBJ(::rs_program_store)
    429 IS_CLEAR_SET_OBJ(::rs_font)
    430 
    431 #undef IS_CLEAR_SET_OBJ
    432 
    433 //////////////////////////////////////////////////////////////////////////////
    434 // Element routines
    435 //////////////////////////////////////////////////////////////////////////////
    436 static void *ElementAt(Allocation *a, RsDataType dt, uint32_t vecSize,
    437                        uint32_t x, uint32_t y, uint32_t z) {
    438   Context *rsc = RsdCpuReference::getTlsContext();
    439   const Type *t = a->getType();
    440   const Element *e = t->getElement();
    441 
    442   char buf[256];
    443   if (x && (x >= t->getLODDimX(0))) {
    444     snprintf(buf, sizeof(buf), "Out range ElementAt X %i of %i", x,
    445              t->getLODDimX(0));
    446     rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
    447     return nullptr;
    448   }
    449 
    450   if (y && (y >= t->getLODDimY(0))) {
    451     snprintf(buf, sizeof(buf), "Out range ElementAt Y %i of %i", y,
    452              t->getLODDimY(0));
    453     rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
    454     return nullptr;
    455   }
    456 
    457   if (z && (z >= t->getLODDimZ(0))) {
    458     snprintf(buf, sizeof(buf), "Out range ElementAt Z %i of %i", z,
    459              t->getLODDimZ(0));
    460     rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
    461     return nullptr;
    462   }
    463 
    464   if (vecSize > 0) {
    465     if (vecSize != e->getVectorSize()) {
    466       snprintf(buf, sizeof(buf), "Vector size mismatch for ElementAt %i of %i",
    467                vecSize, e->getVectorSize());
    468       rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
    469       return nullptr;
    470     }
    471 
    472     if (dt != e->getType()) {
    473       snprintf(buf, sizeof(buf), "Data type mismatch for ElementAt %i of %i",
    474                dt, e->getType());
    475       rsc->setError(RS_ERROR_FATAL_DEBUG, buf);
    476       return nullptr;
    477     }
    478   }
    479 
    480   uint8_t *p = (uint8_t *)a->mHal.drvState.lod[0].mallocPtr;
    481   const uint32_t eSize = e->getSizeBytes();
    482   const uint32_t stride = a->mHal.drvState.lod[0].stride;
    483   const uint32_t dimY = a->mHal.drvState.lod[0].dimY;
    484   return &p[(x * eSize) + (y * stride) + (z * stride * dimY)];
    485 }
    486 
    487 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y,
    488                     uint32_t z) {
    489   const Type *t = const_cast<Allocation *>((Allocation *)a.p)->getType();
    490   const Element *e = t->getElement();
    491   void *tmp = ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
    492   if (tmp != nullptr) memcpy(tmp, ptr, e->getSizeBytes());
    493 }
    494 
    495 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x,
    496                     uint32_t y) {
    497   rsSetElementAt(a, ptr, x, y, 0);
    498 }
    499 
    500 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x) {
    501   rsSetElementAt(a, ptr, x, 0, 0);
    502 }
    503 
    504 const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y,
    505                            uint32_t z) {
    506   return ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z);
    507 }
    508 
    509 const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y) {
    510   return rsGetElementAt(a, x, y, 0);
    511 }
    512 
    513 const void *rsGetElementAt(::rs_allocation a, uint32_t x) {
    514   return rsGetElementAt(a, x, 0, 0);
    515 }
    516 
    517 // Add NOLINT to suppress wrong warnings from clang-tidy.
    518 #define ELEMENT_AT(T, DT, VS)                                                 \
    519   void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x,        \
    520                           uint32_t y, uint32_t z) {                           \
    521     void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z);                  \
    522     if (r != nullptr)                                                         \
    523       ((T *)r)[0] = *val;                                                     \
    524     else                                                                      \
    525       ALOGE("Error from %s", __PRETTY_FUNCTION__);                            \
    526   }                                                                           \
    527   void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x,        \
    528                           uint32_t y) {                                       \
    529     rsSetElementAt_##T(a, val, x, y, 0);                                      \
    530   }                                                                           \
    531   void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x) {      \
    532     rsSetElementAt_##T(a, val, x, 0, 0);                                      \
    533   }                                                                           \
    534   void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y,  \
    535                           uint32_t z) { /*NOLINT*/                            \
    536     void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z);                  \
    537     if (r != nullptr)                                                         \
    538       *val = ((T *)r)[0];                                                     \
    539     else                                                                      \
    540       ALOGE("Error from %s", __PRETTY_FUNCTION__);                            \
    541   }                                                                           \
    542   void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x,              \
    543                           uint32_t y) { /*NOLINT*/                            \
    544     rsGetElementAt_##T(a, val, x, y, 0);                                      \
    545   }                                                                           \
    546   void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x) { /*NOLINT*/ \
    547     rsGetElementAt_##T(a, val, x, 0, 0);                                      \
    548   }
    549 
    550 ELEMENT_AT(char, RS_TYPE_SIGNED_8, 1)
    551 ELEMENT_AT(char2, RS_TYPE_SIGNED_8, 2)
    552 ELEMENT_AT(char3, RS_TYPE_SIGNED_8, 3)
    553 ELEMENT_AT(char4, RS_TYPE_SIGNED_8, 4)
    554 ELEMENT_AT(uchar, RS_TYPE_UNSIGNED_8, 1)
    555 ELEMENT_AT(uchar2, RS_TYPE_UNSIGNED_8, 2)
    556 ELEMENT_AT(uchar3, RS_TYPE_UNSIGNED_8, 3)
    557 ELEMENT_AT(uchar4, RS_TYPE_UNSIGNED_8, 4)
    558 ELEMENT_AT(short, RS_TYPE_SIGNED_16, 1)
    559 ELEMENT_AT(short2, RS_TYPE_SIGNED_16, 2)
    560 ELEMENT_AT(short3, RS_TYPE_SIGNED_16, 3)
    561 ELEMENT_AT(short4, RS_TYPE_SIGNED_16, 4)
    562 ELEMENT_AT(ushort, RS_TYPE_UNSIGNED_16, 1)
    563 ELEMENT_AT(ushort2, RS_TYPE_UNSIGNED_16, 2)
    564 ELEMENT_AT(ushort3, RS_TYPE_UNSIGNED_16, 3)
    565 ELEMENT_AT(ushort4, RS_TYPE_UNSIGNED_16, 4)
    566 ELEMENT_AT(int, RS_TYPE_SIGNED_32, 1)
    567 ELEMENT_AT(int2, RS_TYPE_SIGNED_32, 2)
    568 ELEMENT_AT(int3, RS_TYPE_SIGNED_32, 3)
    569 ELEMENT_AT(int4, RS_TYPE_SIGNED_32, 4)
    570 ELEMENT_AT(uint, RS_TYPE_UNSIGNED_32, 1)
    571 ELEMENT_AT(uint2, RS_TYPE_UNSIGNED_32, 2)
    572 ELEMENT_AT(uint3, RS_TYPE_UNSIGNED_32, 3)
    573 ELEMENT_AT(uint4, RS_TYPE_UNSIGNED_32, 4)
    574 ELEMENT_AT(long, RS_TYPE_SIGNED_64, 1)
    575 ELEMENT_AT(long2, RS_TYPE_SIGNED_64, 2)
    576 ELEMENT_AT(long3, RS_TYPE_SIGNED_64, 3)
    577 ELEMENT_AT(long4, RS_TYPE_SIGNED_64, 4)
    578 ELEMENT_AT(ulong, RS_TYPE_UNSIGNED_64, 1)
    579 ELEMENT_AT(ulong2, RS_TYPE_UNSIGNED_64, 2)
    580 ELEMENT_AT(ulong3, RS_TYPE_UNSIGNED_64, 3)
    581 ELEMENT_AT(ulong4, RS_TYPE_UNSIGNED_64, 4)
    582 ELEMENT_AT(half, RS_TYPE_FLOAT_16, 1)
    583 ELEMENT_AT(half2, RS_TYPE_FLOAT_16, 2)
    584 ELEMENT_AT(half3, RS_TYPE_FLOAT_16, 3)
    585 ELEMENT_AT(half4, RS_TYPE_FLOAT_16, 4)
    586 ELEMENT_AT(float, RS_TYPE_FLOAT_32, 1)
    587 ELEMENT_AT(float2, RS_TYPE_FLOAT_32, 2)
    588 ELEMENT_AT(float3, RS_TYPE_FLOAT_32, 3)
    589 ELEMENT_AT(float4, RS_TYPE_FLOAT_32, 4)
    590 ELEMENT_AT(double, RS_TYPE_FLOAT_64, 1)
    591 ELEMENT_AT(double2, RS_TYPE_FLOAT_64, 2)
    592 ELEMENT_AT(double3, RS_TYPE_FLOAT_64, 3)
    593 ELEMENT_AT(double4, RS_TYPE_FLOAT_64, 4)
    594 
    595 #undef ELEMENT_AT
    596 
    597 #ifndef __LP64__
    598 /*
    599  * We miss some symbols for rs{Get,Set}Element_long,ulong variants because 64
    600  * bit integer values are 'long' in RS-land but might be 'long long' in the
    601  * driver.  Define native_long* and native_ulong* types to be vectors of
    602  * 'long' as seen by the driver and define overloaded versions of
    603  * rsSetElementAt_* and rsGetElementAt_*.  This should get us the correct
    604  * mangled names in the driver.
    605  */
    606 
    607 typedef long native_long2 __attribute__((ext_vector_type(2)));
    608 typedef long native_long3 __attribute__((ext_vector_type(3)));
    609 typedef long native_long4 __attribute__((ext_vector_type(4)));
    610 typedef unsigned long native_ulong2 __attribute__((ext_vector_type(2)));
    611 typedef unsigned long native_ulong3 __attribute__((ext_vector_type(3)));
    612 typedef unsigned long native_ulong4 __attribute__((ext_vector_type(4)));
    613 
    614 // Add NOLINT to suppress wrong warnings from clang-tidy.
    615 #define ELEMENT_AT_OVERLOADS(T, U)                                            \
    616   void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x,        \
    617                           uint32_t y, uint32_t z) {                           \
    618     rsSetElementAt_##T(a, (T *)val, x, y, z);                                 \
    619   }                                                                           \
    620   void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x,        \
    621                           uint32_t y) {                                       \
    622     rsSetElementAt_##T(a, (T *)val, x, y, 0);                                 \
    623   }                                                                           \
    624   void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x) {      \
    625     rsSetElementAt_##T(a, (T *)val, x, 0, 0);                                 \
    626   }                                                                           \
    627   void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y,  \
    628                           uint32_t z) { /*NOLINT*/                            \
    629     rsGetElementAt_##T(a, (T *)val, x, y, z);                                 \
    630   }                                                                           \
    631   void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x,              \
    632                           uint32_t y) { /*NOLINT*/                            \
    633     rsGetElementAt_##T(a, (T *)val, x, y, 0);                                 \
    634   }                                                                           \
    635   void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x) { /*NOLINT*/ \
    636     rsGetElementAt_##T(a, (T *)val, x, 0, 0);                                 \
    637   }
    638 
    639 ELEMENT_AT_OVERLOADS(long2, native_long2)
    640 ELEMENT_AT_OVERLOADS(long3, native_long3)
    641 ELEMENT_AT_OVERLOADS(long4, native_long4)
    642 ELEMENT_AT_OVERLOADS(ulong, unsigned long)
    643 ELEMENT_AT_OVERLOADS(ulong2, native_ulong2)
    644 ELEMENT_AT_OVERLOADS(ulong3, native_ulong3)
    645 ELEMENT_AT_OVERLOADS(ulong4, native_ulong4)
    646 
    647 // We also need variants of rs{Get,Set}ElementAt_long that take 'long long *' as
    648 // we might have this overloaded variant in old APKs.
    649 ELEMENT_AT_OVERLOADS(long, long long)
    650 
    651 #undef ELEMENT_AT_OVERLOADS
    652 #endif
    653 
    654 //////////////////////////////////////////////////////////////////////////////
    655 // ForEach routines
    656 //////////////////////////////////////////////////////////////////////////////
    657 void rsForEachInternal(int slot, rs_script_call *options, int hasOutput,
    658                        int numInputs, ::rs_allocation *allocs) {
    659   Context *rsc = RsdCpuReference::getTlsContext();
    660   Script *s = const_cast<Script *>(RsdCpuReference::getTlsScript());
    661   if (numInputs > RS_KERNEL_MAX_ARGUMENTS) {
    662     rsc->setError(RS_ERROR_BAD_SCRIPT,
    663                   "rsForEachInternal: too many inputs to a kernel.");
    664     return;
    665   }
    666   Allocation *inputs[RS_KERNEL_MAX_ARGUMENTS];
    667   for (int i = 0; i < numInputs; i++) {
    668     inputs[i] = (Allocation *)allocs[i].p;
    669   }
    670   Allocation *out = hasOutput ? (Allocation *)allocs[numInputs].p : nullptr;
    671   rsrForEach(rsc, s, slot, numInputs, numInputs > 0 ? inputs : nullptr, out,
    672              nullptr, 0, (RsScriptCall *)options);
    673 }
    674 
    675 void __attribute__((overloadable))
    676 rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
    677           const void *usr, const rs_script_call *call) {
    678   Context *rsc = RsdCpuReference::getTlsContext();
    679   rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
    680              (Allocation *)out.p, usr, 0, (RsScriptCall *)call);
    681 }
    682 
    683 void __attribute__((overloadable))
    684 rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
    685           const void *usr) {
    686   Context *rsc = RsdCpuReference::getTlsContext();
    687   rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
    688              (Allocation *)out.p, usr, 0, nullptr);
    689 }
    690 
    691 void __attribute__((overloadable))
    692 rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out) {
    693   Context *rsc = RsdCpuReference::getTlsContext();
    694   rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
    695              (Allocation *)out.p, nullptr, 0, nullptr);
    696 }
    697 
    698 // These functions are only supported in 32-bit.
    699 #ifndef __LP64__
    700 void __attribute__((overloadable))
    701 rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
    702           const void *usr, uint32_t usrLen) {
    703   Context *rsc = RsdCpuReference::getTlsContext();
    704   rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
    705              (Allocation *)out.p, usr, usrLen, nullptr);
    706 }
    707 
    708 void __attribute__((overloadable))
    709 rsForEach(::rs_script script, ::rs_allocation in, ::rs_allocation out,
    710           const void *usr, uint32_t usrLen, const rs_script_call *call) {
    711   Context *rsc = RsdCpuReference::getTlsContext();
    712   rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p,
    713              (Allocation *)out.p, usr, usrLen, (RsScriptCall *)call);
    714 }
    715 #endif
    716 
    717 //////////////////////////////////////////////////////////////////////////////
    718 // Message routines
    719 //////////////////////////////////////////////////////////////////////////////
    720 uint32_t rsSendToClient(int cmdID) {
    721   Context *rsc = RsdCpuReference::getTlsContext();
    722   return rsrToClient(rsc, cmdID, (const void *)nullptr, 0);
    723 }
    724 
    725 uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) {
    726   Context *rsc = RsdCpuReference::getTlsContext();
    727   return rsrToClient(rsc, cmdID, data, len);
    728 }
    729 
    730 uint32_t rsSendToClientBlocking(int cmdID) {
    731   Context *rsc = RsdCpuReference::getTlsContext();
    732   return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0);
    733 }
    734 
    735 uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) {
    736   Context *rsc = RsdCpuReference::getTlsContext();
    737   return rsrToClientBlocking(rsc, cmdID, data, len);
    738 }
    739 
    740 //////////////////////////////////////////////////////////////////////////////
    741 // Time routines
    742 //////////////////////////////////////////////////////////////////////////////
    743 
    744 // time_t is int in 32-bit RenderScript.  time_t is long in bionic.  rsTime and
    745 // rsLocaltime are set to explicitly take 'const int *' so we generate the
    746 // correct mangled names.
    747 #ifndef __LP64__
    748 int rsTime(int *timer) {
    749 #else
    750 time_t rsTime(time_t *timer) {
    751 #endif
    752   Context *rsc = RsdCpuReference::getTlsContext();
    753   return rsrTime(rsc, (time_t *)timer);
    754 }
    755 
    756 #ifndef __LP64__
    757 rs_tm *rsLocaltime(rs_tm *local, const int *timer) {
    758 #else
    759 rs_tm *rsLocaltime(rs_tm *local, const time_t *timer) {
    760 #endif
    761   Context *rsc = RsdCpuReference::getTlsContext();
    762   return (rs_tm *)rsrLocalTime(rsc, (tm *)local, (time_t *)timer);
    763 }
    764 
    765 int64_t rsUptimeMillis() {
    766   Context *rsc = RsdCpuReference::getTlsContext();
    767   return rsrUptimeMillis(rsc);
    768 }
    769 
    770 int64_t rsUptimeNanos() {
    771   Context *rsc = RsdCpuReference::getTlsContext();
    772   return rsrUptimeNanos(rsc);
    773 }
    774 
    775 float rsGetDt() {
    776   Context *rsc = RsdCpuReference::getTlsContext();
    777   const Script *sc = RsdCpuReference::getTlsScript();
    778   return rsrGetDt(rsc, sc);
    779 }
    780 
    781 //////////////////////////////////////////////////////////////////////////////
    782 // Debug routines
    783 //////////////////////////////////////////////////////////////////////////////
    784 void rsDebug(const char *s, float f) {
    785   ALOGD("%s %f, 0x%08x", s, f, *((int *)(&f)));
    786 }
    787 
    788 void rsDebug(const char *s, float f1, float f2) {
    789   ALOGD("%s {%f, %f}", s, f1, f2);
    790 }
    791 
    792 void rsDebug(const char *s, float f1, float f2, float f3) {
    793   ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
    794 }
    795 
    796 void rsDebug(const char *s, float f1, float f2, float f3, float f4) {
    797   ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
    798 }
    799 
    800 void rsDebug(const char *s, const float2 *f2) {
    801   float2 f = *f2;
    802   ALOGD("%s {%f, %f}", s, f.x, f.y);
    803 }
    804 
    805 void rsDebug(const char *s, const float3 *f3) {
    806   float3 f = *f3;
    807   ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
    808 }
    809 
    810 void rsDebug(const char *s, const float4 *f4) {
    811   float4 f = *f4;
    812   ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
    813 }
    814 
    815 // Accept a half value converted to float.  This eliminates the need in the
    816 // driver to properly support the half datatype (either by adding compiler flags
    817 // for half or link against compiler_rt).
    818 void rsDebug(const char *s, float f, ushort us) {
    819   ALOGD("%s {%f} {0x%hx}", s, f, us);
    820 }
    821 
    822 void rsDebug(const char *s, const float2 *f2, const ushort2 *us2) {
    823   float2 f = *f2;
    824   ushort2 us = *us2;
    825   ALOGD("%s {%f %f} {0x%hx 0x%hx}", s, f.x, f.y, us.x, us.y);
    826 }
    827 
    828 void rsDebug(const char *s, const float3 *f3, const ushort3 *us3) {
    829   float3 f = *f3;
    830   ushort3 us = *us3;
    831   ALOGD("%s {%f %f %f} {0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, us.x, us.y,
    832         us.z);
    833 }
    834 
    835 void rsDebug(const char *s, const float4 *f4, const ushort4 *us4) {
    836   float4 f = *f4;
    837   ushort4 us = *us4;
    838   ALOGD("%s {%f %f %f %f} {0x%hx 0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, f.w,
    839         us.x, us.y, us.z, us.w);
    840 }
    841 
    842 void rsDebug(const char *s, double d) {
    843   ALOGD("%s %f, 0x%08llx", s, d, *((long long *)(&d)));
    844 }
    845 
    846 void rsDebug(const char *s, const double2 *d2) {
    847   double2 d = *d2;
    848   ALOGD("%s {%f, %f}", s, d.x, d.y);
    849 }
    850 
    851 void rsDebug(const char *s, const double3 *d3) {
    852   double3 d = *d3;
    853   ALOGD("%s {%f, %f, %f}", s, d.x, d.y, d.z);
    854 }
    855 
    856 void rsDebug(const char *s, const double4 *d4) {
    857   double4 d = *d4;
    858   ALOGD("%s {%f, %f, %f, %f}", s, d.x, d.y, d.z, d.w);
    859 }
    860 
    861 void rsDebug(const char *s, const rs_matrix4x4 *m) {
    862   float *f = (float *)m;
    863   ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
    864   ALOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
    865   ALOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
    866   ALOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
    867 }
    868 
    869 void rsDebug(const char *s, const rs_matrix3x3 *m) {
    870   float *f = (float *)m;
    871   ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
    872   ALOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
    873   ALOGD("%s  %f, %f, %f}", s, f[2], f[5], f[8]);
    874 }
    875 
    876 void rsDebug(const char *s, const rs_matrix2x2 *m) {
    877   float *f = (float *)m;
    878   ALOGD("%s {%f, %f", s, f[0], f[2]);
    879   ALOGD("%s  %f, %f}", s, f[1], f[3]);
    880 }
    881 
    882 void rsDebug(const char *s, char c) {
    883   ALOGD("%s %hhd  0x%hhx", s, c, (unsigned char)c);
    884 }
    885 
    886 void rsDebug(const char *s, const char2 *c2) {
    887   char2 c = *c2;
    888   ALOGD("%s {%hhd, %hhd}  0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x,
    889         (unsigned char)c.y);
    890 }
    891 
    892 void rsDebug(const char *s, const char3 *c3) {
    893   char3 c = *c3;
    894   ALOGD("%s {%hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z,
    895         (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z);
    896 }
    897 
    898 void rsDebug(const char *s, const char4 *c4) {
    899   char4 c = *c4;
    900   ALOGD("%s {%hhd, %hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y,
    901         c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z,
    902         (unsigned char)c.w);
    903 }
    904 
    905 void rsDebug(const char *s, unsigned char c) {
    906   ALOGD("%s %hhu  0x%hhx", s, c, c);
    907 }
    908 
    909 void rsDebug(const char *s, const uchar2 *c2) {
    910   uchar2 c = *c2;
    911   ALOGD("%s {%hhu, %hhu}  0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
    912 }
    913 
    914 void rsDebug(const char *s, const uchar3 *c3) {
    915   uchar3 c = *c3;
    916   ALOGD("%s {%hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x,
    917         c.y, c.z);
    918 }
    919 
    920 void rsDebug(const char *s, const uchar4 *c4) {
    921   uchar4 c = *c4;
    922   ALOGD("%s {%hhu, %hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y,
    923         c.z, c.w, c.x, c.y, c.z, c.w);
    924 }
    925 
    926 void rsDebug(const char *s, short c) { ALOGD("%s %hd  0x%hx", s, c, c); }
    927 
    928 void rsDebug(const char *s, const short2 *c2) {
    929   short2 c = *c2;
    930   ALOGD("%s {%hd, %hd}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
    931 }
    932 
    933 void rsDebug(const char *s, const short3 *c3) {
    934   short3 c = *c3;
    935   ALOGD("%s {%hd, %hd, %hd}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y,
    936         c.z);
    937 }
    938 
    939 void rsDebug(const char *s, const short4 *c4) {
    940   short4 c = *c4;
    941   ALOGD("%s {%hd, %hd, %hd, %hd}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z,
    942         c.w, c.x, c.y, c.z, c.w);
    943 }
    944 
    945 void rsDebug(const char *s, unsigned short c) {
    946   ALOGD("%s %hu  0x%hx", s, c, c);
    947 }
    948 
    949 void rsDebug(const char *s, const ushort2 *c2) {
    950   ushort2 c = *c2;
    951   ALOGD("%s {%hu, %hu}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
    952 }
    953 
    954 void rsDebug(const char *s, const ushort3 *c3) {
    955   ushort3 c = *c3;
    956   ALOGD("%s {%hu, %hu, %hu}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y,
    957         c.z);
    958 }
    959 
    960 void rsDebug(const char *s, const ushort4 *c4) {
    961   ushort4 c = *c4;
    962   ALOGD("%s {%hu, %hu, %hu, %hu}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z,
    963         c.w, c.x, c.y, c.z, c.w);
    964 }
    965 
    966 void rsDebug(const char *s, int i) { ALOGD("%s %d  0x%x", s, i, i); }
    967 
    968 void rsDebug(const char *s, const int2 *i2) {
    969   int2 i = *i2;
    970   ALOGD("%s {%d, %d}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
    971 }
    972 
    973 void rsDebug(const char *s, const int3 *i3) {
    974   int3 i = *i3;
    975   ALOGD("%s {%d, %d, %d}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
    976 }
    977 
    978 void rsDebug(const char *s, const int4 *i4) {
    979   int4 i = *i4;
    980   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,
    981         i.y, i.z, i.w);
    982 }
    983 
    984 void rsDebug(const char *s, unsigned int i) { ALOGD("%s %u  0x%x", s, i, i); }
    985 
    986 void rsDebug(const char *s, const uint2 *i2) {
    987   uint2 i = *i2;
    988   ALOGD("%s {%u, %u}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
    989 }
    990 
    991 void rsDebug(const char *s, const uint3 *i3) {
    992   uint3 i = *i3;
    993   ALOGD("%s {%u, %u, %u}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
    994 }
    995 
    996 void rsDebug(const char *s, const uint4 *i4) {
    997   uint4 i = *i4;
    998   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,
    999         i.y, i.z, i.w);
   1000 }
   1001 
   1002 template <typename T>
   1003 static inline long long LL(const T &x) {
   1004   return static_cast<long long>(x);
   1005 }
   1006 
   1007 template <typename T>
   1008 static inline unsigned long long LLu(const T &x) {
   1009   return static_cast<unsigned long long>(x);
   1010 }
   1011 
   1012 void rsDebug(const char *s, long l) {
   1013   ALOGD("%s %lld  0x%llx", s, LL(l), LL(l));
   1014 }
   1015 
   1016 void rsDebug(const char *s, long long ll) {
   1017   ALOGD("%s %lld  0x%llx", s, LL(ll), LL(ll));
   1018 }
   1019 
   1020 void rsDebug(const char *s, const long2 *c) {
   1021   long2 ll = *c;
   1022   ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
   1023         LL(ll.y));
   1024 }
   1025 
   1026 void rsDebug(const char *s, const long3 *c) {
   1027   long3 ll = *c;
   1028   ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
   1029         LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
   1030 }
   1031 
   1032 void rsDebug(const char *s, const long4 *c) {
   1033   long4 ll = *c;
   1034   ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
   1035         LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
   1036 }
   1037 
   1038 void rsDebug(const char *s, unsigned long l) {
   1039   unsigned long long ll = l;
   1040   ALOGD("%s %llu  0x%llx", s, ll, ll);
   1041 }
   1042 
   1043 void rsDebug(const char *s, unsigned long long ll) {
   1044   ALOGD("%s %llu  0x%llx", s, ll, ll);
   1045 }
   1046 
   1047 void rsDebug(const char *s, const ulong2 *c) {
   1048   ulong2 ll = *c;
   1049   ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
   1050         LLu(ll.y));
   1051 }
   1052 
   1053 void rsDebug(const char *s, const ulong3 *c) {
   1054   ulong3 ll = *c;
   1055   ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
   1056         LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
   1057 }
   1058 
   1059 void rsDebug(const char *s, const ulong4 *c) {
   1060   ulong4 ll = *c;
   1061   ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s,
   1062         LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
   1063         LLu(ll.z), LLu(ll.w));
   1064 }
   1065 
   1066 // FIXME: We need to export these function signatures for the compatibility
   1067 // library. The C++ name mangling that LLVM uses for ext_vector_type requires
   1068 // different versions for "long" vs. "long long". Note that the called
   1069 // functions are still using the appropriate 64-bit sizes.
   1070 
   1071 #ifndef __LP64__
   1072 typedef long l2 __attribute__((ext_vector_type(2)));
   1073 typedef long l3 __attribute__((ext_vector_type(3)));
   1074 typedef long l4 __attribute__((ext_vector_type(4)));
   1075 typedef unsigned long ul2 __attribute__((ext_vector_type(2)));
   1076 typedef unsigned long ul3 __attribute__((ext_vector_type(3)));
   1077 typedef unsigned long ul4 __attribute__((ext_vector_type(4)));
   1078 
   1079 void rsDebug(const char *s, const l2 *c) {
   1080   long2 ll = *(const long2 *)c;
   1081   ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
   1082         LL(ll.y));
   1083 }
   1084 
   1085 void rsDebug(const char *s, const l3 *c) {
   1086   long3 ll = *(const long3 *)c;
   1087   ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
   1088         LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
   1089 }
   1090 
   1091 void rsDebug(const char *s, const l4 *c) {
   1092   long4 ll = *(const long4 *)c;
   1093   ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
   1094         LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
   1095 }
   1096 
   1097 void rsDebug(const char *s, const ul2 *c) {
   1098   ulong2 ll = *(const ulong2 *)c;
   1099   ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
   1100         LLu(ll.y));
   1101 }
   1102 
   1103 void rsDebug(const char *s, const ul3 *c) {
   1104   ulong3 ll = *(const ulong3 *)c;
   1105   ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
   1106         LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
   1107 }
   1108 
   1109 void rsDebug(const char *s, const ul4 *c) {
   1110   ulong4 ll = *(const ulong4 *)c;
   1111   ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s,
   1112         LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
   1113         LLu(ll.z), LLu(ll.w));
   1114 }
   1115 #endif
   1116 
   1117 void rsDebug(const char *s, const long2 ll) {
   1118   ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x),
   1119         LL(ll.y));
   1120 }
   1121 
   1122 void rsDebug(const char *s, const long3 ll) {
   1123   ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y),
   1124         LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z));
   1125 }
   1126 
   1127 void rsDebug(const char *s, const long4 ll) {
   1128   ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x),
   1129         LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w));
   1130 }
   1131 
   1132 void rsDebug(const char *s, const ulong2 ll) {
   1133   ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x),
   1134         LLu(ll.y));
   1135 }
   1136 
   1137 void rsDebug(const char *s, const ulong3 ll) {
   1138   ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y),
   1139         LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z));
   1140 }
   1141 
   1142 void rsDebug(const char *s, const ulong4 ll) {
   1143   ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s,
   1144         LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y),
   1145         LLu(ll.z), LLu(ll.w));
   1146 }
   1147 
   1148 void rsDebug(const char *s, const void *p) { ALOGD("%s %p", s, p); }
   1149