rs_allocation.c revision 0052f8dcb5ebb5c9205a1d25445629fb5a772380
1#include "rs_core.rsh"
2#include "rs_graphics.rsh"
3#include "rs_structs.h"
4
5// Opaque Allocation type operations
6extern uint32_t __attribute__((overloadable))
7    rsAllocationGetDimX(rs_allocation a) {
8    Allocation_t *alloc = (Allocation_t *)a.p;
9    return alloc->mHal.drvState.lod[0].dimX;
10}
11
12extern uint32_t __attribute__((overloadable))
13        rsAllocationGetDimY(rs_allocation a) {
14    Allocation_t *alloc = (Allocation_t *)a.p;
15    return alloc->mHal.drvState.lod[0].dimY;
16}
17
18extern uint32_t __attribute__((overloadable))
19        rsAllocationGetDimZ(rs_allocation a) {
20    Allocation_t *alloc = (Allocation_t *)a.p;
21    return alloc->mHal.drvState.lod[0].dimZ;
22}
23
24extern uint32_t __attribute__((overloadable))
25        rsAllocationGetDimLOD(rs_allocation a) {
26    Allocation_t *alloc = (Allocation_t *)a.p;
27    return alloc->mHal.state.hasMipmaps;
28}
29
30extern uint32_t __attribute__((overloadable))
31        rsAllocationGetDimFaces(rs_allocation a) {
32    Allocation_t *alloc = (Allocation_t *)a.p;
33    return alloc->mHal.state.hasFaces;
34}
35
36
37extern rs_element __attribute__((overloadable))
38        rsAllocationGetElement(rs_allocation a) {
39    Allocation_t *alloc = (Allocation_t *)a.p;
40    if (alloc == NULL) {
41        rs_element nullElem = {0};
42        return nullElem;
43    }
44    Type_t *type = (Type_t *)alloc->mHal.state.type;
45    rs_element returnElem = {type->mHal.state.element};
46    return returnElem;
47}
48
49// TODO: this needs to be optimized, obviously
50static void memcpy(void* dst, void* src, size_t size) {
51    char* dst_c = (char*) dst, *src_c = (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
103#else
104
105uint8_t*
106rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y,
107         uint32_t z) {
108    Allocation_t *alloc = (Allocation_t *)a.p;
109    uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
110    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
111    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
112    uint8_t *dp = &p[(sizeOf * x) + (y * stride) +
113                     (z * stride * dimY)];
114    return dp;
115}
116
117#define ELEMENT_AT(T)                                                   \
118                                                                        \
119    void                                                                \
120    rsSetElementAtImpl_##T(rs_allocation a, T val, uint32_t x,          \
121                           uint32_t y, uint32_t z);                     \
122                                                                        \
123    extern void __attribute__((overloadable))                           \
124    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) {            \
125        rsSetElementAtImpl_##T(a, val, x, 0, 0);                        \
126    }                                                                   \
127                                                                        \
128    extern void __attribute__((overloadable))                           \
129    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x,              \
130                       uint32_t y) {                                    \
131        rsSetElementAtImpl_##T(a, val, x, y, 0);                        \
132    }                                                                   \
133                                                                        \
134    extern void __attribute__((overloadable))                           \
135    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y,  \
136                       uint32_t z) {                                    \
137        rsSetElementAtImpl_##T(a, val, x, y, z);                        \
138    }                                                                   \
139                                                                        \
140    T                                                                   \
141    rsGetElementAtImpl_##T(rs_allocation a, uint32_t x, uint32_t y,     \
142                       uint32_t z);                                     \
143                                                                        \
144    extern T __attribute__((overloadable))                              \
145    rsGetElementAt_##T(rs_allocation a, uint32_t x) {                   \
146        return rsGetElementAtImpl_##T(a, x, 0, 0);                      \
147    }                                                                   \
148                                                                        \
149    extern T __attribute__((overloadable))                              \
150    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y) {       \
151        return rsGetElementAtImpl_##T(a, x, y, 0);                      \
152    }                                                                   \
153                                                                        \
154    extern T __attribute__((overloadable))                              \
155    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y,         \
156                       uint32_t z) {                                    \
157        return rsGetElementAtImpl_##T(a, x, y, z);                      \
158    }
159
160
161
162extern const void * __attribute__((overloadable))
163        rsGetElementAt(rs_allocation a, uint32_t x) {
164    Allocation_t *alloc = (Allocation_t *)a.p;
165    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
166    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
167    return &p[eSize * x];
168}
169
170extern const void * __attribute__((overloadable))
171        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
172    Allocation_t *alloc = (Allocation_t *)a.p;
173    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
174    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
175    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
176    return &p[(eSize * x) + (y * stride)];
177}
178
179extern const void * __attribute__((overloadable))
180        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
181    Allocation_t *alloc = (Allocation_t *)a.p;
182    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
183    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
184    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
185    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
186    return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
187}
188extern void __attribute__((overloadable))
189        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
190    Allocation_t *alloc = (Allocation_t *)a.p;
191    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
192    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
193    memcpy((void*)&p[eSize * x], ptr, eSize);
194}
195
196extern void __attribute__((overloadable))
197        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
198    Allocation_t *alloc = (Allocation_t *)a.p;
199    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
200    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
201    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
202    memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
203}
204
205extern void __attribute__((overloadable))
206        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y, uint32_t z) {
207    Allocation_t *alloc = (Allocation_t *)a.p;
208    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
209    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
210    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
211    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
212    memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
213}
214#endif
215
216ELEMENT_AT(char)
217ELEMENT_AT(char2)
218ELEMENT_AT(char3)
219ELEMENT_AT(char4)
220ELEMENT_AT(uchar)
221ELEMENT_AT(uchar2)
222ELEMENT_AT(uchar3)
223ELEMENT_AT(uchar4)
224ELEMENT_AT(short)
225ELEMENT_AT(short2)
226ELEMENT_AT(short3)
227ELEMENT_AT(short4)
228ELEMENT_AT(ushort)
229ELEMENT_AT(ushort2)
230ELEMENT_AT(ushort3)
231ELEMENT_AT(ushort4)
232ELEMENT_AT(int)
233ELEMENT_AT(int2)
234ELEMENT_AT(int3)
235ELEMENT_AT(int4)
236ELEMENT_AT(uint)
237ELEMENT_AT(uint2)
238ELEMENT_AT(uint3)
239ELEMENT_AT(uint4)
240ELEMENT_AT(long)
241ELEMENT_AT(long2)
242ELEMENT_AT(long3)
243ELEMENT_AT(long4)
244ELEMENT_AT(ulong)
245ELEMENT_AT(ulong2)
246ELEMENT_AT(ulong3)
247ELEMENT_AT(ulong4)
248ELEMENT_AT(float)
249ELEMENT_AT(float2)
250ELEMENT_AT(float3)
251ELEMENT_AT(float4)
252ELEMENT_AT(double)
253ELEMENT_AT(double2)
254ELEMENT_AT(double3)
255ELEMENT_AT(double4)
256
257#undef ELEMENT_AT
258
259
260extern const uchar __attribute__((overloadable))
261        rsGetElementAtYuv_uchar_Y(rs_allocation a, uint32_t x, uint32_t y) {
262    return rsGetElementAt_uchar(a, x, y);
263}
264
265extern const uchar __attribute__((overloadable))
266        rsGetElementAtYuv_uchar_U(rs_allocation a, uint32_t x, uint32_t y) {
267
268    Allocation_t *alloc = (Allocation_t *)a.p;
269
270    const size_t cstep = alloc->mHal.drvState.yuv.step;
271    const size_t shift = alloc->mHal.drvState.yuv.shift;
272    const size_t stride = alloc->mHal.drvState.lod[1].stride;
273
274    const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[1].mallocPtr;
275
276    return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
277}
278
279extern const uchar __attribute__((overloadable))
280        rsGetElementAtYuv_uchar_V(rs_allocation a, uint32_t x, uint32_t y) {
281
282    Allocation_t *alloc = (Allocation_t *)a.p;
283
284    const size_t cstep = alloc->mHal.drvState.yuv.step;
285    const size_t shift = alloc->mHal.drvState.yuv.shift;
286    const size_t stride = alloc->mHal.drvState.lod[2].stride;
287
288    const uchar *pin = (const uchar *)alloc->mHal.drvState.lod[2].mallocPtr;
289
290    return pin[((x >> shift) * cstep) + ((y >> shift) * stride)];
291}
292
293