| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <memory> |
| |
| #include <jni.h> |
| #include <RenderScript.h> |
| |
| #include "ScriptC_allocs.h" |
| |
| sp<RS> mRS; |
| |
| sp<Allocation> mBoolAllocation; // boolean |
| |
| sp<Allocation> mCharAllocation; // char |
| sp<Allocation> mChar2Allocation; // char2 |
| sp<Allocation> mChar3Allocation; // char3 |
| sp<Allocation> mChar4Allocation; // char4 |
| |
| sp<Allocation> mUCharAllocation; // uchar |
| sp<Allocation> mUChar2Allocation; // uchar2 |
| sp<Allocation> mUChar3Allocation; // uchar3 |
| sp<Allocation> mUChar4Allocation; // uchar4 |
| |
| sp<Allocation> mShortAllocation; // short |
| sp<Allocation> mShort2Allocation; // short2 |
| sp<Allocation> mShort3Allocation; // short3 |
| sp<Allocation> mShort4Allocation; // short4 |
| |
| sp<Allocation> mUShortAllocation; // ushort |
| sp<Allocation> mUShort2Allocation; // ushort2 |
| sp<Allocation> mUShort3Allocation; // ushort3 |
| sp<Allocation> mUShort4Allocation; // ushort4 |
| |
| sp<Allocation> mIntAllocation; // int |
| sp<Allocation> mInt2Allocation; // int2 |
| sp<Allocation> mInt3Allocation; // int3 |
| sp<Allocation> mInt4Allocation; // int4 |
| |
| sp<Allocation> mUIntAllocation; // uint |
| sp<Allocation> mUInt2Allocation; // uint2 |
| sp<Allocation> mUInt3Allocation; // uint3 |
| sp<Allocation> mUInt4Allocation; // uint4 |
| |
| sp<Allocation> mLongAllocation; // long |
| sp<Allocation> mLong2Allocation; // long2 |
| sp<Allocation> mLong3Allocation; // long3 |
| sp<Allocation> mLong4Allocation; // long4 |
| |
| sp<Allocation> mULongAllocation; // ulong |
| sp<Allocation> mULong2Allocation; // ulong2 |
| sp<Allocation> mULong3Allocation; // ulong3 |
| sp<Allocation> mULong4Allocation; // ulong4 |
| |
| sp<Allocation> mHalfAllocation; // half |
| sp<Allocation> mHalf2Allocation; // half2 |
| sp<Allocation> mHalf3Allocation; // half3 |
| sp<Allocation> mHalf4Allocation; // half4 |
| |
| sp<Allocation> mFloatAllocation; // float |
| sp<Allocation> mFloat2Allocation; // float2 |
| sp<Allocation> mFloat3Allocation; // float3 |
| sp<Allocation> mFloat4Allocation; // float4 |
| |
| sp<Allocation> mDoubleAllocation; // double |
| sp<Allocation> mDouble2Allocation; // double2 |
| sp<Allocation> mDouble3Allocation; // double3 |
| sp<Allocation> mDouble4Allocation; // double4 |
| |
| const int mAllocSize = 24; // Needs to be < CHAR_MAX and divisible by 4. |
| const int mBitmapSize = 64; |
| |
| void createSignedAllocations() { |
| Type::Builder typeI8Builder(mRS, Element::I8(mRS)); |
| typeI8Builder.setX(1); // One element here to test 16 byte memory alignment |
| typeI8Builder.setY(3); |
| typeI8Builder.setZ(8); |
| |
| mCharAllocation = Allocation::createTyped(mRS, typeI8Builder.create()); |
| mChar2Allocation = Allocation::createSized(mRS, Element::I8_2(mRS), mAllocSize / 2); |
| mChar3Allocation = Allocation::createSized(mRS, Element::I8_3(mRS), mAllocSize / 4); |
| mChar4Allocation = Allocation::createSized(mRS, Element::I8_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeI16_2Builder(mRS, Element::I16_2(mRS)); |
| typeI16_2Builder.setX(6); |
| typeI16_2Builder.setY(1); |
| typeI16_2Builder.setZ(2); |
| |
| mShortAllocation = Allocation::createSized(mRS, Element::I16(mRS), mAllocSize); |
| mShort2Allocation = Allocation::createTyped(mRS, typeI16_2Builder.create()); |
| mShort3Allocation = Allocation::createSized(mRS, Element::I16_3(mRS), mAllocSize / 4); |
| mShort4Allocation = Allocation::createSized(mRS, Element::I16_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeI32_3Builder(mRS, Element::I32_3(mRS)); |
| typeI32_3Builder.setX(3); |
| typeI32_3Builder.setY(2); |
| |
| mIntAllocation = Allocation::createSized(mRS, Element::I32(mRS), mAllocSize); |
| mInt2Allocation = Allocation::createSized(mRS, Element::I32_2(mRS), mAllocSize / 2); |
| mInt3Allocation = Allocation::createTyped(mRS, typeI32_3Builder.create()); |
| mInt4Allocation = Allocation::createSized(mRS, Element::I32_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeI64_4Builder(mRS, Element::I64_4(mRS)); |
| typeI64_4Builder.setX(1); |
| typeI64_4Builder.setY(6); |
| |
| mLongAllocation = Allocation::createSized(mRS, Element::I64(mRS), mAllocSize); |
| mLong2Allocation = Allocation::createSized(mRS, Element::I64_2(mRS), mAllocSize / 2); |
| mLong3Allocation = Allocation::createSized(mRS, Element::I64_3(mRS), mAllocSize / 4); |
| mLong4Allocation = Allocation::createTyped(mRS, typeI64_4Builder.create()); |
| |
| mBoolAllocation = Allocation::createSized(mRS, Element::BOOLEAN(mRS), mAllocSize); |
| } |
| |
| void initSignedAllocations() { |
| char *buffer_char = new char[mAllocSize]; |
| short *buffer_short = new short[mAllocSize]; |
| int *buffer_int = new int[mAllocSize]; |
| int64_t *buffer_long = new int64_t[mAllocSize]; |
| char *buffer_bool = new char[mAllocSize]; |
| |
| for(int i = 0; i < mAllocSize; ++i) { |
| buffer_char[i] = (char) i; |
| buffer_short[i] = (short) i; |
| buffer_int[i] = (int) i; |
| buffer_long[i] = (int64_t) i; |
| buffer_bool[i] = (char) (0x01 & i); |
| } |
| |
| mCharAllocation->copy3DRangeFrom(0, 0, 0, 1, 3, 8, buffer_char); |
| mChar2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_char); |
| mChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char); |
| mChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char); |
| |
| delete [] buffer_char; |
| |
| mShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short); |
| mShort2Allocation->copy3DRangeFrom(0, 0, 0, 6, 1, 2, buffer_short); |
| mShort3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short); |
| mShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short); |
| |
| delete [] buffer_short; |
| |
| mIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int); |
| mInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int); |
| mInt3Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_int); |
| mInt4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int); |
| |
| delete [] buffer_int; |
| |
| mLongAllocation->copy1DRangeFrom(0, mAllocSize, buffer_long); |
| mLong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long); |
| mLong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long); |
| mLong4Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_long); |
| |
| delete [] buffer_long; |
| |
| mBoolAllocation->copy1DRangeFrom(0, mAllocSize, buffer_bool); |
| |
| delete [] buffer_bool; |
| } |
| |
| void createUnsignedAllocations() { |
| Type::Builder typeU8_2Builder(mRS, Element::U8_2(mRS)); |
| typeU8_2Builder.setX(2); |
| typeU8_2Builder.setY(6); |
| |
| mUCharAllocation = Allocation::createSized(mRS, Element::U8(mRS), mAllocSize); |
| mUChar2Allocation = Allocation::createTyped(mRS, typeU8_2Builder.create()); |
| mUChar3Allocation = Allocation::createSized(mRS, Element::U8_3(mRS), mAllocSize / 4); |
| mUChar4Allocation = Allocation::createSized(mRS, Element::U8_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeU16_3Builder(mRS, Element::U16_3(mRS)); |
| typeU16_3Builder.setX(1); |
| typeU16_3Builder.setY(6); |
| |
| mUShortAllocation = Allocation::createSized(mRS, Element::U16(mRS), mAllocSize); |
| mUShort2Allocation = Allocation::createSized(mRS, Element::U16_2(mRS), mAllocSize / 2); |
| mUShort3Allocation = Allocation::createTyped(mRS, typeU16_3Builder.create()); |
| mUShort4Allocation = Allocation::createSized(mRS, Element::U16_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeU32_4Builder(mRS, Element::U32_4(mRS)); |
| typeU32_4Builder.setX(1); |
| typeU32_4Builder.setY(1); |
| typeU32_4Builder.setZ(6); |
| |
| mUIntAllocation = Allocation::createSized(mRS, Element::U32(mRS), mAllocSize); |
| mUInt2Allocation = Allocation::createSized(mRS, Element::U32_2(mRS), mAllocSize / 2); |
| mUInt3Allocation = Allocation::createSized(mRS, Element::U32_3(mRS), mAllocSize / 4); |
| mUInt4Allocation = Allocation::createTyped(mRS, typeU32_4Builder.create()); |
| |
| Type::Builder typeU64Builder(mRS, Element::U64(mRS)); |
| typeU64Builder.setX(4); |
| typeU64Builder.setY(3); |
| typeU64Builder.setZ(2); |
| |
| mULongAllocation = Allocation::createTyped(mRS, typeU64Builder.create()); |
| mULong2Allocation = Allocation::createSized(mRS, Element::U64_2(mRS), mAllocSize / 2); |
| mULong3Allocation = Allocation::createSized(mRS, Element::U64_3(mRS), mAllocSize / 4); |
| mULong4Allocation = Allocation::createSized(mRS, Element::U64_4(mRS), mAllocSize / 4); |
| } |
| |
| void initUnsignedAllocations() { |
| char *buffer_char = new char[mAllocSize]; |
| short *buffer_short = new short[mAllocSize]; |
| int *buffer_int = new int[mAllocSize]; |
| uint64_t *buffer_long = new uint64_t[mAllocSize]; |
| |
| for(int i = 0; i < mAllocSize; ++i) { |
| buffer_char[i] = (char) i; |
| buffer_short[i] = (short) i; |
| buffer_int[i] = (int) i; |
| buffer_long[i] = (uint64_t) i; |
| } |
| |
| mUCharAllocation->copy1DRangeFrom(0, mAllocSize, buffer_char); |
| mUChar2Allocation->copy2DRangeFrom(0, 0, 2, 6, buffer_char); |
| mUChar3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char); |
| mUChar4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_char); |
| |
| delete [] buffer_char; |
| |
| mUShortAllocation->copy1DRangeFrom(0, mAllocSize, buffer_short); |
| mUShort2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_short); |
| mUShort3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_short); |
| mUShort4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_short); |
| |
| delete [] buffer_short; |
| |
| mUIntAllocation->copy1DRangeFrom(0, mAllocSize, buffer_int); |
| mUInt2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_int); |
| mUInt3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_int); |
| mUInt4Allocation->copy3DRangeFrom(0, 0, 0, 1, 1, 6, buffer_int); |
| |
| delete [] buffer_int; |
| |
| mULongAllocation->copy3DRangeFrom(0, 0, 0, 4, 3, 2, buffer_long); |
| mULong2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_long); |
| mULong3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long); |
| mULong4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_long); |
| |
| delete [] buffer_long; |
| } |
| |
| void createFloatAllocations() { |
| Type::Builder typeF16_3Builder(mRS, Element::F16_3(mRS)); |
| typeF16_3Builder.setX(1); |
| typeF16_3Builder.setY(6); |
| |
| mHalfAllocation = Allocation::createSized(mRS, Element::F16(mRS), mAllocSize); |
| mHalf2Allocation = Allocation::createSized(mRS, Element::F16_2(mRS), mAllocSize / 2); |
| mHalf3Allocation = Allocation::createTyped(mRS, typeF16_3Builder.create()); |
| mHalf4Allocation = Allocation::createSized(mRS, Element::F16_4(mRS), mAllocSize / 4); |
| |
| Type::Builder typeF32_4Builder(mRS, Element::F32_4(mRS)); |
| typeF32_4Builder.setX(3); |
| typeF32_4Builder.setY(2); |
| |
| mFloatAllocation = Allocation::createSized(mRS, Element::F32(mRS), mAllocSize); |
| mFloat2Allocation = Allocation::createSized(mRS, Element::F32_2(mRS), mAllocSize / 2); |
| mFloat3Allocation = Allocation::createSized(mRS, Element::F32_3(mRS), mAllocSize / 4); |
| mFloat4Allocation = Allocation::createTyped(mRS, typeF32_4Builder.create()); |
| |
| Type::Builder typeF64_2Builder(mRS, Element::F64_2(mRS)); |
| typeF64_2Builder.setX(4); |
| typeF64_2Builder.setY(1); |
| typeF64_2Builder.setZ(3); |
| |
| mDoubleAllocation = Allocation::createSized(mRS, Element::F64(mRS), mAllocSize); |
| mDouble2Allocation = Allocation::createTyped(mRS, typeF64_2Builder.create()); |
| |
| Type::Builder typeF64_3Builder(mRS, Element::F64_3(mRS)); |
| typeF64_3Builder.setX(1); |
| typeF64_3Builder.setY(2); |
| typeF64_3Builder.setZ(3); |
| |
| Type::Builder typeF64_4Builder(mRS, Element::F64_4(mRS)); |
| typeF64_4Builder.setX(1); |
| typeF64_4Builder.setY(2); |
| typeF64_4Builder.setZ(3); |
| |
| mDouble3Allocation = Allocation::createTyped(mRS, typeF64_3Builder.create()); |
| mDouble4Allocation = Allocation::createTyped(mRS, typeF64_4Builder.create()); |
| } |
| |
| void initFloatAllocations() { |
| __fp16 *buffer_half = new __fp16[mAllocSize]; |
| float *buffer_float = new float[mAllocSize]; |
| double *buffer_double = new double[mAllocSize]; |
| |
| for(int i = 0; i < mAllocSize; ++i) { |
| buffer_half[i] = (__fp16) 1 / i; |
| buffer_float[i] = (float) 1 / i; |
| buffer_double[i] = (double) 1 / i; |
| } |
| |
| mHalfAllocation->copy1DRangeFrom(0, mAllocSize, buffer_half); |
| mHalf2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_half); |
| mHalf3Allocation->copy2DRangeFrom(0, 0, 1, 6, buffer_half); |
| mHalf4Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_half); |
| |
| delete [] buffer_half; |
| |
| mFloatAllocation->copy1DRangeFrom(0, mAllocSize, buffer_float); |
| mFloat2Allocation->copy1DRangeFrom(0, mAllocSize/2, buffer_float); |
| mFloat3Allocation->copy1DRangeFrom(0, mAllocSize/4, buffer_float); |
| mFloat4Allocation->copy2DRangeFrom(0, 0, 3, 2, buffer_float); |
| |
| delete [] buffer_float; |
| |
| mDoubleAllocation->copy1DRangeFrom(0, mAllocSize, buffer_double); |
| mDouble2Allocation->copy3DRangeFrom(0, 0, 0, 4, 1, 3, buffer_double); |
| mDouble3Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double); |
| mDouble4Allocation->copy3DRangeFrom(0, 0, 0, 1, 2, 3, buffer_double); |
| |
| delete [] buffer_double; |
| } |
| |
| extern "C" void JNICALL |
| Java_com_android_rs_jniallocations_MainActivity_nativeRS( |
| JNIEnv * env, |
| jclass, |
| jstring pathObj) |
| { |
| mRS = new RS(); |
| |
| const char * path = env->GetStringUTFChars(pathObj, nullptr); |
| mRS->init(path, RS_INIT_LOW_LATENCY | RS_INIT_WAIT_FOR_ATTACH); |
| env->ReleaseStringUTFChars(pathObj, path); |
| |
| sp<ScriptC_allocs> mScript = new ScriptC_allocs(mRS); |
| |
| Type::Builder typeRGBA_888Builder(mRS, Element::RGBA_8888(mRS)); |
| typeRGBA_888Builder.setX(mBitmapSize); |
| typeRGBA_888Builder.setY(mBitmapSize); |
| |
| sp<Allocation> mInAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create()); |
| |
| const int image_area = mBitmapSize*mBitmapSize; |
| const int image_size = image_area*sizeof(int); |
| |
| char *zero_buffer = new char[image_size]; |
| memset(zero_buffer, 0, image_size); |
| mInAllocation->copy1DRangeFrom(0, image_area, zero_buffer); |
| delete [] zero_buffer; |
| |
| sp<Allocation> mOutAllocation = Allocation::createTyped(mRS, typeRGBA_888Builder.create()); |
| createSignedAllocations(); |
| initSignedAllocations(); |
| |
| mRS->finish(); |
| mScript->forEach_swizzle_kernel(mInAllocation, mOutAllocation); |
| mRS->finish(); |
| |
| mCharAllocation.clear(); |
| mChar2Allocation.clear(); |
| mChar3Allocation.clear(); |
| mChar4Allocation.clear(); |
| |
| mShort2Allocation.clear(); |
| mShort3Allocation.clear(); |
| mShort4Allocation.clear(); |
| |
| mIntAllocation.clear(); |
| mInt2Allocation.clear(); |
| mInt3Allocation.clear(); |
| mInt4Allocation.clear(); |
| |
| mLongAllocation.clear(); |
| mLong2Allocation.clear(); |
| mLong3Allocation.clear(); |
| mLong4Allocation.clear(); |
| |
| mBoolAllocation.clear(); |
| |
| createUnsignedAllocations(); |
| initUnsignedAllocations(); |
| |
| mInAllocation = mUShortAllocation; // Host side assignment |
| |
| mRS->finish(); |
| mScript->forEach_square_kernel(mInAllocation, mUIntAllocation); |
| mRS->finish(); |
| |
| mUCharAllocation.clear(); |
| mUChar2Allocation.clear(); |
| mUChar3Allocation.clear(); |
| mUChar4Allocation.clear(); |
| |
| mUShortAllocation.clear(); |
| mUShort2Allocation.clear(); |
| mUShort3Allocation.clear(); |
| mUShort4Allocation.clear(); |
| |
| mUInt2Allocation.clear(); |
| mUInt3Allocation.clear(); |
| mUInt4Allocation.clear(); |
| |
| mULongAllocation.clear(); |
| mULong2Allocation.clear(); |
| mULong3Allocation.clear(); |
| mULong4Allocation.clear(); |
| |
| createFloatAllocations(); |
| initFloatAllocations(); |
| |
| mRS->finish(); |
| mScript->forEach_add_half_kernel(mDouble4Allocation, mDouble3Allocation); |
| mRS->finish(); |
| } |
| |