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