Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Getting Started with RenderScript on Intel® Architecture running the Android* OS

0.00/5 (No votes)
17 Nov 2014CPOL6 min read 8.4K  
RenderScript is a scripting language on Android. You can use it to write high performance graphics rendering and raw computational code.

This article is for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers

Intro

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.

    Image 1

  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.

    Image 2

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.

Disadvantages

  • 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:

private void DalvikFilter() {
    float MonoMult[] = {0.299f, 0.587f, 0.114f};
    int mInPixels[] = new int[mBitmapIn.getHeight() * mBitmapIn.getWidth()];
    int mOutPixels[] = new int[mBitmapOut.getHeight() * mBitmapOut.getWidth()];
    mBitmapIn.getPixels(mInPixels, 0, mBitmapIn.getWidth(), 0, 0,
            mBitmapIn.getWidth(), mBitmapIn.getHeight());
    for(int i = 0;i < mInPixels.length;i++) {
        float r = (float)(mInPixels[i] & 0xff);
        float g = (float)((mInPixels[i] >> 8) & 0xff);
        float b = (float)((mInPixels[i] >> 16) & 0xff);
 
        int mono = (int)(r * MonoMult[0] + g * MonoMult[1] + b * MonoMult[2]);
 
        mOutPixels[i] = mono + (mono << 8) + (mono << 16) + (mInPixels[i] & 0xff000000);
        }
    mBitmapOut.setPixels(mOutPixels, 0, mBitmapOut.getWidth(), 0, 0,
            mBitmapOut.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.

Image 3

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:

private RenderScript mRS;
private Allocation mInAllocation;
private Allocation mOutAllocation;
private ScriptC_mono mScript;
…
private void RS_MonoChromeFilter() {
mRS = RenderScript.create(this);//RenderScript context creating
mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
            Allocation.MipmapControl.MIPMAP_NONE,
                Allocation.USAGE_SCRIPT);/*allocation and initialization of shared memory */
        mOutAllocation = Allocation.createTyped(mRS,
mInAllocation.getType());
        mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); /*creating and binding RenderScript to the context */      
        mScript.forEach_root(mInAllocation, mOutAllocation);/*Call root function by two SMP threads */
         
        mOutAllocation.copyTo(mBitmapOut);
}
 
//mono.rs
//or our small RenderScript
#pragma version(1)
#pragma rs java_package_name(com.example.hellocompute)
 
//multipliers to convert a RGB colors to black and white
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
 
void root(const uchar4 *v_in, uchar4 *v_out) {
  //unpack a color to a float4
  float4 f4 = rsUnpackColor8888(*v_in);
  //take the dot product of the color and the multiplier
  float3 mono = dot(f4.rgb, gMonoMult);
  //repack the float to a color
  *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.

//mono.rs
//or our small RenderScript
#pragma version(1)
#pragma rs java_package_name(com.example.hellocompute)
#pragma rs_fp_imprecise
//multipliers to convert a RGB colors to black and white
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
 
void root(const uchar4 *v_in, uchar4 *v_out) {
  //unpack a color to a float4
  float4 f4 = rsUnpackColor8888(*v_in);
  //take the dot product of the color and the multiplier
  float3 mono = dot(f4.rgb, gMonoMult);
  //repack the float to a color
  *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.

Notices
INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.

UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE PERSONAL INJURY OR DEATH MAY OCCUR.

Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them. The information here is subject to change without notice. Do not finalize a design with this information.

The products described in this document may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.

Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your product order.

Copies of documents which have an order number and are referenced in this document, or other Intel literature, may be obtained by calling 1-800-548-4725, or go to: http://www.intel.com/design/literature.htm.

Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations, and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.

Any software source code reprinted in this document is furnished under a software license and may only be used or copied in accordance with the terms of that license.

Intel, the Intel logo, and Atom are trademarks of Intel Corporation in the U.S. and/or other countries.

Copyright © 2014 Intel Corporation. All rights reserved.

*Other names and brands may be claimed as the property of others.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)