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><project_root>/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 < 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