/* * 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(); }