I am trying to use the Android Renderscript support library on API devices 16 and above, following the steps described here. So far, everything went smoothly.
My Renderscript code is listed below.
#pragma version(1) #pragma rs java_package_name(com.xxx.renderscript.test) #include "rs_time.rsh" rs_script flipScript; rs_allocation gIn; rs_allocation gOut; int width; int height; int direction = 0; void root(uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) { if(direction == 0) { // flip horizontally const uchar4 *element = rsGetElementAt(gIn, width - x, y); float4 color = rsUnpackColor8888(*element); float4 output = {color.r, color.g, color.b}; *v_out = rsPackColorTo8888(output); } else if(direction == 1) { // flip vertically const uchar4 *element = rsGetElementAt(gIn, x, height - y); float4 color = rsUnpackColor8888(*element); float4 output = {color.r, color.g, color.b}; *v_out = rsPackColorTo8888(output); } else if(direction == 2) { // rotate left const uchar4 *element = rsGetElementAt(gIn, width - y, x); float4 color = rsUnpackColor8888(*element); float4 output = {color.r, color.g, color.b}; *v_out = rsPackColorTo8888(output); } else if(direction == 3) { // rotate right const uchar4 *element = rsGetElementAt(gIn, y, height - x); float4 color = rsUnpackColor8888(*element); float4 output = {color.r, color.g, color.b}; *v_out = rsPackColorTo8888(output); } } void flip(int testIdx) { int64_t t0, t1; int64_t t; t0 = rsUptimeNanos(); rsForEach(flipScript, gIn, gOut); t1 = rsUptimeNanos(); t = t1 - t0; rsDebug(" flip: timer on RS side: ", t); }
First, I updated my Android SDK tools to 22.3, and the SDK platform tools to 19. If I click ADT / Help / About ADT / Installation Details, I see that all components have been updated to 22.3.0, except for the developer Tools which are still equal to 21.0.1:
Android DDMS 22.3.0.v201310242005-887826 com.android.ide.eclipse.ddms.feature.group The Android Open Source Project Android Developer Tools 21.0.1.201212060302 com.android.ide.eclipse.adt.package.product null Android Development Tools 22.3.0.v201310242005-887826 com.android.ide.eclipse.adt.feature.group The Android Open Source Project Android Hierarchy Viewer 22.3.0.v201310242005-887826 com.android.ide.eclipse.hierarchyviewer.feature.group The Android Open Source Project Android Native Development Tools 22.3.0.v201310242005-887826 com.android.ide.eclipse.ndk.feature.group The Android Open Source Project Android Traceview 22.3.0.v201310242005-887826 com.android.ide.eclipse.traceview.feature.group The Android Open Source Project Tracer for OpenGL ES 22.3.0.v201310242005-887826 com.android.ide.eclipse.gldebugger.feature.group The Android Open Source Project
Then I edited the file "project.properties", as suggested in the above steps. I also made changes to Tim Murray's comments.
proguard.config=C:/android/adt-bundle-windows-x86_64/sdk/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. target=android-18 renderscript.target=18 renderscript.support.mode=true #sdk.buildtools=19.0.0
In my Java code, I made sure that the packages from the support library were imported. The following is the complete Java file:
package com.xxx.renderscript.test; import android.support.v8.renderscript.*; //import android.renderscript.RenderScript; //import android.renderscript.Allocation; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.View; import android.widget.ImageView; public class RenderScriptTestActivity extends Activity { private final String mLog = this.getClass().getName(); private static final int TESTS_PER_GROUP = 12; private Bitmap mBitmapIn; private Bitmap mBitmapOut; private ImageView mDisplayView; private RenderScript mRS = null; private ScriptC_flip mScriptFlip = null; private Allocation mInPixelsAllocation = null; private Allocation mOutPixelsAllocation = null; //use aSyncTask so we display the image while rendering it. private ImageRenderTask mImageRenderTask = null; private boolean isRsBenchDone = false; @Override protected void onCreate(Bundle savedInstanceState) { Log.i(mLog, "onCreate() "); super.onCreate(savedInstanceState); setContentView(R.layout.layout_rs); mBitmapIn = loadBitmap(R.drawable.city); mBitmapOut = loadBitmap(R.drawable.city); mDisplayView = (ImageView) findViewById(R.id.rs_display); mDisplayView.setImageBitmap(mBitmapOut); // RS instances mRS = RenderScript.create(this); mScriptFlip = new ScriptC_flip(mRS, getResources(), R.raw.flip); mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); } @Override protected void onResume() { Log.i(mLog, "onResume "); super.onResume(); // for thread & display control isRsBenchDone = true; } // initialize flip.rs private void setupRS() { Log.i(mLog, "Initializing flip.rs..."); mScriptFlip.set_flipScript(mScriptFlip); mScriptFlip.set_width(mBitmapIn.getWidth()); mScriptFlip.set_height(mBitmapIn.getHeight()); mScriptFlip.set_gIn(mInPixelsAllocation); mScriptFlip.set_gOut(mOutPixelsAllocation); } @Override protected void onStop() { Log.i(mLog, "onStop "); super.onStop(); } private void resetRS() { mBitmapIn = null; mBitmapOut = null; mRS = null; mScriptFlip = null; mInPixelsAllocation = null; mOutPixelsAllocation = null; } private Bitmap loadBitmap(int resource) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap b_temp = BitmapFactory.decodeResource(getResources(), resource, options); int w = b_temp.getWidth(); int h = b_temp.getHeight(); Config cfg = b_temp.getConfig(); Bitmap b_keep = Bitmap.createBitmap(w, h, cfg); Canvas c = new Canvas(b_keep); c.drawBitmap(b_temp, 0, 0, null); b_temp.recycle(); if (true) { Log.d(mLog, "loadBitmap(): width = " + w + " loadBitmap(): height = " + h); } return b_keep; } // press the button to invoke this function public void benchmark(View v) { if (false == isRsBenchDone) { //do nothing if it not done yet return; } if (mImageRenderTask != null) { if (mImageRenderTask.getStatus() == AsyncTask.Status.RUNNING) { return; } if (mImageRenderTask.getStatus() == AsyncTask.Status.PENDING) { mImageRenderTask.execute(); return; } } // instantiate AsyncTask if not already existed & running Log.i(mLog, "User pressed Start"); SystemClock.sleep(2000); isRsBenchDone = false; setupRS(); mImageRenderTask = new ImageRenderTask(); mImageRenderTask.execute(); } // user presses this button when the test is done and all results have been // recorded. public void pressedRsExit(View view) { Log.i(mLog, "User pressed Exit"); if (isRsBenchDone) { // only exit when we are finished resetRS(); RenderScriptTestActivity.this.finish(); } } /************************************************************************** ** * Since the display must be updated in the main UI thread, and the main * UI thread cannot be put to sleep, we have to use an AsyncTask to update * the display after the image is rendered, and then sleep some time * so that the tester can view the images being displayed. ** **************************************************************************/ private class ImageRenderTask extends AsyncTask<Void, Drawable, Void> { // runs in the UI (main) thread in correspondence to the AsyncTask // updating the drawable. protected void onProgressUpdate(Drawable... values) { Log.i(mLog, "onProgressUpdate..."); super.onProgressUpdate(values); Drawable draw_tmp = values[0]; mDisplayView.setImageDrawable(draw_tmp); mDisplayView.invalidate(); } // runs on the UI (main) thread after the AsyncTask is finished @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // reset the flag to exit isRsBenchDone = true; } @Override protected Void doInBackground(Void... params) { int group_id; int flip_way; //------------------------------------------------------------ // group 4: flip horizontally //------------------------------------------------------------ flip_way = 0; mScriptFlip.set_direction(flip_way); Log.i(mLog, "starting horizontal flipping ... ... ... ..."); // measure group 4 group_id = 4; // used as a switch for render script measureRS(group_id); Log.i(mLog, " horizontal done"); // sleep cannot happen in the main UI thread SystemClock.sleep(2500); updateDisplay(); SystemClock.sleep(2500); //------------------------------------------------------------ // group 5: flip vertically //------------------------------------------------------------ mScriptFlip.set_gIn(mInPixelsAllocation); flip_way = 1; mScriptFlip.set_direction(flip_way); Log.i(mLog, "starting vertical flipping ... ... ... ..."); // measure group 5 group_id = 5; // used as a switch for render script measureRS(group_id); Log.i(mLog, " vertical done"); // sleep cannot happen in the main UI thread SystemClock.sleep(2500); updateDisplay(); SystemClock.sleep(2500); return null; } // run and measure Render Script instances private void measureRS(int group_id) { if ((0==group_id) || (1 == group_id) || (2 == group_id)) { //other stuff } if (3 == group_id) { //other stuff } if ((4==group_id) || (5 == group_id)) { for (int i = 0; i < TESTS_PER_GROUP; i++) { mScriptFlip.invoke_flip(i); } } } // update the displayed image private void updateDisplay() { Log.i(mLog, "updateDisplay..."); //mOutPixelsAllocation.copyTo(mBitmapIn); // this to verify the display. mOutPixelsAllocation.copyTo(mBitmapOut); Bitmap b_temp = Bitmap.createBitmap(mBitmapOut.getWidth(), mBitmapOut.getHeight(), Bitmap.Config.ARGB_8888); Canvas c_temp = new Canvas(b_temp); c_temp.drawBitmap(mBitmapOut, 0, 0, null); Drawable d_temp = new BitmapDrawable(getResources(), b_temp); publishProgress(d_temp); } } }
Finally, in my project properties, I added external JARs to the Java build path:
renderscript-v8.jar - C:\android\adt-bundle-windows-x86_64\sdk\build-tools\19.0.0\renderscript\lib
The code is built without any problems. Then I tested it on several devices. Here are the test results.
Nexus 7 (2012 version updated to Android 4.4) The code ran to end without crashing. However, after the first time Renderscript is called, updating the ImageView results in empty displays. The output bitmap appears to be incorrectly recorded.
Huawei Mate (Android 4.1.2) Code crash immediately after loading from ADT. The following is a list of error messages (message body is limited to 30 thousand characters, so I canβt publish everything):
W/dalvikvm(2246): Refusing to reopen boot DEX '/system/framework/hwframework.jar' E/RenderScript_jni(2246): No GC methods D/dalvikvm(2246): Trying to load lib /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918 D/dalvikvm(2246): Added shared lib /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918 D/dalvikvm(2246): No JNI_OnLoad found in /data/data/com.xxx.renderscript.test/lib/libRSSupport.so 0x41726918, skipping init D/dalvikvm(2246): Trying to load lib /data/data/com.xxx.renderscript.test/lib/librsjni.so 0x41726918 D/dalvikvm(2246): Added shared lib /data/data/com.xxx.renderscript.test/lib/librsjni.so 0x41726918 V/RenderScript_jni(2246): RS compat mode V/RenderScript(2246): 0x5bc7d008 Launching thread(s), CPUs 3 E/RenderScript(2246): Unable to open shared library (/data/data/com.xxx.renderscript.test//lib/librs.flip.so): Cannot load library: reloc_library[1306]: 132 cannot locate '_Z13rsUptimeNanosv'... E/RenderScript(2246): Unable to open system shared library (/system/lib/librs.flip.so): (null) D/AndroidRuntime(2246): Shutting down VM W/dalvikvm(2246): threadid=1: thread exiting with uncaught exception (group=0x40f122a0) E/AndroidRuntime(2246): FATAL EXCEPTION: main E/AndroidRuntime(2246): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.renderscript.test/com.xxx.renderscript.test.RenderScriptTestActivity}: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed.
Sony Xperia Z Ultra C6802 (Android 4.2.2) After a failure with ADT, the code fails with the following error messages (again selected in accordance with the limit of 30 thousand characters):
D/AndroidRuntime(3498): CheckJNI is OFF D/dalvikvm(3498): Trying to load lib libjavacore.so 0x0 D/dalvikvm(3498): Added shared lib libjavacore.so 0x0 D/dalvikvm(3498): Trying to load lib libnativehelper.so 0x0 D/dalvikvm(3498): Added shared lib libnativehelper.so 0x0 I/ActivityManager(903): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=3513 uid=10085 gids={50085, 1015, 1028} I/ActivityManager(903): No longer want com.mobisystems.office:search (pid 2686): empty #34 I/ActivityManager(903): Start proc com.sonymobile.enterprise.service for broadcast com.sonymobile.enterprise.service/.Receiver: pid=3539 uid=1000 gids={41000, 3003, 1015, 1028, 3002, 3001, 3007} D/AndroidRuntime(3498): Calling main entry com.android.commands.am.Am D/dalvikvm(3498): Note: class Landroid/app/ActivityManagerNative; has 157 unimplemented (abstract) methods I/ActivityManager(903): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.xxx.renderscript.test/.RenderScriptTestActivity} from pid 3498 D/AndroidRuntime(3498): Shutting down VM D/jdwp(3498): Got wake-up signal, bailing out of select D/dalvikvm(3498): Debugger has detached; object registry had 1 entries D/dalvikvm(3557): Late-enabling CheckJNI I/ActivityManager(903): Start proc com.xxx.renderscript.test for activity com.xxx.renderscript.test/.RenderScriptTestActivity: pid=3557 uid=10088 gids={50088, 1028} D/dalvikvm(3557): Debugger has detached; object registry had 1 entries I/Icing.InternalIcingCorporaProvider(2583): Updating corpora: A: com.xxx.renderscript.test, C: MAYBE E/.AppDataSearchProvider(2583): Could not connect to AppDataSearchClient to register corpora. W/Icing.InternalIcingCorporaProvider(2583): Corpora registration failed I/com.xxx.renderscript.test.RenderScriptTestActivity(3557): onCreate() E/.AppDataSearchProvider(2583): Could not connect to AppDataSearchClient for notifyTableChanged W/Icing.InternalIcingCorporaProvider(2583): Application table change notification failed. D/dalvikvm(2856): GC_CONCURRENT freed 187K, 73% free 3028K/11084K, paused 3ms+4ms, total 20ms D/ConnectionNotify(3116): queue add:2 D/AudioHardwareALSAExt(329): getParameters() supported_effect D/[APP_SERVICE](3116): package com.xxx.renderscript.test installed D/[APP_SERVICE](3116): add package com.xxx.renderscript.test I/ActivityManager(903): Start proc com.UCMobile for broadcast com.UCMobile/.receivers.SysReceiver: pid=3587 uid=10207 gids={50207, 3003, 1015, 1028} I/dalvikvm(3587): Turning on JNI app bug workarounds for target SDK version 8... D/dalvikvm(3410): GC_CONCURRENT freed 511K, 71% free 3273K/11084K, paused 2ms+1ms, total 20ms D/dalvikvm(3410): WAIT_FOR_CONCURRENT_GC blocked 5ms E/RenderScript_jni(3557): No GC methods D/dalvikvm(3557): Trying to load lib /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8 D/dalvikvm(3557): Added shared lib /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8 D/dalvikvm(3557): No JNI_OnLoad found in /data/app-lib/com.xxx.renderscript.test-1/libRSSupport.so 0x418243f8, skipping init D/dalvikvm(3557): Trying to load lib /data/app-lib/com.xxx.renderscript.test-1/librsjni.so 0x418243f8 D/dalvikvm(3557): Added shared lib /data/app-lib/com.xxx.renderscript.test-1/librsjni.so 0x418243f8 V/RenderScript_jni(3557): RS compat mode V/RenderScript(3557): 0x72b26978 Launching thread(s), CPUs 4 E/RenderScript(3557): Unable to open shared library (/data/data/com.xxx.renderscript.test//lib/librs.flip.so): Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "_Z13rsUptimeNanosv" referenced by "librs.flip.so"... E/RenderScript(3557): Unable to open system shared library (/system/lib/librs.flip.so): (null) D/AndroidRuntime(3557): Shutting down VM W/dalvikvm(3557): threadid=1: thread exiting with uncaught exception (group=0x4154aae0) E/AndroidRuntime(3557): FATAL EXCEPTION: main E/AndroidRuntime(3557): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.renderscript.test/com.xxx.renderscript.test.RenderScriptTestActivity}: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed. E/AndroidRuntime(3557): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2224) E/AndroidRuntime(3557): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2274) E/AndroidRuntime(3557): at android.app.ActivityThread.access$600(ActivityThread.java:150) E/AndroidRuntime(3557): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276) E/AndroidRuntime(3557): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(3557): at android.os.Looper.loop(Looper.java:213) E/AndroidRuntime(3557): at android.app.ActivityThread.main(ActivityThread.java:5153) E/AndroidRuntime(3557): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(3557): at java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime(3557): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) E/AndroidRuntime(3557): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564) E/AndroidRuntime(3557): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime(3557): Caused by: android.support.v8.renderscript.RSRuntimeException: Loading of ScriptC script failed. E/AndroidRuntime(3557): at android.support.v8.renderscript.ScriptC.<init>(ScriptC.java:69) E/AndroidRuntime(3557): at com.xxx.renderscript.test.ScriptC_flip.<init>(ScriptC_flip.java:41) E/AndroidRuntime(3557): at com.xxx.renderscript.test.RenderScriptTestActivity.onCreate(RenderScriptTestActivity.java:53) E/AndroidRuntime(3557): at android.app.Activity.performCreate(Activity.java:5104) E/AndroidRuntime(3557): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) E/AndroidRuntime(3557): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2188) E/AndroidRuntime(3557): ... 11 more W/ActivityManager(903): Force finishing activity com.xxx.renderscript.test/.RenderScriptTestActivity
I would appreciate it if someone could study the problems, be it bugs in my code or Android SDK. Comments / suggestions are welcome Thank you!
[EDIT] I removed the unnecessary things from my code and post the full code here, in the hope that someone will be able to repeat my problem and find a solution. I also added more test results.