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 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 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 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 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 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 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 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