| page.title=RenderScript | |
| parent.title=Computation | |
| parent.link=index.html | |
| @jd:body | |
| <div id="qv-wrapper"> | |
| <div id="qv"> | |
| <h2>In this document</h2> | |
| <ol> | |
| <li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li> | |
| <li><a href="#access-rs-apis">Accessing RenderScript APIs</a> | |
| <ol> | |
| <li><a href="#ide-setup">Setting Up Your Development Environment</a></li> | |
| </ol> | |
| </li> | |
| <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li> | |
| </ol> | |
| <h2>Related Samples</h2> | |
| <ol> | |
| <li><a class="external-link"href="https://github.com/android/platform_development/tree/master/samples/RenderScript/HelloCompute">Hello | |
| Compute</a></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>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.</p> | |
| <p>To begin with RenderScript, there are two main concepts you should understand:</p> | |
| <ul> | |
| <li>High-performance compute kernels are written in a C99-derived language.</li> | |
| <li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel | |
| execution.</li> | |
| </ul> | |
| <h2 id="writing-an-rs-kernel">Writing a RenderScript Kernel</h2> | |
| <p>A RenderScript kernel typically resides in a <code>.rs</code> file in the | |
| <code><project_root>/src/</code> directory; each <code>.rs</code> file is called a | |
| script. Every script contains its own set of kernels, functions, and variables. A script can | |
| contain:</p> | |
| <ul> | |
| <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of the | |
| RenderScript kernel language used in this script. Currently, 1 is the only valid value.</li> | |
| <li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that | |
| declares the package name of the Java classes reflected from this script. | |
| Note that your .rs file must be part of your application package, and not in a | |
| library project.</li> | |
| <li>Some number of invokable functions. An invokable function is a single-threaded RenderScript | |
| function that you can call from your Java code with arbitrary arguments. These are often useful for | |
| initial setup or serial computations within a larger processing pipeline.</li> | |
| <li>Some number of script globals. A script global is equivalent to a global variable in C. You can | |
| access script globals from Java code, and these are often used for parameter passing to RenderScript | |
| kernels.</li> | |
| <li>Some number of compute kernels. A kernel is a parallel function that executes across every | |
| {@link android.renderscript.Element} within an {@link android.renderscript.Allocation}. | |
| <p>A simple kernel may look like the following:</p> | |
| <pre>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; | |
| }</pre> | |
| <p>In most respects, this is identical to a standard C function. The first notable feature is the | |
| <code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the | |
| function is a RenderScript kernel instead of an invokable function. The next feature is the | |
| <code>in</code> 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.</p> | |
| <p>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 <code>rs_allocation</code> script globals and accessed from a kernel or invokable | |
| function via <code>rsGetElementAt_<em>type</em>()</code> or | |
| <code>rsSetElementAt_<em>type</em>()</code>.</p> | |
| <p>A kernel may access the coordinates of the current execution using the <code>x</code>, | |
| <code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the | |
| coordinate arguments must be <code>uint32_t</code>.</p></li> | |
| <li>An optional <code>init()</code> function. An <code>init()</code> 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.</li> | |
| <li>Some number of static script globals and functions. A static script global is equivalent to a | |
| script global except that it cannot be set from Java code. A static function is a standard C | |
| function that can be called from any kernel or invokable function in the script but is not exposed | |
| to the Java API. If a script global or function does not need to be called from Java code, it is | |
| highly recommended that those be declared <code>static</code>.</li> </ul> | |
| <h4>Setting floating point precision</h4> | |
| <p>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:</p> | |
| <ul> | |
| <li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that require | |
| floating point precision as outlined by the IEEE 754-2008 standard. | |
| </li> | |
| <li><code>#pragma rs_fp_relaxed</code> - 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. | |
| </li> | |
| <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision | |
| requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the | |
| following: | |
| <ul> | |
| <li>Operations resulting in -0.0 can return +0.0 instead.</li> | |
| <li>Operations on INF and NAN are undefined.</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| <p>Most applications can use <code>rs_fp_relaxed</code> 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).</p> | |
| <h2 id="access-rs-apis">Accessing RenderScript APIs</h2> | |
| <p>When developing an Android application that uses RenderScript, you can access its API in | |
| one of two ways:</p> | |
| <ul> | |
| <li><strong>{@link android.renderscript}</strong> - The APIs in this class package are | |
| available on devices running Android 3.0 (API level 11) and higher. </li> | |
| <li><strong>{@link android.support.v8.renderscript}</strong> - The APIs in this package are | |
| available through a <a href="{@docRoot}tools/support-library/features.html#v8">Support | |
| Library</a>, which allows you to use them on devices running Android 2.2 (API level 8) and | |
| higher.</li> | |
| </ul> | |
| <p>We strongly recommend using the Support Library APIs for accessing RenderScript because they | |
| provide a wider range of device compatibility. Developers targeting specific versions of | |
| Android can use {@link android.renderscript} if necessary.</p> | |
| <h3 id="ide-setup">Using the RenderScript Support Library APIs</h3> | |
| <p>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:</p> | |
| <ul> | |
| <li>Android SDK Tools revision 22.2 or higher</li> | |
| <li>Android SDK Build-tools revision 18.1.0 or higher</li> | |
| </ul> | |
| <p>You can check and update the installed version of these tools in the | |
| <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</p> | |
| <p>To use the Support Library RenderScript APIs:</p> | |
| <ol> | |
| <li>Make sure you have the required Android SDK version and Build Tools version installed.</li> | |
| <li> Update the settings for the Android build process to include the RenderScript settings: | |
| <ul> | |
| <li>Open the {@code build.gradle} file in the app folder of your application module. </li> | |
| <li>Add the following RenderScript settings to the file: | |
| <pre> | |
| android { | |
| compileSdkVersion 23 | |
| buildToolsVersion "23.0.3" | |
| defaultConfig { | |
| minSdkVersion 8 | |
| targetSdkVersion 19 | |
| <strong> | |
| renderscriptTargetApi 18 | |
| renderscriptSupportModeEnabled true | |
| </strong> | |
| } | |
| } | |
| </pre> | |
| <p>The settings listed above control specific behavior in the Android build process:</p> | |
| <ul> | |
| <li>{@code renderscriptTargetApi} - Specifies the bytecode version to be generated. We | |
| recommend you set this value to the lowest API level able to provide all the functionality | |
| you are using and set {@code renderscriptSupportModeEnabled} to {@code true}. | |
| Valid values for this setting are any integer value | |
| from 11 to the most recently released API level. If your minimum SDK version specified in your | |
| application manifest is set to a different value, that value is ignored and the target value | |
| in the build file is used to set the minimum SDK version.</li> | |
| <li>{@code renderscriptSupportModeEnabled} - Specifies that the generated bytecode should fall | |
| back to a compatible version if the device it is running on does not support the target | |
| version. | |
| </li> | |
| <li>{@code buildToolsVersion} - The version of the Android SDK build tools to use. This value | |
| should be set to {@code 18.1.0} or higher. If this option is not specified, the highest | |
| installed build tools version is used. You should always set this value to ensure the | |
| consistency of builds across development machines with different configurations.</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| <li>In your application classes that use RenderScript, add an import for the Support Library | |
| classes: | |
| <pre> | |
| import android.support.v8.renderscript.*; | |
| </pre> | |
| </li> | |
| </ol> | |
| <h2 id="using-rs-from-java">Using RenderScript from Java Code</h2> | |
| <p>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:</p> | |
| <ol> | |
| <li><strong>Initialize a RenderScript context.</strong> The {@link | |
| android.renderscript.RenderScript} context, created with {@link | |
| android.renderscript.RenderScript#create}, ensures that RenderScript can be used and provides an | |
| object to control the lifetime of all subsequent RenderScript objects. You should consider context | |
| creation to be a potentially long-running operation, since it may create resources on different | |
| pieces of hardware; it should not be in an application's critical path if at all | |
| possible. Typically, an application will have only a single RenderScript context at a time.</li> | |
| <li><strong>Create at least one {@link android.renderscript.Allocation} to be passed to a | |
| script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides | |
| storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation} | |
| objects as their input and output, and {@link android.renderscript.Allocation} objects can be | |
| accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and | |
| <code>rsSetElementAt_<em>type</em>()</code> 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}.</li> | |
| <li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available | |
| to you when using RenderScript: | |
| <ul> | |
| <li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a | |
| href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class | |
| reflected by the RenderScript compiler in order to make it easy to access the script from Java code; | |
| this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel | |
| above was located in <code>invert.rs</code> and a RenderScript context was already located in | |
| <code>mRS</code>, the Java code to instantiate the script would be: | |
| <pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li> | |
| <li><strong>ScriptIntrinsic</strong>: These are built-in RenderScript kernels for common operations, | |
| such as Gaussian blur, convolution, and image blending. For more information, see the subclasses of | |
| {@link android.renderscript.ScriptIntrinsic}.</li> | |
| </ul></li> | |
| <li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link | |
| android.renderscript#createFromBitmap}, an Allocation will be populated with empty data when it is | |
| first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link | |
| android.renderscript.Allocation}.</li> | |
| <li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same | |
| <code>ScriptC_<em>filename</em></code> class with methods named | |
| <code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named | |
| <code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can | |
| also be set in kernels; for example, the <code>rs_allocation</code> variable named | |
| <code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li> | |
| <li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be | |
| reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named | |
| <code>forEach_<em>kernelname</em>()</code>. 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 <code>forEach</code> method. | |
| <p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods | |
| reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li> | |
| <li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to | |
| access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied | |
| back to Java buffers using one of the <code>copy</code> methods in {@link | |
| android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and | |
| function launches as necessary.</li> | |
| <li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed | |
| with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context | |
| object to be garbage collected. This will cause any further use of any object belonging to that | |
| context to throw an exception.</li> </ol> |