From 4f585f7cf9f0366d84dfe78d20c09c64bac6dff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois?= Date: Mon, 12 Feb 2024 15:22:15 +0100 Subject: [PATCH] Throw when ScriptC is used on unsupported ABIs ScriptC won't be supported on any new architecture (for example riscv64), so throw an exception when it is used on an unsupported architecture. Note that using `Build.SUPPORTED_ABIS` includes ABIs supported due to dynamic binary translation, which do not support ScriptC. So we can't use `Build.SUPPORTED_ABIS` to determine if ScriptC is supported or not. Instead we attempt loading `libRS.so`. `libRS.so` is not present on riscv64 images, so this allows us to know if we are on a riscv64 system. A problem occurs on x86 images with binary translation for riscv64 (aka berberis): when running a riscv64 binary, the binary translation system will fallback to the x86 version of the libraries via what is called a "native bridge". This means that `libRS.so` would successfully load on those system, which we do not want because even though it would load it wouldn't run properly. This is why a separate CL in the binary translation codebase was landed that explicitly refuses to load `libRS.so`: https://android-review.git.corp.google.com/c/platform/frameworks/libs/binary_translation/+/2971952 Bug: 206676167 Test: atest CtsRsBlasTestCases:android.cts.rsblas.IntrinsicBLAS#test_L3_SGEMM_API -- --abi x86_64 Change-Id: I2ed2e2ae531046d1d00e9a2d2f864375b0bb3570 --- rs/java/android/renderscript/ScriptC.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java index 67c2caa338a6..4a2f3da0eb06 100644 --- a/rs/java/android/renderscript/ScriptC.java +++ b/rs/java/android/renderscript/ScriptC.java @@ -101,7 +101,19 @@ protected ScriptC(RenderScript rs, String resName, byte[] bitcode32, byte[] bitc setID(id); } - private static void throwExceptionIfSDKTooHigh() { + private static void throwExceptionIfScriptCUnsupported() { + // Checks that this device actually does have an ABI that supports ScriptC. + // + // For an explanation as to why `System.loadLibrary` is used, see discussion at + // https://android-review.googlesource.com/c/platform/frameworks/base/+/2957974/comment/2f908b80_a05292ee + try { + System.loadLibrary("RS"); + } catch (UnsatisfiedLinkError e) { + String s = "This device does not have an ABI that supports ScriptC."; + throw new UnsupportedOperationException(s); + } + + // Throw an exception if the target API is 35 or above String message = "ScriptC scripts are not supported when targeting an API Level >= 35. Please refer " + "to https://developer.android.com/guide/topics/renderscript/migration-guide " @@ -113,7 +125,7 @@ private static void throwExceptionIfSDKTooHigh() { } private static synchronized long internalCreate(RenderScript rs, Resources resources, int resourceID) { - throwExceptionIfSDKTooHigh(); + throwExceptionIfScriptCUnsupported(); byte[] pgm; int pgmLength; InputStream is = resources.openRawResource(resourceID); @@ -150,7 +162,7 @@ private static synchronized long internalCreate(RenderScript rs, Resources resou private static synchronized long internalStringCreate(RenderScript rs, String resName, byte[] bitcode) { // Log.v(TAG, "Create script for resource = " + resName); - throwExceptionIfSDKTooHigh(); + throwExceptionIfScriptCUnsupported(); return rs.nScriptCCreate(resName, RenderScript.getCachePath(), bitcode, bitcode.length); } }