rs_allocation.c revision 98f1f05105146e1caeb124cae6e286c151f63151
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
105static uint8_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    static void                                                         \
120    rsSetElementAtImpl_##T(rs_allocation a, T val, uint32_t x,          \
121                           uint32_t y, uint32_t z) {                    \
122        *(T*)rsOffset(a, sizeof(T), x, y, z) = val;                     \
123    }                                                                   \
124                                                                        \
125    extern void __attribute__((overloadable))                           \
126    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x) {            \
127        rsSetElementAtImpl_##T(a, val, x, 0, 0);                        \
128    }                                                                   \
129                                                                        \
130    extern void __attribute__((overloadable))                           \
131    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x,              \
132                       uint32_t y) {                                    \
133        rsSetElementAtImpl_##T(a, val, x, y, 0);                        \
134    }                                                                   \
135                                                                        \
136    extern void __attribute__((overloadable))                           \
137    rsSetElementAt_##T(rs_allocation a, T val, uint32_t x, uint32_t y,  \
138                       uint32_t z) {                                    \
139        rsSetElementAtImpl_##T(a, val, x, y, z);                        \
140    }                                                                   \
141                                                                        \
142    static T                                                            \
143    rsGetElementAtImpl_##T(rs_allocation a, uint32_t x, uint32_t y,     \
144                       uint32_t z) {                                    \
145        return *(T*)rsOffset(a, sizeof(T), x, y, z);                    \
146    }                                                                   \
147                                                                        \
148    extern T __attribute__((overloadable))                              \
149    rsGetElementAt_##T(rs_allocation a, uint32_t x) {                   \
150        return rsGetElementAtImpl_##T(a, x, 0, 0);                      \
151    }                                                                   \
152                                                                        \
153    extern T __attribute__((overloadable))                              \
154    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y) {       \
155        return rsGetElementAtImpl_##T(a, x, y, 0);                      \
156    }                                                                   \
157                                                                        \
158    extern T __attribute__((overloadable))                              \
159    rsGetElementAt_##T(rs_allocation a, uint32_t x, uint32_t y,         \
160                       uint32_t z) {                                    \
161        return rsGetElementAtImpl_##T(a, x, y, z);                      \
162    }
163
164
165
166extern const void * __attribute__((overloadable))
167        rsGetElementAt(rs_allocation a, uint32_t x) {
168    Allocation_t *alloc = (Allocation_t *)a.p;
169    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
170    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
171    return &p[eSize * x];
172}
173
174extern const void * __attribute__((overloadable))
175        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
176    Allocation_t *alloc = (Allocation_t *)a.p;
177    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
178    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
179    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
180    return &p[(eSize * x) + (y * stride)];
181}
182
183extern const void * __attribute__((overloadable))
184        rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
185    Allocation_t *alloc = (Allocation_t *)a.p;
186    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
187    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
188    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
189    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
190    return &p[(eSize * x) + (y * stride) + (z * stride * dimY)];
191}
192extern void __attribute__((overloadable))
193        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x) {
194    Allocation_t *alloc = (Allocation_t *)a.p;
195    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
196    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
197    memcpy((void*)&p[eSize * x], ptr, eSize);
198}
199
200extern void __attribute__((overloadable))
201        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y) {
202    Allocation_t *alloc = (Allocation_t *)a.p;
203    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
204    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
205    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
206    memcpy((void*)&p[(eSize * x) + (y * stride)], ptr, eSize);
207}
208
209extern void __attribute__((overloadable))
210        rsSetElementAt(rs_allocation a, void* ptr, uint32_t x, uint32_t y, uint32_t z) {
211    Allocation_t *alloc = (Allocation_t *)a.p;
212    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr;
213    const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
214    const uint32_t stride = alloc->mHal.drvState.lod[0].stride;
215    const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY;
216    memcpy((void*)&p[(eSize * x) + (y * stride) + (z * stride * dimY)], ptr, eSize);
217}
218#endif
219
220ELEMENT_AT(char)
221ELEMENT_AT(char2)
222ELEMENT_AT(char3)
223ELEMENT_AT(char4)
224ELEMENT_AT(uchar)
225ELEMENT_AT(uchar2)
226ELEMENT_AT(uchar3)
227ELEMENT_AT(uchar4)
228ELEMENT_AT(short)
229ELEMENT_AT(short2)
230ELEMENT_AT(short3)
231ELEMENT_AT(short4)
232ELEMENT_AT(ushort)
233ELEMENT_AT(ushort2)
234ELEMENT_AT(ushort3)
235ELEMENT_AT(ushort4)
236ELEMENT_AT(int)
237ELEMENT_AT(int2)
238ELEMENT_AT(int3)
239ELEMENT_AT(int4)
240ELEMENT_AT(uint)
241ELEMENT_AT(uint2)
242ELEMENT_AT(uint3)
243ELEMENT_AT(uint4)
244ELEMENT_AT(long)
245ELEMENT_AT(long2)
246ELEMENT_AT(long3)
247ELEMENT_AT(long4)
248ELEMENT_AT(ulong)
249ELEMENT_AT(ulong2)
250ELEMENT_AT(ulong3)
251ELEMENT_AT(ulong4)
252ELEMENT_AT(float)
253ELEMENT_AT(float2)
254ELEMENT_AT(float3)
255ELEMENT_AT(float4)
256ELEMENT_AT(double)
257ELEMENT_AT(double2)
258ELEMENT_AT(double3)
259ELEMENT_AT(double4)
260
261#undef ELEMENT_AT
262
263
264extern const uchar __attribute__((overloadable))
265        rsGetElementAtYuv_uchar_Y(rs_allocation a, uint32_t x, uint32_t y) {
266    return rsGetElementAt_uchar(a, x, y);
267}
268
269extern const uchar __attribute__((overloadable))
270        rsGetElementAtYuv_uchar_U(rs_allocation a, uint32_t x, uint32_t y) {
271
272    Allocation_t *alloc = (Allocation_t *)a.p;
273    const uint32_t yuvID = alloc->mHal.state.yuv;
274    const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[1].mallocPtr;
275    const uint32_t stride = alloc->mHal.drvState.lod[1].stride;
276
277    switch(yuvID) {
278    case 0x32315659: //HAL_PIXEL_FORMAT_YV12:
279        x >>= 1;
280        y >>= 1;
281        return p[x + (y * stride)];
282    case 11: //HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
283        x >>= 1;
284        y >>= 1;
285        return p[(x<<1) + (y * stride)];
286    default:
287        break;
288    }
289
290    return 0;
291}
292
293extern const uchar __attribute__((overloadable))
294        rsGetElementAtYuv_uchar_V(rs_allocation a, uint32_t x, uint32_t y) {
295
296    Allocation_t *alloc = (Allocation_t *)a.p;
297    const uint32_t yuvID = alloc->mHal.state.yuv;
298
299    switch(yuvID) {
300    case 0x32315659: //HAL_PIXEL_FORMAT_YV12:
301        {
302        const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[2].mallocPtr;
303        const uint32_t stride = alloc->mHal.drvState.lod[2].stride;
304        x >>= 1;
305        y >>= 1;
306        return p[x + (y * stride)];
307        }
308    case 11: //HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
309        {
310        const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.lod[1].mallocPtr;
311        const uint32_t stride = alloc->mHal.drvState.lod[1].stride;
312        x >>= 1;
313        y >>= 1;
314        return p[(x<<1) + (y * stride) + 1];
315        }
316    default:
317            break;
318    }
319
320    return 0;
321}
322
323