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