page.title=RenderScript parent.title=Computation parent.link=index.html @jd:body
RenderScript is a framework for running computationally intensive tasks at high performance on Android. RenderScript is primarily oriented for use with data-parallel computation, although serial computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is especially useful for applications performing image processing, computational photography, or computer vision.
To begin with RenderScript, there are two main concepts you should understand:
A RenderScript kernel typically resides in a .rs
file in the
<project_root>/src/
directory; each .rs
file is called a
script. Every script contains its own set of kernels, functions, and variables. A script can
contain:
#pragma version(1)
) that declares the version of the
RenderScript kernel language used in this script. Currently, 1 is the only valid value.#pragma rs java_package_name(com.example.app)
) that
declares the package name of the Java classes reflected from this script.A simple kernel may look like the following:
uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) { uchar4 out = in; out.r = 255 - in.r; out.g = 255 - in.g; out.b = 255 - in.b; return out; }
In most respects, this is identical to a standard C function. The first notable feature is the
__attribute__((kernel))
applied to the function prototype. This denotes that the
function is a RenderScript kernel instead of an invokable function. The next feature is the
in
argument and its type. In a RenderScript kernel, this is a special argument that is
automatically filled in based on the input {@link android.renderscript.Allocation} passed to the
kernel launch. By default, the kernel is run across an entire {@link
android.renderscript.Allocation}, with one execution of the kernel body per {@link
android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable
feature is the return type of the kernel. The value returned from the kernel is automatically
written to the appropriate location in the output {@link android.renderscript.Allocation}. The
RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the
input and output Allocations match the kernel's prototype; if they do not match, an exception is
thrown.
A kernel may have an input {@link android.renderscript.Allocation}, an output {@link
android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output
{@link android.renderscript.Allocation}. If more than one input or output is required, those objects
should be bound to rs_allocation
script globals and accessed from a kernel or invokable
function via rsGetElementAt_type()
or
rsSetElementAt_type()
.
A kernel may access the coordinates of the current execution using the x
,
y
, and z
arguments. These arguments are optional, but the type of the
coordinate arguments must be uint32_t
.
init()
function. An init()
function is a special type of
invokable function that is run when the script is first instantiated. This allows for some
computation to occur automatically at script creation.static
.You can control the required level of floating point precision in a script. This is useful if full IEEE 754-2008 standard (used by default) is not required. The following pragmas can set a different level of floating point precision:
#pragma rs_fp_full
(default if nothing is specified): For apps that require
floating point precision as outlined by the IEEE 754-2008 standard.
#pragma rs_fp_relaxed
- For apps that don’t require strict IEEE 754-2008
compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and
round-towards-zero.
#pragma rs_fp_imprecise
- For apps that don’t have stringent precision
requirements. This mode enables everything in rs_fp_relaxed
along with the
following:
Most applications can use rs_fp_relaxed
without any side effects. This may be very
beneficial on some architectures due to additional optimizations only available with relaxed
precision (such as SIMD CPU instructions).
When developing an Android application that uses RenderScript, you can access its API in one of two ways:
We strongly recommend using the Support Library APIs for accessing RenderScript because they include the latest improvements to the RenderScript compute framework and provide a wider range of device compatibility.
In order to use the Support Library RenderScript APIs, you must configure your development environment to be able to access them. The following Android SDK tools are required for using these APIs:
You can check and update the installed version of these tools in the Android SDK Manager.
Note: Use of Support Library RenderScript APIs is not currently supported with Android Studio or Gradle-based builds.
To use the Support Library RenderScript APIs in Eclipse:
renderscript.target=18 renderscript.support.mode=true sdk.buildtools=18.1.0
import android.support.v8.renderscript.*;
The {@code project.properties} settings listed above control specific behavior in the Android build process:
Using RenderScript from Java code relies on the API classes located in the {@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most applications follow the same basic usage patterns:
rsGetElementAt_type()
and
rsSetElementAt_type()
when bound as script globals. {@link
android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript
code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using
{@link android.renderscript.Allocation#createTyped} or {@link
android.renderscript.Allocation#createFromBitmap}.ScriptC_filename
. For example, if the kernel
above was located in invert.rs
and a RenderScript context was already located in
mRS
, the Java code to instantiate the script would be:
ScriptC_invert invert = new ScriptC_invert(mRenderScript);
copy
methods in {@link
android.renderscript.Allocation}.ScriptC_filename
class with methods named
set_globalname
. For example, in order to set an int
named
elements
, use the Java method set_elements(int)
. RenderScript objects can
also be set in kernels; for example, the rs_allocation
variable named
lookup
can be set with the method set_lookup(Allocation)
.ScriptC_filename
class with methods named
forEach_kernelname()
. These launches are asynchronous, and launches will be
serialized in the order in which they are launched. Depending on the arguments to the kernel, the
method will take either one or two Allocations. By default, a kernel will execute over the entire
input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link
android.renderscript.Script.LaunchOptions} as the last argument to the forEach
method.
Invoked functions can be launched using the invoke_functionname
methods
reflected in the same ScriptC_filename
class.
copy
methods in {@link
android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and
function launches as necessary.