Your RenderScript code has access to a limited set of APIs as it cannot simply call APIs from the NDK or C library. The RenderScript APIs are defined in six header files, located in the SDK's platform/android-xx/renderscript/include
(where xx is the API level, for example, 13):
In Ice Cream Sandwich, the RenderScript APIs are defined in 12 header files. In addition to the six header files above, the following six files were added:
Again, as online documentation for RenderScript is currently quite scant, it is recommended you review these files. One of the big differences between Honeycomb and Ice Cream Sandwich is the addition of comments in these header files. You should therefore refer to the Android 4.0 RenderScript header files whenever possible since you will find more information in those than in the Honeycomb header files.
char
, short
, int
, long
, and float
):In addition to these basic types, this file defines vector types:
Since a 3D framework would not be complete without matrices, several matrix types are also defined:
NOTE: While vector types are defined for both floating-point and integer vectors (for example, float2
, ushort3
, and int4
), matrix types use float only.
Honeycomb MR1 (API level 12) introduced the quaternion type rs_quaternion
(defined as float4
). Additional APIs were also introduced to manipulate this new type.
As you can see, the number of types is relatively high, however each of these types can be seen as a scalar, a vector, or a matrix.
The following types are also defined in rs_types.rsh
and are opaque handles to their Java counterparts:
All these types are also exposed in the Java layer in the android.renderscript
package:
This header file defines the following functions in Honeycomb:
The matrix functions were moved to a dedicated header file in Android 4.0: rs_matrix.rsh
.
As the quaternion type was introduced in Honeycomb MR1 (Android 3.1), new functions were also added to rs_core.rsh
:
This header file went through a metamorphosis in Android 4.0. As a matter of fact, the Honeycomb version of this file was a little bit all over the place, containing matrix, quaternion, debugging, and some math functions. The file was dramatically reorganized in Android 4.0 to define only the following functions:
The matrix, quaternion, and debugging functions were moved to their new respective files (rs_matrix.rsh
, rs_quaternion.rsh
, and rs_debug.rsh
) while the math functions were naturally moved to rs_math.rsh
. Since header files are automatically included, the fact that functions were moved from one header file to another should not affect your script.
This header file is actually somewhat hard to read as it uses many macros to define functions. It contains the main “compute” APIs, and if you played hooky instead of attending math classes, you are in for a shock.
This header file defines the following math functions:
It also defines these few integer functions:
Some other common functions are also defined:
Last but not least, this header file defines some geometric functions:
If you are familiar with OpenCL, you should recognize these APIs. As a matter of fact, the Honeycomb rs_cl.rsh
header file itself refers to the OpenCL documentation as it contains comments referring to sections 6.11.2, 6.11.3, 6.11.4, and 6.11.5, which are the sections in the OpenCL 1.1 specifications covering the math, integer, common, and geometric functions respectively. Listing 9–18 shows these comments from rs_cl.rsh
. You can also refer to the OpenCL documentation for more information, which is freely available on the Khronos website (www.khronos.org/opencl
).
Listing 9–18. Comments Referring To OpenCL In rs_cl.rsh
#ifndef __RS_CL_RSH__
#define __RS_CL_RSH__
...
// Float ops, 6.11.2
...
extern float __attribute__((overloadable)) trunc(float);
FN_FUNC_FN(trunc)
// Int ops (partial), 6.11.3
...
IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
FN_FUNC_FN_F(max)
// 6.11.4
_RS_RUNTIME float __attribute__((overloadable)) clamp(float amount, float low, float high);
...
// 6.11.5
_RS_RUNTIME float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs);
...
#endif
This header file also defines some conversion functions such as convert_int3
, which converts a vector of three elements to a vector of three integers.
This header file defines the following functions in Honeycomb:
As we saw earlier, rsForEach()
is one of the most important functions.
The rsSendToClient()
and rsSendToClientBlocking()
functions (moved to rs_core.rsh
in Android 4.0) are worth mentioning as they allow a script to send data to the Java layer. For the Java layer to be able to receive data, your application will have to register a message handler, as shown in Listing 9–19.
Listing 9–19. Message Handler
RenderScript rs = RenderScript.create(this); // needs a Context as parameter
rs.setMessageHandler(new RenderScript.RSMessageHandler() {
@Override
public void run() {
super.run();
Log.d(TAG, String.valueOf(this.mID) + " " + mData + ", length:" + mLength);
}
});
The handler's mID
, mData
, and mLength
fields will contain the information passed by the script. If your script sends data to the Java layer but no handler is registered, an exception will be thrown.
In Android 4.0, the rs_math.rsh
was also modified to focus exclusively on mathematical functions:
The allocation functions were moved to a new file, rs_allocation.rsh
, which, in addition to the functions introduced in Honeycomb, defines the following two new functions:
The object functions were also moved to a new header file: rs_object.rsh
.
This header files defines the following functions:
In Android 4.0 the following functions were added to rs_graphics.rsh
:
Since the focus of this chapter is not on making you an expert in 3D rendering, we won't review these functions in detail. If you are already familiar with OpenGL, then you should easily be able to use these functions. If you are not, then it is recommended you first get familiar with 3D terms like fragment, vertex, and mesh before you dive into RenderScript.
This file defines the following:
Of particular interest is the rsGetDt()
function, which returns the number of seconds (as a floating-point value) since it was last called. Listing 9–20 shows how this would typically be used in a script.
Listing 9–20. Calling rsGetDt()
#pragma version(1)
#pragma rs java_package_name(com.yourpackagehere)
typedef struct __attribute__((packed, aligned(4))) MyObject {
float x;
float other_property;
} MyObject_t;
MyObject_t *object; // Java layer would have to call bind_object
int root() {
float dt = rsGetDt();
float dx = dt * 10.f; // 10 pixels per second
object->x += dx; // new x position of object
// do something else here, for example to draw the object
return 20;
}
NOTE: While the root()
function returns 20 (that is, 20 milliseconds between frames, or 50 frames per second), the frame rate is not guaranteed. This is why your code should use rsGetDt()
instead of assuming the duration between two frames is the value root()
returns.
New in Android 4.0, this file defines functions that were not defined in Honeycomb:
As their names indicate, these functions perform various operations atomically.
3.133.159.223