diff options
Diffstat (limited to 'docs/html/guide/topics/renderscript')
-rw-r--r-- | docs/html/guide/topics/renderscript/advanced.jd | 730 | ||||
-rw-r--r-- | docs/html/guide/topics/renderscript/compute.jd | 340 | ||||
-rw-r--r-- | docs/html/guide/topics/renderscript/index.jd | 31 | ||||
-rw-r--r-- | docs/html/guide/topics/renderscript/reference.jd | 21 |
4 files changed, 1122 insertions, 0 deletions
diff --git a/docs/html/guide/topics/renderscript/advanced.jd b/docs/html/guide/topics/renderscript/advanced.jd new file mode 100644 index 0000000..58f5e1f --- /dev/null +++ b/docs/html/guide/topics/renderscript/advanced.jd @@ -0,0 +1,730 @@ +page.title=Advanced Renderscript +parent.title=Computation +parent.link=index.html + +@jd:body + + <div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + + <ol> + <li><a href="#native">Renderscript Runtime Layer</a></li> + <li><a href="#reflected">Reflected Layer</a> + <ol> + <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> + + <li> + <a href="#mem-allocation">Memory Allocation APIs</a> + </li> + <li> + <a href="#memory">Working with Memory</a> + <ol> + <li><a href="#allocating-mem">Allocating and binding memory to the Renderscript</a></li> + + <li><a href="#read-write">Reading and writing to memory</a></li> + + </ol> + </li> + </ol> + </div> + </div> + + <p></p> + + <p>Because applications that utilize Renderscript still run inside of the Android VM, + you have access to all of the framework APIs that you are familiar with, but can + utilize Renderscript when appropriate. To facilitate this interaction between + the framework and the Renderscript runtime, an intermediate layer of code is also + present to facilitate communication and memory management between the two levels of code. + This document goes into more detail about these + different layers of code as well as how memory is shared between the Android VM and + Renderscript runtime.</p> + + <h2 id="native">Renderscript Runtime Layer</h2> + + <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 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> + +<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> + + <p>Some key features of the Renderscript runtime libraries include:</p> + + <ul> + + <li>Memory allocation request features</li> + + <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, and date and time + 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>See the Renderscript runtime API reference for more information on the available functions. + + <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 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>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</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>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="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> + +<pre> +void touch(float x, float y, float pressure, int id) { + if (id >= 10) { + return; + } + + touchPos[id].x = x; + touchPos[id].y = y; + touchPressure[id] = pressure; +} +</pre> + +<p>then the following code is generated:</p> + +<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> +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> + +<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> + +<h3 id="var">Variables</h3> + + <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> + + <p>then the following code is generated:</p> + +<pre> +private long mExportVar_unsignedInteger; +public void set_unsignedInteger(long v){ + mExportVar_unsignedInteger = v; + setVar(mExportVarIdx_unsignedInteger, v); +} + +public long get_unsignedInteger(){ + return mExportVar_unsignedInteger; +} + </pre> + + + <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> +typedef struct Point { + float2 position; + float size; +} Point_t; +</pre> + +<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 = 12; + + Float2 position; + float size; + + Item() { + 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), "position"); + eb.add(Element.F32(rs), "size"); + return eb.create(); + } + + public ScriptField_Point(RenderScript rs, int count) { + mItemArray = null; + mIOBuffer = null; + mElement = createElement(rs); + init(rs, count); + } + + public ScriptField_Point(RenderScript rs, int count, int usages) { + mItemArray = null; + mIOBuffer = null; + mElement = createElement(rs); + init(rs, count, usages); + } + + private void copyToArray(Item i, int index) { + if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count + */); + mIOBuffer.reset(index * Item.sizeof); + mIOBuffer.addF32(i.position); + mIOBuffer.addF32(i.size); + } + + public void set(Item i, int index, boolean copyNow) { + if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; + mItemArray[index] = i; + if (copyNow) { + copyToArray(i, index); + mAllocation.setFromFieldPacker(index, mIOBuffer); + } + } + + public Item get(int index) { + if (mItemArray == null) return null; + return mItemArray[index]; + } + + 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].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_position(int index) { + if (mItemArray == null) return null; + return mItemArray[index].position; + } + + public float get_size(int index) { + if (mItemArray == null) return 0; + return mItemArray[index].size; + } + + public void copyAll() { + for (int ct = 0; ct < mItemArray.length; ct++) copyToArray(mItemArray[ct], ct); + mAllocation.setFromFieldPacker(0, mIOBuffer); + } + + public void resize(int newSize) { + if (mItemArray != null) { + int oldSize = mItemArray.length; + int copySize = Math.min(oldSize, newSize); + if (newSize == oldSize) return; + Item ni[] = new Item[newSize]; + 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(myRenderscript, 2, + Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX); + </pre> + </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 RenderScript myRenderscript; +private ScriptC_example script; +private Resources resources; + +public void init(RenderScript rs, Resources res) { + myRenderscript = rs; + resources = res; + + //allocate memory for the struct pointer, calling the constructor + ScriptField_Point touchPoints = new ScriptField_Point(myRenderscript, 2); + + //Create an element manually and allocate memory for the int pointer + intPointer = Allocation.createSized(myRenderscript, Element.I32(myRenderscript), 2); + + //create an instance of the Renderscript, pointing it to the bytecode resource + mScript = new ScriptC_example(myRenderscript, resources, R.raw.example); + + //bind the struct and int pointers to the Renderscript + mScript.bind_touchPoints(touchPoints); + script.bind_intPointer(intPointer); + + ... +} +</pre> + + <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> diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd new file mode 100644 index 0000000..d464c90 --- /dev/null +++ b/docs/html/guide/topics/renderscript/compute.jd @@ -0,0 +1,340 @@ +page.title=Renderscript Computation +parent.title=Computation +parent.link=index.html + +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>In this document</h2> + + <ol> + <li><a href="#overview">Renderscript System Overview</a></li> + <li> + <a href="#creating-renderscript">Creating a Computation Renderscript</a> + + <ol> + <li><a href="#creating-rs-file">Creating the Renderscript file</a></li> + + <li><a href="#calling">Calling the Renderscript code</a></li> + </ol> + </li> + </ol> + + <h2>Related Samples</h2> + + <ol> + <li><a href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">Hello + Compute</a></li> + </ol> + </div> +</div> + + <p>Renderscript offers a high performance computation API at the native +level that you write in C (C99 standard). Renderscript gives your apps the ability to run +operations with automatic parallelization across all available processor cores. +It also supports different types of processors such as the CPU, GPU or DSP. Renderscript +is useful for apps that do image processing, mathematical modeling, or any operations +that require lots of mathematical computation.</p> + +<p>In addition, you have access to all of these features without having to write code to +support different architectures or a different amount of processing cores. You also +do not need to recompile your application for different processor types, because Renderscript +code is compiled on the device at runtime.</p> + +<p class="note"><strong>Deprecation Notice</strong>: Earlier versions of Renderscript included + an experimental graphics engine component. This component +is now deprecated as of Android 4.1 (most of the APIs in <code>rs_graphics.rsh</code> +and the corresponding APIs in {@link android.renderscript}). +If you have apps that render graphics with Renderscript, we highly +recommend you convert your code to another Android graphics rendering option.</p> + + <h2 id="overview">Renderscript System 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 set up 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. 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 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 Renderscript runtime APIs allow you to do the computation + 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 layer calls the reflected layer to access the Renderscript + runtime.</li> + </ul> + +<p>Because of the way Renderscript is structured, the main advantages are:</p> + <ul> + <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 a high performance computation API with seamless parallelization + across the amount of cores on the device.</li> + + <li>Usability: Renderscript simplifies development when possible, such as eliminating JNI glue code.</li> + </ul> + + <p>The main disadvantages are:</p> + + <ul> + <li>Development complexity: Renderscript introduces a new set of APIs that you have to learn.</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> + </ul> + +<p>For a more detailed explanation of how all of these layers work together, see + <a href="{@docRoot}guide/topics/renderscript/advanced.html">Advanced Renderscript</a>.<p> + + +<h2 id="creating-renderscript">Creating a Renderscript</h2> + +<p>Renderscripts scale to the amount of +processing cores available on the device. This is enabled through a function named +<code>rsForEach()</code> (or the <code>forEach_root()</code> method at the Android framework level). +that automatically partitions work across available processing cores on the device. +For now, Renderscript can only take advantage of CPU +cores, but in the future, they can potentially run on other types of processors such as GPUs and +DSPs.</p> + +<p>Implementing a Renderscript involves creating a <code>.rs</code> file that contains +your Renderscript code and calling it at the Android framework level with the +<code>forEach_root()</code> or at the Renderscript runtime level with the +<code>rsForEach()</code> function. The following diagram describes how a typical +Renderscript is set up:</p><img src="{@docRoot}images/rs_compute.png"> + +<p class="img-caption"><strong>Figure 1.</strong> Renderscript overview</p> + +<p>The following sections describe how to create a simple Renderscript and use it in an +Android application. This example uses the <a href= +"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute Renderscript +sample</a> that is provided in the SDK as a guide (some code has been modified from its original +form for simplicity).</p> + +<h3 id="creating-rs-file">Creating the Renderscript file</h3> + +<p>Your Renderscript code resides in <code>.rs</code> and <code>.rsh</code> files in the +<code><project_root>/src/</code> directory. This code contains the computation logic +and declares all necessary variables and pointers. +Every <code>.rs</code> file generally contains the following items:</p> + +<ul> + <li>A pragma declaration (<code>#pragma rs java_package_name(<em>package.name</em>)</code>) + that declares the package name of the <code>.java</code> reflection of this Renderscript.</li> + + <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of + Renderscript that you are using (1 is the only value for now).</li> + + <li><p>A <code>root()</code> function that is the main worker function. The root function is + called by the <code>rsForEach</code> function, which allows the Renderscript code to be called and + executed on multiple cores if they are available. The <code>root()</code> function must return + <code>void</code> and accept the following arguments:</p> + + <ul> + <li>Pointers to memory allocations that are used for the input and output of the + Renderscript. Both of these pointers are required for Android 3.2 (API level 13) platform + versions or older. Android 4.0 (API level 14) and later requires one or both of these + allocations.</li> + </ul> + + <p>The following arguments are optional, but both must be supplied if you choose to use + them:</p> + + <ul> + <li>A pointer for user-defined data that the Renderscript might need to carry out + computations in addition to the necessary allocations. This can be a pointer to a simple + primitive or a more complex struct.</li> + + <li>The size of the user-defined data.</li> + </ul> + </li> + + <li>An optional <code>init()</code> function. This allows you to do any initialization + before the <code>root()</code> function runs, such as initializing variables. This + function runs once and is called automatically when the Renderscript starts, before anything + else in your Renderscript.</li> + + <li>Any variables, pointers, and structures that you wish to use in your Renderscript code (can + be declared in <code>.rsh</code> files if desired)</li> +</ul> + +<p>The following code shows how the <a href= +"{@docRoot}resources/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/mono.html"> +mono.rs</a> file is implemented:</p> +<pre> +#pragma version(1) +#pragma rs java_package_name(com.example.android.rs.hellocompute) + +//multipliers to convert a RGB colors to black and white +const static float3 gMonoMult = {0.299f, 0.587f, 0.114f}; + +void root(const uchar4 *v_in, uchar4 *v_out) { + //unpack a color to a float4 + float4 f4 = rsUnpackColor8888(*v_in); + //take the dot product of the color and the multiplier + float3 mono = dot(f4.rgb, gMonoMult); + //repack the float to a color + *v_out = rsPackColorTo8888(mono); +} +</pre> + +<h3 id="calling">Calling the Renderscript code</h3> + +<p>You can call the Renderscript from your Android framework code by +creating a Renderscript object by instantiating the (<code>ScriptC_<em>script_name</em></code>) +class. This class contains a method, <code>forEach_root()</code>, that lets you invoke +<code>rsForEach</code>. You give it the same parameters that you would if you were invoking it +at the Renderscript runtime level. This technique allows your Android application to offload +intensive mathematical calculations to Renderscript. See the <a href= +"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute</a> sample to see +how a simple Android application can utilize Renderscript.</p> + +<p>To call Renderscript at the Android framework level:</p> + +<ol> + <li>Allocate memory that is needed by the Renderscript in your Android framework code. + You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level + 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only + one or both {@link android.renderscript.Allocation}s.</li> + + <li>Create an instance of the <code>ScriptC_<em>script_name</em></code> class.</li> + + <li>Call <code>forEach_root()</code>, passing in the allocations, the + Renderscript, and any optional user-defined data. The output allocation will contain the output + of the Renderscript.</li> +</ol> + +<p>The following example, taken from the <a href= +"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute</a> sample, processes +a bitmap and outputs a black and white version of it. The +<code>createScript()</code> method carries out the steps described previously. This method calls the +Renderscript, <code>mono.rs</code>, passing in memory allocations that store the bitmap to be processed +as well as the eventual output bitmap. It then displays the processed bitmap onto the screen:</p> +<pre> +package com.example.android.rs.hellocompute; + +import android.app.Activity; +import android.os.Bundle; +import android.graphics.BitmapFactory; +import android.graphics.Bitmap; +import android.renderscript.RenderScript; +import android.renderscript.Allocation; +import android.widget.ImageView; + +public class HelloCompute extends Activity { + private Bitmap mBitmapIn; + private Bitmap mBitmapOut; + + private RenderScript mRS; + private Allocation mInAllocation; + private Allocation mOutAllocation; + private ScriptC_mono mScript; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mBitmapIn = loadBitmap(R.drawable.data); + mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(), + mBitmapIn.getConfig()); + + ImageView in = (ImageView) findViewById(R.id.displayin); + in.setImageBitmap(mBitmapIn); + + ImageView out = (ImageView) findViewById(R.id.displayout); + out.setImageBitmap(mBitmapOut); + + createScript(); + } + private void createScript() { + mRS = RenderScript.create(this); + mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, + Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_SCRIPT); + mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType()); + mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); + mScript.forEach_root(mInAllocation, mOutAllocation); + mOutAllocation.copyTo(mBitmapOut); + } + + private Bitmap loadBitmap(int resource) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + return BitmapFactory.decodeResource(getResources(), resource, options); + } +} +</pre> + +<p>To call Renderscript from another Renderscript file:</p> +<ol> + <li>Allocate memory that is needed by the Renderscript in your Android framework code. + You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level + 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only + one or both {@link android.renderscript.Allocation}s.</li> + + <li>Call <code>rsForEach()</code>, passing in the allocations and any optional user-defined data. + The output allocation will contain the output of the Renderscript.</li> +</ol> + +<pre> +rs_script script; +rs_allocation in_allocation; +rs_allocation out_allocation; +UserData_t data; +... +rsForEach(script, in_allocation, out_allocation, &data, sizeof(data)); +</pre> +</p> +<p>In this example, assume that the script and memory allocations have already been +allocated and bound at the Android framework level and that <code>UserData_t</code> is a struct +declared previously. Passing a pointer to a struct and the size of the struct to <code>rsForEach</code> +is optional, but useful if your Renderscript requires additional information other than +the necessary memory allocations.</p> + +<h3>Setting floating point precision</h3> +<p>You can define the floating point precision required by your compute algorithms. This is useful if you + require less precision than the IEEE 754-2008 standard (used by default). You can define +the floating-point precision level of your script with the following pragmas:</p> + +<ul> + <li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that + require floating point precision as outlined by the IEEE 754-2008 standard. +</li> + <li><code>#pragma rs_fp_relaxed</code> - For apps that don’t require + strict IEEE 754-2008 compliance and can tolerate less precision. This mode enables + flush-to-zero for denorms and round-towards-zero. +</li> + <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision requirements. This mode enables + everything in <code>rs_fp_relaxed</code> along with the following: +<ul> + <li>Operations resulting in -0.0 can return +0.0 instead.</li> + <li>Operations on INF and NAN are undefined.</li> +</ul> +</li> +</ul>
\ No newline at end of file diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd new file mode 100644 index 0000000..b6758bc --- /dev/null +++ b/docs/html/guide/topics/renderscript/index.jd @@ -0,0 +1,31 @@ +page.title=Computation +@jd:body + +<p>Renderscript provides a platform-independent computation engine that operates at the native level. + Use it to accelerate your apps that require extensive computational horsepower.</p> +<div class="landing-docs"> + + <div> + <h3>Blog Articles</h3> + <a +href="http://android-developers.blogspot.com/2012/01/levels-in-renderscript.html"> + <h4>Levels in Renderscript</h4> + <p>For ICS, Renderscript (RS) has been updated with several new features to simplify + adding compute acceleration to your application. RS is interesting for compute + acceleration when you have large buffers of data on which you need to do significant + processing. In this example we will look at applying a levels/saturation operation + on a bitmap.</p> + </a> + + <a +href="http://android-developers.blogspot.com/2011/03/renderscript.html"> + <h4>Renderscript Part 2</h4> + <p>In Introducing Renderscript I gave a brief overview of this technology. + In this post I’ll look at "compute" in more detail. In Renderscript we use + "compute" to mean offloading of data processing from Dalvik code to + Renderscript code which may run on the same or different processor(s).</p> + </a> + </div> + + </div> +</div>
\ No newline at end of file diff --git a/docs/html/guide/topics/renderscript/reference.jd b/docs/html/guide/topics/renderscript/reference.jd new file mode 100644 index 0000000..a9d780a --- /dev/null +++ b/docs/html/guide/topics/renderscript/reference.jd @@ -0,0 +1,21 @@ +page.title=Runtime API Reference +parent.title=Computation +parent.link=index.html + +@jd:body + +<script language="JavaScript"> + +function autoResize(element){ + var newheight; + var newwidth; + + newheight = element.contentWindow.document.body.scrollHeight + 20; + newwidth = element.contentWindow.document.body.scrollWidth; + element.height = (newheight) + "px"; + element.width = (newwidth) + "px"; +} +</script> + + +<iframe SRC="{@docRoot}reference/renderscript/index.html" width="100%" id="iframe" marginheight="0" frameborder="0" onLoad="autoResize(this);"></iframe> |