1 /*
2 * Copyright (C) 2013 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 <jni.h>
18 #include <android/log.h>
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23
24 #include <RenderScript.h>
25
26 #define LOG_TAG "rscpptest"
27 #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
28
29 using namespace android::RSC;
30
31 /*returns an addr aligned to the byte boundary specified by align*/
32 #define align_addr(addr,align) (void *)(((size_t)(addr) + ((align) - 1)) & (size_t) - (align))
33 #define ADDRESS_STORAGE_SIZE sizeof(size_t)
34
aligned_alloc(size_t align,size_t size)35 void * aligned_alloc(size_t align, size_t size) {
36 void * addr, * x = NULL;
37 addr = malloc(size + align - 1 + ADDRESS_STORAGE_SIZE);
38 if (addr) {
39 x = align_addr((unsigned char *) addr + ADDRESS_STORAGE_SIZE, (int) align);
40 /* save the actual malloc address */
41 ((size_t *) x)[-1] = (size_t) addr;
42 }
43 return x;
44 }
45
aligned_free(void * memblk)46 void aligned_free(void * memblk) {
47 if (memblk) {
48 void * addr = (void *) (((size_t *) memblk)[-1]);
49 free(addr);
50 }
51 }
52
makeElement(const sp<RS> & rs,RsDataType dt,int vecSize)53 sp<const Element> makeElement(const sp<RS> &rs, RsDataType dt, int vecSize) {
54 if (vecSize > 1) {
55 return Element::createVector(rs, dt, vecSize);
56 } else {
57 if (dt == RS_TYPE_UNSIGNED_8) {
58 return Element::U8(rs);
59 } else {
60 return Element::F32(rs);
61 }
62 }
63 }
64
Java_android_cts_rscpp_RSInitTest_initTest(JNIEnv * env,jclass obj,jstring pathObj)65 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSInitTest_initTest(JNIEnv * env,
66 jclass obj,
67 jstring pathObj)
68 {
69 const char * path = env->GetStringUTFChars(pathObj, NULL);
70 bool r = true;
71 for (int i = 0; i < 1000; i++) {
72 sp<RS> rs = new RS();
73 r &= rs->init(path);
74 LOGV("Native iteration %i, returned %i", i, (int)r);
75 }
76 env->ReleaseStringUTFChars(pathObj, path);
77 return r;
78 }
79
Java_android_cts_rscpp_RSBlurTest_blurTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray,jboolean singleChannel)80 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSBlurTest_blurTest(JNIEnv * env,
81 jclass obj,
82 jstring pathObj,
83 jint X,
84 jint Y,
85 jbyteArray inputByteArray,
86 jbyteArray outputByteArray,
87 jboolean singleChannel)
88 {
89 const char * path = env->GetStringUTFChars(pathObj, NULL);
90 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
91 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
92
93 sp<RS> rs = new RS();
94 rs->init(path);
95
96 sp<const Element> e;
97 if (singleChannel) {
98 e = Element::A_8(rs);
99 } else {
100 e = Element::RGBA_8888(rs);
101 }
102
103 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
104 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
105 sp<ScriptIntrinsicBlur> blur = ScriptIntrinsicBlur::create(rs, e);
106
107 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
108
109 blur->setRadius(15);
110 blur->setInput(inputAlloc);
111 blur->forEach(outputAlloc);
112 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
113
114 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
115 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
116 env->ReleaseStringUTFChars(pathObj, path);
117 return (rs->getError() == RS_SUCCESS);
118
119 }
120
121 extern "C" JNIEXPORT jboolean JNICALL
Java_android_cts_rscpp_RSConvolveTest_convolveTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray,jfloatArray coeffArray,jboolean is3x3)122 Java_android_cts_rscpp_RSConvolveTest_convolveTest(JNIEnv * env, jclass obj, jstring pathObj,
123 jint X, jint Y, jbyteArray inputByteArray,
124 jbyteArray outputByteArray,
125 jfloatArray coeffArray,
126 jboolean is3x3)
127 {
128 const char * path = env->GetStringUTFChars(pathObj, NULL);
129 jfloat * coeffs = env->GetFloatArrayElements(coeffArray, NULL);
130 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
131 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
132
133
134 sp<RS> rs = new RS();
135 rs->init(path);
136
137 sp<const Element> e = Element::A_8(rs);
138
139 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
140 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
141
142 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
143
144
145 if (is3x3) {
146 sp<ScriptIntrinsicConvolve3x3> convolve = ScriptIntrinsicConvolve3x3::create(rs, e);
147 convolve->setInput(inputAlloc);
148 convolve->setCoefficients(coeffs);
149 convolve->forEach(outputAlloc);
150 } else {
151 sp<ScriptIntrinsicConvolve5x5> convolve = ScriptIntrinsicConvolve5x5::create(rs, e);
152 convolve->setInput(inputAlloc);
153 convolve->setCoefficients(coeffs);
154 convolve->forEach(outputAlloc);
155 }
156
157 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
158
159 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
160 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
161 env->ReleaseFloatArrayElements(coeffArray, coeffs, JNI_ABORT);
162 env->ReleaseStringUTFChars(pathObj, path);
163 return (rs->getError() == RS_SUCCESS);
164
165 }
166
Java_android_cts_rscpp_RSLUTTest_lutTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray)167 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSLUTTest_lutTest(JNIEnv * env,
168 jclass obj,
169 jstring pathObj,
170 jint X,
171 jint Y,
172 jbyteArray inputByteArray,
173 jbyteArray outputByteArray)
174 {
175 const char * path = env->GetStringUTFChars(pathObj, NULL);
176 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
177 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
178
179 sp<RS> rs = new RS();
180 rs->init(path);
181
182 sp<const Element> e = Element::RGBA_8888(rs);
183
184 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
185 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
186 sp<ScriptIntrinsicLUT> lut = ScriptIntrinsicLUT::create(rs, e);
187
188 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
189 unsigned char lutValues[256];
190 for (int i = 0; i < 256; i++) {
191 lutValues[i] = 255-i;
192 }
193 lut->setRed(0, 256, lutValues);
194 lut->setGreen(0, 256, lutValues);
195 lut->setBlue(0, 256, lutValues);
196
197 lut->forEach(inputAlloc,outputAlloc);
198 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
199
200 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
201 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
202 env->ReleaseStringUTFChars(pathObj, path);
203 return (rs->getError() == RS_SUCCESS);
204
205 }
206
Java_android_cts_rscpp_RS3DLUTTest_lutTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jint lutSize,jbyteArray inputByteArray,jbyteArray inputByteArray2,jbyteArray outputByteArray)207 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RS3DLUTTest_lutTest(JNIEnv * env,
208 jclass obj,
209 jstring pathObj,
210 jint X,
211 jint Y,
212 jint lutSize,
213 jbyteArray inputByteArray,
214 jbyteArray inputByteArray2,
215 jbyteArray outputByteArray)
216 {
217 const char * path = env->GetStringUTFChars(pathObj, NULL);
218 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
219 jbyte * input2 = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray2, 0);
220 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
221
222 sp<RS> rs = new RS();
223 rs->init(path);
224
225 sp<const Element> e = Element::RGBA_8888(rs);
226
227 Type::Builder builder(rs, e);
228
229 builder.setX(lutSize);
230 builder.setY(lutSize);
231 builder.setZ(lutSize);
232
233 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
234 sp<Allocation> colorCube = Allocation::createTyped(rs, builder.create());
235 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
236 sp<ScriptIntrinsic3DLUT> lut = ScriptIntrinsic3DLUT::create(rs, e);
237
238 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
239 colorCube->copy3DRangeFrom(0, 0, 0, lutSize, lutSize, lutSize, input2);
240
241 lut->setLUT(colorCube);
242 lut->forEach(inputAlloc,outputAlloc);
243
244 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
245
246 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
247 env->ReleasePrimitiveArrayCritical(inputByteArray2, input2, 0);
248 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
249 env->ReleaseStringUTFChars(pathObj, path);
250 return (rs->getError() == RS_SUCCESS);
251
252 }
253
254 extern "C" JNIEXPORT jboolean JNICALL
Java_android_cts_rscpp_RSColorMatrixTest_colorMatrixTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray,jfloatArray coeffArray,jint optionFlag)255 Java_android_cts_rscpp_RSColorMatrixTest_colorMatrixTest(JNIEnv * env, jclass obj, jstring pathObj,
256 jint X, jint Y, jbyteArray inputByteArray,
257 jbyteArray outputByteArray,
258 jfloatArray coeffArray,
259 jint optionFlag)
260 {
261 const char * path = env->GetStringUTFChars(pathObj, NULL);
262 jfloat * coeffs = env->GetFloatArrayElements(coeffArray, NULL);
263 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
264 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
265
266 sp<RS> rs = new RS();
267 rs->init(path);
268
269 sp<const Element> e = Element::RGBA_8888(rs);
270
271 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
272 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
273
274 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
275
276 sp<ScriptIntrinsicColorMatrix> cm = ScriptIntrinsicColorMatrix::create(rs);
277 if (optionFlag == 0) {
278 cm->setColorMatrix3(coeffs);
279 } else if (optionFlag == 1) {
280 cm->setGreyscale();
281 } else if (optionFlag == 2) {
282 cm->setColorMatrix4(coeffs);
283 } else if (optionFlag == 3) {
284 cm->setYUVtoRGB();
285 } else if (optionFlag == 4) {
286 cm->setRGBtoYUV();
287 } else if (optionFlag == 5) {
288 cm->setColorMatrix4(coeffs);
289 float add[4] = {5.3f, 2.1f, 0.3f, 4.4f};
290 cm->setAdd(add);
291 }
292 cm->forEach(inputAlloc, outputAlloc);
293
294 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
295
296 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
297 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
298 env->ReleaseFloatArrayElements(coeffArray, coeffs, JNI_ABORT);
299 env->ReleaseStringUTFChars(pathObj, path);
300 return (rs->getError() == RS_SUCCESS);
301
302 }
303
304 extern "C" JNIEXPORT jboolean JNICALL
Java_android_cts_rscpp_RSBlendTest_blendTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray,jint optionFlag)305 Java_android_cts_rscpp_RSBlendTest_blendTest(JNIEnv * env, jclass obj, jstring pathObj,
306 jint X, jint Y, jbyteArray inputByteArray,
307 jbyteArray outputByteArray,
308 jint optionFlag)
309 {
310 const char * path = env->GetStringUTFChars(pathObj, NULL);
311 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
312 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
313
314 sp<RS> rs = new RS();
315 rs->init(path);
316
317 sp<const Element> e = Element::RGBA_8888(rs);
318
319 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
320 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, X, Y);
321
322 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
323 outputAlloc->copy2DRangeFrom(0, 0, X, Y, output);
324
325 sp<ScriptIntrinsicBlend> blend = ScriptIntrinsicBlend::create(rs, e);
326 switch(optionFlag) {
327 case 0:
328 blend->forEachAdd(inputAlloc, outputAlloc);
329 break;
330 case 1:
331 blend->forEachClear(inputAlloc, outputAlloc);
332 break;
333 case 2:
334 blend->forEachDst(inputAlloc, outputAlloc);
335 break;
336 case 3:
337 blend->forEachDstAtop(inputAlloc, outputAlloc);
338 break;
339 case 4:
340 blend->forEachDstIn(inputAlloc, outputAlloc);
341 break;
342 case 5:
343 blend->forEachDstOut(inputAlloc, outputAlloc);
344 break;
345 case 6:
346 blend->forEachDstOver(inputAlloc, outputAlloc);
347 break;
348 case 7:
349 blend->forEachMultiply(inputAlloc, outputAlloc);
350 break;
351 case 8:
352 blend->forEachSrc(inputAlloc, outputAlloc);
353 break;
354 case 9:
355 blend->forEachSrcAtop(inputAlloc, outputAlloc);
356 break;
357 case 10:
358 blend->forEachSrcIn(inputAlloc, outputAlloc);
359 break;
360 case 11:
361 blend->forEachSrcOut(inputAlloc, outputAlloc);
362 break;
363 case 12:
364 blend->forEachSrcOver(inputAlloc, outputAlloc);
365 break;
366 case 13:
367 blend->forEachSubtract(inputAlloc, outputAlloc);
368 break;
369 case 14:
370 blend->forEachXor(inputAlloc, outputAlloc);
371 break;
372 default:
373 break;
374 }
375
376 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
377
378 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
379 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
380 env->ReleaseStringUTFChars(pathObj, path);
381 return (rs->getError() == RS_SUCCESS);
382
383 }
384
Java_android_cts_rscpp_RSResizeTest_resizeTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jfloat scaleX,jfloat scaleY,jboolean useByte,jint vecSize,jbyteArray inputByteArray,jbyteArray outputByteArray,jfloatArray inputFloatArray,jfloatArray outputFloatArray)385 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSResizeTest_resizeTest(JNIEnv * env,
386 jclass obj,
387 jstring pathObj,
388 jint X,
389 jint Y,
390 jfloat scaleX,
391 jfloat scaleY,
392 jboolean useByte,
393 jint vecSize,
394 jbyteArray inputByteArray,
395 jbyteArray outputByteArray,
396 jfloatArray inputFloatArray,
397 jfloatArray outputFloatArray
398 )
399 {
400 const char * path = env->GetStringUTFChars(pathObj, NULL);
401
402 sp<RS> rs = new RS();
403 rs->init(path);
404
405 RsDataType dt = RS_TYPE_UNSIGNED_8;
406 if (!useByte) {
407 dt = RS_TYPE_FLOAT_32;
408 }
409 sp<const Element> e = makeElement(rs, dt, vecSize);
410 sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
411
412 int outX = (int) (X * scaleX);
413 int outY = (int) (Y * scaleY);
414 sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, outX, outY);
415 sp<ScriptIntrinsicResize> resize = ScriptIntrinsicResize::create(rs);
416
417 if (useByte) {
418 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
419 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
420 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
421 } else {
422 jfloat * input = (jfloat *) env->GetPrimitiveArrayCritical(inputFloatArray, 0);
423 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
424 env->ReleasePrimitiveArrayCritical(inputFloatArray, input, 0);
425 }
426
427 resize->setInput(inputAlloc);
428 resize->forEach_bicubic(outputAlloc);
429
430 if (useByte) {
431 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
432 outputAlloc->copy2DRangeTo(0, 0, outX, outY, output);
433 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
434 } else {
435 jfloat * output = (jfloat *) env->GetPrimitiveArrayCritical(outputFloatArray, 0);
436 outputAlloc->copy2DRangeTo(0, 0, outX, outY, output);
437 env->ReleasePrimitiveArrayCritical(outputFloatArray, output, 0);
438 }
439
440 env->ReleaseStringUTFChars(pathObj, path);
441 return (rs->getError() == RS_SUCCESS);
442
443 }
444
Java_android_cts_rscpp_RSYuvTest_yuvTest(JNIEnv * env,jclass obj,jstring pathObj,jint X,jint Y,jbyteArray inputByteArray,jbyteArray outputByteArray,jint yuvFormat)445 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSYuvTest_yuvTest(JNIEnv * env,
446 jclass obj,
447 jstring pathObj,
448 jint X,
449 jint Y,
450 jbyteArray inputByteArray,
451 jbyteArray outputByteArray,
452 jint yuvFormat
453 )
454 {
455 const char * path = env->GetStringUTFChars(pathObj, NULL);
456 jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
457 jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
458
459 sp<RS> mRS = new RS();
460 mRS->init(path);
461
462 RsYuvFormat mYuvFormat = (RsYuvFormat)yuvFormat;
463 sp<ScriptIntrinsicYuvToRGB> syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::U8_4(mRS));;
464 sp<Allocation> inputAlloc = nullptr;
465
466 if (mYuvFormat != RS_YUV_NONE) {
467 //syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::YUV(mRS));
468 Type::Builder tb(mRS, Element::YUV(mRS));
469 tb.setX(X);
470 tb.setY(Y);
471 tb.setYuvFormat(mYuvFormat);
472 inputAlloc = Allocation::createTyped(mRS, tb.create());
473 inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
474 } else {
475 //syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::U8(mRS));
476 size_t arrLen = X * Y + ((X + 1) / 2) * ((Y + 1) / 2) * 2;
477 inputAlloc = Allocation::createSized(mRS, Element::U8(mRS), arrLen);
478 inputAlloc->copy1DRangeFrom(0, arrLen, input);
479 }
480
481 sp<const Type> tout = Type::create(mRS, Element::RGBA_8888(mRS), X, Y, 0);
482 sp<Allocation> outputAlloc = Allocation::createTyped(mRS, tout);
483
484 syuv->setInput(inputAlloc);
485 syuv->forEach(outputAlloc);
486
487 outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
488
489 env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
490 env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
491 env->ReleaseStringUTFChars(pathObj, path);
492 return (mRS->getError() == RS_SUCCESS);
493
494 }
495