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="#access-rs-apis">Accessing RenderScript APIs</a>
     14         <ol>
     15           <li><a href="#ide-setup">Setting Up Your Development Environment</a></li>
     16         </ol>
     17       </li>
     18       <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
     19     </ol>
     20 
     21     <h2>Related Samples</h2>
     22 
     23     <ol>
     24       <li><a href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">Hello
     25       Compute</a></li>
     26     </ol>
     27   </div>
     28 </div>
     29 
     30 <p>RenderScript is a framework for running computationally intensive tasks at high performance on
     31 Android. RenderScript is primarily oriented for use with data-parallel computation, although serial
     32 computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize
     33 work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing
     34 you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is
     35 especially useful for applications performing image processing, computational photography, or
     36 computer vision.</p>
     37 
     38 <p>To begin with RenderScript, there are two main concepts you should understand:</p>
     39 <ul>
     40 
     41 <li>High-performance compute kernels are written in a C99-derived language.</li>
     42 
     43 <li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel
     44 execution.</li>
     45 </ul>
     46 
     47 <h2 id="writing-an-rs-kernel">Writing a RenderScript Kernel</h2>
     48 
     49 <p>A RenderScript kernel typically resides in a <code>.rs</code> file in the
     50 <code>&lt;project_root&gt;/src/</code> directory; each <code>.rs</code> file is called a
     51 script. Every script contains its own set of kernels, functions, and variables. A script can
     52 contain:</p>
     53 
     54 <ul>
     55 <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of the
     56 RenderScript kernel language used in this script. Currently, 1 is the only valid value.</li>
     57 
     58 <li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that
     59 declares the package name of the Java classes reflected from this script.</li>
     60 
     61 <li>Some number of invokable functions. An invokable function is a single-threaded RenderScript
     62 function that you can call from your Java code with arbitrary arguments. These are often useful for
     63 initial setup or serial computations within a larger processing pipeline.</li>
     64 
     65 <li>Some number of script globals. A script global is equivalent to a global variable in C. You can
     66 access script globals from Java code, and these are often used for parameter passing to RenderScript
     67 kernels.</li>
     68 
     69 <li>Some number of compute kernels. A kernel is a parallel function that executes across every
     70 {@link android.renderscript.Element} within an {@link android.renderscript.Allocation}.
     71 
     72 <p>A simple kernel may look like the following:</p>
     73 
     74 <pre>uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {
     75   uchar4 out = in;
     76   out.r = 255 - in.r;
     77   out.g = 255 - in.g;
     78   out.b = 255 - in.b;
     79   return out;
     80 }</pre>
     81 
     82 <p>In most respects, this is identical to a standard C function. The first notable feature is the
     83 <code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the
     84 function is a RenderScript kernel instead of an invokable function. The next feature is the
     85 <code>in</code> argument and its type. In a RenderScript kernel, this is a special argument that is
     86 automatically filled in based on the input {@link android.renderscript.Allocation} passed to the
     87 kernel launch. By default, the kernel is run across an entire {@link
     88 android.renderscript.Allocation}, with one execution of the kernel body per {@link
     89 android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable
     90 feature is the return type of the kernel. The value returned from the kernel is automatically
     91 written to the appropriate location in the output {@link android.renderscript.Allocation}. The
     92 RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the
     93 input and output Allocations match the kernel's prototype; if they do not match, an exception is
     94 thrown.</p>
     95 
     96 <p>A kernel may have an input {@link android.renderscript.Allocation}, an output {@link
     97 android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output
     98 {@link android.renderscript.Allocation}. If more than one input or output is required, those objects
     99 should be bound to <code>rs_allocation</code> script globals and accessed from a kernel or invokable
    100 function via <code>rsGetElementAt_<em>type</em>()</code> or
    101 <code>rsSetElementAt_<em>type</em>()</code>.</p>
    102 
    103 <p>A kernel may access the coordinates of the current execution using the <code>x</code>,
    104 <code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the
    105 coordinate arguments must be <code>uint32_t</code>.</p></li>
    106 
    107 <li>An optional <code>init()</code> function. An <code>init()</code> function is a special type of
    108 invokable function that is run when the script is first instantiated. This allows for some
    109 computation to occur automatically at script creation.</li>
    110 
    111 <li>Some number of static script globals and functions. A static script global is equivalent to a
    112 script global except that it cannot be set from Java code. A static function is a standard C
    113 function that can be called from any kernel or invokable function in the script but is not exposed
    114 to the Java API. If a script global or function does not need to be called from Java code, it is
    115 highly recommended that those be declared <code>static</code>.</li> </ul>
    116 
    117 <h4>Setting floating point precision</h4>
    118 
    119 <p>You can control the required level of floating point precision in a script. This is useful if
    120 full IEEE 754-2008 standard (used by default) is not required. The following pragmas can set a
    121 different level of floating point precision:</p>
    122 
    123 <ul>
    124 
    125 <li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that require
    126   floating point precision as outlined by the IEEE 754-2008 standard.
    127 
    128 </li>
    129 
    130   <li><code>#pragma rs_fp_relaxed</code> - For apps that dont require strict IEEE 754-2008
    131     compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and
    132     round-towards-zero.
    133 
    134 </li>
    135 
    136   <li><code>#pragma rs_fp_imprecise</code> - For apps that dont have stringent precision
    137     requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the
    138     following:
    139 
    140 <ul>
    141 
    142   <li>Operations resulting in -0.0 can return +0.0 instead.</li>
    143   <li>Operations on INF and NAN are undefined.</li>
    144 </ul>
    145 </li>
    146 </ul>
    147 
    148 <p>Most applications can use <code>rs_fp_relaxed</code> without any side effects. This may be very
    149 beneficial on some architectures due to additional optimizations only available with relaxed
    150 precision (such as SIMD CPU instructions).</p>
    151 
    152 
    153 <h2 id="access-rs-apis">Accessing RenderScript APIs</h2>
    154 
    155 <p>When developing an Android application that uses RenderScript, you can access its API in
    156   one of two ways:</p>
    157 
    158 <ul>
    159   <li><strong>{@link android.renderscript}</strong> - The APIs in this class package are
    160     available on devices running Android 3.0 (API level 11) and higher. These are the original APIs
    161     for RenderScript and are not currently being updated.</li>
    162   <li><strong>{@link android.support.v8.renderscript}</strong> - The APIs in this package are
    163     available through a <a href="{@docRoot}tools/support-library/features.html#v8">Support
    164     Library</a>, which allows you to use them on devices running Android 2.2 (API level 8) and
    165     higher.</li>
    166 </ul>
    167 
    168 <p>We strongly recommend using the Support Library APIs for accessing RenderScript because they
    169   include the latest improvements to the RenderScript compute framework and provide a wider range
    170   of device compatibility.</p>
    171 
    172 
    173 <h3 id="ide-setup">Using the RenderScript Support Library APIs</h3>
    174 
    175 <p>In order to use the Support Library RenderScript APIs, you must configure your development
    176   environment to be able to access them. The following Android SDK tools are required for using
    177   these APIs:</p>
    178 
    179 <ul>
    180   <li>Android SDK Tools revision 22.2 or higher</li>
    181   <li>Android SDK Build-tools revision 18.1.0 or higher</li>
    182 </ul>
    183 
    184 <p>You can check and update the installed version of these tools in the
    185   <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</p>
    186 
    187 <p class="note">
    188   <strong>Note:</strong> Use of Support Library RenderScript APIs is not currently supported with
    189   Android Studio or Gradle-based builds.
    190 </p>
    191 
    192 <p>To use the Support Library RenderScript APIs in Eclipse:</p>
    193 
    194 <ol>
    195   <li>Make sure you have the required Android SDK version and Build Tools version installed.</li>
    196   <li>Open the {@code project.properties} file in the root folder of your application project.</li>
    197   <li>Add the following lines to the file:
    198 <pre>
    199 renderscript.target=18
    200 renderscript.support.mode=true
    201 sdk.buildtools=18.1.0
    202 </pre>
    203   </li>
    204   <li>In your application classes that use RenderScript, add an import for the Support Library
    205     classes:
    206 <pre>
    207 import android.support.v8.renderscript.*;
    208 </pre>
    209   </li>
    210 </ol>
    211 
    212 <p>The {@code project.properties} settings listed above control specific behavior in the Android
    213   build process:</p>
    214 
    215 <ul>
    216   <li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
    217     recommend you set this value the highest available API level and set {@code
    218     renderscript.support.mode} to {@code true}. Valid values for this setting are any integer value
    219     from 11 to the most recently released API level. If your minimum SDK version specified in your
    220     application manifest is set to a higher value, this value is ignored and the target value is set
    221     to the minimum SDK version.</li>
    222   <li>{@code renderscript.support.mode} - Specifies that the generated bytecode should fall
    223     back to a compatible version if the device it is running on does not support the target version.
    224     </li>
    225   <li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
    226     should be set to {@code 18.1.0} or higher. If this option is not specified, the highest
    227     installed build tools version is used. You should always set this value to ensure the
    228     consistency of builds across development machines with different configurations.</li>
    229 </ul>
    230 
    231 
    232 <h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
    233 
    234 <p>Using RenderScript from Java code relies on the API classes located in the
    235 {@link android.renderscript} or the {@link android.support.v8.renderscript} package. Most
    236 applications follow the same basic usage patterns:</p>
    237 
    238 <ol>
    239 
    240 <li><strong>Initialize a RenderScript context.</strong> The {@link
    241 android.renderscript.RenderScript} context, created with {@link
    242 android.renderscript.RenderScript#create}, ensures that RenderScript can be used and provides an
    243 object to control the lifetime of all subsequent RenderScript objects. You should consider context
    244 creation to be a potentially long-running operation, since it may create resources on different
    245 pieces of hardware; it should not be in an application's critical path if at all
    246 possible. Typically, an application will have only a single RenderScript context at a time.</li>
    247 
    248 <li><strong>Create at least one {@link android.renderscript.Allocation} to be passed to a
    249 script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides
    250 storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation}
    251 objects as their input and output, and {@link android.renderscript.Allocation} objects can be
    252 accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and
    253 <code>rsSetElementAt_<em>type</em>()</code> when bound as script globals. {@link
    254 android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript
    255 code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using
    256 {@link android.renderscript.Allocation#createTyped} or {@link
    257 android.renderscript.Allocation#createFromBitmap}.</li>
    258 
    259 <li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available
    260 to you when using RenderScript:
    261 
    262 <ul>
    263 
    264 <li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a
    265 href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class
    266 reflected by the RenderScript compiler in order to make it easy to access the script from Java code;
    267 this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel
    268 above was located in <code>invert.rs</code> and a RenderScript context was already located in
    269 <code>mRS</code>, the Java code to instantiate the script would be:
    270 
    271 <pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li>
    272 
    273 <li><strong>ScriptIntrinsic</strong>: These are built-in RenderScript kernels for common operations,
    274 such as Gaussian blur, convolution, and image blending. For more information, see the subclasses of
    275 {@link android.renderscript.ScriptIntrinsic}.</li>
    276 
    277 </ul></li>
    278 
    279 <li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link
    280 android.renderscript#createFromBitmap}, an Allocation will be populated with empty data when it is
    281 first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link
    282 android.renderscript.Allocation}.</li>
    283 
    284 <li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same
    285 <code>ScriptC_<em>filename</em></code> class with methods named
    286 <code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named
    287 <code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can
    288 also be set in kernels; for example, the <code>rs_allocation</code> variable named
    289 <code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li>
    290 
    291 <li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be
    292 reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named
    293 <code>forEach_<em>kernelname</em>()</code>. These launches are asynchronous, and launches will be
    294 serialized in the order in which they are launched. Depending on the arguments to the kernel, the
    295 method will take either one or two Allocations. By default, a kernel will execute over the entire
    296 input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link
    297 android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> method.
    298 
    299 <p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods
    300 reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li>
    301 
    302 <li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to
    303 access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied
    304 back to Java buffers using one of the <code>copy</code> methods in {@link
    305 android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and
    306 function launches as necessary.</li>
    307 
    308 <li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed
    309 with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context
    310 object to be garbage collected. This will cause any further use of any object belonging to that
    311 context to throw an exception.</li> </ol>