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:
@@ -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>
|
||||
|
||||
10
docs/html/guide/topics/graphics/renderscript.html
Normal file
10
docs/html/guide/topics/graphics/renderscript.html
Normal 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>
|
||||
@@ -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><sdk_root>/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><sdk_root>/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><sdk_root>/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><android-sdk>/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><project_root>/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><project_root>/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>
|
||||
38
docs/html/guide/topics/renderscript/compute.jd
Normal file
38
docs/html/guide/topics/renderscript/compute.jd
Normal 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>
|
||||
619
docs/html/guide/topics/renderscript/graphics.jd
Normal file
619
docs/html/guide/topics/renderscript/graphics.jd
Normal 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><project_root>/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><project_root>/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>
|
||||
640
docs/html/guide/topics/renderscript/index.jd
Normal file
640
docs/html/guide/topics/renderscript/index.jd
Normal 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><sdk_root>/samples/android-11/RenderScript</code>.
|
||||
You can also see a typical use of RenderScript with the 3D carousel view in the Android 3.x
|
||||
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><sdk_root>/platforms/android-11/renderscript</code> directory of the Android SDK. The
|
||||
headers are automatically included for you, except for the RenderScript graphics specific header file, which
|
||||
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><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This
|
||||
class represents an array of the <code>struct</code> and allows you to allocate memory for a
|
||||
specified number of <code>struct</code>s. This class defines:</p>
|
||||
|
||||
<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 < 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>
|
||||
Reference in New Issue
Block a user