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