311 lines
15 KiB
Plaintext
311 lines
15 KiB
Plaintext
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 href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">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.</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. These are the original APIs
|
||
for RenderScript and are not currently being updated.</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
|
||
include the latest improvements to the RenderScript compute framework and provide a wider range
|
||
of device compatibility.</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 class="note">
|
||
<strong>Note:</strong> Use of Support Library RenderScript APIs is not currently supported with
|
||
Android Studio or Gradle-based builds.
|
||
</p>
|
||
|
||
<p>To use the Support Library RenderScript APIs in Eclipse:</p>
|
||
|
||
<ol>
|
||
<li>Make sure you have the required Android SDK version and Build Tools version installed.</li>
|
||
<li>Open the {@code project.properties} file in the root folder of your application project.</li>
|
||
<li>Add the following lines to the file:
|
||
<pre>
|
||
renderscript.target=18
|
||
renderscript.support.mode=true
|
||
sdk.buildtools=18.1.0
|
||
</pre>
|
||
</li>
|
||
<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>
|
||
|
||
<p>The {@code project.properties} settings listed above control specific behavior in the Android
|
||
build process:</p>
|
||
|
||
<ul>
|
||
<li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
|
||
recommend you set this value the highest available API level and set {@code
|
||
renderscript.support.mode} 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 higher value, this value is ignored and the target value is set
|
||
to the minimum SDK version.</li>
|
||
<li>{@code renderscript.support.mode} - 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 sdk.buildtools} - 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>
|
||
|
||
|
||
<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> |