1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <memory>
18
19 #include <jni.h>
20 #include <RenderScript.h>
21
22 #include "ScriptC_allocs.h"
23
24 sp<RS> mRS;
25
26 sp<Allocation> mBoolAllocation; // boolean
27
28 sp<Allocation> mCharAllocation; // char
29 sp<Allocation> mChar2Allocation; // char2
30 sp<Allocation> mChar3Allocation; // char3
31 sp<Allocation> mChar4Allocation; // char4
32
33 sp<Allocation> mUCharAllocation; // uchar
34 sp<Allocation> mUChar2Allocation; // uchar2
35 sp<Allocation> mUChar3Allocation; // uchar3
36 sp<Allocation> mUChar4Allocation; // uchar4
37
38 sp<Allocation> mShortAllocation; // short
39 sp<Allocation> mShort2Allocation; // short2
40 sp<Allocation> mShort3Allocation; // short3
41 sp<Allocation> mShort4Allocation; // short4
42
43 sp<Allocation> mUShortAllocation; // ushort
44 sp<Allocation> mUShort2Allocation; // ushort2
45 sp<Allocation> mUShort3Allocation; // ushort3
46 sp<Allocation> mUShort4Allocation; // ushort4
47
48 sp<Allocation> mIntAllocation; // int
49 sp<Allocation> mInt2Allocation; // int2
50 sp<Allocation> mInt3Allocation; // int3
51 sp<Allocation> mInt4Allocation; // int4
52
53 sp<Allocation> mUIntAllocation; // uint
54 sp<Allocation> mUInt2Allocation; // uint2
55 sp<Allocation> mUInt3Allocation; // uint3
56 sp<Allocation> mUInt4Allocation; // uint4
57
58 sp<Allocation> mLongAllocation; // long
59 sp<Allocation> mLong2Allocation; // long2
60 sp<Allocation> mLong3Allocation; // long3
61 sp<Allocation> mLong4Allocation; // long4
62
63 sp<Allocation> mULongAllocation; // ulong
64 sp<Allocation> mULong2Allocation; // ulong2
65 sp<Allocation> mULong3Allocation; // ulong3
66 sp<Allocation> mULong4Allocation; // ulong4
67
68 sp<Allocation> mHalfAllocation; // half
69 sp<Allocation> mHalf2Allocation; // half2
70 sp<Allocation> mHalf3Allocation; // half3
71 sp<Allocation> mHalf4Allocation; // half4
72
73 sp<Allocation> mFloatAllocation; // float
74 sp<Allocation> mFloat2Allocation; // float2
75 sp<Allocation> mFloat3Allocation; // float3
76 sp<Allocation> mFloat4Allocation; // float4
77
78 sp<Allocation> mDoubleAllocation; // double
79 sp<Allocation> mDouble2Allocation; // double2
80 sp<Allocation> mDouble3Allocation; // double3
81 sp<Allocation> mDouble4Allocation; // double4
82
83 const int mAllocSize = 24; // Needs to be < CHAR_MAX and divisible by 4.
84 const int mBitmapSize = 64;
85
createSignedAllocations()86 void createSignedAllocations() {
87 Type::Builder typeI8Builder(mRS, Element::I8(mRS));
88 typeI8Builder.setX(1); // One element here to test 16 byte memory alignment
89 typeI8Builder.setY(3);
90 typeI8Builder.setZ(8);
91
92 mCharAllocation = Allocation::createTyped(mRS, typeI8Builder.create());
93 mChar2Allocation = Allocation::createSized(mRS, Element::I8_2(mRS), mAllocSize / 2);
94 mChar3Allocation = Allocation::createSized(mRS, Element::I8_3(mRS), mAllocSize / 4);
95 mChar4Allocation = Allocation::createSized(mRS, Element::I8_4(mRS), mAllocSize / 4);
96
97 Type::Builder typeI16_2Builder(mRS, Element::I16_2(mRS));
98 typeI16_2Builder.setX(6);
99 typeI16_2Builder.setY(1);
100 typeI16_2Builder.setZ(2);
101
102 mShortAllocation = Allocation::createSized(mRS, Element::I16(mRS), mAllocSize);
103 mShort2Allocation = Allocation::createTyped(mRS, typeI16_2Builder.create());
104 mShort3Allocation = Allocation::createSized(mRS, Element::I16_3(mRS), mAllocSize / 4);
105 mShort4Allocation = Allocation::createSized(mRS, Element::I16_4(mRS), mAllocSize / 4);
106
107 Type::Builder typeI32_3Builder(mRS, Element::I32_3(mRS));
108 typeI32_3Builder.setX(3);
109 typeI32_3Builder.setY(2);
110
111 mIntAllocation = Allocation::createSized(mRS, Element::I32(mRS), mAllocSize);
112 mInt2Allocation = Allocation::createSized(mRS, Element::I32_2(mRS), mAllocSize / 2);
113 mInt3Allocation = Allocation::createTyped(mRS, typeI32_3Builder.create());
114 mInt4Allocation = Allocation::createSized(mRS, Element::I32_4(mRS), mAllocSize / 4);
115
116 Type::Builder typeI64_4Builder(mRS, Element::I64_4(mRS));
117 typeI64_4Builder.setX(1);
118 typeI64_4Builder.setY(6);
119
120 mLongAllocation = Allocation::createSized(mRS, Element::I64(mRS), mAllocSize);
121 mLong2Allocation = Allocation::createSized(mRS, Element::I64_2(mRS), mAllocSize / 2);
122 mLong3Allocation = Allocation::createSized(mRS, Element::I64_3(mRS), mAllocSize / 4);
123 mLong4Allocation = Allocation::createTyped(mRS, typeI64_4Builder.create());
124
125 mBoolAllocation = Allocation::createSized(mRS, Element::BOOLEAN(mRS), mAllocSize);
126 }
127
initSignedAllocations()128 void initSignedAllocations() {
129 char *buffer_char = new char[mAllocSize];
130 short *buffer_short = new short[mAllocSize];
131 int *buffer_int = new int[mAllocSize];
132 int64_t *buffer_long = new int64_t[mAllocSize];
133 char *buffer_bool = new char[mAllocSize];
134
135 for(int i = 0; i < mAllocSize; ++i) {
136 buffer_char[i] = (char) i;
137 buffer_short[i] = (short) i;
138 buffer_int[i] = (int) i;
139 buffer_long[i] = (int64_t) i;
140 buffer_bool[i] = (char) (0x01 & i);
141 }
142
143 mCharAllocation->copy3DRangeFrom(0, 0, 0, 1, 3, 8, buffer_char);
144 mChar2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_char);
145 mChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
146 mChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
147
148 delete [] buffer_char;
149
150 mShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short);
151 mShort2Allocation->copy3DRangeFrom(0, 0, 0, 6, 1, 2, buffer_short);
152 mShort3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
153 mShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
154
155 delete [] buffer_short;
156
157 mIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int);
158 mInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int);
159 mInt3Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_int);
160 mInt4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int);
161
162 delete [] buffer_int;
163
164 mLongAllocation->copy1DRangeFrom(0, mAllocSize, buffer_long);
165 mLong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long);
166 mLong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
167 mLong4Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_long);
168
169 delete [] buffer_long;
170
171 mBoolAllocation->copy1DRangeFrom(0, mAllocSize, buffer_bool);
172
173 delete [] buffer_bool;
174 }
175
createUnsignedAllocations()176 void createUnsignedAllocations() {
177 Type::Builder typeU8_2Builder(mRS, Element::U8_2(mRS));
178 typeU8_2Builder.setX(2);
179 typeU8_2Builder.setY(6);
180
181 mUCharAllocation = Allocation::createSized(mRS, Element::U8(mRS), mAllocSize);
182 mUChar2Allocation = Allocation::createTyped(mRS, typeU8_2Builder.create());
183 mUChar3Allocation = Allocation::createSized(mRS, Element::U8_3(mRS), mAllocSize / 4);
184 mUChar4Allocation = Allocation::createSized(mRS, Element::U8_4(mRS), mAllocSize / 4);
185
186 Type::Builder typeU16_3Builder(mRS, Element::U16_3(mRS));
187 typeU16_3Builder.setX(1);
188 typeU16_3Builder.setY(6);
189
190 mUShortAllocation = Allocation::createSized(mRS, Element::U16(mRS), mAllocSize);
191 mUShort2Allocation = Allocation::createSized(mRS, Element::U16_2(mRS), mAllocSize / 2);
192 mUShort3Allocation = Allocation::createTyped(mRS, typeU16_3Builder.create());
193 mUShort4Allocation = Allocation::createSized(mRS, Element::U16_4(mRS), mAllocSize / 4);
194
195 Type::Builder typeU32_4Builder(mRS, Element::U32_4(mRS));
196 typeU32_4Builder.setX(1);
197 typeU32_4Builder.setY(1);
198 typeU32_4Builder.setZ(6);
199
200 mUIntAllocation = Allocation::createSized(mRS, Element::U32(mRS), mAllocSize);
201 mUInt2Allocation = Allocation::createSized(mRS, Element::U32_2(mRS), mAllocSize / 2);
202 mUInt3Allocation = Allocation::createSized(mRS, Element::U32_3(mRS), mAllocSize / 4);
203 mUInt4Allocation = Allocation::createTyped(mRS, typeU32_4Builder.create());
204
205 Type::Builder typeU64Builder(mRS, Element::U64(mRS));
206 typeU64Builder.setX(4);
207 typeU64Builder.setY(3);
208 typeU64Builder.setZ(2);
209
210 mULongAllocation = Allocation::createTyped(mRS, typeU64Builder.create());
211 mULong2Allocation = Allocation::createSized(mRS, Element::U64_2(mRS), mAllocSize / 2);
212 mULong3Allocation = Allocation::createSized(mRS, Element::U64_3(mRS), mAllocSize / 4);
213 mULong4Allocation = Allocation::createSized(mRS, Element::U64_4(mRS), mAllocSize / 4);
214 }
215
initUnsignedAllocations()216 void initUnsignedAllocations() {
217 char *buffer_char = new char[mAllocSize];
218 short *buffer_short = new short[mAllocSize];
219 int *buffer_int = new int[mAllocSize];
220 uint64_t *buffer_long = new uint64_t[mAllocSize];
221
222 for(int i = 0; i < mAllocSize; ++i) {
223 buffer_char[i] = (char) i;
224 buffer_short[i] = (short) i;
225 buffer_int[i] = (int) i;
226 buffer_long[i] = (uint64_t) i;
227 }
228
229 mUCharAllocation->copy1DRangeFrom(0, mAllocSize, buffer_char);
230 mUChar2Allocation->copy2DRangeFrom(0, 0, 2, 6, buffer_char);
231 mUChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
232 mUChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char);
233
234 delete [] buffer_char;
235
236 mUShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short);
237 mUShort2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_short);
238 mUShort3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_short);
239 mUShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short);
240
241 delete [] buffer_short;
242
243 mUIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int);
244 mUInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int);
245 mUInt3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int);
246 mUInt4Allocation->copy3DRangeFrom(0, 0, 0, 1, 1, 6, buffer_int);
247
248 delete [] buffer_int;
249
250 mULongAllocation->copy3DRangeFrom(0, 0, 0, 4, 3, 2, buffer_long);
251 mULong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long);
252 mULong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
253 mULong4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long);
254
255 delete [] buffer_long;
256 }
257
createFloatAllocations()258 void createFloatAllocations() {
259 Type::Builder typeF16_3Builder(mRS, Element::F16_3(mRS));
260 typeF16_3Builder.setX(1);
261 typeF16_3Builder.setY(6);
262
263 mHalfAllocation = Allocation::createSized(mRS, Element::F16(mRS), mAllocSize);
264 mHalf2Allocation = Allocation::createSized(mRS, Element::F16_2(mRS), mAllocSize / 2);
265 mHalf3Allocation = Allocation::createTyped(mRS, typeF16_3Builder.create());
266 mHalf4Allocation = Allocation::createSized(mRS, Element::F16_4(mRS), mAllocSize / 4);
267
268 Type::Builder typeF32_4Builder(mRS, Element::F32_4(mRS));
269 typeF32_4Builder.setX(3);
270 typeF32_4Builder.setY(2);
271
272 mFloatAllocation = Allocation::createSized(mRS, Element::F32(mRS), mAllocSize);
273 mFloat2Allocation = Allocation::createSized(mRS, Element::F32_2(mRS), mAllocSize / 2);
274 mFloat3Allocation = Allocation::createSized(mRS, Element::F32_3(mRS), mAllocSize / 4);
275 mFloat4Allocation = Allocation::createTyped(mRS, typeF32_4Builder.create());
276
277 Type::Builder typeF64_2Builder(mRS, Element::F64_2(mRS));
278 typeF64_2Builder.setX(4);
279 typeF64_2Builder.setY(1);
280 typeF64_2Builder.setZ(3);
281
282 mDoubleAllocation = Allocation::createSized(mRS, Element::F64(mRS), mAllocSize);
283 mDouble2Allocation = Allocation::createTyped(mRS, typeF64_2Builder.create());
284
285 Type::Builder typeF64_3Builder(mRS, Element::F64_3(mRS));
286 typeF64_3Builder.setX(1);
287 typeF64_3Builder.setY(2);
288 typeF64_3Builder.setZ(3);
289
290 Type::Builder typeF64_4Builder(mRS, Element::F64_4(mRS));
291 typeF64_4Builder.setX(1);
292 typeF64_4Builder.setY(2);
293 typeF64_4Builder.setZ(3);
294
295 mDouble3Allocation = Allocation::createTyped(mRS, typeF64_3Builder.create());
296 mDouble4Allocation = Allocation::createTyped(mRS, typeF64_4Builder.create());
297 }
298
initFloatAllocations()299 void initFloatAllocations() {
300 __fp16 *buffer_half = new __fp16[mAllocSize];
301 float *buffer_float = new float[mAllocSize];
302 double *buffer_double = new double[mAllocSize];
303
304 for(int i = 0; i < mAllocSize; ++i) {
305 buffer_half[i] = (__fp16) 1 / i;
306 buffer_float[i] = (float) 1 / i;
307 buffer_double[i] = (double) 1 / i;
308 }
309
310 mHalfAllocation->copy1DRangeFrom(0, mAllocSize, buffer_half);
311 mHalf2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_half);
312 mHalf3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_half);
313 mHalf4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_half);
314
315 delete [] buffer_half;
316
317 mFloatAllocation->copy1DRangeFrom(0, mAllocSize, buffer_float);
318 mFloat2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_float);
319 mFloat3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_float);
320 mFloat4Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_float);
321
322 delete [] buffer_float;
323
324 mDoubleAllocation->copy1DRangeFrom(0, mAllocSize, buffer_double);
325 mDouble2Allocation->copy3DRangeFrom(0, 0, 0, 4, 1, 3, buffer_double);
326 mDouble3Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double);
327 mDouble4Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double);
328
329 delete [] buffer_double;
330 }
331
332 extern "C" void JNICALL
Java_com_android_rs_jniallocations_MainActivity_nativeRS(JNIEnv * env,jclass,jstring pathObj)333 Java_com_android_rs_jniallocations_MainActivity_nativeRS(
334 JNIEnv * env,
335 jclass,
336 jstring pathObj)
337 {
338 mRS = new RS();
339
340 const char * path = env->GetStringUTFChars(pathObj, nullptr);
341 mRS->init(path, RS_INIT_LOW_LATENCY | RS_INIT_WAIT_FOR_ATTACH);
342 env->ReleaseStringUTFChars(pathObj, path);
343
344 sp<ScriptC_allocs> mScript = new ScriptC_allocs(mRS);
345
346 Type::Builder typeRGBA_888Builder(mRS, Element::RGBA_8888(mRS));
347 typeRGBA_888Builder.setX(mBitmapSize);
348 typeRGBA_888Builder.setY(mBitmapSize);
349
350 sp<Allocation> mInAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create());
351
352 const int image_area = mBitmapSize*mBitmapSize;
353 const int image_size = image_area*sizeof(int);
354
355 char *zero_buffer = new char[image_size];
356 memset(zero_buffer, 0, image_size);
357 mInAllocation->copy1DRangeFrom(0, image_area, zero_buffer);
358 delete [] zero_buffer;
359
360 sp<Allocation> mOutAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create());
361 createSignedAllocations();
362 initSignedAllocations();
363
364 mRS->finish();
365 mScript->forEach_swizzle_kernel(mInAllocation, mOutAllocation);
366 mRS->finish();
367
368 mCharAllocation.clear();
369 mChar2Allocation.clear();
370 mChar3Allocation.clear();
371 mChar4Allocation.clear();
372
373 mShort2Allocation.clear();
374 mShort3Allocation.clear();
375 mShort4Allocation.clear();
376
377 mIntAllocation.clear();
378 mInt2Allocation.clear();
379 mInt3Allocation.clear();
380 mInt4Allocation.clear();
381
382 mLongAllocation.clear();
383 mLong2Allocation.clear();
384 mLong3Allocation.clear();
385 mLong4Allocation.clear();
386
387 mBoolAllocation.clear();
388
389 createUnsignedAllocations();
390 initUnsignedAllocations();
391
392 mInAllocation = mUShortAllocation; // Host side assignment
393
394 mRS->finish();
395 mScript->forEach_square_kernel(mInAllocation, mUIntAllocation);
396 mRS->finish();
397
398 mUCharAllocation.clear();
399 mUChar2Allocation.clear();
400 mUChar3Allocation.clear();
401 mUChar4Allocation.clear();
402
403 mUShortAllocation.clear();
404 mUShort2Allocation.clear();
405 mUShort3Allocation.clear();
406 mUShort4Allocation.clear();
407
408 mUInt2Allocation.clear();
409 mUInt3Allocation.clear();
410 mUInt4Allocation.clear();
411
412 mULongAllocation.clear();
413 mULong2Allocation.clear();
414 mULong3Allocation.clear();
415 mULong4Allocation.clear();
416
417 createFloatAllocations();
418 initFloatAllocations();
419
420 mRS->finish();
421 mScript->forEach_add_half_kernel(mDouble4Allocation, mDouble3Allocation);
422 mRS->finish();
423 }
424
425