index.jd revision f197b639ecccc570ee235486f75ba15f87070c28
1page.title=RenderScript
2@jd:body
3
4  <div id="qv-wrapper">
5    <div id="qv">
6      <h2>In this document</h2>
7
8      <ol>
9        <li><a href="#overview">RenderScript System Overview</a></li>
10        <li>
11          <ol>
12            <li><a href="#native">Native RenderScript layer</a></li>
13
14            <li><a href="#reflected">Reflected layer</a></li>
15
16            <li><a href="#framework">Android framework layer</a></li>
17          </ol>
18        </li>
19
20        <li>
21          <a href="#mem-allocation">Memory Allocation APIs</a>
22        </li>
23        <li>
24          <a href="#dynamic">Dynamic Memory Allocations</a>
25          <ol>
26            <li><a href="#pointers">Declaring pointers</a></li>
27
28            <li><a href="#struct-pointer-reflection">How pointers are reflected</a></li>
29
30            <li><a href="#binding">Allocating and binding memory to the RenderScript</a></li>
31
32            <li><a href="#read-write-dynamic">Reading and writing to memory</a></li>
33
34          </ol>
35        </li>
36        <li>
37          <a href="#static">Static Memory Allocations</a>
38        </li>
39      </ol>
40    </div>
41  </div>
42
43  <p>RenderScript offers a high performance 3D graphics rendering and compute API at the native
44  level, which you write in the C (C99 standard). The main advantages of RenderScript are:</p>
45  <ul>
46    <li>Portability: RenderScript is designed to run on many types of devices with different CPU
47    and GPU architectures. It supports all of these architectures without having to target each
48    device, because the code is compiled and cached on the device at runtime.</li>
49
50    <li>Performance: RenderScript provides similar performance to OpenGL with the NDK while
51    offering the portability of the OpenGL APIs provided by the Android framework ({@link
52    android.opengl}). In addition, it also offers a high performance compute API that is not
53    offered by OpenGL.</li>
54
55    <li>Usability: RenderScript simplifies development when possible, such as eliminating JNI glue code
56    and simplifying mesh setup.</li>
57  </ul>
58
59  <p>The main disadvantages are:</p>
60
61  <ul>
62    <li>Development complexity: RenderScript introduces a new set of APIs that you have to learn.
63    RenderScript also handles memory differently compared to OpenGL with the Android framework APIs
64    or NDK.</li>
65
66    <li>Debugging visibility: RenderScript can potentially execute (planned feature for later releases)
67    on processors other than the main CPU (such as the GPU), so if this occurs, debugging becomes more difficult. 
68    </li>
69
70    <li>Less features: RenderScript does not provide as many features as OpenGL such as all the compressed
71    texture formats or GL extensions.</li>
72  </ul>
73
74  <p>You need to consider all of the aspects of RenderScript before deciding when to use it. The following list describes
75  general guidelines on when to use OpenGL (framework APIs or NDK) or RenderScript:</p>
76  <ul>
77    <li>If you are doing simple graphics rendering and performance is not critical, you probably want to use the
78  Android framework OpenGL APIs, which still provide adequate performance, to eliminate the added coding and debugging complexity of
79  RenderScript.</li>
80
81  <li>If you want the most flexibility and features while maintaining relatively good debugging
82  support, you probably want to use OpenGL and the NDK. Applications that require this are high end
83  or complicated games, for example.</li>
84 
85  <li>If you want a solution that is portable, has good performance,
86  and you don't need the full feature set of OpenGL, RenderScript is a good solution. If you also
87  need a high performance compute language, then RenderScript offers that as well.
88  Good candidates for RenderScript are graphics intensive UIs that require 3D rendering, live wallpapers,
89  or applications that require intensive mathematical computation.</li>
90  </ul>
91
92  <p>For an example of RenderScript in action, install the RenderScript sample applications that
93  are shipped with the SDK in <code>&lt;sdk_root&gt;/samples/android-11/RenderScript</code>.
94  You can also see a typical use of RenderScript with the 3D carousel view in the Android 3.x
95  versions of Google Books and YouTube.</p>
96
97  <h2 id="overview">RenderScript System Overview</h2>
98
99  <p>The RenderScript system adopts a control and slave architecture where the low-level native
100  code is controlled by the higher level Android system that runs in a virtual machine (VM). The
101  Android VM still retains all control of memory and lifecycle management and calls the native
102  RenderScript code when necessary. The native code is compiled to intermediate bytecode (LLVM) and
103  packaged inside your application's <code>.apk</code> file. On the device, the bytecode is
104  compiled (just-in-time) to machine code that is further optimized for the device that it is
105  running on. The compiled code on the device is cached, so subsequent uses of the RenderScript
106  enabled application do not recompile the intermediate code. RenderScript has three layers of code
107  to enable communication between the native and Android framework code:</p>
108
109  <ul>
110    <li>The native RenderScript layer does the intensive computation or graphics rendering. You
111    define your native code in <code>.rs</code> and <code>.rsh</code> files.</li>
112
113    <li>The reflected layer is a set of classes that are reflected from the native code. It is basically
114    a wrapper around the native code that allows the Android framework to interact with native RenderScripts.
115    The Android build tools automatically generate the classes for this layer during
116    the build process and eliminates the need to write JNI glue code, like with the NDK.</li>
117
118    <li>The Android framework layer is comprised of the Android framework
119     APIs, which include the {@link android.renderscript} package. This layer gives high level commands
120     like, "rotate the view" or "filter the bitmap", by calling the reflected layer, which in turn calls
121     the native layer. </li>
122  </ul>
123
124  <h3 id="native">Native RenderScript layer</h3>
125
126  <p>The native RenderScript layer consists of your RenderScript code, which is compiled and
127  executed in a compact and well defined runtime. Your RenderScript code has access to a limited
128  amount of functions because it cannot access the NDK or standard C functions, since they must be guaranteed to
129  run on a standard CPU. The RenderScript runtime was designed to run on different types of processors,
130  which may not be the CPU, so it cannot guarantee support for standard C libraries. What
131  RenderScript does offer is an API that supports intensive computation and graphics rendering with a collection of math
132  and graphics APIs.</p>
133
134  <p>Some key features of the native RenderScript libraries include:</p>
135
136  <ul>
137    <li>A large collection of math functions with both scalar and vector typed overloaded versions
138    of many common routines. Operations such as adding, multiplying, dot product, and cross product
139    are available.</li>
140
141    <li>Conversion routines for primitive data types and vectors, matrix routines, date and time
142    routines, and graphics routines.</li>
143
144    <li>Logging functions</li>
145
146    <li>Graphics rendering functions</li>
147
148    <li>Memory allocation request features</li>
149
150    <li>Data types and structures to support the RenderScript system such as Vector types for
151    defining two-, three-, or four-vectors.</li>
152  </ul>
153
154  <p>The <a href="{@docRoot}guide/topics/renderscript/rs-api/files.html">RenderScript header files</a>
155  and LLVM front-end libraries are located in the <code>include</code> and
156  <code>clang-include</code> directories in the
157  <code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code> directory of the Android SDK. The
158  headers are automatically included for you, except for the RenderScript graphics specific header file, which
159  you can include as follows:</p>
160  <pre>
161#include "rs_graphics.rsh"
162</pre>
163
164  <h3 id="reflected">Reflected layer</h3>
165
166  <p>The reflected layer is a set of classes that the Android build tools generate to allow access
167  to the native RenderScript code from the Android VM. This layer defines entry points for
168  RenderScript functions and variables, so that you can interact with them with the Android
169  framework. This layer also provides methods and constructors that allow you to allocate memory
170  for pointers that are defined in your RenderScript code. The following list describes the major
171  components that are reflected:</p>
172
173  <ul>
174    <li>Every <code>.rs</code> file that you create is generated into a class named
175    <code>ScriptC_<em>renderscript_filename</em></code> of type {@link
176    android.renderscript.ScriptC}. This is the <code>.java</code> version of your <code>.rs</code>
177    file, which you can call from the Android framework. This class contains the following
178    reflections:
179
180      <ul>
181        <li>Non-static functions in your <code>.rs</code> file.</li>
182
183        <li>Non-static, global RenderScript variables. Accessor methods are generated for each
184        variable, so you can read and write the natively declared variables from the Android
185        framework. The <code>get</code> method comes with a one-way communication restriction. The
186        last value that is set from the Android framework is always returned during a call to a
187        <code>get</code> method. If the native RenderScript code changes the value, the change does
188        not propagate back to the Android framework layer.
189        If the global variables are initialized
190        in the native RenderScript code, those values are used to initialize the corresponding
191        values in the Android framework layer. If global variables are marked as
192        <code>const</code>, then a <code>set</code> method is not generated.</li>
193        <li>Global pointers generate a special method named <code>bind_<em>pointer_name</em></code>
194        instead of a <code>set()</code> method. This method allows you to bind the memory that is
195        allocated in the Android VM for the pointer to the native RenderScript (you cannot allocate
196        memory in your <code>.rs</code> file). You can read and write to this memory from both the
197        Android framework and RenderScript code. For more information, see <a href="mem-mgmt">Working
198        with Memory and Data</a></li>
199      </ul>
200    </li>
201
202    <li>A <code>struct</code> is reflected into its own class named
203    <code>ScriptField_<em>struct_name</em></code>, which extends {@link
204    android.renderscript.Script.FieldBase}. This class represents an array of the
205    <code>struct</code>, which allows you to allocate memory for one or more instances of this
206    <code>struct</code>.</li>
207  </ul>
208
209  <h3 id="framework">Android framework layer</h3>
210
211  <p>The Android framework layer consists of the usual Android framework APIs, which include the
212    RenderScript APIs in {@link android.renderscript}. This layer handles things such as the
213    Activity lifecycle and memory management of your application. It issues high level commands to
214    the native RenderScript code through the reflected layer and receives events from the user such
215    as touch and input events and relays them to your RenderScript code, if needed.
216  </p>
217
218  <h2 id="mem-allocation">Memory Allocation APIs</h2>
219
220  <p>Before you begin writing your first RenderScript application, you must understand how 
221  memory is allocated for your RenderScript code and how data is shared between the native and VM
222  spaces. RenderScript allows you to access allocated memory in both the native layer
223  and Android system layer. All dynamic and static memory is allocated by the Android VM.
224  The Android VM also does reference counting and garbage collection for you. 
225  You can also explicitly free memory that you no longer need.</p>
226
227  <p class="note"><strong>Note:</strong> To declare temporary memory in your native RenderScript
228  code without allocating it in the Android VM, you can still do things like instantiate a scratch
229  buffer using an array.</p>
230
231  <p>The following classes support the memory management features of RenderScript in the Android
232  VM. You normally do not need to work with these classes directly, because the reflected layer
233  classes provide constructors and methods that set up the memory allocation for you. There are
234  some situations where you would want to use these classes directly to allocate memory on your
235  own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to
236  primitive types.</p>
237
238  <table id="mem-mgmt-table">
239    <tr>
240      <th>Android Object Type</th>
241
242      <th>Description</th>
243    </tr>
244
245    <tr>
246      <td>{@link android.renderscript.Element}</td>
247
248      <td>
249        <p>An element represents one cell of a memory allocation and can have two forms: Basic or
250        Complex.</p>
251
252        <p>A basic element contains a single component of data of any valid RenderScript data type.
253        Examples of basic element data types include a single float value, a float4 vector, or a
254        single RGB-565 color.</p>
255
256        <p>Complex elements contain a list of basic elements and are created from
257        <code>struct</code>s that you declare in your RenderScript code. The most basic primitive
258        type determines the data alignment of the memory. For example, a float4 vector subelement
259        is alligned to <code>sizeof(float)</code> and not <code>sizeof(float4)</code>. The ordering
260        of the elements in memory are the order in which they were added, with each component
261        aligned as necessary.</p>
262      </td>
263    </tr>
264
265    <tr>
266      <td>{@link android.renderscript.Type}</td>
267
268      <td>
269        A type is a memory allocation template and consists of an element and one or more
270        dimensions. It describes the layout of the memory (basically an array of {@link
271        android.renderscript.Element}s) but does not allocate the memory for the data that it
272        describes.
273
274        <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube
275        map). You can assign the X,Y,Z dimensions to any positive integer value within the
276        constraints of available memory. A single dimension allocation has an X dimension of
277        greater than zero while the Y and Z dimensions are zero to indicate not present. For
278        example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is
279        considered one dimensional. The LOD and Faces dimensions are booleans to indicate present
280        or not present.</p>
281      </td>
282    </tr>
283
284    <tr>
285      <td>{@link android.renderscript.Allocation}</td>
286
287      <td>
288        <p>An allocation provides the memory for applications based on a description of the memory
289        that is represented by a {@link android.renderscript.Type}. Allocated memory can exist in
290        many memory spaces concurrently. If memory is modified in one space, you must explicitly
291        synchronize the memory, so that it is updated in all the other spaces that it exists
292        in.</p>
293
294        <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked.
295        For simple arrays there are <code>copyFrom()</code> functions that take an array from the
296        Android system and copy it to the native layer memory store. The unchecked variants allow
297        the Android system to copy over arrays of structures because it does not support
298        structures. For example, if there is an allocation that is an array of n floats, the data
299        contained in a float[n] array or a byte[n*4] array can be copied.</p>
300      </td>
301    </tr>
302  </table>
303
304  <h2 id="dynamic">Working with dynamic memory allocations</h2>
305
306  <p>RenderScript has support for pointers, but you must allocate the memory in your Android framework
307  code. When you declare a global pointer in your <code>.rs</code> file, you allocate memory
308  through the appropriate reflected layer class and bind that memory to the native
309  RenderScript layer. You can read and write to this memory from the Android framework layer as well as the
310  RenderScript layer, which offers you the flexibility to modify variables in the most appropriate
311  layer. The following sections show you how to work with pointers, allocate memory for them, and
312  read and write to the memory.</p>
313
314  <h3 id="pointers">Declaring pointers</h3>
315
316  <p>Because RenderScript is written in C99, declaring a pointer is done in a familiar way. You can
317  declare pointers to a <code>struct</code> or a primitive type, but a <code>struct</code> cannot
318  contain pointers or nested arrays. The following code declares a <code>struct</code>, a pointer
319  to that <code>struct</code>, and a pointer of primitive type <code>int32_t</code> in an <code>.rs</code> file:</p>
320  <pre>
321#pragma version(1)
322#pragma rs java_package_name(com.example.renderscript)
323
324...
325
326typedef struct Point {
327      float2 point;
328  } Point_t;
329
330  Point_t *touchPoints;
331  int32_t *intPointer;
332
333...
334</pre>
335
336<p>You cannot allocate memory for these pointers in your RenderScript code, but the Android
337build tools generate classes for you that allow you to allocate memory in the Android VM for use by
338your RenderScript code. These classes also let you read and write to the memory. The next section
339describes how these classes are generated through reflection.</p>
340
341  <h3>How pointers are reflected</h3>
342
343  <p>Global variables have a getter and setter method generated. A global pointer generates a
344  <code>bind_pointerName()</code> method instead of a set() method. This method allows you to bind
345  the memory that is allocated in the Android VM to the native RenderScript. For example, the two
346  pointers in the previous section generate the following accessor methods in the <code>ScriptC_<em>rs_filename</em></code> file:</p>
347  <pre>
348
349    private ScriptField_Point mExportVar_touchPoints;
350    public void bind_touchPoints(ScriptField_Point v) {
351        mExportVar_touchPoints = v;
352        if (v == null) bindAllocation(null, mExportVarIdx_touchPoints);
353        else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints);
354    }
355
356    public ScriptField_Point get_touchPoints() {
357        return mExportVar_touchPoints;
358    }
359
360    private Allocation mExportVar_intPointer;
361    public void bind_intPointer(Allocation v) {
362        mExportVar_intPointer = v;
363        if (v == null) bindAllocation(null, mExportVarIdx_intPointer);
364        else bindAllocation(v, mExportVarIdx_intPointer);
365    }
366
367    public Allocation get_intPointer() {
368        return mExportVar_intPointer;
369    }
370
371</pre>
372
373  <h3>Allocating and binding memory to the RenderScript</h3>
374
375  <p>When the build tools generate the reflected layer, you can use the appropriate class
376  (<code>ScriptField_Point</code>, in our example) to allocate memory for a pointer. To do this,
377  you call the constructor for the {@link android.renderscript.Script.FieldBase} class and specify
378  the amount of structures that you want to allocate memory for. To allocate memory for a primitive
379  type pointer, you must build an allocation manually, using the memory management classes
380  described in <a href="mem-mgmt-table">Table 1</a>. The example below allocates memory for both
381  the <code>intPointer</code> and <code>touchPoints</code> pointer and binds it to the
382  RenderScript:</p>
383  <pre>
384private RenderScriptGL glRenderer;
385private ScriptC_example script;
386private Resources resources;
387
388public void init(RenderScriptGL rs, Resources res) {
389   //get the rendering context and resources from the calling method
390   glRenderer = rs; 
391   resources = res; 
392   
393   //allocate memory for the struct pointer, calling the constructor
394    ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2); 
395    
396   //Create an element manually and allocate memory for the int pointer 
397    intPointer = Allocation.createSized(glRenderer, Element.I32(glRenderer), 2); 
398    
399    //create an instance of the RenderScript, pointing it to the bytecode resource
400    mScript = new ScriptC_example(glRenderer, resources, R.raw.example); 
401    
402    // bind the struct and int pointers to the RenderScript
403    mScript.bind_touchPoints(touchPoints); 
404    script.bind_intPointer(intPointer);
405    
406    //bind the RenderScript to the rendering context
407    glRenderer.bindRootScript(script);
408}
409</pre>
410
411  <h3>Reading and writing to memory</h3>
412
413  <p>Although you have to allocate memory within the Android VM, you can work with the memory both
414  in your native RenderScript code and in your Android code. Once memory is bound, the native
415  RenderScript can read and write to the memory directly. You can also just use the accessor
416  methods in the reflected classes to access the memory. If you modify memory in the Android
417  framework, it gets automatically synchronized to the native layer. If you modify memory in the <code>.rs</code>
418  file, these changes do not get propagated back to the Android framework.
419  For example, you can modify the struct in your Android code like this:</p>
420  <pre>
421int index = 0;
422boolean copyNow = true;
423Float2 point = new Float2(0.0f, 0.0f);
424touchPoints.set_point(index, point, copyNow);
425</pre>then read it in your native RenderScript code like this:
426  <pre>
427rsDebug("Printing out a Point", touchPoints[0].point.x, touchPoints[0].point.y);
428</pre>
429
430  <h2>Working with statically allocated memory</h2>
431
432  <p>Non-static, global primitives and structs that you declare in your RenderScript are easier to work with,
433  because the memory is statically allocated at compile time. Accessor methods to set and get these
434  variables are generated when the Android build tools generate the reflected layer classes. You
435  can get and set these variables using the provided accessor methods.
436 <p class="note"><strong>Note:</strong> The <code>get</code> method comes with a one-way communication restriction. The last value
437  that is set from the Android framework is always returned during a call to a <code>get</code>
438  method. If the native RenderScript code changes the value, the change does not propagate back to
439  the Android framework layer. If the global variables are initialized in the native RenderScript
440  code, those values are used to initialize the corresponding values in the Android framework
441  layer. If global variables are marked as <code>const</code>, then a <code>set</code> method is
442  not generated.</p>
443  </p>
444
445  <p>For example, if you declare the following primitive in your RenderScript code:</p>
446  <pre>
447  uint32_t unsignedInteger = 1;
448  
449</pre>
450<p>then the following code is generated in <code>ScriptC_<em>script_name</em>.java</code>:</p>
451  <pre>
452 private final static int mExportVarIdx_unsignedInteger = 9;
453    private long mExportVar_unsignedInteger;
454    public void set_unsignedInteger(long v) {
455        mExportVar_unsignedInteger = v;
456        setVar(mExportVarIdx_unsignedInteger, v);
457    }
458
459    public long get_unsignedInteger() {
460        return mExportVar_unsignedInteger;
461    }
462</pre>
463
464  <p class="note"><strong>Note:</strong> The mExportVarIdx_unsignedInteger variable represents the
465  index of the <code>unsignedInteger</code>'s in an array of statically allocated primitives. You do
466  not need to work with or be aware of this index.</p>
467  
468  <p>For a <code>struct</code>, the Android build tools generate a class named
469  <code>&lt;project_root&gt;/gen/com/example/renderscript/ScriptField_struct_name</code>. This
470  class represents an array of the <code>struct</code> and allows you to allocate memory for a
471  specified number of <code>struct</code>s. This class defines:</p>
472
473  <ul>
474    <li>Overloaded constructors that allow you to allocate memory. The
475    <code>ScriptField_<em>struct_name</em>(RenderScript rs, int count)</code> constructor allows
476    you to define the number of structures that you want to allocate memory for with the
477    <code>count</code> parameter. The <code>ScriptField_<em>struct_name</em>(RenderScript rs, int
478    count, int usages)</code> constructor defines an extra parameter, <code>usages</code>, that
479    lets you specify the memory space of this memory allocation. There are four memory space
480    possibilities:
481
482      <ul>
483        <li>{@link android.renderscript.Allocation#USAGE_SCRIPT}: Allocates in the script memory
484        space. This is the default memory space if you do not specify a memory space.</li>
485
486        <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}: Allocates in the
487        texture memory space of the GPU.</li>
488
489        <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_VERTEX}: Allocates in the vertex
490        memory space of the GPU.</li>
491
492        <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_CONSTANTS}: Allocates in the
493        constants memory space of the GPU that is used by the various program objects.</li>
494      </ul>
495
496      <p>You can specify one or all of these memory spaces by OR'ing them together. Doing so notifies
497      the RenderScript runtime that you intend on accessing the data in the specified memory spaces. The following
498      example allocates memory for a custom data type in both the script and vertex memory spaces:</p>
499<pre>
500ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2,
501Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);
502</pre>
503
504      <p>If you modify the memory in one memory space and want to push the updates to the rest of
505      the memory spaces, call <code>rsgAllocationSyncAll()</code> in your RenderScript code to
506      synchronize the memory.</p>
507    </li>
508
509    <li>A static nested class, <code>Item</code>, allows you to create an instance of the
510    <code>struct</code>, in the form of an object. This is useful if it makes more sense to work
511    with the <code>struct</code> in your Android code. When you are done manipulating the object,
512    you can push the object to the allocated memory by calling <code>set(Item i, int index, boolean
513    copyNow)</code> and setting the <code>Item</code> to the desired position in the array. The
514    native RenderScript code automatically has access to the newly written memory.
515
516    <li>Accessor methods to get and set the values of each field in a struct. Each of these
517    accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in the
518    array that you want to read or write to. Each setter method also has a <code>copyNow</code>
519    parameter that specifies whether or not to immediately sync this memory to the native
520    RenderScript layer. To sync any memory that has not been synced, call <code>copyAll()</code>.</li>
521
522    <li>The createElement() method creates an object that describes the memory layout of the struct.</li>
523
524    <li>resize() works much like a <code>realloc</code>, allowing you to expand previously
525    allocated memory, maintaining the current values that were previously set.</li>
526
527    <li>copyAll() synchronizes memory that was set on the framework level to the native level. When you call
528    a set accessor method on a member, there is an optional <code>copyNow</code> boolean parameter that you can specify. Specifying
529    <code>true</code> synchronizes the memory when you call the method. If you specify false, you can call <code>copyAll()</code>
530    once, and it synchronizes memory for the all the properties that are not synchronized.</li>
531  </ul>
532
533  <p>The following example shows the reflected class, <code>ScriptField_Point.java</code> that is
534  generated from the Point <code>struct</code>.</p>
535  <pre>
536package com.example.renderscript;
537
538import android.renderscript.*;
539import android.content.res.Resources;
540
541
542public class ScriptField_Point extends android.renderscript.Script.FieldBase {
543    static public class Item {
544        public static final int sizeof = 8;
545
546        Float2 point;
547
548        Item() {
549            point = new Float2();
550        }
551
552    }
553
554    private Item mItemArray[];
555    private FieldPacker mIOBuffer;
556    public static Element createElement(RenderScript rs) {
557        Element.Builder eb = new Element.Builder(rs);
558        eb.add(Element.F32_2(rs), "point");
559        return eb.create();
560    }
561
562    public  ScriptField_Point(RenderScript rs, int count) {
563        mItemArray = null;
564        mIOBuffer = null;
565        mElement = createElement(rs);
566        init(rs, count);
567    }
568
569    public  ScriptField_Point(RenderScript rs, int count, int usages) {
570        mItemArray = null;
571        mIOBuffer = null;
572        mElement = createElement(rs);
573        init(rs, count, usages);
574    }
575
576    private void copyToArray(Item i, int index) {
577        if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
578        mIOBuffer.reset(index * Item.sizeof);
579        mIOBuffer.addF32(i.point);
580    }
581
582    public void set(Item i, int index, boolean copyNow) {
583        if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
584        mItemArray[index] = i;
585        if (copyNow)  {
586            copyToArray(i, index);
587            mAllocation.setFromFieldPacker(index, mIOBuffer);
588        }
589
590    }
591
592    public Item get(int index) {
593        if (mItemArray == null) return null;
594        return mItemArray[index];
595    }
596
597    public void set_point(int index, Float2 v, boolean copyNow) {
598        if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */)fnati;
599        if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
600        if (mItemArray[index] == null) mItemArray[index] = new Item();
601        mItemArray[index].point = v;
602        if (copyNow)  {
603            mIOBuffer.reset(index * Item.sizeof);
604            mIOBuffer.addF32(v);
605            FieldPacker fp = new FieldPacker(8);
606            fp.addF32(v);
607            mAllocation.setFromFieldPacker(index, 0, fp);
608        }
609
610    }
611
612    public Float2 get_point(int index) {
613        if (mItemArray == null) return null;
614        return mItemArray[index].point;
615    }
616
617    public void copyAll() {
618        for (int ct = 0; ct &lt; mItemArray.length; ct++) copyToArray(mItemArray[ct], ct);
619        mAllocation.setFromFieldPacker(0, mIOBuffer);
620    }
621
622    public void resize(int newSize) {
623        if (mItemArray != null)  {
624            int oldSize = mItemArray.length;
625            int copySize = Math.min(oldSize, newSize);
626            if (newSize == oldSize) return;
627            Item ni[] = new Item[newSize];
628            System.arraycopy(mItemArray, 0, ni, 0, copySize);
629            mItemArray = ni;
630        }
631
632        mAllocation.resize(newSize);
633        if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
634    }
635
636}
637</pre>
638
639</body>
640</html>
641