Home | History | Annotate | Download | only in renderscript
      1 page.title=RenderScript
      2 parent.title=Computation
      3 parent.link=index.html
      4 
      5 @jd:body
      6 
      7 <div id="qv-wrapper">
      8   <div id="qv">
      9     <h2>In this document</h2>
     10 
     11     <ol>
     12       <li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li>
     13       <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
     14     </ol>
     15 
     16     <h2>Related Samples</h2>
     17 
     18     <ol>
     19       <li><a href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">Hello
     20       Compute</a></li>
     21     </ol>
     22   </div>
     23 </div>
     24 
     25 <p>RenderScript is a framework for running computationally intensive tasks at high performance on
     26 Android. RenderScript is primarily oriented for use with data-parallel computation, although serial
     27 computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize
     28 work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing
     29 you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is
     30 especially useful for applications performing image processing, computational photography, or
     31 computer vision.</p>
     32 
     33 <p>To begin with RenderScript, there are two main concepts you should understand:</p>
     34 <ul>
     35 
     36 <li>High-performance compute kernels are written in a C99-derived language.</li>
     37 
     38 <li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel
     39 execution.</li>
     40 </ul>
     41 
     42 <h2 id="writing-an-rs-kernel">Writing a RenderScript Kernel</h2>
     43 
     44 <p>A RenderScript kernel typically resides in a <code>.rs</code> file in the
     45 <code>&lt;project_root&gt;/src/</code> directory; each <code>.rs</code> file is called a
     46 script. Every script contains its own set of kernels, functions, and variables. A script can
     47 contain:</p>
     48 
     49 <ul>
     50 <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of the
     51 RenderScript kernel language used in this script. Currently, 1 is the only valid value.</li>
     52 
     53 <li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that
     54 declares the package name of the Java classes reflected from this script.</li>
     55 
     56 <li>Some number of invokable functions. An invokable function is a single-threaded RenderScript
     57 function that you can call from your Java code with arbitrary arguments. These are often useful for
     58 initial setup or serial computations within a larger processing pipeline.</li>
     59 
     60 <li>Some number of script globals. A script global is equivalent to a global variable in C. You can
     61 access script globals from Java code, and these are often used for parameter passing to RenderScript
     62 kernels.</li>
     63 
     64 <li>Some number of compute kernels. A kernel is a parallel function that executes across every
     65 {@link android.renderscript.Element} within an {@link android.renderscript.Allocation}.
     66 
     67 <p>A simple kernel may look like the following:</p>
     68 
     69 <pre>uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {
     70   uchar4 out = in;
     71   out.r = 255 - in.r;
     72   out.g = 255 - in.g;
     73   out.b = 255 - in.b;
     74   return out;
     75 }</pre>
     76 
     77 <p>In most respects, this is identical to a standard C function. The first notable feature is the
     78 <code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the
     79 function is a RenderScript kernel instead of an invokable function. The next feature is the
     80 <code>in</code> argument and its type. In a RenderScript kernel, this is a special argument that is
     81 automatically filled in based on the input {@link android.renderscript.Allocation} passed to the
     82 kernel launch. By default, the kernel is run across an entire {@link
     83 android.renderscript.Allocation}, with one execution of the kernel body per {@link
     84 android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable
     85 feature is the return type of the kernel. The value returned from the kernel is automatically
     86 written to the appropriate location in the output {@link android.renderscript.Allocation}. The
     87 RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the
     88 input and output Allocations match the kernel's prototype; if they do not match, an exception is
     89 thrown.</p>
     90 
     91 <p>A kernel may have an input {@link android.renderscript.Allocation}, an output {@link
     92 android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output
     93 {@link android.renderscript.Allocation}. If more than one input or output is required, those objects
     94 should be bound to <code>rs_allocation</code> script globals and accessed from a kernel or invokable
     95 function via <code>rsGetElementAt_<em>type</em>()</code> or
     96 <code>rsSetElementAt_<em>type</em>()</code>.</p>
     97 
     98 <p>A kernel may access the coordinates of the current execution using the <code>x</code>,
     99 <code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the
    100 coordinate arguments must be <code>uint32_t</code>.</p></li>
    101 
    102 <li>An optional <code>init()</code> function. An <code>init()</code> function is a special type of
    103 invokable function that is run when the script is first instantiated. This allows for some
    104 computation to occur automatically at script creation.</li>
    105 
    106 <li>Some number of static script globals and functions. A static script global is equivalent to a
    107 script global except that it cannot be set from Java code. A static function is a standard C
    108 function that can be called from any kernel or invokable function in the script but is not exposed
    109 to the Java API. If a script global or function does not need to be called from Java code, it is
    110 highly recommended that those be declared <code>static</code>.</li> </ul>
    111 
    112 <h4>Setting floating point precision</h4>
    113 
    114 <p>You can control the required level of floating point precision in a script. This is useful if
    115 full IEEE 754-2008 standard (used by default) is not required. The following pragmas can set a
    116 different level of floating point precision:</p>
    117 
    118 <ul>
    119 
    120 <li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that require
    121   floating point precision as outlined by the IEEE 754-2008 standard.
    122 
    123 </li>
    124 
    125   <li><code>#pragma rs_fp_relaxed</code> - For apps that dont require strict IEEE 754-2008
    126     compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and
    127     round-towards-zero.
    128 
    129 </li>
    130 
    131   <li><code>#pragma rs_fp_imprecise</code> - For apps that dont have stringent precision
    132     requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the
    133     following:
    134 
    135 <ul>
    136 
    137   <li>Operations resulting in -0.0 can return +0.0 instead.</li>
    138   <li>Operations on INF and NAN are undefined.</li>
    139 </ul>
    140 </li>
    141 </ul>
    142 
    143 <p>Most applications can use <code>rs_fp_relaxed</code> without any side effects. This may be very
    144 beneficial on some architectures due to additional optimizations only available with relaxed
    145 precision (such as SIMD CPU instructions).</p>
    146 
    147 <h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
    148 
    149 <p>Using RenderScript from Java code relies on the {@link android.renderscript} APIs. Most
    150 applications follow the same basic usage patterns:</p>
    151 
    152 <ol>
    153 
    154 <li><strong>Initialize a RenderScript context.</strong> The {@link
    155 android.renderscript.RenderScript} context, created with {@link
    156 android.renderscript.RenderScript#create}, ensures that RenderScript can be used and provides an
    157 object to control the lifetime of all subsequent RenderScript objects. You should consider context
    158 creation to be a potentially long-running operation, since it may create resources on different
    159 pieces of hardware; it should not be in an application's critical path if at all
    160 possible. Typically, an application will have only a single RenderScript context at a time.</li>
    161 
    162 <li><strong>Create at least one {@link android.renderscript.Allocation} to be passed to a
    163 script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides
    164 storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation}
    165 objects as their input and output, and {@link android.renderscript.Allocation} objects can be
    166 accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and
    167 <code>rsSetElementAt_<em>type</em>()</code> when bound as script globals. {@link
    168 android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript
    169 code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using
    170 {@link android.renderscript.Allocation#createTyped} or {@link
    171 android.renderscript.Allocation#createFromBitmap}.</li>
    172 
    173 <li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available
    174 to you when using RenderScript:
    175 
    176 <ul>
    177 
    178 <li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a
    179 href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class
    180 reflected by the RenderScript compiler in order to make it easy to access the script from Java code;
    181 this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel
    182 above was located in <code>invert.rs</code> and a RenderScript context was already located in
    183 <code>mRS</code>, the Java code to instantiate the script would be:
    184 
    185 <pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li>
    186 
    187 <li><strong>ScriptIntrinsic</strong>: These are built-in RenderScript kernels for common operations,
    188 such as Gaussian blur, convolution, and image blending. For more information, see the subclasses of
    189 {@link android.renderscript.ScriptIntrinsic}.</li>
    190 
    191 </ul></li>
    192 
    193 <li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link
    194 android.renderscript#createFromBitmap}, an Allocation will be populated with empty data when it is
    195 first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link
    196 android.renderscript.Allocation}.</li>
    197 
    198 <li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same
    199 <code>ScriptC_<em>filename</em></code> class with methods named
    200 <code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named
    201 <code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can
    202 also be set in kernels; for example, the <code>rs_allocation</code> variable named
    203 <code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li>
    204 
    205 <li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be
    206 reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named
    207 <code>forEach_<em>kernelname</em>()</code>. These launches are asynchronous, and launches will be
    208 serialized in the order in which they are launched. Depending on the arguments to the kernel, the
    209 method will take either one or two Allocations. By default, a kernel will execute over the entire
    210 input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link
    211 android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> method.
    212 
    213 <p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods
    214 reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li>
    215 
    216 <li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to
    217 access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied
    218 back to Java buffers using one of the <code>copy</code> methods in {@link
    219 android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and
    220 function launches as necessary.</li>
    221 
    222 <li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed
    223 with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context
    224 object to be garbage collected. This will cause any further use of any object belonging to that
    225 context to throw an exception.</li> </ol>