am 5d730c92: am 86ef7977: Merge "cherrypick from hc mr1 Change-Id: I106cddd6e22d72c48edeaadbf296b0453813d06a" into honeycomb-mr2

* commit '5d730c9237fdf3252a9aa0c01c1653bae69f4f39':
  cherrypick from hc mr1 Change-Id: I106cddd6e22d72c48edeaadbf296b0453813d06a
This commit is contained in:
Robert Ly
2011-06-14 15:13:21 -07:00
committed by Android Git Automerger
6 changed files with 1324 additions and 719 deletions

View File

@@ -244,9 +244,6 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/graphics/renderscript.html">
<span class="en">3D with Renderscript</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
<span class="en">Property Animation</span>
</a></li>
@@ -255,6 +252,23 @@
</a></li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/renderscript/index.html">
<span class="en">RenderScript</span>
</a>
<span class="new-child">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html">
<span class="en">3D Graphics</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
<span class="en">Compute</span>
</a>
</li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
<span class="en">Audio and Video</span>
</a></li>

View File

@@ -0,0 +1,10 @@
<html>
<head>
<meta http-equiv="refresh" content="0;url=http://developer.android.com/guide/topics/renderscript/index.html">
<title>Redirecting...</title>
</head>
<body>
<p>You should be redirected. Please <a
href="http://developer.android.com/guide/topics/renderscript/index.html">click here</a>.</p>
</body>
</html>

View File

@@ -1,716 +0,0 @@
page.title=3D Rendering and Computation with Renderscript
parent.title=Graphics
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="#api">API Overview</a>
<ol>
<li><a href="#native-api">Native Renderscript APIs</a></li>
<li><a href="#reflective-api">Reflected layer APIs</a></li>
<li><a href="#graphics-api">Graphics APIs</a></li>
</ol>
</li>
<li>
<a href="#developing">Developing a Renderscript application</a>
<ol>
<li><a href="#hello-graphics">The Hello Graphics application</a></li>
</ol>
</li>
</ol>
<h2>Related Samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/Renderscript/Balls/index.html">Balls</a></li>
<li><a href="{@docRoot}resources/samples/Renderscript/Fountain/index.html">Fountain</a></li>
<li><a href="{@docRoot}resources/samples/Renderscript/HelloCompute/index.html">Hello Compute</a></li>
<li><a href="{@docRoot}resources/samples/Renderscript/HelloWorld/index.html">Hello World</a></li>
<li><a href="{@docRoot}resources/samples/Renderscript/Samples/index.html">Samples</a></li>
</ol>
</div>
</div>
<p>The Renderscript system offers high performance 3D rendering and mathematical computation at
the native level. The Renderscript APIs are intended for developers who are comfortable with
developing in C (C99 standard) and want to maximize performance in their applications. The
Renderscript system improves performance by running as native code on the device, but it also
features cross-platform functionality. To achieve this, the Android build tools compile your
Renderscript <code>.rs</code> file to intermediate bytecode and package it 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. This eliminates the
need to target a specific architecture during the development process. The compiled code on the
device is cached, so subsequent uses of the Renderscript enabled application do not recompile the
intermediate code.</p>
<p>The disadvantage of the Renderscript system is that it adds complexity to the development and
debugging processes. Debugging visibility can be limited, because the
Renderscript system can execute on processors other than the main CPU (such as the GPU), so if
this occurs, debugging becomes more difficult. The target use is for performance
critical code where the traditional framework APIs (such as using {@link android.opengl}) are not sufficient.
If what you are rendering or computing is very simple and does not require much processing power, you should still use the
traditional framework APIs for ease of development. Remember the tradeoffs between development and
debugging complexity versus performance when deciding to use Renderscript. </p>
<p>For an example of Renderscript in action, see the 3D carousel view in the Android 3.0 versions
of Google Books and YouTube or install the Renderscript sample applications that are shipped with
the SDK in <code>&lt;sdk_root&gt;/samples/android-11/Renderscript</code>.</p>
<h2 id="overview">Renderscript System Overview</h2>
<p>The Renderscript system adopts a control and slave architecture where the low-level native
code is controlled by the higher level Android system that runs in the virtual machine (VM). When
you use the Renderscript system, there are three layers that exist:</p>
<ul>
<li>The native Renderscript layer consists of native libraries that are packaged with the SDK.
The native Renderscript <code>.rs</code> files compute mathematical operations, render graphics,
or both. This layer does the intensive computation or graphics rendering and returns the result
back to the Android VM through the reflected layer.</li>
<li>The reflected layer is a set of generated Android framework classes reflected from
the native Renderscript code that you wrote. This layer acts as a bridge between the native
Renderscript layer and the Android system layer. The Android build tools automatically generate
the classes for this layer during the build process. This layer also includes a set of Android
framework APIs that provide the memory and resource allocation classes to support this layer.</li>
<li>The Android system layer consists of the traditional framework APIs, which include the Renderscript
APIs in {@link android.renderscript}. This layer handles things such as the Activity lifecycle
management of your application and calls the reflected layer to communicate with the native Renderscript code.</li>
</ul>
<p>To fully understand how the Renderscript system works, you must understand how the reflected
layer is generated and how it interacts with the native Renderscript layer and Android system
layer. The reflected layer provides the entry points into the native code, enabling the Android
system to give high level commands like, "rotate the view" or "filter the bitmap" to the
native layer, which does the heavy lifting. To accomplish this, you need to create logic
to hook together all of these layers so that they can correctly communicate.</p>
<p>At the root of everything is your Renderscript, which is the actual C code that you write and
save to a <code>.rs</code> file in your project. There are two kinds of Renderscripts: compute
and graphics. A compute Renderscript does not do any graphics rendering while a graphics
Renderscript does.</p>
<p>When you create Renderscript <code>.rs</code> files, equivalent, reflected classes
are generated by the build tools and expose the native functions and data types and structures
to the Android system. The following list describes the major components of your native Renderscript
code that is reflected:</p>
<ul>
<li>The non-static functions in your Renderscript (<code>.rs</code> file) are reflected into
<code><em>ScriptC_renderscript_filename</em></code> of type {@link
android.renderscript.ScriptC}.</li>
<li>Any non-static, global Renderscript variables are reflected into
<code><em>ScriptC_renderscript_filename</em></code>.
Accessor methods are generated, so the Android system layer can access the values.
The <code>get</code> method comes with a one-way communication restriction.
The Android system layer always caches the last value that is set and returns that 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 system layer.
If the global variables are initialized in the native Renderscript code, those values are used
to initialize the corresponding values in the Android system. If global variables are marked as <code>const</code>,
then a <code>set</code> method is not generated.
</li>
<li>Structs are reflected into their own classes, one for each struct, into a class named
<code>ScriptField_<em>struct_name</em></code> of type {@link
android.renderscript.Script.FieldBase}.</li>
<li>Global pointers have a special property. They provide attachment points where the Android system can attach allocations.
If the global pointer is a user defined structure type, it must be a type that is legal for reflection (primitives
or Renderscript data types). The Android system can call the reflected class to allocate memory and
optionally populate data, then attach it to the Renderscript.
For arrays of basic types, the procedure is similar, except a reflected class is not needed.
Renderscripts should not directly set the exported global pointers.</li>
</ul>
<p>The Android framework API also has a corresponding Renderscript context object, {@link
android.renderscript.RenderScript} (for a compute Renderscript) or {@link
android.renderscript.RenderScriptGL} (for a graphics Renderscript). This context object allows
you to bind to the reflected Renderscript class, so that the Renderscript context knows what its
corresponding native Renderscript is. If you have a graphics Renderscript context, you can also
specify a variety of Programs (stages in the graphics pipeline) to tweek how your graphics are
rendered. A graphics Renderscript context also needs a surface to render on, {@link
android.renderscript.RSSurfaceView}, which gets passed into its constructor.</p>
<h2 id="api">API overview</h2>
<p>Renderscript code is compiled and executed in a compact and well defined runtime, which has
access to a limited amount of functions. Renderscript cannot use the NDK or standard C functions,
because these functions are assumed to be running on a standard CPU. The Renderscript runtime
chooses the best processor to execute the code, 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 with an extensive collection of math APIs. The following sections group the APIs
into three distinct categories.</p>
<h3 id="native-api">Native Renderscript APIs</h3>
<p>The Renderscript headers are located in the <code>include</code> and
<code>clang-include</code> directories in the
<code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code> directory of the Android SDK.
The headers are automatically included for you, except for the graphics specific header,
which you can define as follows:</p>
<pre>#include "rs_graphics.rsh"</pre>
<p>Some key features of the native Renderscript libraries include:
<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>
<li>Conversion routines for primitive data types and vectors, matrix routines, date and time
routines, and graphics routines.</li>
<li>Logging functions</li>
<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 defining two-, three-, or four-vectors.</li>
</ul>
<h3 id="reflective-api">Reflected layer APIs</h3>
<p>These classes are mainly used by the reflected classes that are generated from your native Renderscript
code. They allocate and manage memory for your Renderscript on the Android system side.
You normally do not need to call these classes directly.</p>
<p>Because of the constraints of the Renderscript native layer, you cannot do any dynamic
memory allocation in your Renderscript <code>.rs</code> file.
The native Renderscript layer can request memory from the Android system layer, which allocates memory
for you and does reference counting to figure out when to free the memory. A memory allocation
is taken care of by the {@link android.renderscript.Allocation} class and memory is requested
in your Renderscript code with the <code>the rs_allocation</code> type.
All references to Renderscript objects are counted, so when your Renderscript native code
or system code no longer references a particular {@link android.renderscript.Allocation}, it destroys itself.
Alternatively, you can call {@link android.renderscript.Allocation#destroy destroy()} from the
Android system level, which decreases the reference to the {@link android.renderscript.Allocation}.
If no references exist after the decrease, the {@link android.renderscript.Allocation} destroys itself.
The Android system object, which at this point is just an empty shell, is eventually garbage collected.
</p>
<p>The following classes are mainly used by the reflected layer classes:</p>
<table>
<tr>
<th>Android Object Type</th>
<th>Renderscript Native Type</th>
<th>Description</th>
</tr>
<tr>
<td>{@link android.renderscript.Element}</td>
<td>rs_element</td>
<td>
An {@link android.renderscript.Element} is the most basic element of a memory type. An
element represents one cell of a memory allocation. An element can have two forms: Basic or
Complex. They are typically created from C structures in your Renderscript
code during the reflection process. Elements cannot contain pointers or nested arrays.
The other common source of elements is bitmap formats.
<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 sub-elements and names that is basically a reflection
of a C struct. You access the sub-elements by name from a script or vertex program. The
most basic primitive type determines the data alignment of the structure. For example, a
float4 vector 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>rs_type</td>
<td>A Type is an allocation template that consists of an element and one or more dimensions.
It describes the layout of the memory but does not allocate storage for the data that it
describes. 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.</td>
</tr>
<tr>
<td>{@link android.renderscript.Allocation}</td>
<td>rs_allocation</td>
<td>
<p>An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
android.renderscript.Allocation} allocates memory based on a description of the memory that
is represented by a {@link android.renderscript.Type}. The type describes an array of elements that
represent the memory to be allocated. Allocations are the primary way data moves into and
out of scripts.</p>
<p>Memory is user-synchronized and it's possible for allocations to exist in multiple
memory spaces concurrently. For example, if you make a call to the graphics card to load a
bitmap, you give it the bitmap to load from in the system memory. After that call returns,
the graphics memory contains its own copy of the bitmap so you can choose whether or not to
maintain the bitmap in the system memory. If the Renderscript system modifies an allocation
that is used by other targets, it must call {@link android.renderscript#syncAll syncAll()} to push the updates to
the memory. Otherwise, the results are undefined.</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. Both type checked and
unchecked copies are provided. 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 n floats, you can copy the data contained in a
float[n] array or a byte[n*4] array.</p>
</td>
</tr>
<tr>
<td>{@link android.renderscript.Script}</td>
<td>rs_script</td>
<td>Renderscript scripts do much of the work in the native layer. This class is generated
from a Renderscript file that has the <code>.rs</code> file extension. This class is named
<code>ScriptC_<em>rendersript_filename</em></code> when it gets generated.</td>
</tr>
</table>
<h3 id="graphics-api">Graphics API</h3>
<p>Renderscript provides a number of graphics APIs for hardware-accelerated 3D rendering. The
Renderscript graphics APIs include a stateful context, {@link
android.renderscript.RenderScriptGL} that contains the current rendering state. The primary state
consists of the objects that are attached to the rendering context, which are the graphics Renderscript
and the four program types. The main working function of the graphics Renderscript is the code that is
defined in the <code>root()</code> function. The <code>root()</code> function is called each time the surface goes through a frame
refresh. The four program types mirror a traditional graphical rendering pipeline and are:</p>
<ul>
<li>Vertex</li>
<li>Fragment</li>
<li>Store</li>
<li>Raster</li>
</ul>
<p>Graphical scripts have more properties beyond a basic computational script, and they call the
'rsg'-prefixed functions defined in the <code>rs_graphics.rsh</code> header file. A graphics
Renderscript can also set four pragmas that control the default bindings to the {@link
android.renderscript.RenderScriptGL} context when the script is executing:</p>
<ul>
<li>stateVertex</li>
<li>stateFragment</li>
<li>stateRaster</li>
<li>stateStore</li>
</ul>
<p>The possible values are <code>parent</code> or <code>default</code> for each pragma. Using
<code>default</code> says that when a script is executed, the bindings to the graphical context
are the system defaults. Using <code>parent</code> says that the state should be the same as it
is in the calling script. If this is a root script, the parent
state is taken from the bind points as set in the {@link android.renderscript.RenderScriptGL}
bind methods in the control environment (VM environment).</p>
<p>For example, you can define this at the top of your native graphics Renderscript code:</p>
<pre>
#pragma stateVertex(parent)
#pragma stateStore(parent)
</pre>
<p>The following table describes the major graphics specific APIs that are available to you:</p>
<table>
<tr>
<th>Android Object Type</th>
<th>Renderscript Native Type</th>
<th>Description</th>
</tr>
<tr>
<td>{@link android.renderscript.ProgramVertex}</td>
<td>rs_program_vertex</td>
<td>
<p>The Renderscript vertex program, also known as a vertex shader, describes the stage in the
graphics pipeline responsible for manipulating geometric data in a user-defined way. The
object is constructed by providing Renderscript with the following data:</p>
<ul>
<li>An Element describing its varying inputs or attributes</li>
<li>GLSL shader string that defines the body of the program</li>
<li>a Type that describes the layout of an Allocation containing constant or uniform
inputs</li>
</ul>
<p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
graphics context by calling
{@link android.renderscript.RenderScriptGL#bindProgramVertex bindProgramVertex()}. It is then used for all
subsequent draw calls until you bind a new program. If the program has constant inputs, the
user needs to bind an allocation containing those inputs. The allocation's type must match
the one provided during creation. The Renderscript library then does all the necessary
plumbing to send those constants to the graphics hardware. Varying inputs to the shader,
such as position, normal, and texture coordinates are matched by name between the input
Element and the Mesh object being drawn. The signatures don't have to be exact or in any
strict order. As long as the input name in the shader matches a channel name and size
available on the mesh, the run-time would take care of connecting the two. Unlike OpenGL,
there is no need to link the vertex and fragment programs.</p>
<p> To bind shader constructs to the Program, declare a struct containing the necessary shader constants in your native Renderscript code.
This struct is generated into a reflected class that you can use as a constant input element
during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
You would then bind this Allocation to the Program and the Renderscript system sends the data that
is contained in the struct to the hardware when necessary. To update shader constants, you change the values
in the Allocation and notify the native Renderscript code of the change.</p>
</td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramFragment}</td>
<td>rs_program_fragment</td>
<td><p>The Renderscript fragment program, also known as the fragment shader, is responsible for
manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string
containing the program body, textures inputs, and a Type object describing the constants used
by the program. Like the vertex programs, when an allocation with constant input values is
bound to the shader, its values are sent to the graphics program automatically. Note that the
values inside the allocation are not explicitly tracked. If they change between two draw
calls using the same program object, notify the runtime of that change by calling
rsgAllocationSyncAll so it could send the new values to hardware. Communication between the
vertex and fragment programs is handled internally in the GLSL code. For example, if the
fragment program is expecting a varying input called varTex0, the GLSL code inside the
program vertex must provide it.</p>
<p> To bind shader constructs to the this Program, declare a struct containing the necessary shader constants in your native Renderscript code.
This struct is generated into a reflected class that you can use as a constant input element
during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
You would then bind this Allocation to the Program and the Renderscript system sends the data that
is contained in the struct to the hardware when necessary. To update shader constants, you change the values
in the Allocation and notify the native Renderscript code of the change.</p></td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramStore}</td>
<td>rs_program_store</td>
<td>The Renderscript ProgramStore contains a set of parameters that control how the graphics
hardware writes to the framebuffer. It could be used to enable and disable depth writes and
testing, setup various blending modes for effects like transparency and define write masks
for color components.</td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramRaster}</td>
<td>rs_program_raster</td>
<td>Program raster is primarily used to specify whether point sprites are enabled and to
control the culling mode. By default back faces are culled.</td>
</tr>
<tr>
<td>{@link android.renderscript.Sampler}</td>
<td>rs_sampler</td>
<td>A Sampler object defines how data is extracted from textures. Samplers are bound to
Program objects (currently only a Fragment Program) alongside the texture whose sampling they
control. These objects are used to specify such things as edge clamping behavior, whether
mip-maps are used and the amount of anisotropy required. There may be situations where
hardware limitations prevent the exact behavior from being matched. In these cases, the
runtime attempts to provide the closest possible approximation. For example, the user
requested 16x anisotropy, but only 8x was set because it's the best available on the
hardware.</td>
</tr>
<tr>
<td>{@link android.renderscript.Mesh}</td>
<td>rs_mesh</td>
<td>A collection of allocations that represent vertex data (positions, normals, texture
coordinates) and index data such as triangles and lines. Vertex data can be interleaved
within one allocation, provided separately as multiple allocation objects, or done as a
combination of the above. The layout of these allocations will be extracted from their
Elements. When a vertex channel name matches an input in the vertex program, Renderscript
automatically connects the two. Moreover, even allocations that cannot be directly mapped to
graphics hardware can be stored as part of the mesh. Such allocations can be used as a
working area for vertex-related computation and will be ignored by the hardware. Parts of the
mesh could be rendered with either explicit index sets or primitive types.</td>
</tr>
<tr>
<td>{@link android.renderscript.Font}</td>
<td>rs_font</td>
<td>
<p>This class gives you a way to draw hardware accelerated text. Internally, the glyphs are
rendered using the Freetype library, and an internal cache of rendered glyph bitmaps is
maintained. Each font object represents a combination of a typeface and point sizes.
Multiple font objects can be created to represent faces such as bold and italic and to
create different font sizes. During creation, the framework determines the device screen's
DPI to ensure proper sizing across multiple configurations.</p>
<p>Font rendering can impact performance. Even though though the state changes are
transparent to the user, they are happening internally. It is more efficient to render
large batches of text in sequence, and it is also more efficient to render multiple
characters at once instead of one by one.</p>
<p>Font color and transparency are not part of the font object and can be freely modified
in the script to suit the your needs. Font colors work as a state machine, and every new
call to draw text will use the last color set in the script.</p>
</td>
</tr>
</table>
<h2 id="developing">Developing a Renderscript application</h2>
<p>The basic workflow of developing a Renderscript application is:</p>
<ol>
<li>Analyze your application's requirements and figure out what you want to develop with
Renderscript. To take full advantage of the Renderscript system, you want to use it when the computation
or graphics performance you're getting with the traditional framework APIs is
insufficient.</li>
<li>Design the interface of your Renderscript code and implement it using the native
Renderscript APIs that are included in the Android SDK in
<code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code>.</li>
<li>Create an Android project as you would normally, in Eclipse or with the
<code>android</code> tool.</li>
<li>Place your Renderscript files in <code>src</code> folder of the Android project so that the
build tools can generate the reflected layer classes.</li>
<li>Create your application, calling the Renderscript through the reflected class layer when
you need to.</li>
<li>Build, install, and run your application as you would normally.</li>
</ol>
<p>To see how a simple Renderscript application is put together, see the
<a href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript samples</a>
and <a href="#hello-graphics">The Hello Graphics Application</a> section of the documentation.</p>
<h3 id="hello-graphics">The Hello Graphics Application</h3>
<p>This small application demonstrates the structure of a simple Renderscript application. You
can model your Renderscript application after the basic structure of this application. You can
find the complete source in the SDK in the
<code>&lt;android-sdk&gt;/samples/android-11/HelloWorldRS directory</code>. The
application uses Renderscript to draw the string, "Hello World!" to the screen and redraws the
text whenever the user touches the screen at the location of the touch. This application is only
a demonstration and you should not use the Renderscript system to do something this trivial. The
application contains the following source files:</p>
<ul>
<li><code>HelloWorld</code>: The main Activity for the application. This class is present to
provide Activity lifecycle management. It mainly delegates work to HelloWorldView, which is the
Renderscript surface that the sample actually draws on.</li>
<li><code>HelloWorldView</code>: The Renderscript surface that the graphics render on. If you
are using Renderscript for graphics rendering, you must have a surface to render on. If you are
using it for computatational operations only, then you do not need this.</li>
<li><code>HelloWorldRS</code>: The class that calls the native Renderscript code through high
level entry points that are generated by the Android build tools.</li>
<li><code>helloworld.rs</code>: The Renderscript native code that draws the text on the
screen.</li>
<li>
<p>The <code>&lt;project_root&gt;/gen</code> directory contains the reflected layer classes
that are generated by the Android build tools. You will notice a
<code>ScriptC_helloworld</code> class, which is the reflective version of the Renderscript
and contains the entry points into the <code>helloworld.rs</code> native code. This file does
not appear until you run a build.</p>
</li>
</ul>
<p>Each file has its own distinct use. The following files comprise the main parts of the sample and
demonstrate in detail how the sample works:</p>
<dl>
<dt><code>helloworld.rs</code></dt>
<dd>
The native Renderscript code is contained in the <code>helloworld.rs</code> file. Every
<code>.rs</code> file must contain two pragmas that define the version of Renderscript
that it is using (1 is the only version for now), and the package name that the reflected
classes should be generated with. For example:
<pre>
#pragma version(1)
#pragma rs java_package_name(com.my.package.name)
</pre>
<p>An <code>.rs</code> file can also declare two special functions:</p>
<ul>
<li>
<code>init()</code>: This function is called once for each instance of this Renderscript
file that is loaded on the device, before the script is accessed in any other way by the
Renderscript system. The <code>init()</code> is ideal for doing one time setup after the
machine code is loaded such as initializing complex constant tables. The
<code>init()</code> function for the <code>helloworld.rs</code> script sets the initial
location of the text that is rendered to the screen:
<pre>
void init(){
gTouchX = 50.0f;
gTouchY = 50.0f;
}
</pre>
</li>
<li>
<code>root()</code>: This function is the default worker function for this Renderscript
file. For graphics Renderscript applications, like this one, the Renderscript system
expects this function to render the frame that is going to be displayed. It is called
every time the frame refreshes. The <code>root()</code> function for the
<code>helloworld.rs</code> script sets the background color of the frame, the color of
the text, and then draws the text where the user last touched the screen:
<pre>
int root(int launchID) {
// Clear the background color
rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Tell the runtime what the font color should be
rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
// Introduce ourselves to the world by drawing a greeting
// at the position that the user touched on the screen
rsgDrawText("Hello World!", gTouchX, gTouchY);
// Return value tells RS roughly how often to redraw
// in this case 20 ms
return 20;
}
</pre>
<p>The return value, <code>20</code>, is the desired frame refresh rate in milliseconds.
The real screen refresh rate depends on the hardware, computation, and rendering
complexity that the <code>root()</code> function has to execute. A value of
<code>0</code> tells the screen to render only once and to only render again when a
change has been made to one of the properties that are being modified by the Renderscript
code.</p>
<p>Besides the <code>init()</code> and <code>root()</code> functions, you can define the
other native functions, structs, data types, and any other logic for your Renderscript.
You can even define separate header files as <code>.rsh</code> files.</p>
</li>
</ul>
</dd>
<dt><code>ScriptC_helloworld</code></dt>
<dd>This class is generated by the Android build tools and is the reflected version of the
<code>helloworld.rs</code> Renderscript. It provides a a high level entry point into the
<code>helloworld.rs</code> native code by defining the corresponding methods that you can call
from the traditional framework APIs.</dd>
<dt><code>helloworld.bc</code> bytecode</dt>
<dd>This file is the intermediate, platform-independent bytecode that gets compiled on the
device when the Renderscript application runs. It is generated by the Android build tools and
is packaged with the <code>.apk</code> file and subsequently compiled on the device at runtime.
This file is located in the <code>&lt;project_root&gt;/res/raw/</code> directory and is named
<code>rs_filename.bc</code>. You need to bind these files to your Renderscript context before
call any Renderscript code from your Android application. You can reference them in your code
with <code>R.id.rs_filename</code>.</dd>
<dt><code>HelloWorldView</code> class</dt>
<dd>
This class represents the Surface View that the Renderscript graphics are drawn on. It does
some administrative tasks in the <code>ensureRenderScript()</code> method that sets up the
Renderscript system. This method creates a {@link android.renderscript.RenderScriptGL}
object, which represents the context of the Renderscript and creates a default surface to
draw on (you can set the surface properties such as alpha and bit depth in the {@link
android.renderscript.RenderScriptGL.SurfaceConfig} class ). When a {@link
android.renderscript.RenderScriptGL} is instantiated, this class calls the
<code>HelloRS</code> class and creates the instance of the actual Renderscript graphics
renderer.
<pre>
// Renderscipt context
private RenderScriptGL mRS;
// Script that does the rendering
private HelloWorldRS mRender;
private void ensureRenderScript() {
if (mRS == null) {
// Initialize Renderscript with desired surface characteristics.
// In this case, just use the defaults
RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
mRS = createRenderScriptGL(sc);
// Create an instance of the Renderscript that does the rendering
mRender = new HelloWorldRS();
mRender.init(mRS, getResources());
}
}
</pre>
<p>This class also handles the important lifecycle events and relays touch events to the
Renderscript renderer. When a user touches the screen, it calls the renderer,
<code>HelloWorldRS</code> and asks it to draw the text on the screen at the new location.</p>
<pre>
public boolean onTouchEvent(MotionEvent ev) {
// Pass touch events from the system to the rendering script
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mRender.onActionDown((int)ev.getX(), (int)ev.getY());
return true;
}
return false;
}
</pre>
</dd>
<dt><code>HelloWorldRS</code></dt>
<dd>
This class represents the Renderscript renderer for the <code>HelloWorldView</code> Surface
View. It interacts with the native Renderscript code that is defined in
<code>helloworld.rs</code> through the interfaces exposed by <code>ScriptC_helloworld</code>.
To be able to call the native code, it creates an instance of the Renderscript reflected
class, <code>ScriptC_helloworld</code>. The reflected Renderscript object binds the
Renderscript bytecode (<code>R.raw.helloworld</code>) and the Renderscript context, {@link
android.renderscript.RenderScriptGL}, so the context knows to use the right Renderscript to
render its surface.
<pre>
private Resources mRes;
private RenderScriptGL mRS;
private ScriptC_helloworld mScript;
private void initRS() {
mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld);
mRS.bindRootScript(mScript);
}
</pre>
</dd>
</dl>

View File

@@ -0,0 +1,38 @@
page.title=Compute
parent.title=RenderScript
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Related Samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">Hello
Compute</a></li>
<li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li>
</ol>
</div>
</div>
<p>RenderScript exposes a set of compute APIs that you can use to do intensive computational operations.
You can use the compute APIs in the context of a graphics RenderScript such as calculating the
transformation of many geometric objects in a scene. You can also create a standalone compute RenderScript that does not
draw anything to the screen such as bitmap image processing for a photo editor application.
The RenderScript compute APIs are mainly defined in the <code>rs_cl.rsh</code> header</p>
<p>Compute RenderScripts are simpler to setup and implement as there is no graphics rendering involved.
You can offload computational aspects of your application to RenderScript by creating a native RenderScript
file (.rs) and using the generated reflected layer class to call functions in the <code>.rs</code> file.
<p>See the <a href="{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute</a>
sample in the Android SDK for more
information on how to create a simple compute RenderScript.</p>
<p>
See the <a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a>
sample in the Android SDK for more
information on how to create a compute RenderScript that is used in a graphics RenderScript.
The compute RenderScript is contained in
<a href="{@docRoot}resources/samples/RenderScript/Balls/src/com/example/android/rs/balls/ball_physics.html">balls_physics.rs</a>.
</p>

View File

@@ -0,0 +1,619 @@
page.title=3D Graphics
parent.title=RenderScript
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li>
<a href="#developing">Developing a RenderScript application</a>
<ol>
<li><a href="#hello-graphics">The Hello Graphics application</a></li>
</ol>
</li>
</ol>
<h2>Related Samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li>
<li><a href=
"{@docRoot}resources/samples/Renderscript/Fountain/index.html">Fountain</a></li>
<li><a href="{@docRoot}resources/samples/RenderScript/HelloWorld/index.html">Hello
World</a></li>
<li><a href="{@docRoot}resources/samples/RenderScript/Samples/index.html">Samples</a></li>
</ol>
</div>
</div>
<p>RenderScript provides a number of graphics APIs for 3D rendering, both at the Android
framework level as well as at the native level. For instance, the Android framework APIs let you
create meshes and define shaders to customize the graphical rendering pipeline. The native
RenderScript graphics APIs lets you draw the actual meshes to render your scene. In general, you
will need to be familiar with APIs to appropriately render 3D graphics on an Android-powered
device.</p>
<h2>Creating a Graphics RenderScript</h2>
<p>Because of the various layers of code when writing a RenderScript application, it is useful to
create the following files for a scene that you want to render:</p>
<ul>
<li>The native RenderScript <code>.rs</code> file. This file contains the logic to do the
graphics rendering.</li>
<li>The RenderScript entry point class that allows your view to interact with the code defined
in the <code>.rs</code> file. This class contains a RenderScript object(instance of
<code>ScriptC_<em>renderscript_file</em></code>), which allows your Android framework code to
call the native RenderScript code. This class also creates the {@link
android.renderscript.RenderScriptGL} context object, which contains the current rendering state
of the RenderScript such as programs (vertex and fragment shaders, for example) that you want
to define and bind to the graphics pipeline. The context object attaches to the RenderScript
object (instance of <code><em>ScriptC_renderscript_file</em></code>) that does the rendering.
Our example names this class <code>HelloWorldRS</code>.</li>
<li>Create a class that extends {@link android.renderscript.RSSurfaceView} to provide a surface
to render on. If you want to implement callbacks from events inherited from {@link
android.view.View}, such as {@link android.view.View#onTouchEvent onTouchEvent()} and {@link
android.view.View#onKeyDown onKeyDown()}, do so in this class as well.</li>
<li>Create a class that is the main Activity class, like you would with any Android
application. This class sets your {@link android.renderscript.RSSurfaceView} as the content
view for this Activity.</li>
</ul>
<p>The following sections describe how to implement these three classes by using the HelloWorld
RenderScript sample that is provided in the SDK as a guide (some code has been modified from its
original form for simplicity).</p>
<h3>Creating the native RenderScript file</h3>
<p>Your native RenderScript code resides in a <code>.rs</code> file in the
<code>&lt;project_root&gt;/src/</code> directory. You can also define <code>.rsh</code> header
files. This code contains the logic to render your graphics and declares all necessary variables
and pointers. Every graphics <code>.rs</code> file generally contains the following items:</p>
<ul>
<li>A pragma (<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 (<code>#pragma version(1)</code>) that declares the version of RenderScript that
you are using (1 is the only value for now).</li>
<li>A <code>#include</code> of the rs_graphics.rsh header file.</li>
<li>A <code>root()</code> function. This is the main worker function for your RenderScript and
calls RenderScript graphics APIs to draw meshes to the surface. This function is called every
time a frame refresh occurs, which is specified as its return value. A <code>0</code> specified
for the return value says to only render the frame when a property of the scene that you are
rendering changes. A non-zero positive integer specifies the refresh rate of the frame in
milliseconds.
<p class="note"><strong>Note:</strong> The RenderScript runtime makes its best effort to
refresh the frame at the specified rate. For example, if you are creating a live wallpaper
and set the return value to 50, the runtime renders the wallpaper at 20fps if it has just
enough or more resources to do so, and renders as fast as it can if it does not.</p>
<p>For more
information on using the RenderScript graphics functions, see <a href=
"using-graphics-api">Using the Graphics APIs</a>.</p>
</li>
<li>An <code>init()</code> function. This allows you to do any initialization of your
RenderScript 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. Creating this function is optional.</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 <code>helloworld.rs</code> file is implemented:</p>
<pre>
#pragma version(1)
// Tell which java package name the reflected files should belong to
#pragma rs java_package_name(com.android.rs.helloworld)
// Built-in header with graphics APIs
#include "rs_graphics.rsh"
// gTouchX and gTouchY are variables that are reflected for use
// by the Android framework API. This RenderScript uses them to be notified of touch events.
int gTouchX;
int gTouchY;
// This is invoked automatically when the script is created and initializes the variables
// in the Android framework layer as well.
void init() {
gTouchX = 50.0f;
gTouchY = 50.0f;
}
int root(int launchID) {
// Clear the background color
rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Tell the runtime what the font color should be
rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
// Introuduce ourselves to the world by drawing a greeting
// at the position user touched on the screen
rsgDrawText("Hello World!", gTouchX, gTouchY);
// Return value tells RS roughly how often to redraw
// in this case 20 ms
return 20;
}
</pre>
<h3>Creating the RenderScript entry point class</h3>
<p>When you create a RenderScript (<code>.rs</code>) file, it is helpful to create a
corresponding Android framework class that is an entry point into the <code>.rs</code> file. In
this entry point class, you create a RenderScript object by instantiating a
<code>ScriptC_<em>rs_filename</em></code> and binding it to the RenderScript context. The
RenderScript object is attached to the RenderScript bytecode, which is platform-independent and
gets compiled on the device when the RenderScript application runs. Both the
<code>ScriptC_<em>rs_filename</em></code> class and bytecode is generated by the Android build
tools and is packaged with the <code>.apk</code> file. The bytecode file is located in the
<code>&lt;project_root&gt;/res/raw/</code> directory and is named <code>rs_filename.bc</code>.
You refer to the bytecode as a resource (<code>R.raw.<em>rs_filename</em></code>). when creating
the RenderScript object..</p>
<p>You then bind the RenderScript object to the RenderScript context, so that the surface view
knows what code to use to render graphics. The following code shows how the
<code>HelloWorldRS</code> class is implemented:</p>
<pre>
package com.android.rs.helloworld;
import android.content.res.Resources;
import android.renderscript.*;
public class HelloWorldRS {
//context and resources are obtained from RSSurfaceView, which calls init()
private Resources mRes;
private RenderScriptGL mRS;
//Declare the RenderScript object
private ScriptC_helloworld mScript;
public HelloWorldRS() {
}
/**
* This provides us with the RenderScript context and resources
* that allow us to create the RenderScript object
*/
public void init(RenderScriptGL rs, Resources res) {
mRS = rs;
mRes = res;
initRS();
}
/**
* Calls native RenderScript functions (set_gTouchX and set_gTouchY)
* through the reflected layer class ScriptC_helloworld to pass in
* touch point data.
*/
public void onActionDown(int x, int y) {
mScript.set_gTouchX(x);
mScript.set_gTouchY(y);
}
/**
* Binds the RenderScript object to the RenderScript context
*/
private void initRS() {
//create the RenderScript object
mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld);
//bind the RenderScript object to the RenderScript context
mRS.bindRootScript(mScript);
}
}
</pre>
<h3>Creating the surface view</h3>
<p>To create a surface view to render graphics on, create a class that extends {@link
android.renderscript.RSSurfaceView}. This class also creates a RenderScript context object
({@link android.renderscript.RenderScriptGL} and passes it to the Rendscript entry point class to
bind the two. The following code shows how the <code>HelloWorldView</code> class is
implemented:</p>
<pre>
package com.android.rs.helloworld;
import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScriptGL;
import android.content.Context;
import android.view.MotionEvent;
public class HelloWorldView extends RSSurfaceView {
// RenderScript context
private RenderScriptGL mRS;
// RenderScript entry point object that does the rendering
private HelloWorldRS mRender;
public HelloWorldView(Context context) {
super(context);
initRS();
}
private void initRS() {
if (mRS == null) {
// Initialize RenderScript with default surface characteristics.
RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
//Create the RenderScript context
mRS = createRenderScriptGL(sc);
// Create an instance of the RenderScript entry point class
mRender = new HelloWorldRS();
// Call the entry point class to bind it to this context
mRender.init(mRS, getResources());
}
}
/**
* Rebind everything when the window becomes attached
*/
protected void onAttachedToWindow() {
super.onAttachedToWindow();
initRS();
}
/**
* Stop rendering when window becomes detached
*/
protected void onDetachedFromWindow() {
// Handle the system event and clean up
mRender = null;
if (mRS != null) {
mRS = null;
destroyRenderScriptGL();
}
}
/**
* Use callbacks to relay data to RenderScript entry point class
*/
public boolean onTouchEvent(MotionEvent ev) {
// Pass touch events from the system to the rendering script
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mRender.onActionDown((int)ev.getX(), (int)ev.getY());
return true;
}
return false;
}
}
</pre>
<h3>Creating the Activity</h3>
<p>Applications that use RenderScript still adhere to activity lifecyle, and are part of the same
view hierarchy as traditional Android applications, which is handled by the Android VM. This
Activity class sets its view to be the {@link android.renderscript.RSSurfaceView} and handles
lifecycle callback events appropriately. The following code shows how the <code>HelloWorld</code>
class is implemented:</p>
<pre>
public class HelloWorldActivity extends Activity {
//Custom view to use with RenderScript
private HelloWorldView view;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Create surface view and set it as the content of our Activity
mView = new HelloWorldView(this);
setContentView(view);
}
protected void onResume() {
// Ideally an app should implement onResume() and onPause()
// to take appropriate action when the activity loses focus
super.onResume();
view.resume();
}
protected void onPause() {
// Ideally an app should implement onResume() and onPause()
// to take appropriate action when the activity loses focus
super.onPause();
view.pause();
}
}
</pre>
<h2>Drawing</h2>
<h3>Drawing using the rsgDraw functions</h3>
<p>The native RenderScript APIs provide a few convenient functions to easily draw a polygon to
the screen. You call these in your <code>root()</code> function to have them render to the
surface view. These functions are available for simple drawing and should not be used for complex
graphics rendering:</p>
<ul>
<li><code>rsgDrawRect()</code>: Sets up a mesh and draws a rectangle to the screen. It uses the
top left vertex and bottom right vertex of the rectangle to draw.</li>
<li><code>rsgDrawQuad()</code>: Sets up a mesh and draws a quadrilateral to the screen.</li>
<li><code>rsgDrawQuadTexCoords()</code>: Sets up a mesh and draws a textured quadrilateral to
the screen.</li>
</ul>
<h3>Drawing with a mesh</h3>
<p>When you want to draw complex shapes and textures to the screen, instantiate a {@link
android.renderscript.Mesh} and draw it to the screen with <code>rsgDrawMesh()</code>. A {@link
android.renderscript.Mesh} is a collection of allocations that represent vertex data (positions,
normals, texture coordinates) and index data such as triangles and lines. You can build a Mesh in
three different ways:</p>
<ul>
<li>Build the mesh with the {@link android.renderscript.Mesh.TriangleMeshBuilder} class, which
allows you to specify a set of vertices and indices for each triangle that you want to draw.
The downside of doing it this way is there is no way to specify the vertices in your native
RenderScript code.</li>
<li>Build the mesh using an {@link android.renderscript.Allocation} or a set of {@link
android.renderscript.Allocation}s with the {@link android.renderscript.Mesh.AllocationBuilder}
class. This allows you to build a mesh with vertices already stored in memory, which allows you
to set the vertices in native or Android code.</li>
<li>Build the mesh with the {@link android.renderscript.Mesh.Builder} class. This is a
convenience method for when you know what data types you want to use to build your mesh, but
don't want to make separate memory allocations like with {@link
android.renderscript.Mesh.AllocationBuilder}. You can specify the types that you want and this
mesh builder automatically creates the memory allocations for you.</li>
</ul>
<p>To create a mesh using the {@link android.renderscript.Mesh.TriangleMeshBuilder}, you need to
supply it with a set of vertices and the indices for the vertices that comprise the triangle. For
example, the following code specifies three vertices, which are added to an internal array,
indexed in the order they were added. The call to {@link
android.renderscript.Mesh.TriangleMeshBuilder#addTriangle addTriangle()} draws the triangle with
vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).</p>
<pre>
int float2VtxSize = 2;
Mesh.TriangleMeshBuilder triangle = new Mesh.TriangleMeshBuilder(renderscriptGL,
float2VtxSize, Mesh.TriangleMeshBuilder.COLOR);
triangles.addVertex(300.f, 300.f);
triangles.addVertex(150.f, 450.f);
triangles.addVertex(450.f, 450.f);
triangles.addTriangle(0 , 1, 2);
Mesh smP = triangle.create(true);
script.set_mesh(smP);
</pre>
<p>To draw a mesh using the {@link android.renderscript.Mesh.AllocationBuilder}, you need to
supply it with one or more allocations that contain the vertex data:</p>
<pre>
Allocation vertices;
...
Mesh.AllocationBuilder triangle = new Mesh.AllocationBuilder(mRS);
smb.addVertexAllocation(vertices.getAllocation());
smb.addIndexSetType(Mesh.Primitive.TRIANGLE);
Mesh smP = smb.create();
script.set_mesh(smP);
</pre>
<p>In your native RenderScript code, draw the built mesh to the screen:</p>
<pre>
rs_mesh mesh;
...
int root(){
...
rsgDrawMesh(mesh);
...
return 0; //specify a non zero, positive integer to specify the frame refresh.
//0 refreshes the frame only when the mesh changes.
}
</pre>
<h2 id="shaders">Shaders</h2>
<p>You can attach four program objects to the {@link android.renderscript.RenderScriptGL} context
to customize the rendering pipeline. For example, you can create vertex and fragment shaders in
GLSL or build a raster program object with provided methods without writing GLSL code. The four
program objects mirror a traditional graphical rendering pipeline:</p>
<table>
<tr>
<th>Android Object Type</th>
<th>RenderScript Native Type</th>
<th>Description</th>
</tr>
<tr>
<td>{@link android.renderscript.ProgramVertex}</td>
<td>rs_program_vertex</td>
<td>
<p>The RenderScript vertex program, also known as a vertex shader, describes the stage in
the graphics pipeline responsible for manipulating geometric data in a user-defined way.
The object is constructed by providing RenderScript with the following data:</p>
<ul>
<li>An Element describing its varying inputs or attributes</li>
<li>GLSL shader string that defines the body of the program</li>
<li>a Type that describes the layout of an Allocation containing constant or uniform
inputs</li>
</ul>
<p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex
bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new
program. If the program has constant inputs, the user needs to bind an allocation
containing those inputs. The allocation's type must match the one provided during creation.
The RenderScript library then does all the necessary plumbing to send those constants to
the graphics hardware. Varying inputs to the shader, such as position, normal, and texture
coordinates are matched by name between the input Element and the Mesh object being drawn.
The signatures don't have to be exact or in any strict order. As long as the input name in
the shader matches a channel name and size available on the mesh, the run-time would take
care of connecting the two. Unlike OpenGL, there is no need to link the vertex and fragment
programs.</p>
<p>To bind shader constructs to the Program, declare a struct containing the necessary
shader constants in your native RenderScript code. This struct is generated into a
reflected class that you can use as a constant input element during the Program's creation.
It is an easy way to create an instance of this struct as an allocation. You would then
bind this Allocation to the Program and the RenderScript system sends the data that is
contained in the struct to the hardware when necessary. To update shader constants, you
change the values in the Allocation and notify the native RenderScript code of the
change.</p>
</td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramFragment}</td>
<td>rs_program_fragment</td>
<td>
<p>The RenderScript fragment program, also known as the fragment shader, is responsible for
manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string
containing the program body, textures inputs, and a Type object describing the constants
used by the program. Like the vertex programs, when an allocation with constant input
values is bound to the shader, its values are sent to the graphics program automatically.
Note that the values inside the allocation are not explicitly tracked. If they change
between two draw calls using the same program object, notify the runtime of that change by
calling rsgAllocationSyncAll so it could send the new values to hardware. Communication
between the vertex and fragment programs is handled internally in the GLSL code. For
example, if the fragment program is expecting a varying input called varTex0, the GLSL code
inside the program vertex must provide it.</p>
<p>To bind shader constants to this program, declare a struct containing the necessary
shader constants in your native RenderScript code. This struct is generated into a
reflected class that you can use as a constant input element during the Program's creation.
It is an easy way to create an instance of this struct as an allocation. You would then
bind this Allocation to the Program and the RenderScript system sends the data that is
contained in the struct to the hardware when necessary. To update shader constants, you
change the values in the Allocation and notify the native RenderScript code of the
change.</p>
</td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramStore}</td>
<td>rs_program_store</td>
<td>The RenderScript ProgramStore contains a set of parameters that control how the graphics
hardware writes to the framebuffer. It could be used to enable and disable depth writes and
testing, setup various blending modes for effects like transparency and define write masks
for color components.</td>
</tr>
<tr>
<td>{@link android.renderscript.ProgramRaster}</td>
<td>rs_program_raster</td>
<td>Program raster is primarily used to specify whether point sprites are enabled and to
control the culling mode. By default back faces are culled.</td>
</tr>
</table>
<p>The following example defines a vertex shader in GLSL and binds it to the RenderScript:</p>
<pre>
private RenderScriptGL glRenderer; //rendering context
private ScriptField_Point mPoints; //vertices
private ScriptField_VpConsts mVpConsts; //shader constants
...
ProgramVertex.Builder sb = new ProgramVertex.Builder(glRenderer);
String t = "varying vec4 varColor;\n" +
"void main() {\n" +
" vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
" pos.xy = ATTRIB_position;\n" +
" gl_Position = UNI_MVP * pos;\n" +
" varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
" gl_PointSize = ATTRIB_size;\n" +
"}\n";
sb.setShader(t);
sb.addConstant(mVpConsts.getType());
sb.addInput(mPoints.getElement());
ProgramVertex pvs = sb.create();
pvs.bindConstants(mVpConsts.getAllocation(), 0);
glRenderer.bindProgramVertex(pvs);
</pre>
<p>The <a href=
"{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p>
<h3>Shader bindings</h3>
<p>You can also set four pragmas that control the shaders' default bindings to the {@link
android.renderscript.RenderScriptGL} context when the script is executing:</p>
<ul>
<li>stateVertex</li>
<li>stateFragment</li>
<li>stateRaster</li>
<li>stateStore</li>
</ul>
<p>The possible values for each pragma are <code>parent</code> or <code>default</code>. Using
<code>default</code> binds the shaders to the graphical context with the system defaults. The
default shader is defined below:</p>
<pre>
("varying vec4 varColor;\n");
("varying vec2 varTex0;\n");
("void main() {\n");
(" gl_Position = UNI_MVP * ATTRIB_position;\n");
(" gl_PointSize = 1.0;\n");
(" varColor = ATTRIB_color;\n");
(" varTex0 = ATTRIB_texture0;\n");
("}\n");
</pre>
<p>Using <code>parent</code> binds the shaders in the same manner as it is bound in the calling
script. If this is the root script, the parent state is taken from the bind points that are set
by the {@link android.renderscript.RenderScriptGL} bind methods.</p>
<p>For example, you can define this at the top of your native graphics RenderScript code to have
the Vertex and Store shaders inherent the bind properties from their parent scripts:</p>
<pre>
#pragma stateVertex(parent)
#pragma stateStore(parent)
</pre>
<h3>Defining a sampler</h3>
<p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures.
Samplers are bound to Program objects (currently only a Fragment Program) alongside the texture
whose sampling they control. These objects are used to specify such things as edge clamping
behavior, whether mip-maps are used, and the amount of anisotropy required. There might be
situations where hardware does not support the desired behavior of the sampler. In these cases,
the runtime attempts to provide the closest possible approximation. For example, the user
requested 16x anisotropy, but only 8x was set because it's the best available on the
hardware.</p>
<p>The <a href=
"{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
RsRenderStatesRS</a> sample has many examples on how to create a sampler and bind it to a
Fragment program.</p>
</body>
</html>

View File

@@ -0,0 +1,640 @@
page.title=RenderScript
@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>
<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>
</ol>
</li>
<li>
<a href="#mem-allocation">Memory Allocation APIs</a>
</li>
<li>
<a href="#dynamic">Dynamic Memory Allocations</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="#read-write-dynamic">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>
<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>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>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>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
are shipped with the SDK in <code>&lt;sdk_root&gt;/samples/android-11/RenderScript</code>.
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
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>
<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>
</ul>
<h3 id="native">Native RenderScript layer</h3>
<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>
<p>Some key features of the native RenderScript libraries include:</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>
<li>Conversion routines for primitive data types and vectors, matrix routines, date and time
routines, and graphics routines.</li>
<li>Logging functions</li>
<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
defining two-, three-, or four-vectors.</li>
</ul>
<p>The <a href="{@docRoot}guide/topics/renderscript/rs-api/files.html">RenderScript header files</a>
and LLVM front-end libraries are located in the <code>include</code> and
<code>clang-include</code> directories in the
<code>&lt;sdk_root&gt;/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
you can include as follows:</p>
<pre>
#include "rs_graphics.rsh"
</pre>
<h3 id="reflected">Reflected layer</h3>
<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
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:
<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>
</ul>
</li>
<li>A <code>struct</code> is reflected into its own class named
<code>ScriptField_<em>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>
<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>
<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);
}
</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>
<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>
<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);
}
public long get_unsignedInteger() {
return mExportVar_unsignedInteger;
}
</pre>
<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>&lt;project_root&gt;/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>
<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 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>
<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 <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;
import android.renderscript.*;
import android.content.res.Resources;
public class ScriptField_Point extends android.renderscript.Script.FieldBase {
static public class Item {
public static final int sizeof = 8;
Float2 point;
Item() {
point = 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");
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.point);
}
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_point(int index, Float2 v, boolean copyNow) {
if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */)fnati;
if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */];
if (mItemArray[index] == null) mItemArray[index] = new Item();
mItemArray[index].point = 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 Float2 get_point(int index) {
if (mItemArray == null) return null;
return mItemArray[index].point;
}
public void copyAll() {
for (int ct = 0; ct &lt; 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>
</body>
</html>