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 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 46 void aligned_free(void * memblk) { 47 if (memblk) { 48 void * addr = (void *) (((size_t *) memblk)[-1]); 49 free(addr); 50 } 51 } 52 53 sp<const Element> makeElement(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 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 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 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 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 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 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 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 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 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