Home | History | Annotate | Download | only in renderscript
      1 page.title=Advanced 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="#native">RenderScript Runtime Layer</a></li>
     13         <li><a href="#reflected">Reflected Layer</a>
     14           <ol>
     15             <li><a href="#func">Functions</a></li>
     16             <li><a href="#var">Variables</a></li>
     17             <li><a href="#pointer">Pointers</a></li>
     18             <li><a href="#struct">Structs</a></li>
     19           </ol>
     20         </li>
     21 
     22         <li>
     23           <a href="#mem-allocation">Memory Allocation APIs</a>
     24         </li>
     25         <li>
     26           <a href="#memory">Working with Memory</a>
     27           <ol>
     28             <li><a href="#allocating-mem">Allocating and binding memory to the RenderScript</a></li>
     29 
     30             <li><a href="#read-write">Reading and writing to memory</a></li>
     31 
     32           </ol>
     33         </li>
     34       </ol>
     35     </div>
     36   </div>
     37 
     38   <p></p>
     39 
     40   <p>Because applications that utilize RenderScript still run inside of the Android VM,
     41   you have access to all of the framework APIs that you are familiar with, but can
     42   utilize RenderScript when appropriate. To facilitate this interaction between
     43   the framework and the RenderScript runtime, an intermediate layer of code is also
     44   present to facilitate communication and memory management between the two levels of code.
     45   This document goes into more detail about these
     46   different layers of code as well as how memory is shared between the Android VM and
     47   RenderScript runtime.</p>
     48 
     49   <h2 id="native">RenderScript Runtime Layer</h2>
     50 
     51   <p>Your RenderScript code is compiled and
     52   executed in a compact and well-defined runtime layer. The RenderScript runtime APIs offer support for
     53 intensive computation that is portable and automatically scalable to the
     54 amount of cores available on a processor.
     55 </p>
     56 <p class="note"><strong>Note:</strong> The standard C functions in the NDK must be
     57   guaranteed to run on a CPU, so RenderScript cannot access these libraries,
     58   because RenderScript is designed to run on different types of processors.</p>
     59 
     60 <p>You define your RenderScript code in <code>.rs</code>
     61   and <code>.rsh</code> files in the <code>src/</code> directory of your Android project. The code
     62   is compiled to intermediate bytecode by the
     63   <code>llvm</code> compiler that runs as part of an Android build. When your application
     64   runs on a device, the bytecode is then compiled (just-in-time) to machine code by another
     65   <code>llvm</code> compiler that resides on the device. The machine code is optimized for the
     66   device and also cached, so subsequent uses of the RenderScript enabled application do not
     67   recompile the bytecode.</p>
     68 
     69   <p>Some key features of the RenderScript runtime libraries include:</p>
     70 
     71   <ul>
     72 
     73     <li>Memory allocation request features</li>
     74 
     75     <li>A large collection of math functions with both scalar and vector typed overloaded versions
     76     of many common routines. Operations such as adding, multiplying, dot product, and cross product
     77     are available as well as atomic arithmetic and comparison functions.</li>
     78 
     79     <li>Conversion routines for primitive data types and vectors, matrix routines, and date and time
     80     routines</li>
     81 
     82     <li>Data types and structures to support the RenderScript system such as Vector types for
     83     defining two-, three-, or four-vectors.</li>
     84 
     85     <li>Logging functions</li>
     86   </ul>
     87 
     88   <p>See the RenderScript runtime API reference for more information on the available functions.
     89 
     90   <h2 id="reflected">Reflected Layer</h2>
     91 
     92   <p>The reflected layer is a set of classes that the Android build tools generate to allow access
     93   to the RenderScript runtime from the Android framework. This layer also provides methods
     94 and constructors that allow you to allocate and work with memory for pointers that are defined in
     95 your RenderScript code. The following list describes the major
     96   components that are reflected:</p>
     97 
     98   <ul>
     99     <li>Every <code>.rs</code> file that you create is generated into a class named
    100     <code>project_root/gen/package/name/ScriptC_<em>renderscript_filename</em></code> of
    101 type {@link android.renderscript.ScriptC}. This file is the <code>.java</code> version of your
    102 <code>.rs</code> file, which you can call from the Android framework. This class contains the
    103 following items reflected from the <code>.rs</code> file:
    104 
    105       <ul>
    106         <li>Non-static functions</li>
    107 
    108         <li>Non-static, global RenderScript variables. Accessor methods are generated for each
    109         variable, so you can read and write the RenderScript variables from the Android
    110         framework. If a global variable is initialized at the RenderScript runtime layer, those
    111 values are used to initialize the corresponding values in the Android framework layer. If global
    112 variables are marked as <code>const</code>, then a <code>set</code> method is not
    113 generated.</p></li>
    114 
    115         <li>Global pointers</li>
    116       </ul>
    117     </li>
    118 
    119     <li>A <code>struct</code> is reflected into its own class named
    120 
    121     <code>project_root/gen/package/name/ScriptField_struct_name</em></code>, which extends {@link
    122     android.renderscript.Script.FieldBase}. This class represents an array of the
    123     <code>struct</code>, which allows you to allocate memory for one or more instances of this
    124     <code>struct</code>.</li>
    125   </ul>
    126 
    127 
    128 <h3 id="func">Functions</h3>
    129 <p>Functions are reflected into the script class itself, located in
    130 <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For
    131 example, if you define the following function in your RenderScript code:</p>
    132 
    133 <pre>
    134 void touch(float x, float y, float pressure, int id) {
    135     if (id >= 10) {
    136         return;
    137     }
    138 
    139     touchPos[id].x = x;
    140     touchPos[id].y = y;
    141     touchPressure[id] = pressure;
    142 }
    143 </pre>
    144 
    145 <p>then the following Java code is generated:</p>
    146 
    147 <pre>
    148 public void invoke_touch(float x, float y, float pressure, int id) {
    149     FieldPacker touch_fp = new FieldPacker(16);
    150     touch_fp.addF32(x);
    151     touch_fp.addF32(y);
    152     touch_fp.addF32(pressure);
    153     touch_fp.addI32(id);
    154     invoke(mExportFuncIdx_touch, touch_fp);
    155 }
    156 </pre>
    157 <p>
    158 Functions cannot have return values, because the RenderScript system is designed to be
    159 asynchronous. When your Android framework code calls into RenderScript, the call is queued and is
    160 executed when possible. This restriction allows the RenderScript system to function without constant
    161 interruption and increases efficiency. If functions were allowed to have return values, the call
    162 would block until the value was returned.</p>
    163 
    164 <p>
    165 If you want the RenderScript code to send a value back to the Android framework, use the
    166 <a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a>
    167 function.
    168 </p>
    169 
    170 <h3 id="var">Variables</h3>
    171 
    172   <p>Variables of supported types are reflected into the script class itself, located in
    173 <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor
    174 methods is generated for each variable. For example, if you define the following variable in
    175 your RenderScript code:</p>
    176   <pre>uint32_t unsignedInteger = 1;</pre>
    177 
    178   <p>then the following Java code is generated:</p>
    179 
    180 <pre>
    181 private long mExportVar_unsignedInteger;
    182 public void set_unsignedInteger(long v){
    183     mExportVar_unsignedInteger = v;
    184     setVar(mExportVarIdx_unsignedInteger, v);
    185 }
    186 
    187 public long get_unsignedInteger(){
    188     return mExportVar_unsignedInteger;
    189 }
    190   </pre>
    191 
    192 
    193   <h3 id="struct">Structs</h3>
    194   <p>Structs are reflected into their own classes, located in
    195     <code>&lt;project_root&gt;/gen/com/example/renderscript/ScriptField_struct_name</code>. This
    196     class represents an array of the <code>struct</code> and allows you to allocate memory for a
    197     specified number of <code>struct</code>s. For example, if you define the following struct:</p>
    198 <pre>
    199 typedef struct Point {
    200     float2 position;
    201     float size;
    202 } Point_t;
    203 </pre>
    204 
    205 <p>then the following code is generated in <code>ScriptField_Point.java</code>:
    206 <pre>
    207 package com.example.android.rs.hellocompute;
    208 
    209 import android.renderscript.*;
    210 import android.content.res.Resources;
    211 
    212   /**
    213   * @hide
    214   */
    215 public class ScriptField_Point extends android.renderscript.Script.FieldBase {
    216 
    217     static public class Item {
    218         public static final int sizeof = 12;
    219 
    220         Float2 position;
    221         float size;
    222 
    223         Item() {
    224             position = new Float2();
    225         }
    226     }
    227 
    228     private Item mItemArray[];
    229     private FieldPacker mIOBuffer;
    230     public static Element createElement(RenderScript rs) {
    231         Element.Builder eb = new Element.Builder(rs);
    232         eb.add(Element.F32_2(rs), "position");
    233         eb.add(Element.F32(rs), "size");
    234         return eb.create();
    235     }
    236 
    237     public  ScriptField_Point(RenderScript rs, int count) {
    238         mItemArray = null;
    239         mIOBuffer = null;
    240         mElement = createElement(rs);
    241         init(rs, count);
    242     }
    243 
    244     public  ScriptField_Point(RenderScript rs, int count, int usages) {
    245         mItemArray = null;
    246         mIOBuffer = null;
    247         mElement = createElement(rs);
    248         init(rs, count, usages);
    249     }
    250 
    251     private void copyToArray(Item i, int index) {
    252         if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count
    253         */);
    254         mIOBuffer.reset(index * Item.sizeof);
    255         mIOBuffer.addF32(i.position);
    256         mIOBuffer.addF32(i.size);
    257     }
    258 
    259     public void set(Item i, int index, boolean copyNow) {
    260         if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
    261         mItemArray[index] = i;
    262         if (copyNow)  {
    263             copyToArray(i, index);
    264             mAllocation.setFromFieldPacker(index, mIOBuffer);
    265         }
    266     }
    267 
    268     public Item get(int index) {
    269         if (mItemArray == null) return null;
    270         return mItemArray[index];
    271     }
    272 
    273     public void set_position(int index, Float2 v, boolean copyNow) {
    274         if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
    275         if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
    276         if (mItemArray[index] == null) mItemArray[index] = new Item();
    277         mItemArray[index].position = v;
    278         if (copyNow) {
    279             mIOBuffer.reset(index * Item.sizeof);
    280             mIOBuffer.addF32(v);
    281             FieldPacker fp = new FieldPacker(8);
    282             fp.addF32(v);
    283             mAllocation.setFromFieldPacker(index, 0, fp);
    284         }
    285     }
    286 
    287     public void set_size(int index, float v, boolean copyNow) {
    288         if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
    289         if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
    290         if (mItemArray[index] == null) mItemArray[index] = new Item();
    291         mItemArray[index].size = v;
    292         if (copyNow)  {
    293             mIOBuffer.reset(index * Item.sizeof + 8);
    294             mIOBuffer.addF32(v);
    295             FieldPacker fp = new FieldPacker(4);
    296             fp.addF32(v);
    297             mAllocation.setFromFieldPacker(index, 1, fp);
    298         }
    299     }
    300 
    301     public Float2 get_position(int index) {
    302         if (mItemArray == null) return null;
    303         return mItemArray[index].position;
    304     }
    305 
    306     public float get_size(int index) {
    307         if (mItemArray == null) return 0;
    308         return mItemArray[index].size;
    309     }
    310 
    311     public void copyAll() {
    312         for (int ct = 0; ct &lt; mItemArray.length; ct++) copyToArray(mItemArray[ct], ct);
    313         mAllocation.setFromFieldPacker(0, mIOBuffer);
    314     }
    315 
    316     public void resize(int newSize) {
    317         if (mItemArray != null)  {
    318             int oldSize = mItemArray.length;
    319             int copySize = Math.min(oldSize, newSize);
    320             if (newSize == oldSize) return;
    321             Item ni[] = new Item[newSize];
    322             System.arraycopy(mItemArray, 0, ni, 0, copySize);
    323             mItemArray = ni;
    324         }
    325         mAllocation.resize(newSize);
    326         if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
    327     }
    328 }
    329 </pre>
    330 
    331 <p>The generated code is provided to you as a convenience to allocate memory for structs requested
    332 by the RenderScript runtime and to interact with <code>struct</code>s
    333 in memory. Each <code>struct</code>'s class defines the following methods and constructors:</p>
    334 
    335   <ul>
    336     <li>Overloaded constructors that allow you to allocate memory. The
    337       <code>ScriptField_<em>struct_name</em>(RenderScript rs, int count)</code> constructor allows
    338       you to define the number of structures that you want to allocate memory for with the
    339       <code>count</code> parameter. The <code>ScriptField_<em>struct_name</em>(RenderScript rs, int
    340         count, int usages)</code> constructor defines an extra parameter, <code>usages</code>, that
    341       lets you specify the memory space of this memory allocation. There are four memory space
    342       possibilities:
    343 
    344       <ul>
    345         <li>{@link android.renderscript.Allocation#USAGE_SCRIPT}: Allocates in the script memory
    346           space. This is the default memory space if you do not specify a memory space.</li>
    347 
    348         <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}: Allocates in the
    349           texture memory space of the GPU.</li>
    350 
    351         <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_VERTEX}: Allocates in the vertex
    352           memory space of the GPU.</li>
    353 
    354         <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_CONSTANTS}: Allocates in the
    355           constants memory space of the GPU that is used by the various program objects.</li>
    356       </ul>
    357 
    358       <p>You can specify multiple memory spaces by using the bitwise <code>OR</code> operator. Doing so
    359         notifies the RenderScript runtime that you intend on accessing the data in the
    360         specified memory spaces. The following example allocates memory for a custom data type
    361         in both the script and vertex memory spaces:</p>
    362       <pre>
    363         ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2,
    364         Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);
    365       </pre>
    366     </li>
    367 
    368     <li>A static nested class, <code>Item</code>, allows you to create an instance of the
    369       <code>struct</code>, in the form of an object. This nested class is useful if it makes more sense to work
    370       with the <code>struct</code> in your Android code. When you are done manipulating the object,
    371       you can push the object to the allocated memory by calling <code>set(Item i, int index,
    372         boolean copyNow)</code> and setting the <code>Item</code> to the desired position in
    373 the array. The RenderScript runtime automatically has access to the newly written memory.
    374 
    375       <li>Accessor methods to get and set the values of each field in a struct. Each of these
    376         accessor methods has an <code>index</code> parameter to specify the <code>struct</code> in
    377         the array that you want to read or write to. Each setter method also has a
    378 <code>copyNow</code> parameter that specifies whether or not to immediately sync this memory
    379 to the RenderScript runtime. To sync any memory that has not been synced, call
    380         <code>copyAll()</code>.</li>
    381 
    382       <li>The <code>createElement()</code> method creates a description of the struct in memory. This
    383       description is used to allocate memory consisting of one or many elements.</li>
    384 
    385       <li><code>resize()</code> works much like a <code>realloc()</code> in C, allowing you to
    386 expand previously allocated memory, maintaining the current values that were previously
    387 created.</li>
    388 
    389       <li><code>copyAll()</code> synchronizes memory that was set on the framework level to the
    390 RenderScript runtime. When you call a set accessor method on a member, there is an optional
    391 <code>copyNow</code> boolean parameter that you can specify. Specifying
    392         <code>true</code> synchronizes the memory when you call the method. If you specify false,
    393         you can call <code>copyAll()</code> once, and it synchronizes memory for all the
    394 properties that are not yet synchronized.</li>
    395     </ul>
    396 
    397   <h3 id="pointer">Pointers</h3>
    398   <p>Global pointers are reflected into the script class itself, located in
    399 <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You
    400 can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a
    401 <code>struct</code> cannot contain pointers or nested arrays. For example, if you define the
    402 following pointers to a <code>struct</code> and <code>int32_t</code></p>
    403 
    404 <pre>
    405 typedef struct Point {
    406     float2 position;
    407     float size;
    408 } Point_t;
    409 
    410 Point_t *touchPoints;
    411 int32_t *intPointer;
    412 </pre>
    413   <p>then the following Java code is generated:</p>
    414 
    415 <pre>
    416 private ScriptField_Point mExportVar_touchPoints;
    417 public void bind_touchPoints(ScriptField_Point v) {
    418     mExportVar_touchPoints = v;
    419     if (v == null) bindAllocation(null, mExportVarIdx_touchPoints);
    420     else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints);
    421 }
    422 
    423 public ScriptField_Point get_touchPoints() {
    424     return mExportVar_touchPoints;
    425 }
    426 
    427 private Allocation mExportVar_intPointer;
    428 public void bind_intPointer(Allocation v) {
    429     mExportVar_intPointer = v;
    430     if (v == null) bindAllocation(null, mExportVarIdx_intPointer);
    431     else bindAllocation(v, mExportVarIdx_intPointer);
    432 }
    433 
    434 public Allocation get_intPointer() {
    435     return mExportVar_intPointer;
    436 }
    437   </pre>
    438 
    439 <p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code>
    440 (instead of a <code>set()</code> method) are generated. The <code>bind_<em>pointer_name</em></code> method allows you to bind the memory
    441 that is allocated in the Android VM to the RenderScript runtime (you cannot allocate
    442 memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working
    443 with Allocated Memory</a>.
    444 </p>
    445 
    446 
    447   <h2 id="mem-allocation">Memory Allocation APIs</h2>
    448 
    449  <p>Applications that use RenderScript still run in the Android VM. The actual RenderScript code, however, runs natively and
    450   needs access to the memory allocated in the Android VM. To accomplish this, you must
    451   attach the memory that is allocated in the VM to the RenderScript runtime. This
    452 process, called binding, allows the RenderScript runtime to seamlessly work with memory that it
    453 requests but cannot explicitly allocate. The end result is essentially the same as if you had
    454 called <code>malloc</code> in C. The added benefit is that the Android VM can carry out garbage collection as well as
    455 share memory with the RenderScript runtime layer. Binding is only necessary for dynamically allocated memory. Statically
    456 allocated memory is automatically created for your RenderScript code at compile time. See <a href="#figure1">Figure 1</a>
    457 for more information on how memory allocation occurs.
    458 </p>
    459 
    460   <p>To support this memory allocation system, there are a set of APIs that allow the Android VM to
    461 allocate memory and offer similar functionality to a <code>malloc</code> call. These classes
    462 essentially describe how memory should be allocated and also carry out the allocation. To better
    463 understand how these classes work, it is useful to think of them in relation to a simple
    464 <code>malloc</code> call that can look like this: </p>
    465 
    466   <pre>array = (int *)malloc(sizeof(int)*10);</pre>
    467 
    468   <p>The <code>malloc</code> call can be broken up into two parts: the size of the memory being allocated (<code>sizeof(int)</code>),
    469   along with how many units of that memory should be allocated (10). The Android framework provides classes for these two parts as
    470   well as a class to represent <code>malloc</code> itself.</p>
    471 
    472   <p>The {@link android.renderscript.Element} class represents the (<code>sizeof(int)</code>) portion
    473   of the <code>malloc</code> call and encapsulates one cell of a memory allocation, such as a single
    474   float value or a struct. The {@link android.renderscript.Type} class encapsulates the {@link android.renderscript.Element}
    475   and the amount of elements to allocate (10 in our example). You can think of a {@link android.renderscript.Type} as
    476   an array of {@link android.renderscript.Element}s. The {@link android.renderscript.Allocation} class does the actual
    477   memory allocation based on a given {@link android.renderscript.Type} and represents the actual allocated memory.</p>
    478 
    479   <p>In most situations, you do not need to call these memory allocation APIs directly. The reflected layer
    480   classes generate code to use these APIs automatically and all you need to do to allocate memory is call a
    481   constructor that is declared in one of the reflected layer classes and then bind
    482   the resulting memory {@link android.renderscript.Allocation} to the RenderScript.
    483   There are some situations where you would want to use these classes directly to allocate memory on your
    484   own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to
    485   primitive types. You can see how to do this in the
    486   <a href="#allocating-mem">Allocating and binding memory to the RenderScript</a> section.
    487   The following table describes the three memory management classes in more detail:</p>
    488 
    489   <table id="mem-mgmt-table">
    490     <tr>
    491       <th>Android Object Type</th>
    492 
    493       <th>Description</th>
    494     </tr>
    495 
    496     <tr>
    497       <td>{@link android.renderscript.Element}</td>
    498 
    499       <td>
    500         <p>An element describes one cell of a memory allocation and can have two forms: basic or
    501         complex.</p>
    502 
    503         <p>A basic element contains a single component of data of any valid RenderScript data type.
    504         Examples of basic element data types include a single <code>float</code> value, a <code>float4</code> vector, or a
    505         single RGB-565 color.</p>
    506 
    507         <p>Complex elements contain a list of basic elements and are created from
    508         <code>struct</code>s that you declare in your RenderScript code. For instance an allocation
    509         can contain multiple <code>struct</code>s arranged in order in memory. Each struct is considered as its
    510         own element, rather than each data type within that struct.</p>
    511       </td>
    512     </tr>
    513 
    514     <tr>
    515       <td>{@link android.renderscript.Type}</td>
    516 
    517       <td>
    518         <p>A type is a memory allocation template and consists of an element and one or more
    519         dimensions. It describes the layout of the memory (basically an array of {@link
    520         android.renderscript.Element}s) but does not allocate the memory for the data that it
    521         describes.</p>
    522 
    523         <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube
    524         map). You can set the X,Y,Z dimensions to any positive integer value within the
    525         constraints of available memory. A single dimension allocation has an X dimension of
    526         greater than zero while the Y and Z dimensions are zero to indicate not present. For
    527         example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is
    528         considered one dimensional. The LOD and Faces dimensions are booleans to indicate present
    529         or not present.</p>
    530       </td>
    531     </tr>
    532 
    533     <tr>
    534       <td>{@link android.renderscript.Allocation}</td>
    535 
    536       <td>
    537         <p>An allocation provides the memory for applications based on a description of the memory
    538         that is represented by a {@link android.renderscript.Type}. Allocated memory can exist in
    539         many memory spaces concurrently. If memory is modified in one space, you must explicitly
    540         synchronize the memory, so that it is updated in all the other spaces in which it exists.
    541         </p>
    542 
    543         <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked.
    544         For simple arrays there are <code>copyFrom()</code> functions that take an array from the
    545         Android system and copy it to the native layer memory store. The unchecked variants allow
    546         the Android system to copy over arrays of structures because it does not support
    547         structures. For example, if there is an allocation that is an array of n floats, the data
    548         contained in a float[n] array or a <code>byte[n*4]</code> array can be copied.</p>
    549       </td>
    550     </tr>
    551   </table>
    552 
    553   <h2 id="memory">Working with Memory</h2>
    554 
    555 <p>Non-static, global variables that you declare in your RenderScript are allocated memory at compile time.
    556 You can work with these variables directly in your RenderScript code without having to allocate
    557 memory for them at the Android framework level. The Android framework layer also has access to these variables
    558 with the provided accessor methods that are generated in the reflected layer classes. If these variables are
    559 initialized at the RenderScript runtime layer, those values are used to initialize the corresponding
    560 values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is
    561 not generated.</p>
    562 
    563 
    564 <p class="note"><strong>Note:</strong> If you are using certain RenderScript structures that contain pointers, such as
    565 <code>rs_program_fragment</code> and <code>rs_allocation</code>, you have to obtain an object of the
    566 corresponding Android framework class first and then call the <code>set</code> method for that
    567 structure to bind the memory to the RenderScript runtime. You cannot directly manipulate these structures
    568 at the RenderScript runtime layer. This restriction is not applicable to user-defined structures
    569 that contain pointers, because they cannot be exported to a reflected layer class
    570 in the first place. A compiler error is generated if you try to declare a non-static, global
    571 struct that contains a pointer.
    572 </p>
    573 
    574 <p>RenderScript also has support for pointers, but you must explicitly allocate the memory in your
    575 Android framework code. When you declare a global pointer in your <code>.rs</code> file, you
    576 allocate memory through the appropriate reflected layer class and bind that memory to the native
    577 RenderScript layer. You can interact with this memory from the Android framework layer as well as
    578 the RenderScript layer, which offers you the flexibility to modify variables in the most
    579 appropriate layer.</p>
    580 
    581 
    582 
    583   <h3 id="allocating-mem">Allocating and binding dynamic memory to the RenderScript</h3>
    584 
    585   <p>To allocate dynamic memory, you need to call the constructor of a
    586   {@link android.renderscript.Script.FieldBase} class, which is the most common way. An alternative is to create an
    587   {@link android.renderscript.Allocation} manually, which is required for things such as primitive type pointers. You should
    588   use a {@link android.renderscript.Script.FieldBase} class constructor whenever available for simplicity.
    589   After obtaining a memory allocation, call the reflected <code>bind</code> method of the pointer to bind the allocated memory to the
    590   RenderScript runtime.</p>
    591   <p>The example below allocates memory for both a primitive type pointer,
    592    <code>intPointer</code>, and a pointer to a struct, <code>touchPoints</code>. It also binds the memory to the
    593   RenderScript:</p>
    594   <pre>
    595 private RenderScript myRenderScript;
    596 private ScriptC_example script;
    597 private Resources resources;
    598 
    599 public void init(RenderScript rs, Resources res) {
    600     myRenderScript = rs;
    601     resources = res;
    602 
    603     //allocate memory for the struct pointer, calling the constructor
    604     ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2);
    605 
    606     //Create an element manually and allocate memory for the int pointer
    607     intPointer = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2);
    608 
    609     //create an instance of the RenderScript, pointing it to the bytecode resource
    610     mScript = new ScriptC_example(myRenderScript, resources, R.raw.example);
    611 
    612     //bind the struct and int pointers to the RenderScript
    613     mScript.bind_touchPoints(touchPoints);
    614     script.bind_intPointer(intPointer);
    615 
    616    ...
    617 }
    618 </pre>
    619 
    620   <h3>Reading and writing to memory</h3>
    621   <p>You can read and write to statically and dynamically allocated memory both at the RenderScript runtime
    622   and Android framework layer.</p>
    623 
    624 <p>Statically allocated memory comes with a one-way communication restriction
    625 at the RenderScript runtime level. When RenderScript code changes the value of a variable, it is not
    626 communicated back to the Android framework layer for efficiency purposes. The last value
    627 that is set from the Android framework is always returned during a call to a <code>get</code>
    628 method. However, when Android framework code modifies a variable, that change can be communicated to
    629 the RenderScript runtime automatically or synchronized at a later time. If you need to send data
    630 from the RenderScript runtime to the Android framework layer, you can use the
    631 <a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> function
    632 to overcome this limitation.
    633 </p>
    634 <p>When working with dynamically allocated memory, any changes at the RenderScript runtime layer are propagated
    635 back to the Android framework layer if you modified the memory allocation using its associated pointer.
    636 Modifying an object at the Android framework layer immediately propagates that change back to the RenderScript
    637 runtime layer.</p>
    638 
    639   <h4>Reading and writing to global variables</h4>
    640 
    641   <p>Reading and writing to global variables is a straightforward process. You can use the accessor methods
    642   at the Android framework level or set them directly in the RenderScript code. Keep in mind that any
    643   changes that you make in your RenderScript code are not propagated back to the Android framework layer.</p>
    644 
    645   <p>For example, given the following struct declared in a file named <code>rsfile.rs</code>:</p>
    646 <pre>
    647 typedef struct Point {
    648     int x;
    649     int y;
    650 } Point_t;
    651 
    652 Point_t point;
    653 
    654 </pre>
    655 <p>You can assign values to the struct like this directly in <code>rsfile.rs</code>. These values are not
    656 propagated back to the Android framework level:</p>
    657 <pre>
    658 point.x = 1;
    659 point.y = 1;
    660 </pre>
    661 
    662 <p>You can assign values to the struct at the Android framework layer like this. These values are
    663 propagated back to the RenderScript runtime level:</p>
    664 <pre>
    665 ScriptC_rsfile mScript;
    666 
    667 ...
    668 
    669 Item i = new ScriptField_Point.Item();
    670 i.x = 1;
    671 i.y = 1;
    672 mScript.set_point(i);
    673 </pre>
    674 
    675 <p>You can read the values in your RenderScript code like this:</p>
    676 
    677 <pre>
    678 rsDebug("Printing out a Point", point.x, point.y);
    679 </pre>
    680 
    681 <p>You can read the values in the Android framework layer with the following code. Keep in mind that this
    682 code only returns a value if one was set at the Android framework level. You will get a null pointer
    683 exception if you only set the value at the RenderScript runtime level:</p>
    684 
    685 <pre>
    686 Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y);
    687 System.out.println(point.get_x() + " " + point.get_y());
    688 </pre>
    689 
    690 <h4>Reading and writing global pointers</h4>
    691 
    692 <p>Assuming that memory has been allocated in the Android framework level and bound to the RenderScript runtime,
    693 you can read and write memory from the Android framework level by using the <code>get</code> and <code>set</code> methods for that pointer.
    694 In the RenderScript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated
    695 back to the Android framework layer, unlike with statically allocated memory.</p>
    696 
    697 <p>For example, given the following pointer to a <code>struct</code> in a file named <code>rsfile.rs</code>:</p>
    698 <pre>
    699 typedef struct Point {
    700     int x;
    701     int y;
    702 } Point_t;
    703 
    704 Point_t *point;
    705 </pre>
    706 
    707 <p>Assuming you already allocated memory at the Android framework layer, you can access values in
    708 the <code>struct</code> as normal. Any changes you make to the struct via its pointer variable
    709 are automatically available to the Android framework layer:</p>
    710 
    711 <pre>
    712 point[index].x = 1;
    713 point[index].y = 1;
    714 </pre>
    715 
    716 <p>You can read and write values to the pointer at the Android framework layer as well:
    717 <pre>
    718 ScriptField_Point p = new ScriptField_Point(mRS, 1);
    719     Item i = new ScriptField_Point.Item();
    720     i.x=100;
    721     i.y = 100;
    722     p.set(i, 0, true);
    723     mScript.bind_point(p);
    724 
    725     points.get_x(0);            //read x and y from index 0
    726     points.get_x(0);
    727 </pre>
    728 
    729 <p>Once memory is already bound, you do not have to rebind the memory to the RenderScript
    730 runtime every time you make a change to a value.</p>
    731