Improve Java reflection for 32-bit versus 64-bit differences.
Bug: 32780232
Bug: 20260865
Bug: 21597073
This CL goes along with a frameworks/compile/slang change that
contains the actual fixes. This CL makes three changes:
1) Adds RenderScript.getPointerSize() method to compatibility library
for use by reflected code.
2) Adds UT_reflection3264 test case to tests/java_api/RSUnitTests.
3) Fixes test case apitest.rs to conform to 32-bit/64-bit consistency
requirements.
Test: many
- RsTest aosp_x86_64-eng (aosp, emulator) 32-bit and 64-bit
- RSTestBackward
- aosp_arm-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_arm64-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- RSTest_Backward19
- aosp_arm-eng
- n5 KLP MR2 Release (KT)
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- RSTest_CompatLib
- aosp_arm-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_arm64-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_x86-eng
- emulator aosp
- aosp_x86_64-eng
- emulator aosp
- RSTest_Compat19
- aosp_arm-eng
- n5 KLP MR2 Release (KT)
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_x86
- emulator aosp
Merged-In: I35d5d62014be9f389c1499605efad7303cbd8b2e
Merged-In: If65a3b7fbe281d24e9707a02304a1e676bf3a072
Merged-In: I101e30c69062a65fde1d928a2396db0fb7d86497
Merged-In: I6b563f4e8ba861303246334f8857eec7b86b5fda
Change-Id: I4764aac63a880a7594c05ce9a6c5afc20f4d52d3
(cherry picked from commit a5eaa3f317eca21b72429b0616acc0882852efdc)
diff --git a/support/java/src/android/support/v8/renderscript/RenderScript.java b/support/java/src/android/support/v8/renderscript/RenderScript.java
index 19a33d7..13c5dc2 100644
--- a/support/java/src/android/support/v8/renderscript/RenderScript.java
+++ b/support/java/src/android/support/v8/renderscript/RenderScript.java
@@ -131,10 +131,22 @@
return useNative;
}
/*
- * Detect the bitness of the VM to allow FieldPacker to do the right thing.
+ * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing.
*/
static native int rsnSystemGetPointerSize();
static int sPointerSize;
+ static public int getPointerSize() {
+ // We provide an accessor rather than making the data item public for two reasons.
+ // 1) Prevents anyone outside this class from writing the data item.
+ // 2) Prevents anyone outside this class from reading the data item unless a class
+ // instance has been created (ensuring the data item has been initialized).
+ // DISCLAIMER: Reflection can circumvent these preventive measures.
+ synchronized(lock) {
+ if (!sInitialized)
+ throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated");
+ }
+ return sPointerSize;
+ }
/**
* Determines whether or not we should be thunking into the native
diff --git a/tests/java_api/RSTestBackward/src/com/android/rs/testbackward/RSTests.java b/tests/java_api/RSTestBackward/src/com/android/rs/testbackward/RSTests.java
index 52b7580..776187a 100644
--- a/tests/java_api/RSTestBackward/src/com/android/rs/testbackward/RSTests.java
+++ b/tests/java_api/RSTestBackward/src/com/android/rs/testbackward/RSTests.java
@@ -57,6 +57,7 @@
validClasses.add(UT_noroot.class);
validClasses.add(UT_primitives.class);
validClasses.add(UT_refcount.class);
+ validClasses.add(UT_reflection3264.class);
validClasses.add(UT_rsdebug.class);
validClasses.add(UT_rstime.class);
validClasses.add(UT_rstypes.class);
diff --git a/tests/java_api/RSTestBackward19/Android.mk b/tests/java_api/RSTestBackward19/Android.mk
index 1ba4313..0ccb741 100644
--- a/tests/java_api/RSTestBackward19/Android.mk
+++ b/tests/java_api/RSTestBackward19/Android.mk
@@ -81,6 +81,8 @@
$(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
diff --git a/tests/java_api/RSTestBackward19/src/com/android/rs/testbackward19/RSTests.java b/tests/java_api/RSTestBackward19/src/com/android/rs/testbackward19/RSTests.java
index fb8e62d..c5a4baf 100644
--- a/tests/java_api/RSTestBackward19/src/com/android/rs/testbackward19/RSTests.java
+++ b/tests/java_api/RSTestBackward19/src/com/android/rs/testbackward19/RSTests.java
@@ -57,6 +57,7 @@
validClasses.add(UT_noroot.class);
validClasses.add(UT_primitives.class);
validClasses.add(UT_refcount.class);
+ validClasses.add(UT_reflection3264.class);
validClasses.add(UT_rsdebug.class);
validClasses.add(UT_rstime.class);
validClasses.add(UT_rstypes.class);
diff --git a/tests/java_api/RSTestForward/Android.mk b/tests/java_api/RSTestForward/Android.mk
index d0c9cc1..d61c310 100644
--- a/tests/java_api/RSTestForward/Android.mk
+++ b/tests/java_api/RSTestForward/Android.mk
@@ -96,6 +96,8 @@
$(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
@@ -192,6 +194,8 @@
$(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rstime.java\
@@ -298,6 +302,8 @@
$(my_rs_unit_tests_path)/primitives.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
@@ -427,6 +433,8 @@
$(my_rs_unit_tests_path)/reduce_backward.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
@@ -570,6 +578,8 @@
$(my_rs_unit_tests_path)/reduce_backward.rs\
$(my_rs_unit_tests_path)/UT_refcount.java\
$(my_rs_unit_tests_path)/refcount.rs\
+ $(my_rs_unit_tests_path)/UT_reflection3264.java\
+ $(my_rs_unit_tests_path)/reflection3264.rs\
$(my_rs_unit_tests_path)/UT_rsdebug.java\
$(my_rs_unit_tests_path)/rsdebug.rs\
$(my_rs_unit_tests_path)/UT_rsdebug_23.java\
diff --git a/tests/java_api/RSUnitTests/RSUnitTests.py b/tests/java_api/RSUnitTests/RSUnitTests.py
index ea050c7..a8fdc4e 100644
--- a/tests/java_api/RSUnitTests/RSUnitTests.py
+++ b/tests/java_api/RSUnitTests/RSUnitTests.py
@@ -65,6 +65,7 @@
'noroot',
'primitives',
'refcount',
+ 'reflection3264',
'rsdebug',
'rstime',
'rstypes',
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_reflection3264.java b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_reflection3264.java
new file mode 100644
index 0000000..f621fcd
--- /dev/null
+++ b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/UT_reflection3264.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package com.android.rs.unittest;
+
+import android.content.Context;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Short4;
+import android.renderscript.Type;
+import android.util.Log;
+import java.util.Random;
+
+import static junit.framework.Assert.assertEquals;
+
+public class UT_reflection3264 extends UnitTest {
+ private static final String TAG = "reflection3264";
+
+ public UT_reflection3264(Context ctx) {
+ super("reflection3264", ctx);
+ }
+
+ private final int xSize = 17, ySize = 23; // arbitrary values
+
+ private final long seed = 20170609; // arbitrary value
+
+ private static long unsigned(int v) {
+ if (v >= 0)
+ return (long)v;
+ else
+ return (long)v + ((long)1 << 32);
+ }
+
+ private static short unsigned(byte v) {
+ if (v >= 0)
+ return (short)v;
+ else
+ return (short)((short)v + (short)(1 << 8));
+ }
+
+ public void run() {
+ Random r = new Random(seed);
+
+ RenderScript pRS = createRenderScript(true);
+ ScriptC_reflection3264 s = new ScriptC_reflection3264(pRS);
+
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.U8_4(pRS));
+ typeBuilder.setX(xSize).setY(ySize);
+ Allocation inputAllocation = Allocation.createTyped(pRS, typeBuilder.create());
+ byte[] inputArray = new byte[xSize * ySize * 4];
+ r.nextBytes(inputArray);
+ inputAllocation.copyFrom(inputArray);
+
+ ScriptField_user_t.Item usrData = new ScriptField_user_t.Item();
+ usrData.ans = new Short4(
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()));
+ s.set_expect_ans(usrData.ans);
+ usrData.x = unsigned(r.nextInt());
+ s.set_expect_x(usrData.x);
+ usrData.y = unsigned(r.nextInt());
+ s.set_expect_y(usrData.y);
+
+ usrData.alloc = inputAllocation;
+
+ Allocation outputAllocation = Allocation.createTyped(pRS, typeBuilder.create());
+
+ s.set_expect_dAlloc_GetDimX(xSize);
+ s.set_expect_sAlloc_GetDimX(xSize);
+ final int dXOff = r.nextInt();
+ s.set_expect_dXOff(dXOff);
+ final int dMip = r.nextInt();
+ s.set_expect_dMip(dMip);
+ final int count = r.nextInt();
+ s.set_expect_count(count);
+ final int sXOff = r.nextInt();
+ s.set_expect_sXOff(sXOff);
+ final int sMip = r.nextInt();
+ s.set_expect_sMip(sMip);
+ s.invoke_args(outputAllocation, dXOff, dMip, count, inputAllocation, sXOff, sMip);
+
+ s.forEach_root(outputAllocation, usrData);
+ byte[] outputArray = new byte[xSize * ySize * 4];
+ outputAllocation.copyTo(outputArray);
+
+ for (int i = 0; i < xSize; ++i)
+ for (int j = 0; j < ySize; ++j) {
+ int idx = j * xSize + i;
+ assertEquals("[" + i + "][" + j + "]", inputArray[idx], outputArray[idx]);
+ }
+
+ s.invoke_check_asserts();
+ pRS.finish();
+ inputAllocation.destroy();
+ outputAllocation.destroy();
+ s.destroy();
+ pRS.destroy();
+ }
+}
diff --git a/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rs b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rs
new file mode 100644
index 0000000..159b318
--- /dev/null
+++ b/tests/java_api/RSUnitTests/src/com/android/rs/unittest/reflection3264.rs
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 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 "shared.rsh"
+
+typedef struct user_t {
+ uchar4 ans;
+ uint x;
+ uint y;
+ rs_allocation alloc;
+} user;
+
+uchar4 expect_ans;
+uint expect_x;
+uint expect_y;
+
+uint32_t expect_dAlloc_GetDimX;
+int expect_dXOff;
+int expect_dMip;
+int expect_count;
+uint32_t expect_sAlloc_GetDimX;
+int expect_sXOff;
+int expect_sMip;
+
+static bool failed = false;
+
+// See http://b/21597073 "Broken structure layout for RenderScript on 32-bit/64-bit compiles"
+void root(uchar4 *output, const user * usr, uint x, uint y) {
+ if (!x && !y) {
+ // Only check one coordinate, so as to avoid contention on global variable "failed"
+ _RS_ASSERT(usr->ans.x == expect_ans.x);
+ _RS_ASSERT(usr->ans.y == expect_ans.y);
+ _RS_ASSERT(usr->ans.z == expect_ans.z);
+ _RS_ASSERT(usr->ans.w == expect_ans.w);
+ _RS_ASSERT(usr->x == expect_x);
+ _RS_ASSERT(usr->y == expect_y);
+ }
+
+ uchar4 * e_in = (uchar4*)rsGetElementAt(usr->alloc, x, y);
+ *output = *e_in;
+}
+
+// See http://b/32780232 "Corrupted rs_allocation instances when passed as arguments to invocables"
+void args(rs_allocation dAlloc, int dXOff, int dMip, int count,
+ rs_allocation sAlloc, int sXOff, int sMip) {
+ _RS_ASSERT(rsIsObject(dAlloc) &&
+ (rsAllocationGetDimX(dAlloc) == expect_dAlloc_GetDimX));
+ _RS_ASSERT(dXOff == expect_dXOff);
+ _RS_ASSERT(dMip == expect_dMip);
+ _RS_ASSERT(count == expect_count);
+ _RS_ASSERT(rsIsObject(sAlloc) &&
+ (rsAllocationGetDimX(sAlloc) == expect_sAlloc_GetDimX));
+ _RS_ASSERT(sXOff == expect_sXOff);
+ _RS_ASSERT(sMip == expect_sMip);
+}
+
+void check_asserts() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
diff --git a/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs b/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs
index 6facb41..b0829a3 100644
--- a/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs
+++ b/tests/java_api/RSUnitTests/supportlibonlysrc/com/android/rs/unittest/apitest.rs
@@ -36,7 +36,7 @@
volatile rs_sampler_value rsv;
-volatile rs_time_t rst;
+volatile static rs_time_t rst;
volatile static rs_tm rstm;
char *allocPtr;
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_reflection3264.java b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_reflection3264.java
new file mode 100644
index 0000000..0717d05
--- /dev/null
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/UT_reflection3264.java
@@ -0,0 +1,117 @@
+// This file is automatically generated from
+// frameworks/rs/tests/java_api/RSUnitTests/RSUnitTests.py
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package com.android.rs.unittest;
+
+import android.content.Context;
+import android.support.v8.renderscript.Allocation;
+import android.support.v8.renderscript.Element;
+import android.support.v8.renderscript.RenderScript;
+import android.support.v8.renderscript.Short4;
+import android.support.v8.renderscript.Type;
+import android.util.Log;
+import java.util.Random;
+
+import static junit.framework.Assert.assertEquals;
+
+public class UT_reflection3264 extends UnitTest {
+ private static final String TAG = "reflection3264";
+
+ public UT_reflection3264(Context ctx) {
+ super("reflection3264", ctx);
+ }
+
+ private final int xSize = 17, ySize = 23; // arbitrary values
+
+ private final long seed = 20170609; // arbitrary value
+
+ private static long unsigned(int v) {
+ if (v >= 0)
+ return (long)v;
+ else
+ return (long)v + ((long)1 << 32);
+ }
+
+ private static short unsigned(byte v) {
+ if (v >= 0)
+ return (short)v;
+ else
+ return (short)((short)v + (short)(1 << 8));
+ }
+
+ public void run() {
+ Random r = new Random(seed);
+
+ RenderScript pRS = createRenderScript(true);
+ ScriptC_reflection3264 s = new ScriptC_reflection3264(pRS);
+
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.U8_4(pRS));
+ typeBuilder.setX(xSize).setY(ySize);
+ Allocation inputAllocation = Allocation.createTyped(pRS, typeBuilder.create());
+ byte[] inputArray = new byte[xSize * ySize * 4];
+ r.nextBytes(inputArray);
+ inputAllocation.copyFrom(inputArray);
+
+ ScriptField_user_t.Item usrData = new ScriptField_user_t.Item();
+ usrData.ans = new Short4(
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()),
+ unsigned((byte)r.nextInt()));
+ s.set_expect_ans(usrData.ans);
+ usrData.x = unsigned(r.nextInt());
+ s.set_expect_x(usrData.x);
+ usrData.y = unsigned(r.nextInt());
+ s.set_expect_y(usrData.y);
+
+ usrData.alloc = inputAllocation;
+
+ Allocation outputAllocation = Allocation.createTyped(pRS, typeBuilder.create());
+
+ s.set_expect_dAlloc_GetDimX(xSize);
+ s.set_expect_sAlloc_GetDimX(xSize);
+ final int dXOff = r.nextInt();
+ s.set_expect_dXOff(dXOff);
+ final int dMip = r.nextInt();
+ s.set_expect_dMip(dMip);
+ final int count = r.nextInt();
+ s.set_expect_count(count);
+ final int sXOff = r.nextInt();
+ s.set_expect_sXOff(sXOff);
+ final int sMip = r.nextInt();
+ s.set_expect_sMip(sMip);
+ s.invoke_args(outputAllocation, dXOff, dMip, count, inputAllocation, sXOff, sMip);
+
+ s.forEach_root(outputAllocation, usrData);
+ byte[] outputArray = new byte[xSize * ySize * 4];
+ outputAllocation.copyTo(outputArray);
+
+ for (int i = 0; i < xSize; ++i)
+ for (int j = 0; j < ySize; ++j) {
+ int idx = j * xSize + i;
+ assertEquals("[" + i + "][" + j + "]", inputArray[idx], outputArray[idx]);
+ }
+
+ s.invoke_check_asserts();
+ pRS.finish();
+ inputAllocation.destroy();
+ outputAllocation.destroy();
+ s.destroy();
+ pRS.destroy();
+ }
+}
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs
index 43a7cbe..28f6c8f 100644
--- a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/apitest.rs
@@ -38,7 +38,7 @@
volatile rs_sampler_value rsv;
-volatile rs_time_t rst;
+volatile static rs_time_t rst;
volatile static rs_tm rstm;
char *allocPtr;
diff --git a/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rs b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rs
new file mode 100644
index 0000000..e6959e5
--- /dev/null
+++ b/tests/java_api/RSUnitTests/supportlibsrc_gen/com/android/rs/unittest/reflection3264.rs
@@ -0,0 +1,79 @@
+// This file is automatically generated from
+// frameworks/rs/tests/java_api/RSUnitTests/RSUnitTests.py
+/*
+ * Copyright (C) 2017 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 "shared.rsh"
+
+typedef struct user_t {
+ uchar4 ans;
+ uint x;
+ uint y;
+ rs_allocation alloc;
+} user;
+
+uchar4 expect_ans;
+uint expect_x;
+uint expect_y;
+
+uint32_t expect_dAlloc_GetDimX;
+int expect_dXOff;
+int expect_dMip;
+int expect_count;
+uint32_t expect_sAlloc_GetDimX;
+int expect_sXOff;
+int expect_sMip;
+
+static bool failed = false;
+
+// See http://b/21597073 "Broken structure layout for RenderScript on 32-bit/64-bit compiles"
+void root(uchar4 *output, const user * usr, uint x, uint y) {
+ if (!x && !y) {
+ // Only check one coordinate, so as to avoid contention on global variable "failed"
+ _RS_ASSERT(usr->ans.x == expect_ans.x);
+ _RS_ASSERT(usr->ans.y == expect_ans.y);
+ _RS_ASSERT(usr->ans.z == expect_ans.z);
+ _RS_ASSERT(usr->ans.w == expect_ans.w);
+ _RS_ASSERT(usr->x == expect_x);
+ _RS_ASSERT(usr->y == expect_y);
+ }
+
+ uchar4 * e_in = (uchar4*)rsGetElementAt(usr->alloc, x, y);
+ *output = *e_in;
+}
+
+// See http://b/32780232 "Corrupted rs_allocation instances when passed as arguments to invocables"
+void args(rs_allocation dAlloc, int dXOff, int dMip, int count,
+ rs_allocation sAlloc, int sXOff, int sMip) {
+ _RS_ASSERT(rsIsObject(dAlloc) &&
+ (rsAllocationGetDimX(dAlloc) == expect_dAlloc_GetDimX));
+ _RS_ASSERT(dXOff == expect_dXOff);
+ _RS_ASSERT(dMip == expect_dMip);
+ _RS_ASSERT(count == expect_count);
+ _RS_ASSERT(rsIsObject(sAlloc) &&
+ (rsAllocationGetDimX(sAlloc) == expect_sAlloc_GetDimX));
+ _RS_ASSERT(sXOff == expect_sXOff);
+ _RS_ASSERT(sMip == expect_sMip);
+}
+
+void check_asserts() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}