• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Advanced Renderscript
2parent.title=Computation
3parent.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
53intensive computation that is portable and automatically scalable to the
54amount 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 does 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
94and constructors that allow you to allocate and work with memory for pointers that are defined in
95your 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
101type {@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
103following 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
111values are used to initialize the corresponding values in the Android framework layer. If global
112variables are marked as <code>const</code>, then a <code>set</code> method is not
113generated.</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
131example, if you declare the following function in your Renderscript code:</p>
132
133<pre>
134void 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 code is generated:</p>
146
147<pre>
148public 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>
158Functions cannot have a return value, because the Renderscript system is designed to be
159asynchronous. When your Android framework code calls into Renderscript, the call is queued and is
160executed when possible. This restriction allows the Renderscript system to function without constant
161interruption and increases efficiency. If functions were allowed to have return values, the call
162would block until the value was returned.</p>
163
164<p>
165If 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>
167function.
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
174methods are generated for each variable. For example, if you declare the following variable in
175your Renderscript code:</p>
176  <pre>uint32_t unsignedInteger = 1;</pre>
177
178  <p>then the following code is generated:</p>
179
180<pre>
181private long mExportVar_unsignedInteger;
182public void set_unsignedInteger(long v){
183    mExportVar_unsignedInteger = v;
184    setVar(mExportVarIdx_unsignedInteger, v);
185}
186
187public 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 declare the following struct:</p>
198<pre>
199typedef 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>
207package com.example.android.rs.hellocompute;
208
209import android.renderscript.*;
210import android.content.res.Resources;
211
212  /**
213  * @hide
214  */
215public 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
332by the Renderscript runtime and to interact with <code>struct</code>s
333in 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
373the 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 have 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
379to 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
386expand previously allocated memory, maintaining the current values that were previously
387created.</li>
388
389      <li><code>copyAll()</code> synchronizes memory that was set on the framework level to the
390Renderscript 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
394properties that are not yet synchronized.</li>
395    </ul>
396
397  <h3 id="pointer">Pointers</h3>
398  <p>Pointers are reflected into the script class itself, located in
399<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You
400can 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 declare the
402following pointers to a <code>struct</code> and <code>int32_t</code></p>
403
404<pre>
405typedef struct Point {
406    float2 position;
407    float size;
408} Point_t;
409
410Point_t *touchPoints;
411int32_t *intPointer;
412</pre>
413  <p>then the following code is generated in:</p>
414
415<pre>
416private ScriptField_Point mExportVar_touchPoints;
417public 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
423public ScriptField_Point get_touchPoints() {
424    return mExportVar_touchPoints;
425}
426
427private Allocation mExportVar_intPointer;
428public 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
434public 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) is generated. This method allows you to bind the memory
441that is allocated in the Android VM to the Renderscript runtime (you cannot allocate
442memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working
443with 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
452process, called binding, allows the Renderscript runtime to seamlessly work with memory that it
453requests but cannot explicitly allocate. The end result is essentially the same as if you had
454called <code>malloc</code> in C. The added benefit is that the Android VM can carry out garbage collection as well as
455share memory with the Renderscript runtime layer. Binding is only necessary for dynamically allocated memory. Statically
456allocated memory is automatically created for your Renderscript code at compile time. See <a href="#figure1">Figure 1</a>
457for 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
461allocate memory and offer similar functionality to a <code>malloc</code> call. These classes
462essentially describe how memory should be allocated and also carry out the allocation. To better
463understand 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 assign 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.
556You can work with these variables directly in your Renderscript code without having to allocate
557memory for them at the Android framework level. The Android framework layer also has access to these variables
558with the provided accessor methods that are generated in the reflected layer classes. If these variables are
559initialized at the Renderscript runtime layer, those values are used to initialize the corresponding
560values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is
561not 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
566corresponding Android framework class first and then call the <code>set</code> method for that
567structure to bind the memory to the Renderscript runtime. You cannot directly manipulate these structures
568at the Renderscript runtime layer. This restriction is not applicable to user-defined structures
569that contain pointers, because they cannot be exported to a reflected layer class
570in the first place. A compiler error is generated if you try to declare a non-static, global
571struct that contains a pointer.
572</p>
573
574<p>Renderscript also has support for pointers, but you must explicitly allocate the memory in your
575Android framework code. When you declare a global pointer in your <code>.rs</code> file, you
576allocate memory through the appropriate reflected layer class and bind that memory to the native
577Renderscript layer. You can interact with this memory from the Android framework layer as well as
578the Renderscript layer, which offers you the flexibility to modify variables in the most
579appropriate 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>
595private RenderScript myRenderscript;
596private ScriptC_example script;
597private Resources resources;
598
599public 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
625at the Renderscript runtime level. When Renderscript code changes the value of a variable, it is not
626communicated back to the Android framework layer for efficiency purposes. The last value
627that is set from the Android framework is always returned during a call to a <code>get</code>
628method. However, when Android framework code modifies a variable, that change can be communicated to
629the Renderscript runtime automatically or synchronized at a later time. If you need to send data
630from 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
632to overcome this limitation.
633</p>
634<p>When working with dynamically allocated memory, any changes at the Renderscript runtime layer are propagated
635back to the Android framework layer if you modified the memory allocation using its associated pointer.
636Modifying an object at the Android framework layer immediately propagates that change back to the Renderscript
637runtime 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>
647typedef struct Point {
648    int x;
649    int y;
650} Point_t;
651
652Point_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
656propagated back to the Android framework level:</p>
657<pre>
658point.x = 1;
659point.y = 1;
660</pre>
661
662<p>You can assign values to the struct at the Android framework layer like this. These values are
663propagated back to the Renderscript runtime level:</p>
664<pre>
665ScriptC_rsfile mScript;
666
667...
668
669Item i = new ScriptField_Point.Item();
670i.x = 1;
671i.y = 1;
672mScript.set_point(i);
673</pre>
674
675<p>You can read the values in your Renderscript code like this:</p>
676
677<pre>
678rsDebug("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
682code only returns a value if one was set at the Android framework level. You will get a null pointer
683exception if you only set the value at the Renderscript runtime level:</p>
684
685<pre>
686Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y);
687System.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,
693you can read and write memory from the Android framework level by using the <code>get</code> and <code>set</code> methods for that pointer.
694In the Renderscript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated
695back 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>
699typedef struct Point {
700    int x;
701    int y;
702} Point_t;
703
704Point_t *point;
705</pre>
706
707<p>Assuming you already allocated memory at the Android framework layer, you can access values in
708the <code>struct</code> as normal. Any changes you make to the struct via its pointer variable
709are automatically available to the Android framework layer:</p>
710
711<pre>
712point[index].x = 1;
713point[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>
718ScriptField_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
730runtime every time you make a change to a value.</p>
731