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