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