Guide to using RenderScript on Intel architecture running the Android OS

Published Date
09 - Feb - 2015
| Last Updated
09 - Feb - 2015
Guide to using RenderScript on Intel architecture running the And...


RenderScript is a scripting language on Android. You can use it to write high performance graphics rendering and raw computational code.

The RenderScript API includes high performance functions for 2D/3D rendering and mathematical calculations. It allows you to describe a task with the same type of independent calculations over a large volume of data and divide it into similar subtasks that can be executed quickly and in parallel on multi-core processor platforms running Android.

This technology can improve the performance of a number of Dalvik applications related to image processing, image recognition, physical models, etc., which in turn stay machine independent.

About the RenderScript technology within Android

  1. RenderScript offline compilation

    RenderScript first appeared in Honeycomb / Android 3.0 (in API 11). In the Android SDK directory platform tools you can find llvm-rs-cc (offline compiler) to compile RenderScript (*.rs file) into byte code (*.bc file) and generate Java* classes of objects (*.java files) for structures, global variables within RenderScript and RenderScript itself. llvm-rs-cc is based on the Clang compiler with a few changes for Android, which is a front-end for the LLVM compiler. This picture describes how offline compilation works.

  2. RenderScript run-time compilation

    The new Android framework is built on the LLVM back-end and is responsible for run-time compiling of byte code, linking with the right libraries, and launching and controlling RenderScript. This framework consists of the following components: libbcc engaged in LLVM context initialization, parsing pragmas and other metadata in the byte code, bytecode’s compilation and dynamic linking with the needed libraries from libRS. libRS contains libraries (math, time, drawing, ref counting, ...), structures, and data types (Script, Type, Element, Allocation, Mesh, various matrices, ...). The picture below shows runtime compilation.

Advantages of RenderScript:

  • The compiler produces machine-independent applications because the RenderScript byte code included in the apk file at run time will be compiled to native code for the CPU of the platform where it will be launched.
  • High speed execution is achieved due to parallelization of computing, run-time compiler optimization, and native code execution.


  • A lack of detailed documentation for RenderScript complicates application development. Limited runtime documentation for RenderScript run-time API is shown here. However, you can find a detailed "Getting Started" here.
  • There is no support to execute RenderScript threads on a GPU or DSP. You may encounter problems with the run-time balancing of threads in heterogeneous runs and using shared memory.

Example Usage of RenderScript: Converting RGB-color to monochrome image

RenderScript is based in C. You’ll be able to quickly learn it if you already know C. In addition, the principles of using it are similar to OpenGL*.

In our work at Intel, we often accelerate Dalvik functions using either RenderScript or OpenGL.

Here is an example of a Dalvik function, Dalvik_MonoChromeFilter, that is responsible for converting an RGB-color image to a monochrome one:

01private void DalvikFilter() {
02float MonoMult[] = {0.299f, 0.587f, 0.114f};
03int mInPixels[] = new int[mBitmapIn.getHeight() * mBitmapIn.getWidth()];
04int mOutPixels[] = new int[mBitmapOut.getHeight() * mBitmapOut.getWidth()];
05mBitmapIn.getPixels(mInPixels, 0, mBitmapIn.getWidth(), 0, 0,
06mBitmapIn.getWidth(), mBitmapIn.getHeight());
07for(int i = 0;i < mInPixels.length;i++) {
08float r = (float)(mInPixels[i] & 0xff);
09float g = (float)((mInPixels[i] >> 8) & 0xff);
10float b = (float)((mInPixels[i] >> 16) & 0xff);
12int mono = (int)(r * MonoMult[0] + g * MonoMult[1] + b * MonoMult[2]);
14mOutPixels[i] = mono + (mono << 8) + (mono << 16) + (mInPixels[i] & 0xff000000);
16mBitmapOut.setPixels(mOutPixels, 0, mBitmapOut.getWidth(), 0, 0,
17mBitmapOut.getWidth(), mBitmapOut.getHeight());

As you can see the code has a simple loop with independent iterations processing a stream of pixels.

For the experiment, we ran our code on a Lenovo K900 with an Intel® Atom™ processor and a 600x1024 picture of a LEGO* monster carrying Christmas gifts.

Here is an example of a function RS_MonoChromeFilter (the RenderScript implementation was taken from the Android SDK licensed under the Apache 2.0 license) to convert an RGB-color image to monochrome image:

01private RenderScript mRS;
02private Allocation mInAllocation;
03private Allocation mOutAllocation;
04private ScriptC_mono mScript;
06private void RS_MonoChromeFilter() {
07mRS = RenderScript.create(this);//RenderScript context creating
08mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
10Allocation.USAGE_SCRIPT);/*allocation and initialization of shared memory */
11mOutAllocation = Allocation.createTyped(mRS,
13mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); /*creating and binding RenderScript to the context */ 
14mScript.forEach_root(mInAllocation, mOutAllocation);/*Call root function by two SMP threads */
20//or our small RenderScript
21#pragma version(1)
22#pragma rs java_package_name(com.example.hellocompute)
24//multipliers to convert a RGB colors to black and white
25const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
27void root(const uchar4 *v_in, uchar4 *v_out) {
28//unpack a color to a float4
29float4 f4 = rsUnpackColor8888(*v_in);
30//take the dot product of the color and the multiplier
31float3 mono = dot(f4.rgb, gMonoMult);
32//repack the float to a color
33*v_out = rsPackColorTo8888(mono);

Example of RenderScript optimization

RenderScript’s performance can be improved by using more aggressive optimizations for floating-point operations. In the next code snippet, we added the rs_fp_imprecise pragma to RenderScript to speed up the calculations without losing any quality in the picture.

02//or our small RenderScript
03#pragma version(1)
04#pragma rs java_package_name(com.example.hellocompute)
05#pragma rs_fp_imprecise
06//multipliers to convert a RGB colors to black and white
07const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
09void root(const uchar4 *v_in, uchar4 *v_out) {
10//unpack a color to a float4
11float4 f4 = rsUnpackColor8888(*v_in);
12//take the dot product of the color and the multiplier
13float3 mono = dot(f4.rgb, gMonoMult);
14//repack the float to a color
15*v_out = rsPackColorTo8888(mono);

The optimized code produces the same quality monochrome image, one without artifacts and distortion. There is no mechanism for explicit control of run-time compiler optimization RenderScript, in contrast to the NDK, because compiler flags were previously declared inside Android for each platform (x86, ARM, etc.).

About the Authors

Stanislav Pavlov works in the Software & Service Group at Intel Corporation. He has 10+ years of experience in software development. His main interest is optimization of performance, power consumption, and parallel programming. In his current role as an Application Engineer providing technical support for Intel®-based devices, Stanislav works closely with software developers and SoC architects to help them achieve the best possible performance on Intel platforms. Stanislav holds a Master's degree in Mathematical Economics from the National Research University Higher School of Economics. He is currently pursuing an MBA in the Moscow Business School.

Roman Kazantsev, the co-author of this blog, is also a Senior Software Engineer in the Software & Service Group and works on encryption projects. He holds a Master’s degree in Computer Science from Nizhniy Novgorod State University where he is currently pursuing his PhD.

For more such Android resources and tools from Intel, please visit the Intel® Developer Zone