diff options
Diffstat (limited to 'docs/html/guide/topics/renderscript/index.jd')
-rw-r--r-- | docs/html/guide/topics/renderscript/index.jd | 1075 |
1 files changed, 620 insertions, 455 deletions
diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd index 148705c..b2d9f84 100644 --- a/docs/html/guide/topics/renderscript/index.jd +++ b/docs/html/guide/topics/renderscript/index.jd @@ -1,4 +1,4 @@ -page.title=RenderScript +page.title=Renderscript @jd:body <div id="qv-wrapper"> @@ -6,14 +6,14 @@ page.title=RenderScript <h2>In this document</h2> <ol> - <li><a href="#overview">RenderScript System Overview</a></li> - <li> + <li><a href="#overview">Renderscript Overview</a></li> + <li><a href="#native">Renderscript Runtime Layer</a></li> + <li><a href="#reflected">Reflected Layer</a> <ol> - <li><a href="#native">Native RenderScript layer</a></li> - - <li><a href="#reflected">Reflected layer</a></li> - - <li><a href="#framework">Android framework layer</a></li> + <li><a href="#func">Functions</a></li> + <li><a href="#var">Variables</a></li> + <li><a href="#pointer">Pointers</a></li> + <li><a href="#struct">Structs</a></li> </ol> </li> @@ -21,540 +21,284 @@ page.title=RenderScript <a href="#mem-allocation">Memory Allocation APIs</a> </li> <li> - <a href="#dynamic">Dynamic Memory Allocations</a> + <a href="#memory">Working with Memory</a> <ol> - <li><a href="#pointers">Declaring pointers</a></li> - - <li><a href="#struct-pointer-reflection">How pointers are reflected</a></li> - - <li><a href="#binding">Allocating and binding memory to the RenderScript</a></li> + <li><a href="#allocating-mem">Allocating and binding memory to the Renderscript</a></li> - <li><a href="#read-write-dynamic">Reading and writing to memory</a></li> + <li><a href="#read-write">Reading and writing to memory</a></li> </ol> </li> - <li> - <a href="#static">Static Memory Allocations</a> - </li> </ol> </div> </div> - <p>RenderScript offers a high performance 3D graphics rendering and compute API at the native - level, which you write in the C (C99 standard). The main advantages of RenderScript are:</p> + <p>Renderscript offers a high performance 3D graphics rendering and compute API at the native + level that you write in C (C99 standard). The main advantages of Renderscript are:</p> <ul> - <li>Portability: RenderScript is designed to run on many types of devices with different CPU - and GPU architectures. It supports all of these architectures without having to target each - device, because the code is compiled and cached on the device at runtime.</li> + <li>Portability: Renderscript is designed to run on many types of devices with different + processor (CPU, GPU, and DSP for instance) architectures. It supports all of these architectures without + having to target each device, because the code is compiled and cached on the device + at runtime.</li> - <li>Performance: RenderScript provides similar performance to OpenGL with the NDK while - offering the portability of the OpenGL APIs provided by the Android framework ({@link - android.opengl}). In addition, it also offers a high performance compute API that is not - offered by OpenGL.</li> + <li>Performance: Renderscript provides similar performance to OpenGL with the NDK and also + provides a high performance compute API that is not offered by OpenGL.</li> - <li>Usability: RenderScript simplifies development when possible, such as eliminating JNI glue code + <li>Usability: Renderscript simplifies development when possible, such as eliminating JNI glue code and simplifying mesh setup.</li> </ul> <p>The main disadvantages are:</p> <ul> - <li>Development complexity: RenderScript introduces a new set of APIs that you have to learn. - RenderScript also handles memory differently compared to OpenGL with the Android framework APIs - or NDK.</li> + <li>Development complexity: Renderscript introduces a new set of APIs that you have to learn. + Renderscript also allocates memory differently compared to OpenGL with the Android framework APIs. + However, these issues are not hard to understand and Renderscript offers many features that + make it easier than OpenGL to initialize rendering.</li> - <li>Debugging visibility: RenderScript can potentially execute (planned feature for later releases) - on processors other than the main CPU (such as the GPU), so if this occurs, debugging becomes more difficult. + <li>Debugging visibility: Renderscript can potentially execute (planned feature for later releases) + on processors other than the main CPU (such as the GPU), so if this occurs, debugging becomes more difficult. </li> - - <li>Less features: RenderScript does not provide as many features as OpenGL such as all the compressed - texture formats or GL extensions.</li> </ul> - <p>You need to consider all of the aspects of RenderScript before deciding when to use it. The following list describes - general guidelines on when to use OpenGL (framework APIs or NDK) or RenderScript:</p> - <ul> - <li>If you are doing simple graphics rendering and performance is not critical, you probably want to use the - Android framework OpenGL APIs, which still provide adequate performance, to eliminate the added coding and debugging complexity of - RenderScript.</li> - - <li>If you want the most flexibility and features while maintaining relatively good debugging - support, you probably want to use OpenGL and the NDK. Applications that require this are high end - or complicated games, for example.</li> - - <li>If you want a solution that is portable, has good performance, - and you don't need the full feature set of OpenGL, RenderScript is a good solution. If you also - need a high performance compute language, then RenderScript offers that as well. - Good candidates for RenderScript are graphics intensive UIs that require 3D rendering, live wallpapers, - or applications that require intensive mathematical computation.</li> - </ul> - <p>For an example of RenderScript in action, install the RenderScript sample applications that + <p>For an example of Renderscript in action, install the Renderscript sample applications that are shipped with the SDK in <code><sdk_root>/samples/android-11/RenderScript</code>. - You can also see a typical use of RenderScript with the 3D carousel view in the Android 3.x + You can also see a typical use of Renderscript with the 3D carousel view in the Android 3.x versions of Google Books and YouTube.</p> - <h2 id="overview">RenderScript System Overview</h2> - - <p>The RenderScript system adopts a control and slave architecture where the low-level native + <h2 id="overview">Renderscript Overview</h2> + <p>The Renderscript runtime operates at the native level and still needs to communicate +with the Android VM, so the way a Renderscript application is setup is different from a pure VM +application. An application that uses Renderscript is still a traditional Android application that +runs in the VM, but you write Renderscript code for the parts of your program that require +it. Using Renderscript can be as simple as offloading a few math calculations or as complicated as +rendering an entire 3D game. No matter what you use it for, Renderscript remains platform +independent, so you do not have to target multiple architectures (for example, +ARM v5, ARM v7, x86).</p> + + <p>The Renderscript system adopts a control and slave architecture where the low-level Renderscript runtime code is controlled by the higher level Android system that runs in a virtual machine (VM). The - Android VM still retains all control of memory and lifecycle management and calls the native - RenderScript code when necessary. The native code is compiled to intermediate bytecode (LLVM) and - packaged inside your application's <code>.apk</code> file. On the device, the bytecode is - compiled (just-in-time) to machine code that is further optimized for the device that it is - running on. The compiled code on the device is cached, so subsequent uses of the RenderScript - enabled application do not recompile the intermediate code. RenderScript has three layers of code - to enable communication between the native and Android framework code:</p> + Android VM still retains all control of memory management and binds memory that it allocates to + the Renderscript runtime, so the Renderscript code can access it. The Android framework makes +asynchronous calls to Renderscript, and the calls are placed in a message queue and processed +as soon as possible. Figure 1 shows how the Renderscript system is structured.</p> + + <img id="figure1" src="{@docRoot}images/rs_overview.png" /> + <p class="img-caption"><strong>Figure 1.</strong> Renderscript system overview</p> + + <p>When using Renderscript, there are three layers of APIs that enable communication between the + Renderscript runtime and Android framework code:</p> <ul> - <li>The native RenderScript layer does the intensive computation or graphics rendering. You - define your native code in <code>.rs</code> and <code>.rsh</code> files.</li> - - <li>The reflected layer is a set of classes that are reflected from the native code. It is basically - a wrapper around the native code that allows the Android framework to interact with native RenderScripts. - The Android build tools automatically generate the classes for this layer during - the build process and eliminates the need to write JNI glue code, like with the NDK.</li> - - <li>The Android framework layer is comprised of the Android framework - APIs, which include the {@link android.renderscript} package. This layer gives high level commands - like, "rotate the view" or "filter the bitmap", by calling the reflected layer, which in turn calls - the native layer. </li> + <li>The Renderscript runtime APIs allow you to do the computation or graphics rendering + that is required by your application.</li> + + <li>The reflected layer APIs are a set of classes that are reflected from your Renderscript +runtime code. It is basically a wrapper around the Renderscript code that allows the Android +framework to interact with the Renderscript runtime. The Android build tools automatically generate the +classes for this layer during the build process. These classes eliminate the need to write JNI glue +code, like with the NDK.</li> + + <li>The Android framework APIs, which include the {@link android.renderscript} package, allow you to + build your application using traditional Android components such as activities and views. When + using Renderscript, this layer calls the reflected layer to access the Renderscript + runtime.</li> </ul> - <h3 id="native">Native RenderScript layer</h3> + <p></p> - <p>The native RenderScript layer consists of your RenderScript code, which is compiled and - executed in a compact and well defined runtime. Your RenderScript code has access to a limited - amount of functions because it cannot access the NDK or standard C functions, since they must be guaranteed to - run on a standard CPU. The RenderScript runtime was designed to run on different types of processors, - which may not be the CPU, so it cannot guarantee support for standard C libraries. What - RenderScript does offer is an API that supports intensive computation and graphics rendering with a collection of math - and graphics APIs.</p> + <h2 id="native">Renderscript Runtime Layer</h2> - <p>Some key features of the native RenderScript libraries include:</p> + <p>Your Renderscript code is compiled and + executed in a compact and well-defined runtime layer. The Renderscript runtime APIs offer support for +intensive computation and graphics rendering that is portable and automatically scalable to the +amount of cores available on a processor. +</p> +<p class="note"><strong>Note:</strong> The standard C functions in the NDK must be + guaranteed to run on a CPU, so Renderscript cannot access these libraries, + because Renderscript is designed to run on different types of processors.</p> - <ul> - <li>A large collection of math functions with both scalar and vector typed overloaded versions - of many common routines. Operations such as adding, multiplying, dot product, and cross product - are available.</li> +<p>You define your Renderscript code in <code>.rs</code> + and <code>.rsh</code> files in the <code>src/</code> directory of your Android project. The code + is compiled to intermediate bytecode by the + <code>llvm</code> compiler that runs as part of an Android build. When your application + runs on a device, the bytecode is then compiled (just-in-time) to machine code by another + <code>llvm</code> compiler that resides on the device. The machine code is optimized for the + device and also cached, so subsequent uses of the Renderscript enabled application does not + recompile the bytecode.</p> - <li>Conversion routines for primitive data types and vectors, matrix routines, date and time - routines, and graphics routines.</li> + <p>Some key features of the Renderscript runtime libraries include:</p> - <li>Logging functions</li> + <ul> <li>Graphics rendering functions</li> <li>Memory allocation request features</li> - <li>Data types and structures to support the RenderScript system such as Vector types for + <li>A large collection of math functions with both scalar and vector typed overloaded versions + of many common routines. Operations such as adding, multiplying, dot product, and cross product + are available as well as atomic arithmetic and comparison functions.</li> + + <li>Conversion routines for primitive data types and vectors, matrix routines, date and time + routines, and graphics routines.</li> + + <li>Data types and structures to support the Renderscript system such as Vector types for defining two-, three-, or four-vectors.</li> + + <li>Logging functions</li> </ul> - <p>The RenderScript header files and LLVM front-end libraries are located in the <code>include/</code> and - <code>clang-include/</code> directories in the - <code><sdk_root>/platforms/android-11/renderscript/</code> directory of the Android SDK. The - headers are automatically included for you, except for the RenderScript graphics specific header file, which + <p>See the Renderscript runtime API reference for more information on the available functions. The + Renderscript header files are automatically included for you, except for the Renderscript graphics header file, which you can include as follows:</p> - <pre> -#include "rs_graphics.rsh" -</pre> - <h3 id="reflected">Reflected layer</h3> +<pre>#include "rs_graphics.rsh"</pre> + + <h2 id="reflected">Reflected Layer</h2> <p>The reflected layer is a set of classes that the Android build tools generate to allow access - to the native RenderScript code from the Android VM. This layer defines entry points for - RenderScript functions and variables, so that you can interact with them with the Android - framework. This layer also provides methods and constructors that allow you to allocate memory - for pointers that are defined in your RenderScript code. The following list describes the major + to the Renderscript runtime from the Android framework. This layer also provides methods +and constructors that allow you to allocate and work with memory for pointers that are defined in +your Renderscript code. The following list describes the major components that are reflected:</p> <ul> <li>Every <code>.rs</code> file that you create is generated into a class named - <code>ScriptC_<em>renderscript_filename</em></code> of type {@link - android.renderscript.ScriptC}. This is the <code>.java</code> version of your <code>.rs</code> - file, which you can call from the Android framework. This class contains the following - reflections: + <code>project_root/gen/package/name/ScriptC_<em>renderscript_filename</em></code> of +type {@link android.renderscript.ScriptC}. This file is the <code>.java</code> version of your +<code>.rs</code> file, which you can call from the Android framework. This class contains the +following items reflected from the <code>.rs</code> file: <ul> - <li>Non-static functions in your <code>.rs</code> file.</li> - - <li>Non-static, global RenderScript variables. Accessor methods are generated for each - variable, so you can read and write the natively declared variables from the Android - framework. The <code>get</code> method comes with a one-way communication restriction. The - last value that is set from the Android framework is always returned during a call to a - <code>get</code> method. If the native RenderScript code changes the value, the change does - not propagate back to the Android framework layer. - If the global variables are initialized - in the native RenderScript code, those values are used to initialize the corresponding - values in the Android framework layer. If global variables are marked as - <code>const</code>, then a <code>set</code> method is not generated.</li> - <li>Global pointers generate a special method named <code>bind_<em>pointer_name</em></code> - instead of a <code>set()</code> method. This method allows you to bind the memory that is - allocated in the Android VM for the pointer to the native RenderScript (you cannot allocate - memory in your <code>.rs</code> file). You can read and write to this memory from both the - Android framework and RenderScript code. For more information, see <a href="mem-mgmt">Working - with Memory and Data</a></li> + <li>Non-static functions</li> + + <li>Non-static, global Renderscript variables. Accessor methods are generated for each + variable, so you can read and write the Renderscript variables from the Android + framework. If a global variable is initialized at the Renderscript runtime layer, those +values are used to initialize the corresponding values in the Android framework layer. If global +variables are marked as <code>const</code>, then a <code>set</code> method is not +generated.</p></li> + + <li>Global pointers</li> </ul> </li> <li>A <code>struct</code> is reflected into its own class named - <code>ScriptField_<em>struct_name</em></code>, which extends {@link + + <code>project_root/gen/package/name/ScriptField_struct_name</em></code>, which extends {@link android.renderscript.Script.FieldBase}. This class represents an array of the <code>struct</code>, which allows you to allocate memory for one or more instances of this <code>struct</code>.</li> </ul> - <h3 id="framework">Android framework layer</h3> - - <p>The Android framework layer consists of the usual Android framework APIs, which include the - RenderScript APIs in {@link android.renderscript}. This layer handles things such as the - Activity lifecycle and memory management of your application. It issues high level commands to - the native RenderScript code through the reflected layer and receives events from the user such - as touch and input events and relays them to your RenderScript code, if needed. - </p> - - <h2 id="mem-allocation">Memory Allocation APIs</h2> - - <p>Before you begin writing your first RenderScript application, you must understand how - memory is allocated for your RenderScript code and how data is shared between the native and VM - spaces. RenderScript allows you to access allocated memory in both the native layer - and Android system layer. All dynamic and static memory is allocated by the Android VM. - The Android VM also does reference counting and garbage collection for you. - You can also explicitly free memory that you no longer need.</p> - - <p class="note"><strong>Note:</strong> To declare temporary memory in your native RenderScript - code without allocating it in the Android VM, you can still do things like instantiate a scratch - buffer using an array.</p> - - <p>The following classes support the memory management features of RenderScript in the Android - VM. You normally do not need to work with these classes directly, because the reflected layer - classes provide constructors and methods that set up the memory allocation for you. There are - some situations where you would want to use these classes directly to allocate memory on your - own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to - primitive types.</p> - - <table id="mem-mgmt-table"> - <tr> - <th>Android Object Type</th> - - <th>Description</th> - </tr> - - <tr> - <td>{@link android.renderscript.Element}</td> - - <td> - <p>An element represents one cell of a memory allocation and can have two forms: Basic or - Complex.</p> - - <p>A basic element contains a single component of data of any valid RenderScript data type. - Examples of basic element data types include a single float value, a float4 vector, or a - single RGB-565 color.</p> - - <p>Complex elements contain a list of basic elements and are created from - <code>struct</code>s that you declare in your RenderScript code. The most basic primitive - type determines the data alignment of the memory. For example, a float4 vector subelement - is alligned to <code>sizeof(float)</code> and not <code>sizeof(float4)</code>. The ordering - of the elements in memory are the order in which they were added, with each component - aligned as necessary.</p> - </td> - </tr> - - <tr> - <td>{@link android.renderscript.Type}</td> - <td> - A type is a memory allocation template and consists of an element and one or more - dimensions. It describes the layout of the memory (basically an array of {@link - android.renderscript.Element}s) but does not allocate the memory for the data that it - describes. - - <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube - map). You can assign the X,Y,Z dimensions to any positive integer value within the - constraints of available memory. A single dimension allocation has an X dimension of - greater than zero while the Y and Z dimensions are zero to indicate not present. For - example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is - considered one dimensional. The LOD and Faces dimensions are booleans to indicate present - or not present.</p> - </td> - </tr> - - <tr> - <td>{@link android.renderscript.Allocation}</td> +<h3 id="func">Functions</h3> +<p>Functions are reflected into the script class itself, located in +<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For +example, if you declare the following function in your Renderscript code:</p> - <td> - <p>An allocation provides the memory for applications based on a description of the memory - that is represented by a {@link android.renderscript.Type}. Allocated memory can exist in - many memory spaces concurrently. If memory is modified in one space, you must explicitly - synchronize the memory, so that it is updated in all the other spaces that it exists - in.</p> - - <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked. - For simple arrays there are <code>copyFrom()</code> functions that take an array from the - Android system and copy it to the native layer memory store. The unchecked variants allow - the Android system to copy over arrays of structures because it does not support - structures. For example, if there is an allocation that is an array of n floats, the data - contained in a float[n] array or a byte[n*4] array can be copied.</p> - </td> - </tr> - </table> - - <h2 id="dynamic">Working with dynamic memory allocations</h2> - - <p>RenderScript has support for pointers, but you must allocate the memory in your Android framework - code. When you declare a global pointer in your <code>.rs</code> file, you allocate memory - through the appropriate reflected layer class and bind that memory to the native - RenderScript layer. You can read and write to this memory from the Android framework layer as well as the - RenderScript layer, which offers you the flexibility to modify variables in the most appropriate - layer. The following sections show you how to work with pointers, allocate memory for them, and - read and write to the memory.</p> - - <h3 id="pointers">Declaring pointers</h3> - - <p>Because RenderScript is written in C99, declaring a pointer is done in a familiar way. You can - declare pointers to a <code>struct</code> or a primitive type, but a <code>struct</code> cannot - contain pointers or nested arrays. The following code declares a <code>struct</code>, a pointer - to that <code>struct</code>, and a pointer of primitive type <code>int32_t</code> in an <code>.rs</code> file:</p> - <pre> -#pragma version(1) -#pragma rs java_package_name(com.example.renderscript) - -... - -typedef struct Point { - float2 point; - } Point_t; - - Point_t *touchPoints; - int32_t *intPointer; - -... -</pre> - -<p>You cannot allocate memory for these pointers in your RenderScript code, but the Android -build tools generate classes for you that allow you to allocate memory in the Android VM for use by -your RenderScript code. These classes also let you read and write to the memory. The next section -describes how these classes are generated through reflection.</p> - - <h3>How pointers are reflected</h3> - - <p>Global variables have a getter and setter method generated. A global pointer generates a - <code>bind_pointerName()</code> method instead of a set() method. This method allows you to bind - the memory that is allocated in the Android VM to the native RenderScript. For example, the two - pointers in the previous section generate the following accessor methods in the <code>ScriptC_<em>rs_filename</em></code> file:</p> - <pre> - - private ScriptField_Point mExportVar_touchPoints; - public void bind_touchPoints(ScriptField_Point v) { - mExportVar_touchPoints = v; - if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); - else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints); - } - - public ScriptField_Point get_touchPoints() { - return mExportVar_touchPoints; - } - - private Allocation mExportVar_intPointer; - public void bind_intPointer(Allocation v) { - mExportVar_intPointer = v; - if (v == null) bindAllocation(null, mExportVarIdx_intPointer); - else bindAllocation(v, mExportVarIdx_intPointer); - } - - public Allocation get_intPointer() { - return mExportVar_intPointer; +<pre> +void touch(float x, float y, float pressure, int id) { + if (id >= 10) { + return; } -</pre> - - <h3>Allocating and binding memory to the RenderScript</h3> - - <p>When the build tools generate the reflected layer, you can use the appropriate class - (<code>ScriptField_Point</code>, in our example) to allocate memory for a pointer. To do this, - you call the constructor for the {@link android.renderscript.Script.FieldBase} class and specify - the amount of structures that you want to allocate memory for. To allocate memory for a primitive - type pointer, you must build an allocation manually, using the memory management classes - described in <a href="mem-mgmt-table">Table 1</a>. The example below allocates memory for both - the <code>intPointer</code> and <code>touchPoints</code> pointer and binds it to the - RenderScript:</p> - <pre> -private RenderScriptGL glRenderer; -private ScriptC_example script; -private Resources resources; - -public void init(RenderScriptGL rs, Resources res) { - //get the rendering context and resources from the calling method - glRenderer = rs; - resources = res; - - //allocate memory for the struct pointer, calling the constructor - ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2); - - //Create an element manually and allocate memory for the int pointer - intPointer = Allocation.createSized(glRenderer, Element.I32(glRenderer), 2); - - //create an instance of the RenderScript, pointing it to the bytecode resource - mScript = new ScriptC_example(glRenderer, resources, R.raw.example); - - // bind the struct and int pointers to the RenderScript - mScript.bind_touchPoints(touchPoints); - script.bind_intPointer(intPointer); - - //bind the RenderScript to the rendering context - glRenderer.bindRootScript(script); + touchPos[id].x = x; + touchPos[id].y = y; + touchPressure[id] = pressure; } </pre> - <h3>Reading and writing to memory</h3> - - <p>Although you have to allocate memory within the Android VM, you can work with the memory both - in your native RenderScript code and in your Android code. Once memory is bound, the native - RenderScript can read and write to the memory directly. You can also just use the accessor - methods in the reflected classes to access the memory. If you modify memory in the Android - framework, it gets automatically synchronized to the native layer. If you modify memory in the <code>.rs</code> - file, these changes do not get propagated back to the Android framework. - For example, you can modify the struct in your Android code like this:</p> - <pre> -int index = 0; -boolean copyNow = true; -Float2 point = new Float2(0.0f, 0.0f); -touchPoints.set_point(index, point, copyNow); -</pre>then read it in your native RenderScript code like this: - <pre> -rsDebug("Printing out a Point", touchPoints[0].point.x, touchPoints[0].point.y); -</pre> +<p>then the following code is generated:</p> - <h2>Working with statically allocated memory</h2> - - <p>Non-static, global primitives and structs that you declare in your RenderScript are easier to work with, - because the memory is statically allocated at compile time. Accessor methods to set and get these - variables are generated when the Android build tools generate the reflected layer classes. You - can get and set these variables using the provided accessor methods. - <p class="note"><strong>Note:</strong> The <code>get</code> method comes with a one-way communication restriction. The last value - that is set from the Android framework is always returned during a call to a <code>get</code> - method. If the native RenderScript code changes the value, the change does not propagate back to - the Android framework layer. If the global variables are initialized in the native RenderScript - code, those values are used to initialize the corresponding values in the Android framework - layer. If global variables are marked as <code>const</code>, then a <code>set</code> method is - not generated.</p> - </p> - - <p>For example, if you declare the following primitive in your RenderScript code:</p> - <pre> - uint32_t unsignedInteger = 1; - +<pre> +public void invoke_touch(float x, float y, float pressure, int id) { + FieldPacker touch_fp = new FieldPacker(16); + touch_fp.addF32(x); + touch_fp.addF32(y); + touch_fp.addF32(pressure); + touch_fp.addI32(id); + invoke(mExportFuncIdx_touch, touch_fp); +} </pre> -<p>then the following code is generated in <code>ScriptC_<em>script_name</em>.java</code>:</p> - <pre> - private final static int mExportVarIdx_unsignedInteger = 9; - private long mExportVar_unsignedInteger; - public void set_unsignedInteger(long v) { - mExportVar_unsignedInteger = v; - setVar(mExportVarIdx_unsignedInteger, v); - } +<p> +Functions cannot have a return value, because the Renderscript system is designed to be +asynchronous. When your Android framework code calls into Renderscript, the call is queued and is +executed when possible. This restriction allows the Renderscript system to function without constant +interruption and increases efficiency. If functions were allowed to have return values, the call +would block until the value was returned.</p> - public long get_unsignedInteger() { - return mExportVar_unsignedInteger; - } -</pre> +<p> +If you want the Renderscript code to send a value back to the Android framework, use the +<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> +function. +</p> - <p class="note"><strong>Note:</strong> The mExportVarIdx_unsignedInteger variable represents the - index of the <code>unsignedInteger</code>'s in an array of statically allocated primitives. You do - not need to work with or be aware of this index.</p> - - <p>For a <code>struct</code>, the Android build tools generate a class named - <code><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This - class represents an array of the <code>struct</code> and allows you to allocate memory for a - specified number of <code>struct</code>s. This class defines:</p> +<h3 id="var">Variables</h3> - <ul> - <li>Overloaded constructors that allow you to allocate memory. The - <code>ScriptField_<em>struct_name</em>(RenderScript rs, int count)</code> constructor allows - you to define the number of structures that you want to allocate memory for with the - <code>count</code> parameter. The <code>ScriptField_<em>struct_name</em>(RenderScript rs, int - count, int usages)</code> constructor defines an extra parameter, <code>usages</code>, that - lets you specify the memory space of this memory allocation. There are four memory space - possibilities: + <p>Variables of supported types are reflected into the script class itself, located in +<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor +methods are generated for each variable. For example, if you declare the following variable in +your Renderscript code:</p> + <pre>uint32_t unsignedInteger = 1;</pre> - <ul> - <li>{@link android.renderscript.Allocation#USAGE_SCRIPT}: Allocates in the script memory - space. This is the default memory space if you do not specify a memory space.</li> + <p>then the following code is generated:</p> - <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}: Allocates in the - texture memory space of the GPU.</li> +<pre> +private long mExportVar_unsignedInteger; +public void set_unsignedInteger(long v){ + mExportVar_unsignedInteger = v; + setVar(mExportVarIdx_unsignedInteger, v); +} - <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_VERTEX}: Allocates in the vertex - memory space of the GPU.</li> +public long get_unsignedInteger(){ + return mExportVar_unsignedInteger; +} + </pre> - <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_CONSTANTS}: Allocates in the - constants memory space of the GPU that is used by the various program objects.</li> - </ul> - <p>You can specify one or all of these memory spaces by OR'ing them together. Doing so notifies - the RenderScript runtime that you intend on accessing the data in the specified memory spaces. The following - example allocates memory for a custom data type in both the script and vertex memory spaces:</p> + <h3 id="struct">Structs</h3> + <p>Structs are reflected into their own classes, located in + <code><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This + class represents an array of the <code>struct</code> and allows you to allocate memory for a + specified number of <code>struct</code>s. For example, if you declare the following struct:</p> <pre> -ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2, -Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX); +typedef struct Point { + float2 position; + float size; +} Point_t; </pre> - <p>If you modify the memory in one memory space and want to push the updates to the rest of - the memory spaces, call <code>rsgAllocationSyncAll()</code> in your RenderScript code to - synchronize the memory.</p> - </li> - - <li>A static nested class, <code>Item</code>, allows you to create an instance of the - <code>struct</code>, in the form of an object. This is useful if it makes more sense to work - with the <code>struct</code> in your Android code. When you are done manipulating the object, - you can push the object to the allocated memory by calling <code>set(Item i, int index, boolean - copyNow)</code> and setting the <code>Item</code> to the desired position in the array. The - native RenderScript code automatically has access to the newly written memory. - - <li>Accessor methods to get and set the values of each field in a struct. Each of these - accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in the - array that you want to read or write to. Each setter method also has a <code>copyNow</code> - parameter that specifies whether or not to immediately sync this memory to the native - RenderScript layer. To sync any memory that has not been synced, call <code>copyAll()</code>.</li> - - <li>The createElement() method creates an object that describes the memory layout of the struct.</li> - - <li>resize() works much like a <code>realloc</code>, allowing you to expand previously - allocated memory, maintaining the current values that were previously set.</li> - - <li>copyAll() synchronizes memory that was set on the framework level to the native level. When you call - a set accessor method on a member, there is an optional <code>copyNow</code> boolean parameter that you can specify. Specifying - <code>true</code> synchronizes the memory when you call the method. If you specify false, you can call <code>copyAll()</code> - once, and it synchronizes memory for the all the properties that are not synchronized.</li> - </ul> - - <p>The following example shows the reflected class, <code>ScriptField_Point.java</code> that is - generated from the Point <code>struct</code>.</p> - <pre> -package com.example.renderscript; +<p>then the following code is generated in <code>ScriptField_Point.java</code>: +<pre> +package com.example.android.rs.hellocompute; import android.renderscript.*; import android.content.res.Resources; - + /** + * @hide + */ public class ScriptField_Point extends android.renderscript.Script.FieldBase { + static public class Item { - public static final int sizeof = 8; + public static final int sizeof = 12; - Float2 point; + Float2 position; + float size; Item() { - point = new Float2(); + position = new Float2(); } - } private Item mItemArray[]; private FieldPacker mIOBuffer; public static Element createElement(RenderScript rs) { Element.Builder eb = new Element.Builder(rs); - eb.add(Element.F32_2(rs), "point"); + eb.add(Element.F32_2(rs), "position"); + eb.add(Element.F32(rs), "size"); return eb.create(); } @@ -573,9 +317,11 @@ public class ScriptField_Point extends android.renderscript.Script.FieldBase { } private void copyToArray(Item i, int index) { - if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); + if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count + */); mIOBuffer.reset(index * Item.sizeof); - mIOBuffer.addF32(i.point); + mIOBuffer.addF32(i.position); + mIOBuffer.addF32(i.size); } public void set(Item i, int index, boolean copyNow) { @@ -585,7 +331,6 @@ public class ScriptField_Point extends android.renderscript.Script.FieldBase { copyToArray(i, index); mAllocation.setFromFieldPacker(index, mIOBuffer); } - } public Item get(int index) { @@ -593,24 +338,42 @@ public class ScriptField_Point extends android.renderscript.Script.FieldBase { return mItemArray[index]; } - public void set_point(int index, Float2 v, boolean copyNow) { - if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */)fnati; + public void set_position(int index, Float2 v, boolean copyNow) { + if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); - mItemArray[index].point = v; - if (copyNow) { + mItemArray[index].position = v; + if (copyNow) { mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 0, fp); } + } + public void set_size(int index, float v, boolean copyNow) { + if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); + if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; + if (mItemArray[index] == null) mItemArray[index] = new Item(); + mItemArray[index].size = v; + if (copyNow) { + mIOBuffer.reset(index * Item.sizeof + 8); + mIOBuffer.addF32(v); + FieldPacker fp = new FieldPacker(4); + fp.addF32(v); + mAllocation.setFromFieldPacker(index, 1, fp); + } } - public Float2 get_point(int index) { + public Float2 get_position(int index) { if (mItemArray == null) return null; - return mItemArray[index].point; + return mItemArray[index].position; + } + + public float get_size(int index) { + if (mItemArray == null) return 0; + return mItemArray[index].size; } public void copyAll() { @@ -627,13 +390,415 @@ public class ScriptField_Point extends android.renderscript.Script.FieldBase { System.arraycopy(mItemArray, 0, ni, 0, copySize); mItemArray = ni; } - mAllocation.resize(newSize); if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); } +} +</pre> + +<p>The generated code is provided to you as a convenience to allocate memory for structs requested +by the Renderscript runtime and to interact with <code>struct</code>s +in memory. Each <code>struct</code>'s class defines the following methods and constructors:</p> + + <ul> + <li>Overloaded constructors that allow you to allocate memory. The + <code>ScriptField_<em>struct_name</em>(RenderScript rs, int count)</code> constructor allows + you to define the number of structures that you want to allocate memory for with the + <code>count</code> parameter. The <code>ScriptField_<em>struct_name</em>(RenderScript rs, int + count, int usages)</code> constructor defines an extra parameter, <code>usages</code>, that + lets you specify the memory space of this memory allocation. There are four memory space + possibilities: + + <ul> + <li>{@link android.renderscript.Allocation#USAGE_SCRIPT}: Allocates in the script memory + space. This is the default memory space if you do not specify a memory space.</li> + + <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}: Allocates in the + texture memory space of the GPU.</li> + + <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_VERTEX}: Allocates in the vertex + memory space of the GPU.</li> + + <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_CONSTANTS}: Allocates in the + constants memory space of the GPU that is used by the various program objects.</li> + </ul> + + <p>You can specify multiple memory spaces by using the bitwise <code>OR</code> operator. Doing so + notifies the Renderscript runtime that you intend on accessing the data in the + specified memory spaces. The following example allocates memory for a custom data type + in both the script and vertex memory spaces:</p> + <pre> + ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2, + Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX); + </pre> + + <p>If you modify the memory in one memory space and want to push the updates to the rest of + the memory spaces, call <a href="{@docRoot}reference/renderscript/rs__graphics_8rsh.html"> + <code>rsgAllocationSyncAll()</code></a> in your Renderscript code to + synchronize the memory.</p> + </li> + + <li>A static nested class, <code>Item</code>, allows you to create an instance of the + <code>struct</code>, in the form of an object. This nested class is useful if it makes more sense to work + with the <code>struct</code> in your Android code. When you are done manipulating the object, + you can push the object to the allocated memory by calling <code>set(Item i, int index, + boolean copyNow)</code> and setting the <code>Item</code> to the desired position in +the array. The Renderscript runtime automatically has access to the newly written memory. + + <li>Accessor methods to get and set the values of each field in a struct. Each of these + accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in + the array that you want to read or write to. Each setter method also has a +<code>copyNow</code> parameter that specifies whether or not to immediately sync this memory +to the Renderscript runtime. To sync any memory that has not been synced, call + <code>copyAll()</code>.</li> + + <li>The <code>createElement()</code> method creates a description of the struct in memory. This + description is used to allocate memory consisting of one or many elements.</li> + + <li><code>resize()</code> works much like a <code>realloc()</code> in C, allowing you to +expand previously allocated memory, maintaining the current values that were previously +created.</li> + + <li><code>copyAll()</code> synchronizes memory that was set on the framework level to the +Renderscript runtime. When you call a set accessor method on a member, there is an optional +<code>copyNow</code> boolean parameter that you can specify. Specifying + <code>true</code> synchronizes the memory when you call the method. If you specify false, + you can call <code>copyAll()</code> once, and it synchronizes memory for all the +properties that are not yet synchronized.</li> + </ul> + + <h3 id="pointer">Pointers</h3> + <p>Pointers are reflected into the script class itself, located in +<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You +can declare pointers to a <code>struct</code> or any of the supported Renderscript types, but a +<code>struct</code> cannot contain pointers or nested arrays. For example, if you declare the +following pointers to a <code>struct</code> and <code>int32_t</code></p> + +<pre> +typedef struct Point { + float2 position; + float size; +} Point_t; + +Point_t *touchPoints; +int32_t *intPointer; +</pre> + <p>then the following code is generated in:</p> + +<pre> +private ScriptField_Point mExportVar_touchPoints; +public void bind_touchPoints(ScriptField_Point v) { + mExportVar_touchPoints = v; + if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); + else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints); +} + +public ScriptField_Point get_touchPoints() { + return mExportVar_touchPoints; +} + +private Allocation mExportVar_intPointer; +public void bind_intPointer(Allocation v) { + mExportVar_intPointer = v; + if (v == null) bindAllocation(null, mExportVarIdx_intPointer); + else bindAllocation(v, mExportVarIdx_intPointer); +} + +public Allocation get_intPointer() { + return mExportVar_intPointer; +} + </pre> + +<p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code> +(instead of a <code>set()</code> method) is generated. This method allows you to bind the memory +that is allocated in the Android VM to the Renderscript runtime (you cannot allocate +memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working +with Allocated Memory</a>. +</p> + + + <h2 id="mem-allocation">Memory Allocation APIs</h2> + + <p>Applications that use Renderscript still run in the Android VM. The actual Renderscript code, however, runs natively and + needs access to the memory allocated in the Android VM. To accomplish this, you must + attach the memory that is allocated in the VM to the Renderscript runtime. This +process, called binding, allows the Renderscript runtime to seamlessly work with memory that it +requests but cannot explicitly allocate. The end result is essentially the same as if you had +called <code>malloc</code> in C. The added benefit is that the Android VM can carry out garbage collection as well as +share memory with the Renderscript runtime layer. Binding is only necessary for dynamically allocated memory. Statically +allocated memory is automatically created for your Renderscript code at compile time. See <a href="#figure1">Figure 1</a> +for more information on how memory allocation occurs. +</p> + + <p>To support this memory allocation system, there are a set of APIs that allow the Android VM to +allocate memory and offer similar functionality to a <code>malloc</code> call. These classes +essentially describe how memory should be allocated and also carry out the allocation. To better +understand how these classes work, it is useful to think of them in relation to a simple +<code>malloc</code> call that can look like this: </p> + + <pre>array = (int *)malloc(sizeof(int)*10);</pre> + + <p>The <code>malloc</code> call can be broken up into two parts: the size of the memory being allocated (<code>sizeof(int)</code>), + along with how many units of that memory should be allocated (10). The Android framework provides classes for these two parts as + well as a class to represent <code>malloc</code> itself.</p> + + <p>The {@link android.renderscript.Element} class represents the (<code>sizeof(int)</code>) portion + of the <code>malloc</code> call and encapsulates one cell of a memory allocation, such as a single + float value or a struct. The {@link android.renderscript.Type} class encapsulates the {@link android.renderscript.Element} + and the amount of elements to allocate (10 in our example). You can think of a {@link android.renderscript.Type} as + an array of {@link android.renderscript.Element}s. The {@link android.renderscript.Allocation} class does the actual + memory allocation based on a given {@link android.renderscript.Type} and represents the actual allocated memory.</p> + + <p>In most situations, you do not need to call these memory allocation APIs directly. The reflected layer + classes generate code to use these APIs automatically and all you need to do to allocate memory is call a + constructor that is declared in one of the reflected layer classes and then bind + the resulting memory {@link android.renderscript.Allocation} to the Renderscript. + There are some situations where you would want to use these classes directly to allocate memory on your + own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to + primitive types. You can see how to do this in the + <a href="#allocating-mem">Allocating and binding memory to the Renderscript</a> section. + The following table describes the three memory management classes in more detail:</p> + + <table id="mem-mgmt-table"> + <tr> + <th>Android Object Type</th> + + <th>Description</th> + </tr> + + <tr> + <td>{@link android.renderscript.Element}</td> + + <td> + <p>An element describes one cell of a memory allocation and can have two forms: basic or + complex.</p> + + <p>A basic element contains a single component of data of any valid Renderscript data type. + Examples of basic element data types include a single <code>float</code> value, a <code>float4</code> vector, or a + single RGB-565 color.</p> + + <p>Complex elements contain a list of basic elements and are created from + <code>struct</code>s that you declare in your Renderscript code. For instance an allocation + can contain multiple <code>struct</code>s arranged in order in memory. Each struct is considered as its + own element, rather than each data type within that struct.</p> + </td> + </tr> + + <tr> + <td>{@link android.renderscript.Type}</td> + + <td> + <p>A type is a memory allocation template and consists of an element and one or more + dimensions. It describes the layout of the memory (basically an array of {@link + android.renderscript.Element}s) but does not allocate the memory for the data that it + describes.</p> + + <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube + map). You can assign the X,Y,Z dimensions to any positive integer value within the + constraints of available memory. A single dimension allocation has an X dimension of + greater than zero while the Y and Z dimensions are zero to indicate not present. For + example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is + considered one dimensional. The LOD and Faces dimensions are booleans to indicate present + or not present.</p> + </td> + </tr> + + <tr> + <td>{@link android.renderscript.Allocation}</td> + + <td> + <p>An allocation provides the memory for applications based on a description of the memory + that is represented by a {@link android.renderscript.Type}. Allocated memory can exist in + many memory spaces concurrently. If memory is modified in one space, you must explicitly + synchronize the memory, so that it is updated in all the other spaces in which it exists. + </p> + + <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked. + For simple arrays there are <code>copyFrom()</code> functions that take an array from the + Android system and copy it to the native layer memory store. The unchecked variants allow + the Android system to copy over arrays of structures because it does not support + structures. For example, if there is an allocation that is an array of n floats, the data + contained in a float[n] array or a <code>byte[n*4]</code> array can be copied.</p> + </td> + </tr> + </table> + + <h2 id="memory">Working with Memory</h2> + +<p>Non-static, global variables that you declare in your Renderscript are allocated memory at compile time. +You can work with these variables directly in your Renderscript code without having to allocate +memory for them at the Android framework level. The Android framework layer also has access to these variables +with the provided accessor methods that are generated in the reflected layer classes. If these variables are +initialized at the Renderscript runtime layer, those values are used to initialize the corresponding +values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is +not generated.</p> + + +<p class="note"><strong>Note:</strong> If you are using certain Renderscript structures that contain pointers, such as +<code>rs_program_fragment</code> and <code>rs_allocation</code>, you have to obtain an object of the +corresponding Android framework class first and then call the <code>set</code> method for that +structure to bind the memory to the Renderscript runtime. You cannot directly manipulate these structures +at the Renderscript runtime layer. This restriction is not applicable to user-defined structures +that contain pointers, because they cannot be exported to a reflected layer class +in the first place. A compiler error is generated if you try to declare a non-static, global +struct that contains a pointer. +</p> + +<p>Renderscript also has support for pointers, but you must explicitly allocate the memory in your +Android framework code. When you declare a global pointer in your <code>.rs</code> file, you +allocate memory through the appropriate reflected layer class and bind that memory to the native +Renderscript layer. You can interact with this memory from the Android framework layer as well as +the Renderscript layer, which offers you the flexibility to modify variables in the most +appropriate layer.</p> + + + + <h3 id="allocating-mem">Allocating and binding dynamic memory to the Renderscript</h3> + + <p>To allocate dynamic memory, you need to call the constructor of a + {@link android.renderscript.Script.FieldBase} class, which is the most common way. An alternative is to create an + {@link android.renderscript.Allocation} manually, which is required for things such as primitive type pointers. You should + use a {@link android.renderscript.Script.FieldBase} class constructor whenever available for simplicity. + After obtaining a memory allocation, call the reflected <code>bind</code> method of the pointer to bind the allocated memory to the + Renderscript runtime.</p> + <p>The example below allocates memory for both a primitive type pointer, + <code>intPointer</code>, and a pointer to a struct, <code>touchPoints</code>. It also binds the memory to the + Renderscript:</p> + <pre> +private RenderScriptGL glRenderer; +private ScriptC_example script; +private Resources resources; + +public void init(RenderScriptGL rs, Resources res) { + //get the rendering context and resources from the calling method + glRenderer = rs; + resources = res; + + //allocate memory for the struct pointer, calling the constructor + ScriptField_Point touchPoints = new ScriptField_Point(glRenderer, 2); + + //Create an element manually and allocate memory for the int pointer + intPointer = Allocation.createSized(glRenderer, Element.I32(glRenderer), 2); + + //create an instance of the Renderscript, pointing it to the bytecode resource + mScript = new ScriptC_example(glRenderer, resources, R.raw.example); + //bind the struct and int pointers to the Renderscript + mScript.bind_touchPoints(touchPoints); + script.bind_intPointer(intPointer); + + ... } </pre> -</body> -</html> + <h3>Reading and writing to memory</h3> + <p>You can read and write to statically and dynamically allocated memory both at the Renderscript runtime + and Android framework layer.</p> + +<p>Statically allocated memory comes with a one-way communication restriction +at the Renderscript runtime level. When Renderscript code changes the value of a variable, it is not +communicated back to the Android framework layer for efficiency purposes. The last value +that is set from the Android framework is always returned during a call to a <code>get</code> +method. However, when Android framework code modifies a variable, that change can be communicated to +the Renderscript runtime automatically or synchronized at a later time. If you need to send data +from the Renderscript runtime to the Android framework layer, you can use the +<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> function +to overcome this limitation. +</p> +<p>When working with dynamically allocated memory, any changes at the Renderscript runtime layer are propagated +back to the Android framework layer if you modified the memory allocation using its associated pointer. +Modifying an object at the Android framework layer immediately propagates that change back to the Renderscript +runtime layer.</p> + + <h4>Reading and writing to global variables</h4> + + <p>Reading and writing to global variables is a straightforward process. You can use the accessor methods + at the Android framework level or set them directly in the Renderscript code. Keep in mind that any + changes that you make in your Renderscript code are not propagated back to the Android framework layer.</p> + + <p>For example, given the following struct declared in a file named <code>rsfile.rs</code>:</p> +<pre> +typedef struct Point { + int x; + int y; +} Point_t; + +Point_t point; + +</pre> +<p>You can assign values to the struct like this directly in <code>rsfile.rs</code>. These values are not +propagated back to the Android framework level:</p> +<pre> +point.x = 1; +point.y = 1; +</pre> + +<p>You can assign values to the struct at the Android framework layer like this. These values are +propagated back to the Renderscript runtime level:</p> +<pre> +ScriptC_rsfile mScript; + +... + +Item i = new ScriptField_Point.Item(); +i.x = 1; +i.y = 1; +mScript.set_point(i); +</pre> + +<p>You can read the values in your Renderscript code like this:</p> + +<pre> +rsDebug("Printing out a Point", point.x, point.y); +</pre> + +<p>You can read the values in the Android framework layer with the following code. Keep in mind that this +code only returns a value if one was set at the Android framework level. You will get a null pointer +exception if you only set the value at the Renderscript runtime level:</p> + +<pre> +Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y); +System.out.println(point.get_x() + " " + point.get_y()); +</pre> + +<h4>Reading and writing global pointers</h4> + +<p>Assuming that memory has been allocated in the Android framework level and bound to the Renderscript runtime, +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. +In the Renderscript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated +back to the Android framework layer, unlike with statically allocated memory.</p> + +<p>For example, given the following pointer to a <code>struct</code> in a file named <code>rsfile.rs</code>:</p> +<pre> +typedef struct Point { + int x; + int y; +} Point_t; + +Point_t *point; +</pre> + +<p>Assuming you already allocated memory at the Android framework layer, you can access values in +the <code>struct</code> as normal. Any changes you make to the struct via its pointer variable +are automatically available to the Android framework layer:</p> + +<pre> +point[index].x = 1; +point[index].y = 1; +</pre> + +<p>You can read and write values to the pointer at the Android framework layer as well: +<pre> +ScriptField_Point p = new ScriptField_Point(mRS, 1); + Item i = new ScriptField_Point.Item(); + i.x=100; + i.y = 100; + p.set(i, 0, true); + mScript.bind_point(p); + + points.get_x(0); //read x and y from index 0 + points.get_x(0); +</pre> + +<p>Once memory is already bound, you do not have to rebind the memory to the Renderscript +runtime every time you make a change to a value.</p> |