1 #include "rs_core.rsh"
2
3 /*****************************************************************************
4 * CAUTION
5 *
6 * The following structure layout provides a more efficient way to access
7 * internal members of the C++ class Allocation owned by librs. Unfortunately,
8 * since this class has virtual members, we can't simply use offsetof() or any
9 * other compiler trickery to dynamically get the appropriate values at
10 * build-time. This layout may need to be updated whenever
11 * frameworks/base/libs/rs/rsAllocation.h is modified.
12 *
13 * Having the layout information available in this file allows us to
14 * accelerate functionality like rsAllocationGetDimX(). Without this
15 * information, we would not be able to inline the bitcode, thus resulting in
16 * potential runtime performance penalties for tight loops operating on
17 * allocations.
18 *
19 *****************************************************************************/
20 typedef struct Allocation {
21 char __pad[44];
22 struct Hal {
23 struct State {
24 uint32_t dimensionX;
25 uint32_t dimensionY;
26 uint32_t dimensionZ;
27 uint32_t elementSizeBytes;
28 bool hasMipmaps;
29 bool hasFaces;
30 bool hasReferences;
31 } state;
32
33 struct DrvState {
34 void * mallocPtr;
35 } drvState;
36 } mHal;
37 } Allocation_t;
38
39 /* Declaration of 4 basic functions in libRS */
40 extern void __attribute__((overloadable))
41 rsDebug(const char *, float, float);
42 extern void __attribute__((overloadable))
43 rsDebug(const char *, float, float, float);
44 extern void __attribute__((overloadable))
45 rsDebug(const char *, float, float, float, float);
46 extern float4 __attribute__((overloadable)) convert_float4(uchar4 c);
47
48 /* Implementation of Core Runtime */
49
rsDebug(const char * s,float2 v)50 extern void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
51 rsDebug(s, v.x, v.y);
52 }
53
rsDebug(const char * s,float3 v)54 extern void __attribute__((overloadable)) rsDebug(const char *s, float3 v) {
55 rsDebug(s, v.x, v.y, v.z);
56 }
57
rsDebug(const char * s,float4 v)58 extern void __attribute__((overloadable)) rsDebug(const char *s, float4 v) {
59 rsDebug(s, v.x, v.y, v.z, v.w);
60 }
61
rsPackColorTo8888(float r,float g,float b)62 extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
63 {
64 uchar4 c;
65 c.x = (uchar)(r * 255.f + 0.5f);
66 c.y = (uchar)(g * 255.f + 0.5f);
67 c.z = (uchar)(b * 255.f + 0.5f);
68 c.w = 255;
69 return c;
70 }
71
rsPackColorTo8888(float r,float g,float b,float a)72 extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
73 {
74 uchar4 c;
75 c.x = (uchar)(r * 255.f + 0.5f);
76 c.y = (uchar)(g * 255.f + 0.5f);
77 c.z = (uchar)(b * 255.f + 0.5f);
78 c.w = (uchar)(a * 255.f + 0.5f);
79 return c;
80 }
81
rsPackColorTo8888(float3 color)82 extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
83 {
84 color *= 255.f;
85 color += 0.5f;
86 uchar4 c = {color.x, color.y, color.z, 255};
87 return c;
88 }
89
rsPackColorTo8888(float4 color)90 extern uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
91 {
92 color *= 255.f;
93 color += 0.5f;
94 uchar4 c = {color.x, color.y, color.z, color.w};
95 return c;
96 }
97
rsUnpackColor8888(uchar4 c)98 extern float4 rsUnpackColor8888(uchar4 c)
99 {
100 float4 ret = (float4)0.003921569f;
101 ret *= convert_float4(c);
102 return ret;
103 }
104
105 /////////////////////////////////////////////////////
106 // Matrix ops
107 /////////////////////////////////////////////////////
108
109 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix4x4 * m,uint32_t row,uint32_t col,float v)110 rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) {
111 m->m[row * 4 + col] = v;
112 }
113
114 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix4x4 * m,uint32_t row,uint32_t col)115 rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) {
116 return m->m[row * 4 + col];
117 }
118
119 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix3x3 * m,uint32_t row,uint32_t col,float v)120 rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) {
121 m->m[row * 3 + col] = v;
122 }
123
124 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix3x3 * m,uint32_t row,uint32_t col)125 rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) {
126 return m->m[row * 3 + col];
127 }
128
129 extern void __attribute__((overloadable))
rsMatrixSet(rs_matrix2x2 * m,uint32_t row,uint32_t col,float v)130 rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) {
131 m->m[row * 2 + col] = v;
132 }
133
134 extern float __attribute__((overloadable))
rsMatrixGet(const rs_matrix2x2 * m,uint32_t row,uint32_t col)135 rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) {
136 return m->m[row * 2 + col];
137 }
138
139
140 extern float4 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix4x4 * m,float4 in)141 rsMatrixMultiply(const rs_matrix4x4 *m, float4 in) {
142 float4 ret;
143 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w);
144 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + (m->m[13] * in.w);
145 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + (m->m[14] * in.w);
146 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + (m->m[15] * in.w);
147 return ret;
148 }
149 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float4 in)150 rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
151 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
152 }
153
154 extern float4 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix4x4 * m,float3 in)155 rsMatrixMultiply(const rs_matrix4x4 *m, float3 in) {
156 float4 ret;
157 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12];
158 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + (m->m[9] * in.z) + m->m[13];
159 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + (m->m[10] * in.z) + m->m[14];
160 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + (m->m[11] * in.z) + m->m[15];
161 return ret;
162 }
163 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float3 in)164 rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
165 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
166 }
167
168 extern float4 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix4x4 * m,float2 in)169 rsMatrixMultiply(const rs_matrix4x4 *m, float2 in) {
170 float4 ret;
171 ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12];
172 ret.y = (m->m[1] * in.x) + (m->m[5] * in.y) + m->m[13];
173 ret.z = (m->m[2] * in.x) + (m->m[6] * in.y) + m->m[14];
174 ret.w = (m->m[3] * in.x) + (m->m[7] * in.y) + m->m[15];
175 return ret;
176 }
177 extern float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 * m,float2 in)178 rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
179 return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
180 }
181
182 extern float3 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix3x3 * m,float3 in)183 rsMatrixMultiply(const rs_matrix3x3 *m, float3 in) {
184 float3 ret;
185 ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z);
186 ret.y = (m->m[1] * in.x) + (m->m[4] * in.y) + (m->m[7] * in.z);
187 ret.z = (m->m[2] * in.x) + (m->m[5] * in.y) + (m->m[8] * in.z);
188 return ret;
189 }
190 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float3 in)191 rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
192 return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
193 }
194
195
196 extern float3 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix3x3 * m,float2 in)197 rsMatrixMultiply(const rs_matrix3x3 *m, float2 in) {
198 float3 ret;
199 ret.x = (m->m[0] * in.x) + (m->m[3] * in.y);
200 ret.y = (m->m[1] * in.x) + (m->m[4] * in.y);
201 ret.z = (m->m[2] * in.x) + (m->m[5] * in.y);
202 return ret;
203 }
204 extern float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 * m,float2 in)205 rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
206 return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
207 }
208
209 extern float2 __attribute__((overloadable))
rsMatrixMultiply(const rs_matrix2x2 * m,float2 in)210 rsMatrixMultiply(const rs_matrix2x2 *m, float2 in) {
211 float2 ret;
212 ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
213 ret.y = (m->m[1] * in.x) + (m->m[3] * in.y);
214 return ret;
215 }
216 extern float2 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 * m,float2 in)217 rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
218 return rsMatrixMultiply((const rs_matrix2x2 *)m, in);
219 }
220
221 /////////////////////////////////////////////////////
222 // int ops
223 /////////////////////////////////////////////////////
224
rsClamp(uint amount,uint low,uint high)225 extern uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
226 return amount < low ? low : (amount > high ? high : amount);
227 }
rsClamp(int amount,int low,int high)228 extern int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
229 return amount < low ? low : (amount > high ? high : amount);
230 }
rsClamp(ushort amount,ushort low,ushort high)231 extern ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
232 return amount < low ? low : (amount > high ? high : amount);
233 }
rsClamp(short amount,short low,short high)234 extern short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
235 return amount < low ? low : (amount > high ? high : amount);
236 }
rsClamp(uchar amount,uchar low,uchar high)237 extern uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
238 return amount < low ? low : (amount > high ? high : amount);
239 }
rsClamp(char amount,char low,char high)240 extern char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
241 return amount < low ? low : (amount > high ? high : amount);
242 }
243
244 // Opaque Allocation type operations
245 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimX(rs_allocation a)246 rsAllocationGetDimX(rs_allocation a) {
247 Allocation_t *alloc = (Allocation_t *)a.p;
248 return alloc->mHal.state.dimensionX;
249 }
250
251 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimY(rs_allocation a)252 rsAllocationGetDimY(rs_allocation a) {
253 Allocation_t *alloc = (Allocation_t *)a.p;
254 return alloc->mHal.state.dimensionY;
255 }
256
257 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimZ(rs_allocation a)258 rsAllocationGetDimZ(rs_allocation a) {
259 Allocation_t *alloc = (Allocation_t *)a.p;
260 return alloc->mHal.state.dimensionZ;
261 }
262
263 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimLOD(rs_allocation a)264 rsAllocationGetDimLOD(rs_allocation a) {
265 Allocation_t *alloc = (Allocation_t *)a.p;
266 return alloc->mHal.state.hasMipmaps;
267 }
268
269 extern uint32_t __attribute__((overloadable))
rsAllocationGetDimFaces(rs_allocation a)270 rsAllocationGetDimFaces(rs_allocation a) {
271 Allocation_t *alloc = (Allocation_t *)a.p;
272 return alloc->mHal.state.hasFaces;
273 }
274
275 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x)276 rsGetElementAt(rs_allocation a, uint32_t x) {
277 Allocation_t *alloc = (Allocation_t *)a.p;
278 const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
279 const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
280 return &p[eSize * x];
281 }
282
283 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x,uint32_t y)284 rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y) {
285 Allocation_t *alloc = (Allocation_t *)a.p;
286 const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
287 const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
288 const uint32_t dimX = alloc->mHal.state.dimensionX;
289 return &p[eSize * (x + y * dimX)];
290 }
291
292 extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation a,uint32_t x,uint32_t y,uint32_t z)293 rsGetElementAt(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) {
294 Allocation_t *alloc = (Allocation_t *)a.p;
295 const uint8_t *p = (const uint8_t *)alloc->mHal.drvState.mallocPtr;
296 const uint32_t eSize = alloc->mHal.state.elementSizeBytes;
297 const uint32_t dimX = alloc->mHal.state.dimensionX;
298 const uint32_t dimY = alloc->mHal.state.dimensionY;
299 return &p[eSize * (x + y * dimX + z * dimX * dimY)];
300 }
301
302