1 #include "rs_core.rsh"
2 #include "rs_structs.h"
3 
4 // Opaque Allocation type operations
5 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimX(rs_allocation a)6     rsAllocationGetDimX(rs_allocation a) {
7     Allocation_t *alloc = (Allocation_t *)a.p;
8     return alloc->mHal.drvState.lod[0].dimX;
9 }
10 
11 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimY(rs_allocation a)12         rsAllocationGetDimY(rs_allocation a) {
13     Allocation_t *alloc = (Allocation_t *)a.p;
14     return alloc->mHal.drvState.lod[0].dimY;
15 }
16 
17 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimZ(rs_allocation a)18         rsAllocationGetDimZ(rs_allocation a) {
19     Allocation_t *alloc = (Allocation_t *)a.p;
20     return alloc->mHal.drvState.lod[0].dimZ;
21 }
22 
23 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimLOD(rs_allocation a)24         rsAllocationGetDimLOD(rs_allocation a) {
25     Allocation_t *alloc = (Allocation_t *)a.p;
26     return alloc->mHal.state.hasMipmaps;
27 }
28 
29 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimFaces(rs_allocation a)30         rsAllocationGetDimFaces(rs_allocation a) {
31     Allocation_t *alloc = (Allocation_t *)a.p;
32     return alloc->mHal.state.hasFaces;
33 }
34 
35 
36 extern rs_element __attribute__((overloadable))
rsAllocationGetElement(rs_allocation a)37         rsAllocationGetElement(rs_allocation a) {
38     Allocation_t *alloc = (Allocation_t *)a.p;
39     if (alloc == NULL) {
40         rs_element nullElem = RS_NULL_OBJ;
41         return nullElem;
42     }
43     Type_t *type = (Type_t *)alloc->mHal.state.type;
44     rs_element returnElem = {
45         type->mHal.state.element
46 #ifdef __LP64__
47         , 0, 0, 0
48 #endif
49     };
50     rs_element rs_retval = RS_NULL_OBJ;
51     rsSetObject(&rs_retval, returnElem);
52     return rs_retval;
53 }
54 
55 // TODO: this needs to be optimized, obviously
local_memcpy(void * dst,const void * src,size_t size)56 static void local_memcpy(void* dst, const void* src, size_t size) {
57     char* dst_c = (char*) dst;
58     const char* src_c = (const char*) src;
59     for (; size > 0; size--) {
60         *dst_c++ = *src_c++;
61     }
62 }
63 
64 uint8_t*
rsOffset(rs_allocation a,uint32_t sizeOf,uint32_t x,uint32_t y,uint32_t z)65 rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y,
66          uint32_t z) {
67     Allocation_t *alloc = (Allocation_t *)a.p;
68     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
69     const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride;
70     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
71     uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
72                      (z * stride * dimY)];
73     return dp;
74 }
75 
76 uint8_t*
rsOffsetNs(rs_allocation a,uint32_t x,uint32_t y,uint32_t z)77 rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
78     Allocation_t *alloc = (Allocation_t *)a.p;
79     uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
80     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
81     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
82     const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;;
83     uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
84                      (z * stride * dimY)];
85     return dp;
86 }
87 
88 #ifdef RS_DEBUG_RUNTIME
89 #define ELEMENT_AT(T)                                                   \
90     extern void __attribute__((overloadable))                           \
91         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x);  \
92     extern void __attribute__((overloadable))                           \
93         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y); \
94     extern void __attribute__((overloadable))                           \
95         rsSetElementAt_##T(rs_allocation a, const T *val, uint32_t x, uint32_t y, uint32_t z); \
96     extern void __attribute__((overloadable))                           \
97         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x);  \
98     extern void __attribute__((overloadable))                           \
99         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y); \
100     extern void __attribute__((overloadable))                           \
101         rsGetElementAt_##T(rs_allocation a, T *val, uint32_t x, uint32_t y, uint32_t z); \
102                                                                         \
103     extern void __attribute__((overloadable))                           \
104     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) {            \
105         rsSetElementAt_##T(a, &val, x);                                 \
106     }                                                                   \
107     extern void __attribute__((overloadable))                           \
108     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
109         rsSetElementAt_##T(a, &val, x, y);                              \
110     }                                                                   \
111     extern void __attribute__((overloadable))                           \
112     rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
113         rsSetElementAt_##T(a, &val, x, y, z);                           \
114     }                                                                   \
115     extern T __attribute__((overloadable))                              \
116     rsGetElementAt_##T(rs_allocation a, uint32_t x) {                   \
117         T tmp;                                                          \
118         rsGetElementAt_##T(a, &tmp, x);                                 \
119         return tmp;                                                     \
120     }                                                                   \
121     extern T __attribute__((overloadable))                              \
122     rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y) {       \
123         T tmp;                                                          \
124         rsGetElementAt_##T(a, &tmp, x, y);                              \
125         return tmp;                                                     \
126     }                                                                   \
127     extern T __attribute__((overloadable))                              \
128     rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
129         T tmp;                                                          \
130         rsGetElementAt_##T(a, &tmp, x, y, z);                           \
131         return tmp;                                                     \
132     }
133 #else  // NOT RS_DEBUG_RUNTIME
134 
135 #define SET_ELEMENT_AT_TYPE_IMPL(T, typename)                                    \
136     void                                                                \
137     rsSetElementAtImpl_##typename(rs_allocation a, typename val, uint32_t x,   \
138                                   uint32_t y, uint32_t z);
139 
140 #define GET_ELEMENT_AT_TYPE_IMPL(T, typename)                                \
141     typename                                                            \
142     rsGetElementAtImpl_##typename(rs_allocation a, uint32_t x, uint32_t y, \
143                                   uint32_t z);
144 
145 #define SET_ELEMENT_AT_TYPE_DEF(T, typename)                                    \
146     extern void __attribute__((overloadable))                           \
147     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x) {     \
148         rsSetElementAtImpl_##typename(a, (typename)val, x, 0, 0);              \
149     }                                                                   \
150                                                                         \
151     extern void __attribute__((overloadable))                           \
152     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x,       \
153                               uint32_t y) {                             \
154         rsSetElementAtImpl_##typename(a, (typename)val, x, y, 0);              \
155     }                                                                   \
156                                                                         \
157     extern void __attribute__((overloadable))                           \
158     rsSetElementAt_##typename(rs_allocation a, T val, uint32_t x, uint32_t y, \
159                               uint32_t z) {                             \
160         rsSetElementAtImpl_##typename(a, (typename)val, x, y, z);              \
161     }
162 
163 #define GET_ELEMENT_AT_TYPE_DEF(T, typename)                                \
164     extern typename __attribute__((overloadable))                       \
165     rsGetElementAt_##typename(rs_allocation a, uint32_t x) {            \
166         return (typename)rsGetElementAtImpl_##typename(a, x, 0, 0);     \
167     }                                                                   \
168                                                                         \
169     extern typename __attribute__((overloadable))                       \
170     rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y) { \
171         return (typename)rsGetElementAtImpl_##typename(a, x, y, 0);     \
172     }                                                                   \
173                                                                         \
174     extern typename __attribute__((overloadable))                       \
175     rsGetElementAt_##typename(rs_allocation a, uint32_t x, uint32_t y,  \
176                               uint32_t z) {                             \
177         return (typename)rsGetElementAtImpl_##typename(a, x, y, z);     \
178     }
179 
180 #define SET_ELEMENT_AT(T) SET_ELEMENT_AT_TYPE_IMPL(T, T) \
181     SET_ELEMENT_AT_TYPE_DEF(T, T)
182 #define GET_ELEMENT_AT(T) GET_ELEMENT_AT_TYPE_IMPL(T, T) \
183     GET_ELEMENT_AT_TYPE_DEF(T, T)
184 
185 #define ELEMENT_AT(T)                           \
186     SET_ELEMENT_AT(T)                           \
187     GET_ELEMENT_AT(T)
188 
189 #endif // RS_DEBUG_RUNTIME
190 
191 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x)192         rsGetElementAt(rs_allocation a, uint32_t x) {
193     Allocation_t *alloc = (Allocation_t *)a.p;
194     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
195     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
196     return &p[eSize * x];
197 }
198 
199 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x,uint32_t y)200         rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
201     Allocation_t *alloc = (Allocation_t *)a.p;
202     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
203     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
204     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
205     return &p[(eSize * x) + (y * stride)];
206 }
207 
208 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x,uint32_t y,uint32_t z)209         rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
210     Allocation_t *alloc = (Allocation_t *)a.p;
211     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
212     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
213     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
214     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
215     return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
216 }
217 extern void __attribute__((overloadable))
rsSetElementAt(rs_allocation a,void * ptr,uint32_t x)218         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
219     Allocation_t *alloc = (Allocation_t *)a.p;
220     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
221     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
222     local_memcpy((void*)&p[eSize * x], ptr, eSize);
223 }
224 
225 extern void __attribute__((overloadable))
rsSetElementAt(rs_allocation a,void * ptr,uint32_t x,uint32_t y)226         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
227     Allocation_t *alloc = (Allocation_t *)a.p;
228     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
229     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
230     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
231     local_memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
232 }
233 
234 extern void __attribute__((overloadable))
rsSetElementAt(rs_allocation a,void * ptr,uint32_t x,uint32_t y,uint32_t z)235         rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y, uint32_t z) {
236     Allocation_t *alloc = (Allocation_t *)a.p;
237     const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
238     const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
239     const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
240     const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
241     local_memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
242 }
243 
244 ELEMENT_AT(char)
245 ELEMENT_AT(char2)
246 ELEMENT_AT(char3)
247 ELEMENT_AT(char4)
248 ELEMENT_AT(uchar)
249 ELEMENT_AT(uchar2)
250 ELEMENT_AT(uchar3)
251 ELEMENT_AT(uchar4)
252 ELEMENT_AT(short)
253 ELEMENT_AT(short2)
254 ELEMENT_AT(short3)
255 ELEMENT_AT(short4)
256 ELEMENT_AT(ushort)
257 ELEMENT_AT(ushort2)
258 ELEMENT_AT(ushort3)
259 ELEMENT_AT(ushort4)
260 ELEMENT_AT(int)
261 ELEMENT_AT(int2)
262 ELEMENT_AT(int3)
263 ELEMENT_AT(int4)
264 ELEMENT_AT(uint)
265 ELEMENT_AT(uint2)
266 ELEMENT_AT(uint3)
267 ELEMENT_AT(uint4)
268 ELEMENT_AT(long)
269 ELEMENT_AT(long2)
270 ELEMENT_AT(long3)
271 ELEMENT_AT(long4)
272 ELEMENT_AT(ulong)
273 ELEMENT_AT(ulong2)
274 ELEMENT_AT(ulong3)
275 ELEMENT_AT(ulong4)
276 ELEMENT_AT(half)
277 ELEMENT_AT(half2)
278 ELEMENT_AT(half3)
279 ELEMENT_AT(half4)
280 ELEMENT_AT(float)
281 ELEMENT_AT(float2)
282 ELEMENT_AT(float3)
283 ELEMENT_AT(float4)
284 ELEMENT_AT(double)
285 ELEMENT_AT(double2)
286 ELEMENT_AT(double3)
287 ELEMENT_AT(double4)
288 
289 typedef unsigned long long ull;
290 typedef unsigned long long ull2 __attribute__((ext_vector_type(2)));
291 typedef unsigned long long ull3 __attribute__((ext_vector_type(3)));
292 typedef unsigned long long ull4 __attribute__((ext_vector_type(4)));
293 
294 #ifndef RS_DEBUG_RUNTIME
SET_ELEMENT_AT_TYPE_IMPL(ull,ulong)295 SET_ELEMENT_AT_TYPE_IMPL(ull, ulong)
296 SET_ELEMENT_AT_TYPE_IMPL(ull2, ulong2)
297 SET_ELEMENT_AT_TYPE_IMPL(ull3, ulong3)
298 SET_ELEMENT_AT_TYPE_IMPL(ull4, ulong4)
299 
300 #undef SET_ELEMENT_AT_TYPE_DEF
301 #undef GET_ELEMENT_AT_TYPE_DEF
302 #undef SET_ELEMENT_AT_TYPE_IMPL
303 #undef GET_ELEMENT_AT_TYPE_IMPL
304 #undef ELEMENT_AT_TYPE
305 #endif
306 
307 #undef ELEMENT_AT
308 
309 
310 extern uchar __attribute__((overloadable))
311         rsGetElementAtYuv_uchar_Y(rs_allocation a, uint32_t x, uint32_t y) {
312     return rsGetElementAt_uchar(a, x, y);
313 }
314 
315 extern uchar __attribute__((overloadable))
rsGetElementAtYuv_uchar_U(rs_allocation a,uint32_t x,uint32_t y)316         rsGetElementAtYuv_uchar_U(rs_allocation a, uint32_t x, uint32_t y) {
317 
318     Allocation_t *alloc = (Allocation_t *)a.p;
319 
320     const size_t cstep = alloc->mHal.drvState.yuv.step;
321     const size_t shift = alloc->mHal.drvState.yuv.shift;
322     const size_t stride = alloc->mHal.drvState.lod[1].stride;
323 
324     const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[1].mallocPtr;
325 
326     return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
327 }
328 
329 extern uchar __attribute__((overloadable))
rsGetElementAtYuv_uchar_V(rs_allocation a,uint32_t x,uint32_t y)330         rsGetElementAtYuv_uchar_V(rs_allocation a, uint32_t x, uint32_t y) {
331 
332     Allocation_t *alloc = (Allocation_t *)a.p;
333 
334     const size_t cstep = alloc->mHal.drvState.yuv.step;
335     const size_t shift = alloc->mHal.drvState.yuv.shift;
336     const size_t stride = alloc->mHal.drvState.lod[2].stride;
337 
338     const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[2].mallocPtr;
339 
340     return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
341 }
342 
343 #define VOP_IMPL(T)                                                          \
344     extern void __rsAllocationVStoreXImpl_##T(rs_allocation a, const T val, uint32_t x, uint32_t y, uint32_t z); \
345     extern T __rsAllocationVLoadXImpl_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z);
346 
347 #define VOP_DEF(T)                                                      \
348     extern void __attribute__((overloadable))                           \
349     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x) {       \
350         __rsAllocationVStoreXImpl_##T(a, val, x, 0, 0);                 \
351     }                                                                   \
352     extern void __attribute__((overloadable))                           \
353     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y) { \
354         __rsAllocationVStoreXImpl_##T(a, val, x, y, 0);                 \
355     }                                                                   \
356     extern void __attribute__((overloadable))                           \
357     rsAllocationVStoreX_##T(rs_allocation a, T val, uint32_t x, uint32_t y, uint32_t z) { \
358         __rsAllocationVStoreXImpl_##T(a, val, x, y, z);                 \
359     }                                                                   \
360     extern T __attribute__((overloadable))                              \
361     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x) {               \
362         return __rsAllocationVLoadXImpl_##T(a, x, 0, 0);                \
363     }                                                                   \
364     extern T __attribute__((overloadable))                              \
365     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y) {   \
366         return __rsAllocationVLoadXImpl_##T(a, x, y, 0);                \
367     }                                                                   \
368     extern T __attribute__((overloadable))                              \
369     rsAllocationVLoadX_##T(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { \
370         return __rsAllocationVLoadXImpl_##T(a, x, y, z);                \
371     }
372 
373 #define VOP(T) VOP_IMPL(T) \
374     VOP_DEF(T)
375 
376 VOP(char2)
377 VOP(char3)
378 VOP(char4)
379 VOP(uchar2)
380 VOP(uchar3)
381 VOP(uchar4)
382 VOP(short2)
383 VOP(short3)
384 VOP(short4)
385 VOP(ushort2)
386 VOP(ushort3)
387 VOP(ushort4)
388 VOP(int2)
389 VOP(int3)
390 VOP(int4)
391 VOP(uint2)
392 VOP(uint3)
393 VOP(uint4)
394 VOP(long2)
395 VOP(long3)
396 VOP(long4)
397 VOP(ulong2)
398 VOP(ulong3)
399 VOP(ulong4)
400 VOP(float2)
401 VOP(float3)
402 VOP(float4)
403 VOP(double2)
404 VOP(double3)
405 VOP(double4)
406 
407 #undef VOP_IMPL
408 #undef VOP_DEF
409 #undef VOP
410 
411 static const rs_element kInvalidElement = RS_NULL_OBJ;
412 
413 extern rs_element __attribute__((overloadable)) rsCreateElement(
414         int32_t dt, int32_t dk, bool isNormalized, uint32_t vecSize);
415 
416 extern rs_type __attribute__((overloadable)) rsCreateType(
417     rs_element element, uint32_t dimX, uint32_t dimY, uint32_t dimZ,
418     bool mipmaps, bool faces, rs_yuv_format yuv_format);
419 
420 extern rs_allocation __attribute__((overloadable)) rsCreateAllocation(
421         rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages,
422         void *ptr);
423 
rsCreateElement(rs_data_type data_type)424 rs_element __attribute__((overloadable)) rsCreateElement(
425         rs_data_type data_type) {
426 
427     switch (data_type) {
428         case RS_TYPE_BOOLEAN:
429         case RS_TYPE_FLOAT_16:
430         case RS_TYPE_FLOAT_32:
431         case RS_TYPE_FLOAT_64:
432         case RS_TYPE_SIGNED_8:
433         case RS_TYPE_SIGNED_16:
434         case RS_TYPE_SIGNED_32:
435         case RS_TYPE_SIGNED_64:
436         case RS_TYPE_UNSIGNED_8:
437         case RS_TYPE_UNSIGNED_16:
438         case RS_TYPE_UNSIGNED_32:
439         case RS_TYPE_UNSIGNED_64:
440         case RS_TYPE_MATRIX_4X4:
441         case RS_TYPE_MATRIX_3X3:
442         case RS_TYPE_MATRIX_2X2:
443         case RS_TYPE_ELEMENT:
444         case RS_TYPE_TYPE:
445         case RS_TYPE_ALLOCATION:
446         case RS_TYPE_SCRIPT:
447             return rsCreateElement(data_type, RS_KIND_USER, false, 1);
448         default:
449             rsDebug("Invalid data_type", data_type);
450             return kInvalidElement;
451     }
452 }
453 
rsCreateVectorElement(rs_data_type data_type,uint32_t vector_width)454 rs_element __attribute__((overloadable)) rsCreateVectorElement(
455         rs_data_type data_type, uint32_t vector_width) {
456     if (vector_width < 2 || vector_width > 4) {
457         rsDebug("Invalid vector_width", vector_width);
458         return kInvalidElement;
459     }
460     switch (data_type) {
461         case RS_TYPE_BOOLEAN:
462         case RS_TYPE_FLOAT_16:
463         case RS_TYPE_FLOAT_32:
464         case RS_TYPE_FLOAT_64:
465         case RS_TYPE_SIGNED_8:
466         case RS_TYPE_SIGNED_16:
467         case RS_TYPE_SIGNED_32:
468         case RS_TYPE_SIGNED_64:
469         case RS_TYPE_UNSIGNED_8:
470         case RS_TYPE_UNSIGNED_16:
471         case RS_TYPE_UNSIGNED_32:
472         case RS_TYPE_UNSIGNED_64:
473             return rsCreateElement(data_type, RS_KIND_USER, false,
474                                    vector_width);
475         default:
476             rsDebug("Invalid data_type for vector element", data_type);
477             return kInvalidElement;
478     }
479 }
480 
rsCreatePixelElement(rs_data_type data_type,rs_data_kind data_kind)481 rs_element __attribute__((overloadable)) rsCreatePixelElement(
482         rs_data_type data_type, rs_data_kind data_kind) {
483     if (data_type != RS_TYPE_UNSIGNED_8 &&
484         data_type != RS_TYPE_UNSIGNED_16 &&
485         data_type != RS_TYPE_UNSIGNED_5_6_5 &&
486         data_type != RS_TYPE_UNSIGNED_4_4_4_4 &&
487         data_type != RS_TYPE_UNSIGNED_5_5_5_1) {
488 
489         rsDebug("Invalid data_type for pixel element", data_type);
490         return kInvalidElement;
491     }
492     if (data_kind != RS_KIND_PIXEL_L &&
493         data_kind != RS_KIND_PIXEL_A &&
494         data_kind != RS_KIND_PIXEL_LA &&
495         data_kind != RS_KIND_PIXEL_RGB &&
496         data_kind != RS_KIND_PIXEL_RGBA &&
497         data_kind != RS_KIND_PIXEL_DEPTH &&
498         data_kind != RS_KIND_PIXEL_YUV) {
499 
500         rsDebug("Invalid data_kind for pixel element", data_type);
501         return kInvalidElement;
502     }
503     if (data_type == RS_TYPE_UNSIGNED_5_6_5 && data_kind != RS_KIND_PIXEL_RGB) {
504         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
505         return kInvalidElement;
506     }
507     if (data_type == RS_TYPE_UNSIGNED_5_5_5_1 &&
508         data_kind != RS_KIND_PIXEL_RGBA) {
509 
510         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
511         return kInvalidElement;
512     }
513     if (data_type == RS_TYPE_UNSIGNED_4_4_4_4 &&
514         data_kind != RS_KIND_PIXEL_RGBA) {
515 
516         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
517         return kInvalidElement;
518     }
519     if (data_type == RS_TYPE_UNSIGNED_16 && data_kind != RS_KIND_PIXEL_DEPTH) {
520         rsDebug("Bad data_type and data_kind combo", data_type, data_kind);
521         return kInvalidElement;
522     }
523 
524     int vector_width = 1;
525     switch (data_kind) {
526         case RS_KIND_PIXEL_LA:
527             vector_width = 2;
528             break;
529         case RS_KIND_PIXEL_RGB:
530             vector_width = 3;
531             break;
532         case RS_KIND_PIXEL_RGBA:
533             vector_width = 4;
534             break;
535         case RS_KIND_PIXEL_DEPTH:
536             vector_width = 2;
537             break;
538         default:
539             break;
540     }
541 
542     return rsCreateElement(data_type, data_kind, true, vector_width);
543 }
544 
rsCreateType(rs_element element,uint32_t dimX,uint32_t dimY,uint32_t dimZ)545 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
546                                                    uint32_t dimX, uint32_t dimY,
547                                                    uint32_t dimZ) {
548     return rsCreateType(element, dimX, dimY, dimZ, false, false, RS_YUV_NONE);
549 }
550 
rsCreateType(rs_element element,uint32_t dimX,uint32_t dimY)551 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
552                                                    uint32_t dimX,
553                                                    uint32_t dimY) {
554     return rsCreateType(element, dimX, dimY, 0, false, false, RS_YUV_NONE);
555 }
556 
rsCreateType(rs_element element,uint32_t dimX)557 rs_type __attribute__((overloadable)) rsCreateType(rs_element element,
558                                                    uint32_t dimX) {
559     return rsCreateType(element, dimX, 0, 0, false, false, RS_YUV_NONE);
560 }
561 
rsCreateAllocation(rs_type type,uint32_t usage)562 rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type,
563                                                                uint32_t usage) {
564     return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE, usage, NULL);
565 }
566 
rsCreateAllocation(rs_type type)567 rs_allocation __attribute__((overloadable)) rsCreateAllocation(rs_type type) {
568     return rsCreateAllocation(type, RS_ALLOCATION_MIPMAP_NONE,
569                               RS_ALLOCATION_USAGE_SCRIPT, NULL);
570 }
571