blob: 6a72b979006cc6257a1a62e13444fa9e97bf421f [file] [log] [blame]
Tim Murray015d2682013-05-30 12:34:40 -07001page.title=Advanced RenderScript
Robert Ly864090e2012-06-17 18:22:17 -07002parent.title=Computation
3parent.link=index.html
4
Robert Lyf197b632011-06-08 22:23:42 -07005@jd:body
6
7 <div id="qv-wrapper">
8 <div id="qv">
9 <h2>In this document</h2>
10
11 <ol>
Tim Murray015d2682013-05-30 12:34:40 -070012 <li><a href="#native">RenderScript Runtime Layer</a></li>
Robert Lyb078d942012-01-05 10:50:39 -080013 <li><a href="#reflected">Reflected Layer</a>
Robert Lyf197b632011-06-08 22:23:42 -070014 <ol>
Robert Lyb078d942012-01-05 10:50:39 -080015 <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>
Robert Lyf197b632011-06-08 22:23:42 -070019 </ol>
20 </li>
21
22 <li>
23 <a href="#mem-allocation">Memory Allocation APIs</a>
24 </li>
25 <li>
Robert Lyb078d942012-01-05 10:50:39 -080026 <a href="#memory">Working with Memory</a>
Robert Lyf197b632011-06-08 22:23:42 -070027 <ol>
Tim Murray015d2682013-05-30 12:34:40 -070028 <li><a href="#allocating-mem">Allocating and binding memory to the RenderScript</a></li>
Robert Lyf197b632011-06-08 22:23:42 -070029
Robert Lyb078d942012-01-05 10:50:39 -080030 <li><a href="#read-write">Reading and writing to memory</a></li>
Robert Lyf197b632011-06-08 22:23:42 -070031
32 </ol>
33 </li>
Robert Lyf197b632011-06-08 22:23:42 -070034 </ol>
35 </div>
36 </div>
37
Robert Ly864090e2012-06-17 18:22:17 -070038 <p></p>
Robert Lyf197b632011-06-08 22:23:42 -070039
Tim Murray015d2682013-05-30 12:34:40 -070040 <p>Because applications that utilize RenderScript still run inside of the Android VM,
Robert Ly864090e2012-06-17 18:22:17 -070041 you have access to all of the framework APIs that you are familiar with, but can
Tim Murray015d2682013-05-30 12:34:40 -070042 utilize RenderScript when appropriate. To facilitate this interaction between
43 the framework and the RenderScript runtime, an intermediate layer of code is also
Robert Ly864090e2012-06-17 18:22:17 -070044 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
Tim Murray015d2682013-05-30 12:34:40 -070047 RenderScript runtime.</p>
Robert Lyf197b632011-06-08 22:23:42 -070048
Tim Murray015d2682013-05-30 12:34:40 -070049 <h2 id="native">RenderScript Runtime Layer</h2>
Robert Lyf197b632011-06-08 22:23:42 -070050
Tim Murray015d2682013-05-30 12:34:40 -070051 <p>Your RenderScript code is compiled and
52 executed in a compact and well-defined runtime layer. The RenderScript runtime APIs offer support for
Robert Ly864090e2012-06-17 18:22:17 -070053intensive computation that is portable and automatically scalable to the
Robert Lyb078d942012-01-05 10:50:39 -080054amount of cores available on a processor.
55</p>
56<p class="note"><strong>Note:</strong> The standard C functions in the NDK must be
Tim Murray015d2682013-05-30 12:34:40 -070057 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>
Robert Lyb078d942012-01-05 10:50:39 -080059
Tim Murray015d2682013-05-30 12:34:40 -070060<p>You define your RenderScript code in <code>.rs</code>
Robert Lyb078d942012-01-05 10:50:39 -080061 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
Tim Murray015d2682013-05-30 12:34:40 -070066 device and also cached, so subsequent uses of the RenderScript enabled application does not
Robert Lyb078d942012-01-05 10:50:39 -080067 recompile the bytecode.</p>
68
Tim Murray015d2682013-05-30 12:34:40 -070069 <p>Some key features of the RenderScript runtime libraries include:</p>
Robert Lyf197b632011-06-08 22:23:42 -070070
71 <ul>
Robert Lyf197b632011-06-08 22:23:42 -070072
Robert Lyf197b632011-06-08 22:23:42 -070073 <li>Memory allocation request features</li>
74
Robert Lyb078d942012-01-05 10:50:39 -080075 <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
Robert Ly864090e2012-06-17 18:22:17 -070079 <li>Conversion routines for primitive data types and vectors, matrix routines, and date and time
80 routines</li>
Robert Lyb078d942012-01-05 10:50:39 -080081
Tim Murray015d2682013-05-30 12:34:40 -070082 <li>Data types and structures to support the RenderScript system such as Vector types for
Robert Lyf197b632011-06-08 22:23:42 -070083 defining two-, three-, or four-vectors.</li>
Robert Lyb078d942012-01-05 10:50:39 -080084
85 <li>Logging functions</li>
Robert Lyf197b632011-06-08 22:23:42 -070086 </ul>
87
Tim Murray015d2682013-05-30 12:34:40 -070088 <p>See the RenderScript runtime API reference for more information on the available functions.
Robert Lyb078d942012-01-05 10:50:39 -080089
90 <h2 id="reflected">Reflected Layer</h2>
Robert Lyf197b632011-06-08 22:23:42 -070091
92 <p>The reflected layer is a set of classes that the Android build tools generate to allow access
Tim Murray015d2682013-05-30 12:34:40 -070093 to the RenderScript runtime from the Android framework. This layer also provides methods
Robert Lyb078d942012-01-05 10:50:39 -080094and constructors that allow you to allocate and work with memory for pointers that are defined in
Tim Murray015d2682013-05-30 12:34:40 -070095your RenderScript code. The following list describes the major
Robert Lyf197b632011-06-08 22:23:42 -070096 components that are reflected:</p>
97
98 <ul>
99 <li>Every <code>.rs</code> file that you create is generated into a class named
Robert Lyb078d942012-01-05 10:50:39 -0800100 <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:
Robert Lyf197b632011-06-08 22:23:42 -0700104
105 <ul>
Robert Lyb078d942012-01-05 10:50:39 -0800106 <li>Non-static functions</li>
Robert Lyf197b632011-06-08 22:23:42 -0700107
Tim Murray015d2682013-05-30 12:34:40 -0700108 <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
Robert Lyb078d942012-01-05 10:50:39 -0800111values 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>
Robert Lyf197b632011-06-08 22:23:42 -0700116 </ul>
117 </li>
118
119 <li>A <code>struct</code> is reflected into its own class named
Robert Lyb078d942012-01-05 10:50:39 -0800120
121 <code>project_root/gen/package/name/ScriptField_struct_name</em></code>, which extends {@link
Robert Lyf197b632011-06-08 22:23:42 -0700122 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
Robert Lyf197b632011-06-08 22:23:42 -0700127
Robert Lyb078d942012-01-05 10:50:39 -0800128<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
Tim Murray015d2682013-05-30 12:34:40 -0700131example, if you declare the following function in your RenderScript code:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700132
Robert Lyb078d942012-01-05 10:50:39 -0800133<pre>
134void touch(float x, float y, float pressure, int id) {
135 if (id >= 10) {
136 return;
137 }
Robert Lyf197b632011-06-08 22:23:42 -0700138
Robert Lyb078d942012-01-05 10:50:39 -0800139 touchPos[id].x = x;
140 touchPos[id].y = y;
141 touchPressure[id] = pressure;
142}
Robert Lyf197b632011-06-08 22:23:42 -0700143</pre>
144
Robert Lyb078d942012-01-05 10:50:39 -0800145<p>then the following code is generated:</p>
Robert Lyf197b632011-06-08 22:23:42 -0700146
Robert Lyb078d942012-01-05 10:50:39 -0800147<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>
Tim Murray015d2682013-05-30 12:34:40 -0700158Functions 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
Robert Lyb078d942012-01-05 10:50:39 -0800161interruption and increases efficiency. If functions were allowed to have return values, the call
162would block until the value was returned.</p>
Robert Lyf197b632011-06-08 22:23:42 -0700163
Robert Lyb078d942012-01-05 10:50:39 -0800164<p>
Tim Murray015d2682013-05-30 12:34:40 -0700165If you want the RenderScript code to send a value back to the Android framework, use the
Robert Lyf11ffc112012-02-22 10:59:12 -0800166<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a>
167function.
Robert Lyb078d942012-01-05 10:50:39 -0800168</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
Tim Murray015d2682013-05-30 12:34:40 -0700175your RenderScript code:</p>
Robert Lyb078d942012-01-05 10:50:39 -0800176 <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
Robert Lyf197b632011-06-08 22:23:42 -0700192
Robert Lyb078d942012-01-05 10:50:39 -0800193 <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>
Robert Lyf197b632011-06-08 22:23:42 -0700198<pre>
Robert Lyb078d942012-01-05 10:50:39 -0800199typedef struct Point {
Robert Lyf11ffc112012-02-22 10:59:12 -0800200 float2 position;
201 float size;
Robert Lyb078d942012-01-05 10:50:39 -0800202} Point_t;
Robert Lyf197b632011-06-08 22:23:42 -0700203</pre>
204
Robert Lyb078d942012-01-05 10:50:39 -0800205<p>then the following code is generated in <code>ScriptField_Point.java</code>:
206<pre>
207package com.example.android.rs.hellocompute;
Robert Lyf197b632011-06-08 22:23:42 -0700208
209import android.renderscript.*;
210import android.content.res.Resources;
211
Robert Lyb078d942012-01-05 10:50:39 -0800212 /**
213 * @hide
214 */
Robert Lyf197b632011-06-08 22:23:42 -0700215public class ScriptField_Point extends android.renderscript.Script.FieldBase {
Robert Lyf197b632011-06-08 22:23:42 -0700216
Robert Lyb078d942012-01-05 10:50:39 -0800217 static public class Item {
218 public static final int sizeof = 12;
219
220 Float2 position;
221 float size;
Robert Lyf197b632011-06-08 22:23:42 -0700222
223 Item() {
Robert Lyb078d942012-01-05 10:50:39 -0800224 position = new Float2();
Robert Lyf197b632011-06-08 22:23:42 -0700225 }
Robert Lyf197b632011-06-08 22:23:42 -0700226 }
227
228 private Item mItemArray[];
229 private FieldPacker mIOBuffer;
230 public static Element createElement(RenderScript rs) {
231 Element.Builder eb = new Element.Builder(rs);
Robert Lyb078d942012-01-05 10:50:39 -0800232 eb.add(Element.F32_2(rs), "position");
233 eb.add(Element.F32(rs), "size");
Robert Lyf197b632011-06-08 22:23:42 -0700234 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) {
Robert Lyb078d942012-01-05 10:50:39 -0800252 if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count
253 */);
Robert Lyf197b632011-06-08 22:23:42 -0700254 mIOBuffer.reset(index * Item.sizeof);
Robert Lyb078d942012-01-05 10:50:39 -0800255 mIOBuffer.addF32(i.position);
256 mIOBuffer.addF32(i.size);
Robert Lyf197b632011-06-08 22:23:42 -0700257 }
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 }
Robert Lyf197b632011-06-08 22:23:42 -0700266 }
267
268 public Item get(int index) {
269 if (mItemArray == null) return null;
270 return mItemArray[index];
271 }
272
Robert Lyb078d942012-01-05 10:50:39 -0800273 public void set_position(int index, Float2 v, boolean copyNow) {
274 if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
Robert Lyf197b632011-06-08 22:23:42 -0700275 if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
276 if (mItemArray[index] == null) mItemArray[index] = new Item();
Robert Lyb078d942012-01-05 10:50:39 -0800277 mItemArray[index].position = v;
278 if (copyNow) {
Robert Lyf197b632011-06-08 22:23:42 -0700279 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 }
Robert Lyf197b632011-06-08 22:23:42 -0700285 }
286
Robert Lyb078d942012-01-05 10:50:39 -0800287 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) {
Robert Lyf197b632011-06-08 22:23:42 -0700302 if (mItemArray == null) return null;
Robert Lyb078d942012-01-05 10:50:39 -0800303 return mItemArray[index].position;
304 }
305
306 public float get_size(int index) {
307 if (mItemArray == null) return 0;
308 return mItemArray[index].size;
Robert Lyf197b632011-06-08 22:23:42 -0700309 }
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 }
Robert Lyf197b632011-06-08 22:23:42 -0700325 mAllocation.resize(newSize);
326 if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */);
327 }
Robert Lyf197b632011-06-08 22:23:42 -0700328}
329</pre>
330
Robert Lyb078d942012-01-05 10:50:39 -0800331<p>The generated code is provided to you as a convenience to allocate memory for structs requested
Tim Murray015d2682013-05-30 12:34:40 -0700332by the RenderScript runtime and to interact with <code>struct</code>s
Robert Lyb078d942012-01-05 10:50:39 -0800333in 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
Tim Murray015d2682013-05-30 12:34:40 -0700359 notifies the RenderScript runtime that you intend on accessing the data in the
Robert Lyb078d942012-01-05 10:50:39 -0800360 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>
Tim Murray015d2682013-05-30 12:34:40 -0700363 ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2,
Robert Lyb078d942012-01-05 10:50:39 -0800364 Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);
365 </pre>
Robert Lyb078d942012-01-05 10:50:39 -0800366 </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
Tim Murray015d2682013-05-30 12:34:40 -0700373the array. The RenderScript runtime automatically has access to the newly written memory.
Robert Lyb078d942012-01-05 10:50:39 -0800374
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
Tim Murray015d2682013-05-30 12:34:40 -0700379to the RenderScript runtime. To sync any memory that has not been synced, call
Robert Lyb078d942012-01-05 10:50:39 -0800380 <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
Tim Murray015d2682013-05-30 12:34:40 -0700390RenderScript runtime. When you call a set accessor method on a member, there is an optional
Robert Lyb078d942012-01-05 10:50:39 -0800391<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
Robert Lyf11ffc112012-02-22 10:59:12 -0800397 <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
Tim Murray015d2682013-05-30 12:34:40 -0700400can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a
Robert Lyf11ffc112012-02-22 10:59:12 -0800401<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
Tim Murray015d2682013-05-30 12:34:40 -0700441that is allocated in the Android VM to the RenderScript runtime (you cannot allocate
Robert Lyf11ffc112012-02-22 10:59:12 -0800442memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working
443with Allocated Memory</a>.
444</p>
445
446
Robert Lyb078d942012-01-05 10:50:39 -0800447 <h2 id="mem-allocation">Memory Allocation APIs</h2>
448
Tim Murray015d2682013-05-30 12:34:40 -0700449 <p>Applications that use RenderScript still run in the Android VM. The actual RenderScript code, however, runs natively and
Robert Lyb078d942012-01-05 10:50:39 -0800450 needs access to the memory allocated in the Android VM. To accomplish this, you must
Tim Murray015d2682013-05-30 12:34:40 -0700451 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
Robert Lyb078d942012-01-05 10:50:39 -0800453requests 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
Tim Murray015d2682013-05-30 12:34:40 -0700455share 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>
Robert Lyb078d942012-01-05 10:50:39 -0800457for 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
Tim Murray015d2682013-05-30 12:34:40 -0700482 the resulting memory {@link android.renderscript.Allocation} to the RenderScript.
Robert Lyb078d942012-01-05 10:50:39 -0800483 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
Tim Murray015d2682013-05-30 12:34:40 -0700486 <a href="#allocating-mem">Allocating and binding memory to the RenderScript</a> section.
Robert Lyb078d942012-01-05 10:50:39 -0800487 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
Tim Murray015d2682013-05-30 12:34:40 -0700503 <p>A basic element contains a single component of data of any valid RenderScript data type.
Robert Lyb078d942012-01-05 10:50:39 -0800504 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
Tim Murray015d2682013-05-30 12:34:40 -0700508 <code>struct</code>s that you declare in your RenderScript code. For instance an allocation
Robert Lyb078d942012-01-05 10:50:39 -0800509 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
Tim Murray015d2682013-05-30 12:34:40 -0700555<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
Robert Lyb078d942012-01-05 10:50:39 -0800557memory 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
Tim Murray015d2682013-05-30 12:34:40 -0700559initialized at the RenderScript runtime layer, those values are used to initialize the corresponding
Robert Lyb078d942012-01-05 10:50:39 -0800560values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is
561not generated.</p>
562
563
Tim Murray015d2682013-05-30 12:34:40 -0700564<p class="note"><strong>Note:</strong> If you are using certain RenderScript structures that contain pointers, such as
Robert Lyb078d942012-01-05 10:50:39 -0800565<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
Tim Murray015d2682013-05-30 12:34:40 -0700567structure 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
Robert Lyaf166752012-04-10 10:57:33 -0700569that 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.
Robert Lyb078d942012-01-05 10:50:39 -0800572</p>
573
Tim Murray015d2682013-05-30 12:34:40 -0700574<p>RenderScript also has support for pointers, but you must explicitly allocate the memory in your
Robert Lyb078d942012-01-05 10:50:39 -0800575Android 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
Tim Murray015d2682013-05-30 12:34:40 -0700577RenderScript 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
Robert Lyb078d942012-01-05 10:50:39 -0800579appropriate layer.</p>
580
581
582
Tim Murray015d2682013-05-30 12:34:40 -0700583 <h3 id="allocating-mem">Allocating and binding dynamic memory to the RenderScript</h3>
Robert Lyb078d942012-01-05 10:50:39 -0800584
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
Tim Murray015d2682013-05-30 12:34:40 -0700590 RenderScript runtime.</p>
Robert Lyb078d942012-01-05 10:50:39 -0800591 <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
Tim Murray015d2682013-05-30 12:34:40 -0700593 RenderScript:</p>
Robert Lyb078d942012-01-05 10:50:39 -0800594 <pre>
Tim Murray015d2682013-05-30 12:34:40 -0700595private RenderScript myRenderScript;
Robert Lyb078d942012-01-05 10:50:39 -0800596private ScriptC_example script;
597private Resources resources;
598
Robert Ly864090e2012-06-17 18:22:17 -0700599public void init(RenderScript rs, Resources res) {
Tim Murray015d2682013-05-30 12:34:40 -0700600 myRenderScript = rs;
Robert Lyb078d942012-01-05 10:50:39 -0800601 resources = res;
602
603 //allocate memory for the struct pointer, calling the constructor
Tim Murray015d2682013-05-30 12:34:40 -0700604 ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2);
Robert Lyb078d942012-01-05 10:50:39 -0800605
606 //Create an element manually and allocate memory for the int pointer
Tim Murray015d2682013-05-30 12:34:40 -0700607 intPointer = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2);
Robert Lyb078d942012-01-05 10:50:39 -0800608
Tim Murray015d2682013-05-30 12:34:40 -0700609 //create an instance of the RenderScript, pointing it to the bytecode resource
610 mScript = new ScriptC_example(myRenderScript, resources, R.raw.example);
Robert Lyb078d942012-01-05 10:50:39 -0800611
Tim Murray015d2682013-05-30 12:34:40 -0700612 //bind the struct and int pointers to the RenderScript
Robert Lyb078d942012-01-05 10:50:39 -0800613 mScript.bind_touchPoints(touchPoints);
614 script.bind_intPointer(intPointer);
615
616 ...
617}
618</pre>
619
620 <h3>Reading and writing to memory</h3>
Tim Murray015d2682013-05-30 12:34:40 -0700621 <p>You can read and write to statically and dynamically allocated memory both at the RenderScript runtime
Robert Lyb078d942012-01-05 10:50:39 -0800622 and Android framework layer.</p>
623
624<p>Statically allocated memory comes with a one-way communication restriction
Tim Murray015d2682013-05-30 12:34:40 -0700625at the RenderScript runtime level. When RenderScript code changes the value of a variable, it is not
Robert Lyb078d942012-01-05 10:50:39 -0800626communicated 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
Tim Murray015d2682013-05-30 12:34:40 -0700629the 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
Robert Lyf11ffc112012-02-22 10:59:12 -0800631<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> function
Robert Lyb078d942012-01-05 10:50:39 -0800632to overcome this limitation.
633</p>
Tim Murray015d2682013-05-30 12:34:40 -0700634<p>When working with dynamically allocated memory, any changes at the RenderScript runtime layer are propagated
Robert Lyb078d942012-01-05 10:50:39 -0800635back to the Android framework layer if you modified the memory allocation using its associated pointer.
Tim Murray015d2682013-05-30 12:34:40 -0700636Modifying an object at the Android framework layer immediately propagates that change back to the RenderScript
Robert Lyb078d942012-01-05 10:50:39 -0800637runtime 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
Tim Murray015d2682013-05-30 12:34:40 -0700642 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>
Robert Lyb078d942012-01-05 10:50:39 -0800644
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
Tim Murray015d2682013-05-30 12:34:40 -0700662<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>
Robert Lyb078d942012-01-05 10:50:39 -0800664<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
Tim Murray015d2682013-05-30 12:34:40 -0700675<p>You can read the values in your RenderScript code like this:</p>
Robert Lyb078d942012-01-05 10:50:39 -0800676
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
Tim Murray015d2682013-05-30 12:34:40 -0700683exception if you only set the value at the RenderScript runtime level:</p>
Robert Lyb078d942012-01-05 10:50:39 -0800684
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
Tim Murray015d2682013-05-30 12:34:40 -0700692<p>Assuming that memory has been allocated in the Android framework level and bound to the RenderScript runtime,
Robert Lyb078d942012-01-05 10:50:39 -0800693you can read and write memory from the Android framework level by using the <code>get</code> and <code>set</code> methods for that pointer.
Tim Murray015d2682013-05-30 12:34:40 -0700694In the RenderScript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated
Robert Lyb078d942012-01-05 10:50:39 -0800695back 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
Tim Murray015d2682013-05-30 12:34:40 -0700729<p>Once memory is already bound, you do not have to rebind the memory to the RenderScript
Robert Lyb078d942012-01-05 10:50:39 -0800730runtime every time you make a change to a value.</p>