From f197b639ecccc570ee235486f75ba15f87070c28 Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Wed, 8 Jun 2011 22:23:42 -0700 Subject: cherrypick from hc mr1 Change-Id: I106cddd6e22d72c48edeaadbf296b0453813d06a Change-Id: I8b7848139e93df385d0727f9536be73124687cc7 --- docs/html/guide/guide_toc.cs | 20 +- docs/html/guide/topics/graphics/renderscript.html | 10 + docs/html/guide/topics/graphics/renderscript.jd | 716 ---------------------- docs/html/guide/topics/renderscript/compute.jd | 38 ++ docs/html/guide/topics/renderscript/graphics.jd | 619 +++++++++++++++++++ docs/html/guide/topics/renderscript/index.jd | 640 +++++++++++++++++++ 6 files changed, 1324 insertions(+), 719 deletions(-) create mode 100644 docs/html/guide/topics/graphics/renderscript.html delete mode 100644 docs/html/guide/topics/graphics/renderscript.jd create mode 100644 docs/html/guide/topics/renderscript/compute.jd create mode 100644 docs/html/guide/topics/renderscript/graphics.jd create mode 100644 docs/html/guide/topics/renderscript/index.jd diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 916da0994d79..55d711f7adf2 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -244,9 +244,6 @@
  • 3D with OpenGL
  • -
  • - 3D with Renderscript -
  • Property Animation
  • @@ -255,6 +252,23 @@ +
  • +
    + RenderScript + + new!
    + +
  • +
  • Audio and Video
  • diff --git a/docs/html/guide/topics/graphics/renderscript.html b/docs/html/guide/topics/graphics/renderscript.html new file mode 100644 index 000000000000..454d39288d73 --- /dev/null +++ b/docs/html/guide/topics/graphics/renderscript.html @@ -0,0 +1,10 @@ + + + +Redirecting... + + +

    You should be redirected. Please click here.

    + + \ No newline at end of file diff --git a/docs/html/guide/topics/graphics/renderscript.jd b/docs/html/guide/topics/graphics/renderscript.jd deleted file mode 100644 index 60bffdb1a49a..000000000000 --- a/docs/html/guide/topics/graphics/renderscript.jd +++ /dev/null @@ -1,716 +0,0 @@ -page.title=3D Rendering and Computation with Renderscript -parent.title=Graphics -parent.link=index.html -@jd:body - -
    - -
    - -

    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 .rs file to intermediate bytecode and package it inside your - application's .apk 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.

    - -

    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.

    - -

    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 <sdk_root>/samples/android-11/Renderscript.

    - -

    Renderscript System Overview

    - -

    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:

    - - - -

    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.

    - -

    At the root of everything is your Renderscript, which is the actual C code that you write and - save to a .rs 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.

    - -

    When you create Renderscript .rs 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:

    - - - -

    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.

    - -

    API overview

    - -

    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.

    - - -

    Native Renderscript APIs

    - -

    The Renderscript headers are located in the include and - clang-include directories in the - <sdk_root>/platforms/android-11/renderscript directory of the Android SDK. - The headers are automatically included for you, except for the graphics specific header, - which you can define as follows:

    - -
    #include "rs_graphics.rsh"
    - -

    Some key features of the native Renderscript libraries include: -

    - -

    Reflected layer APIs

    - -

    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.

    - -

    Because of the constraints of the Renderscript native layer, you cannot do any dynamic - memory allocation in your Renderscript .rs 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 the rs_allocation 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. -

    - -

    The following classes are mainly used by the reflected layer classes:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Android Object TypeRenderscript Native TypeDescription
    {@link android.renderscript.Element}rs_element - 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. - -

    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.

    - -

    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 sizeof(float) and not - sizeof(float4). The ordering of the elements in memory are the order in which - they were added, with each component aligned as necessary.

    -
    {@link android.renderscript.Type}rs_typeA 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.
    {@link android.renderscript.Allocation}rs_allocation -

    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.

    - -

    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.

    - -

    Allocation data is uploaded in one of two primary ways: type checked and type unchecked. - For simple arrays there are copyFrom() 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.

    -
    {@link android.renderscript.Script}rs_scriptRenderscript scripts do much of the work in the native layer. This class is generated - from a Renderscript file that has the .rs file extension. This class is named - ScriptC_rendersript_filename when it gets generated.
    - -

    Graphics API

    - -

    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 root() function. The root() function is called each time the surface goes through a frame - refresh. The four program types mirror a traditional graphical rendering pipeline and are:

    - - - -

    Graphical scripts have more properties beyond a basic computational script, and they call the - 'rsg'-prefixed functions defined in the rs_graphics.rsh 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:

    - - - -

    The possible values are parent or default for each pragma. Using - default says that when a script is executed, the bindings to the graphical context - are the system defaults. Using parent 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).

    - -

    For example, you can define this at the top of your native graphics Renderscript code:

    -
    -#pragma stateVertex(parent)
    -#pragma stateStore(parent)
    -
    - -

    The following table describes the major graphics specific APIs that are available to you:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Android Object TypeRenderscript Native TypeDescription
    {@link android.renderscript.ProgramVertex}rs_program_vertex -

    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:

    - -
      -
    • An Element describing its varying inputs or attributes
    • - -
    • GLSL shader string that defines the body of the program
    • - -
    • a Type that describes the layout of an Allocation containing constant or uniform - inputs
    • -
    - -

    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.

    -

    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.

    -
    {@link android.renderscript.ProgramFragment}rs_program_fragment

    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.

    -

    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.

    {@link android.renderscript.ProgramStore}rs_program_storeThe 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.
    {@link android.renderscript.ProgramRaster}rs_program_rasterProgram raster is primarily used to specify whether point sprites are enabled and to - control the culling mode. By default back faces are culled.
    {@link android.renderscript.Sampler}rs_samplerA 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.
    {@link android.renderscript.Mesh}rs_meshA 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.
    {@link android.renderscript.Font}rs_font -

    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.

    - -

    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.

    - -

    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.

    -
    - - -

    Developing a Renderscript application

    - -

    The basic workflow of developing a Renderscript application is:

    - -
      -
    1. 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.
    2. - -
    3. Design the interface of your Renderscript code and implement it using the native - Renderscript APIs that are included in the Android SDK in - <sdk_root>/platforms/android-11/renderscript.
    4. - -
    5. Create an Android project as you would normally, in Eclipse or with the - android tool.
    6. - -
    7. Place your Renderscript files in src folder of the Android project so that the - build tools can generate the reflected layer classes.
    8. - -
    9. Create your application, calling the Renderscript through the reflected class layer when - you need to.
    10. - -
    11. Build, install, and run your application as you would normally.
    12. -
    - -

    To see how a simple Renderscript application is put together, see the - Renderscript samples - and The Hello Graphics Application section of the documentation.

    - -

    The Hello Graphics Application

    - -

    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 - <android-sdk>/samples/android-11/HelloWorldRS directory. 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:

    - - - -

    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:

    - -
    -
    helloworld.rs
    - -
    - The native Renderscript code is contained in the helloworld.rs file. Every - .rs 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: -
    -#pragma version(1)
    -
    -#pragma rs java_package_name(com.my.package.name)
    -
    -

    An .rs file can also declare two special functions:

    - -
      -
    • - init(): 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 init() is ideal for doing one time setup after the - machine code is loaded such as initializing complex constant tables. The - init() function for the helloworld.rs script sets the initial - location of the text that is rendered to the screen: -
      -void init(){
      -    gTouchX = 50.0f;
      -    gTouchY = 50.0f;
      -}
      -
      -
    • - -
    • - root(): 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 root() function for the - helloworld.rs 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: -
      -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;
      -}
      -
      - -

      The return value, 20, is the desired frame refresh rate in milliseconds. - The real screen refresh rate depends on the hardware, computation, and rendering - complexity that the root() function has to execute. A value of - 0 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.

      - -

      Besides the init() and root() 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 .rsh files.

      -
    • -
    -
    - -
    ScriptC_helloworld
    - -
    This class is generated by the Android build tools and is the reflected version of the - helloworld.rs Renderscript. It provides a a high level entry point into the - helloworld.rs native code by defining the corresponding methods that you can call - from the traditional framework APIs.
    - -
    helloworld.bc bytecode
    - -
    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 .apk file and subsequently compiled on the device at runtime. - This file is located in the <project_root>/res/raw/ directory and is named - rs_filename.bc. 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 R.id.rs_filename.
    - -
    HelloWorldView class
    - -
    - This class represents the Surface View that the Renderscript graphics are drawn on. It does - some administrative tasks in the ensureRenderScript() 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 - HelloRS class and creates the instance of the actual Renderscript graphics - renderer. -
    -// 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());
    -        }
    -    }
    -
    - -

    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, - HelloWorldRS and asks it to draw the text on the screen at the new location.

    -
    -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;
    -}
    -
    -
    - -
    HelloWorldRS
    - -
    - This class represents the Renderscript renderer for the HelloWorldView Surface - View. It interacts with the native Renderscript code that is defined in - helloworld.rs through the interfaces exposed by ScriptC_helloworld. - To be able to call the native code, it creates an instance of the Renderscript reflected - class, ScriptC_helloworld. The reflected Renderscript object binds the - Renderscript bytecode (R.raw.helloworld) and the Renderscript context, {@link - android.renderscript.RenderScriptGL}, so the context knows to use the right Renderscript to - render its surface. -
    -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);
    -}
    -
    -
    -
    \ No newline at end of file diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd new file mode 100644 index 000000000000..e4c22830fc32 --- /dev/null +++ b/docs/html/guide/topics/renderscript/compute.jd @@ -0,0 +1,38 @@ +page.title=Compute +parent.title=RenderScript +parent.link=index.html +@jd:body + +
    +
    + +

    Related Samples

    + +
      +
    1. Hello + Compute
    2. +
    3. Balls
    4. +
    +
    +
    + +

    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 rs_cl.rsh header

    + +

    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 .rs file. + +

    See the HelloCompute + sample in the Android SDK for more + information on how to create a simple compute RenderScript.

    +

    + See the Balls + 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 + balls_physics.rs. +

    \ No newline at end of file diff --git a/docs/html/guide/topics/renderscript/graphics.jd b/docs/html/guide/topics/renderscript/graphics.jd new file mode 100644 index 000000000000..d8be85f124b1 --- /dev/null +++ b/docs/html/guide/topics/renderscript/graphics.jd @@ -0,0 +1,619 @@ +page.title=3D Graphics +parent.title=RenderScript +parent.link=index.html +@jd:body + +
    +
    +

    In this document

    + +
      +
    1. + Developing a RenderScript application + +
        +
      1. The Hello Graphics application
      2. +
      +
    2. +
    + +

    Related Samples

    + +
      +
    1. Balls
    2. + +
    3. Fountain
    4. + +
    5. Hello + World
    6. + +
    7. Samples
    8. +
    +
    +
    + +

    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.

    + +

    Creating a Graphics RenderScript

    + +

    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:

    + + + +

    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).

    + +

    Creating the native RenderScript file

    + +

    Your native RenderScript code resides in a .rs file in the + <project_root>/src/ directory. You can also define .rsh header + files. This code contains the logic to render your graphics and declares all necessary variables + and pointers. Every graphics .rs file generally contains the following items:

    + + + +

    The following code shows how the helloworld.rs file is implemented:

    +
    +#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;
    +}
    +
    + +

    Creating the RenderScript entry point class

    + +

    When you create a RenderScript (.rs) file, it is helpful to create a + corresponding Android framework class that is an entry point into the .rs file. In + this entry point class, you create a RenderScript object by instantiating a + ScriptC_rs_filename 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 + ScriptC_rs_filename class and bytecode is generated by the Android build + tools and is packaged with the .apk file. The bytecode file is located in the + <project_root>/res/raw/ directory and is named rs_filename.bc. + You refer to the bytecode as a resource (R.raw.rs_filename). when creating + the RenderScript object..

    + +

    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 + HelloWorldRS class is implemented:

    +
    +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);
    +    }
    +}
    +
    +
    + +

    Creating the surface view

    + +

    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 HelloWorldView class is + implemented:

    +
    +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;
    +    }
    +}
    +
    +
    + +

    Creating the Activity

    + +

    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 HelloWorld + class is implemented:

    +
    +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();
    +    }
    +}
    +
    + +

    Drawing

    + +

    Drawing using the rsgDraw functions

    + +

    The native RenderScript APIs provide a few convenient functions to easily draw a polygon to + the screen. You call these in your root() 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:

    + + + +

    Drawing with a mesh

    + +

    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 rsgDrawMesh(). 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:

    + + + +

    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).

    +
    +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);
    +
    + +

    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:

    +
    +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);
    +
    + +

    In your native RenderScript code, draw the built mesh to the screen:

    +
    +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.
    +}
    +
    + +

    Shaders

    + +

    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:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Android Object TypeRenderScript Native TypeDescription
    {@link android.renderscript.ProgramVertex}rs_program_vertex +

    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:

    + +
      +
    • An Element describing its varying inputs or attributes
    • + +
    • GLSL shader string that defines the body of the program
    • + +
    • a Type that describes the layout of an Allocation containing constant or uniform + inputs
    • +
    + +

    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.

    + +

    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.

    +
    {@link android.renderscript.ProgramFragment}rs_program_fragment +

    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.

    + +

    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.

    +
    {@link android.renderscript.ProgramStore}rs_program_storeThe 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.
    {@link android.renderscript.ProgramRaster}rs_program_rasterProgram raster is primarily used to specify whether point sprites are enabled and to + control the culling mode. By default back faces are culled.
    + +

    The following example defines a vertex shader in GLSL and binds it to the RenderScript:

    +
    +    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);
    +
    +
    +
    + +

    The + RsRenderStatesRS sample has many examples on how to create a shader without writing GLSL.

    + +

    Shader bindings

    + +

    You can also set four pragmas that control the shaders' default bindings to the {@link + android.renderscript.RenderScriptGL} context when the script is executing:

    + + + +

    The possible values for each pragma are parent or default. Using + default binds the shaders to the graphical context with the system defaults. The + default shader is defined below:

    +
    +("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");
    +
    + +

    Using parent 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.

    + +

    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:

    +
    +#pragma stateVertex(parent)
    +#pragma stateStore(parent)
    +
    + +

    Defining a sampler

    + +

    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.

    + +

    The + RsRenderStatesRS sample has many examples on how to create a sampler and bind it to a + Fragment program.

    + + + diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd new file mode 100644 index 000000000000..eb773109e427 --- /dev/null +++ b/docs/html/guide/topics/renderscript/index.jd @@ -0,0 +1,640 @@ +page.title=RenderScript +@jd:body + +
    + +
    + +

    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:

    + + +

    The main disadvantages are:

    + + + +

    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:

    + + +

    For an example of RenderScript in action, install the RenderScript sample applications that + are shipped with the SDK in <sdk_root>/samples/android-11/RenderScript. + 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.

    + +

    RenderScript System Overview

    + +

    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 .apk 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:

    + + + +

    Native RenderScript layer

    + +

    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.

    + +

    Some key features of the native RenderScript libraries include:

    + + + +

    The RenderScript header files + and LLVM front-end libraries are located in the include and + clang-include directories in the + <sdk_root>/platforms/android-11/renderscript 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:

    +
    +#include "rs_graphics.rsh"
    +
    + +

    Reflected layer

    + +

    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:

    + + + +

    Android framework layer

    + +

    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. +

    + +

    Memory Allocation APIs

    + +

    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.

    + +

    Note: 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.

    + +

    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.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Android Object TypeDescription
    {@link android.renderscript.Element} +

    An element represents one cell of a memory allocation and can have two forms: Basic or + Complex.

    + +

    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.

    + +

    Complex elements contain a list of basic elements and are created from + structs 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 sizeof(float) and not sizeof(float4). The ordering + of the elements in memory are the order in which they were added, with each component + aligned as necessary.

    +
    {@link android.renderscript.Type} + 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. + +

    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.

    +
    {@link android.renderscript.Allocation} +

    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.

    + +

    Allocation data is uploaded in one of two primary ways: type checked and type unchecked. + For simple arrays there are copyFrom() 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.

    +
    + +

    Working with dynamic memory allocations

    + +

    RenderScript has support for pointers, but you must allocate the memory in your Android framework + code. When you declare a global pointer in your .rs 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.

    + +

    Declaring pointers

    + +

    Because RenderScript is written in C99, declaring a pointer is done in a familiar way. You can + declare pointers to a struct or a primitive type, but a struct cannot + contain pointers or nested arrays. The following code declares a struct, a pointer + to that struct, and a pointer of primitive type int32_t in an .rs file:

    +
    +#pragma version(1)
    +#pragma rs java_package_name(com.example.renderscript)
    +
    +...
    +
    +typedef struct Point {
    +      float2 point;
    +  } Point_t;
    +
    +  Point_t *touchPoints;
    +  int32_t *intPointer;
    +
    +...
    +
    + +

    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.

    + +

    How pointers are reflected

    + +

    Global variables have a getter and setter method generated. A global pointer generates a + bind_pointerName() 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 ScriptC_rs_filename file:

    +
    +
    +    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;
    +    }
    +
    +
    + +

    Allocating and binding memory to the RenderScript

    + +

    When the build tools generate the reflected layer, you can use the appropriate class + (ScriptField_Point, 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 Table 1. The example below allocates memory for both + the intPointer and touchPoints pointer and binds it to the + RenderScript:

    +
    +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);
    +}
    +
    + +

    Reading and writing to memory

    + +

    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 .rs + 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:

    +
    +int index = 0;
    +boolean copyNow = true;
    +Float2 point = new Float2(0.0f, 0.0f);
    +touchPoints.set_point(index, point, copyNow);
    +
    then read it in your native RenderScript code like this: +
    +rsDebug("Printing out a Point", touchPoints[0].point.x, touchPoints[0].point.y);
    +
    + +

    Working with statically allocated memory

    + +

    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. +

    Note: The get 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 get + 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 const, then a set method is + not generated.

    +

    + +

    For example, if you declare the following primitive in your RenderScript code:

    +
    +  uint32_t unsignedInteger = 1;
    +  
    +
    +

    then the following code is generated in ScriptC_script_name.java:

    +
    + 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;
    +    }
    +
    + +

    Note: The mExportVarIdx_unsignedInteger variable represents the + index of the unsignedInteger's in an array of statically allocated primitives. You do + not need to work with or be aware of this index.

    + +

    For a struct, the Android build tools generate a class named + <project_root>/gen/com/example/renderscript/ScriptField_struct_name. This + class represents an array of the struct and allows you to allocate memory for a + specified number of structs. This class defines:

    + + + +

    The following example shows the reflected class, ScriptField_Point.java that is + generated from the Point struct.

    +
    +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 */);
    +    }
    +
    +}
    +
    + + + -- cgit v1.2.3-59-g8ed1b