• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
failIfInKernel(Context * rsc,const char * funcName)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
rsGetAllocation(const void * ptr)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
rsGetAllocation(const void * ptr)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 
rsAllocationIoSend(::rs_allocation a)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 
rsAllocationIoReceive(::rs_allocation a)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))
rsAllocationCopy1DRange(::rs_allocation dstAlloc,uint32_t dstOff,uint32_t dstMip,uint32_t count,::rs_allocation srcAlloc,uint32_t srcOff,uint32_t srcMip)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))
rsAllocationCopy2DRange(::rs_allocation dstAlloc,uint32_t dstXoff,uint32_t dstYoff,uint32_t dstMip,rs_allocation_cubemap_face dstFace,uint32_t width,uint32_t height,::rs_allocation srcAlloc,uint32_t srcXoff,uint32_t srcYoff,uint32_t srcMip,rs_allocation_cubemap_face srcFace)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 
CreateElement(RsDataType dt,RsDataKind dk,bool isNormalized,uint32_t vecSize)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 
CreateType(RsElement element,uint32_t dimX,uint32_t dimY,uint32_t dimZ,bool mipmaps,bool faces,uint32_t yuv_format)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 
CreateAllocation(RsType type,RsAllocationMipmapControl mipmaps,uint32_t usages,void * ptr)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.
rsCreateElement(int32_t dt,int32_t dk,bool isNormalized,uint32_t vecSize)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 
rsCreateType(::rs_element element,uint32_t dimX,uint32_t dimY,uint32_t dimZ,bool mipmaps,bool faces,rs_yuv_format yuv_format)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 
rsCreateAllocation(::rs_type type,rs_allocation_mipmap_control mipmaps,uint32_t usages,void * ptr)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
rsCreateElement(int32_t dt,int32_t dk,bool isNormalized,uint32_t vecSize)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 
rsCreateType(::rs_element element,uint32_t dimX,uint32_t dimY,uint32_t dimZ,bool mipmaps,bool faces,rs_yuv_format yuv_format)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 
rsCreateAllocation(::rs_type type,rs_allocation_mipmap_control mipmaps,uint32_t usages,void * ptr)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)
IS_CLEAR_SET_OBJ(::rs_type)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 
rsSetElementAt(::rs_allocation a,const void * ptr,uint32_t x,uint32_t y,uint32_t z)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 
rsSetElementAt(::rs_allocation a,const void * ptr,uint32_t x,uint32_t y)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 
rsSetElementAt(::rs_allocation a,const void * ptr,uint32_t x)500 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x) {
501   rsSetElementAt(a, ptr, x, 0, 0);
502 }
503 
rsGetElementAt(::rs_allocation a,uint32_t x,uint32_t y,uint32_t z)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 
rsGetElementAt(::rs_allocation a,uint32_t x,uint32_t y)509 const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y) {
510   return rsGetElementAt(a, x, y, 0);
511 }
512 
rsGetElementAt(::rs_allocation a,uint32_t x)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 
ELEMENT_AT_OVERLOADS(long2,native_long2)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))
rsForEach(::rs_script script,::rs_allocation in,::rs_allocation out,const void * usr,const rs_script_call * call)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))
rsForEach(::rs_script script,::rs_allocation in,::rs_allocation out,const void * usr)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))
rsForEach(::rs_script script,::rs_allocation in,::rs_allocation out)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))
rsForEach(::rs_script script,::rs_allocation in,::rs_allocation out,const void * usr,uint32_t usrLen)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))
rsForEach(::rs_script script,::rs_allocation in,::rs_allocation out,const void * usr,uint32_t usrLen,const rs_script_call * call)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 //////////////////////////////////////////////////////////////////////////////
rsSendToClient(int cmdID)720 uint32_t rsSendToClient(int cmdID) {
721   Context *rsc = RsdCpuReference::getTlsContext();
722   return rsrToClient(rsc, cmdID, (const void *)nullptr, 0);
723 }
724 
rsSendToClient(int cmdID,const void * data,uint32_t len)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 
rsSendToClientBlocking(int cmdID)730 uint32_t rsSendToClientBlocking(int cmdID) {
731   Context *rsc = RsdCpuReference::getTlsContext();
732   return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0);
733 }
734 
rsSendToClientBlocking(int cmdID,const void * data,uint32_t len)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__
rsTime(int * timer)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