From b078d942911d5e1cf9533f7fe3e156c579ba396e Mon Sep 17 00:00:00 2001 From: Robert Ly Date: Thu, 5 Jan 2012 10:50:39 -0800 Subject: [PATCH] cherrypick from master docs: Renderscript changes Change-Id: Ic84b7d8c5c48e118f337e60c8bb5b8bc68b0da16 Change-Id: I8bd2ba1f0a4f284c52cfd6de817744264d2c50de --- docs/html/guide/guide_toc.cs | 5 +- .../html/guide/topics/renderscript/compute.jd | 273 +- .../guide/topics/renderscript/graphics.jd | 930 +++-- docs/html/guide/topics/renderscript/index.jd | 1058 +++--- docs/html/images/rs_compute.graffle | 2445 +++++++++++++ docs/html/images/rs_compute.png | Bin 0 -> 55098 bytes docs/html/images/rs_graphics.graffle | 3107 +++++++++++++++++ docs/html/images/rs_graphics.png | Bin 0 -> 79030 bytes docs/html/images/rs_overview.graffle | 3012 ++++++++++++++++ docs/html/images/rs_overview.png | Bin 0 -> 63620 bytes 10 files changed, 10062 insertions(+), 768 deletions(-) create mode 100644 docs/html/images/rs_compute.graffle create mode 100644 docs/html/images/rs_compute.png create mode 100644 docs/html/images/rs_graphics.graffle create mode 100644 docs/html/images/rs_graphics.png create mode 100644 docs/html/images/rs_overview.graffle create mode 100644 docs/html/images/rs_overview.png diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 0078f4f314b7b..e239bb1dadf95 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -271,7 +271,8 @@
  • - RenderScript + Renderscript + updated
  • - WiFi Direct new! + Wi-Fi Direct new!
  • diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd index 8f08f595b0f10..e827f003f97de 100644 --- a/docs/html/guide/topics/renderscript/compute.jd +++ b/docs/html/guide/topics/renderscript/compute.jd @@ -1,38 +1,253 @@ page.title=Compute -parent.title=RenderScript +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. +

    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 positions of many objects in a scene. You can also create standalone compute +Renderscripts such as one that does image processing for a photo editor application.

    -

    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 +

    Compute Renderscripts scale to the amount of +processing cores available on the device. This is enabled through a function named +rsForEach() (or the forEach_root() method at the Android framework level). +that automatically partitions work across available processing cores on the device. +For now, compute Renderscripts can only take advantage of CPU +cores, but in the future, they can potentially run on other types of processors such as GPUs and +DSPs.

    + +

    Creating a Compute Renderscript

    + +

    Implementing a compute Renderscript creating a .rs file that contains +your Renderscript code and calling it at the Android framework level with the +forEach_root() or at the Renderscript runtime level with the +rsForEach() function. The following diagram describes how a typical compute +Renderscript is set up:

    + +

    Figure 1. Compute Renderscript overview

    + +

    The following sections describe how to create a simple compute Renderscript and use it in an +Android application. This example uses the HelloCompute Renderscript +sample that is provided in the SDK as a guide (some code has been modified from its original +form for simplicity).

    + +

    Creating the Renderscript file

    + +

    Your Renderscript code resides in .rs and .rsh files in the +<project_root>/src/ directory. This code contains the compute logic +and declares all necessary variables and pointers. +Every compute .rs file generally contains the following items:

    + + + +

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

    +
    +#pragma version(1)
    +#pragma rs java_package_name(com.example.android.rs.hellocompute)
    +
    +//multipliers to convert a RGB colors to black and white
    +const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
    +
    +void root(const uchar4 *v_in, uchar4 *v_out) {
    +  //unpack a color to a float4
    +  float4 f4 = rsUnpackColor8888(*v_in);
    +  //take the dot product of the color and the multiplier
    +  float3 mono = dot(f4.rgb, gMonoMult);
    +  //repack the float to a color
    +  *v_out = rsPackColorTo8888(mono);
    +}
    +
    + +

    Calling the Renderscript code

    + +

    You can do Renderscript to Renderscript calls with rsForEach in situations +such as when a graphics Renderscript needs to do a lot of computational operations. The Renderscript +Balls sample shows how +this is setup. The balls.rs +graphics Renderscript calls the balls_physics.rs +compute Renderscript to calculate the location of the balls that are rendered to the screen.

    + +

    Another way to use a compute Renderscript is to call it from your Android framework code by +creating a Renderscript object by instantiating the (ScriptC_script_name) +class. This class contains a method, forEach_root(), that lets you invoke +rsForEach. You give it the same parameters that you would if you were invoking it +at the Renderscript runtime level. This technique allows your Android application to offload +intensive mathematical calculations to Renderscript. See the HelloCompute sample to see +how a simple Android application can utilize a compute Renderscript.

    + +

    To call a compute Renderscript at the Android framework level:

    + +
      +
    1. Allocate memory that is needed by the compute Renderscript in your Android framework code. + You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level + 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only + one or both {@link android.renderscript.Allocation}s.
    2. + +
    3. Create an instance of the ScriptC_script_name class.
    4. + +
    5. Call forEach_root(), passing in the allocations, the + Renderscript, and any optional user-defined data. The output allocation will contain the output + of the compute Renderscript.
    6. +
    + +

    In the following example, taken from the HelloCompute sample, processes +a bitmap and outputs a black and white version of it. The +createScript() method carries out the steps described previously. This method the compute +Renderscript, mono.rs, passing in memory allocations that store the bitmap to be processed +as well as the eventual output bitmap. It then displays the processed bitmap onto the screen:

    +
    +package com.example.android.rs.hellocompute;
    +
    +import android.app.Activity;
    +import android.os.Bundle;
    +import android.graphics.BitmapFactory;
    +import android.graphics.Bitmap;
    +import android.renderscript.RenderScript;
    +import android.renderscript.Allocation;
    +import android.widget.ImageView;
    +
    +public class HelloCompute extends Activity {
    +  private Bitmap mBitmapIn;
    +  private Bitmap mBitmapOut;
    +
    +  private RenderScript mRS;
    +  private Allocation mInAllocation;
    +  private Allocation mOutAllocation;
    +  private ScriptC_mono mScript;
    +
    +  @Override
    +  protected void onCreate(Bundle savedInstanceState) {
    +      super.onCreate(savedInstanceState);
    +      setContentView(R.layout.main);
    +
    +      mBitmapIn = loadBitmap(R.drawable.data);
    +      mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
    +                                       mBitmapIn.getConfig());
    +
    +      ImageView in = (ImageView) findViewById(R.id.displayin);
    +      in.setImageBitmap(mBitmapIn);
    +
    +      ImageView out = (ImageView) findViewById(R.id.displayout);
    +      out.setImageBitmap(mBitmapOut);
    +
    +      createScript();
    +  }
    +  private void createScript() {
    +      mRS = RenderScript.create(this);
    +      mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
    +          Allocation.MipmapControl.MIPMAP_NONE,
    +          Allocation.USAGE_SCRIPT);
    +      mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
    +      mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);
    +      mScript.forEach_root(mInAllocation, mOutAllocation);
    +      mOutAllocation.copyTo(mBitmapOut);
    +  }
    +
    +  private Bitmap loadBitmap(int resource) {
    +      final BitmapFactory.Options options = new BitmapFactory.Options();
    +      options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    +      return BitmapFactory.decodeResource(getResources(), resource, options);
    +  }
    +}
    +
    + +

    To call a compute Renderscript from another Renderscript file:

    +
      +
    1. Allocate memory that is needed by the compute Renderscript in your Android framework code. + You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level + 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only + one or both {@link android.renderscript.Allocation}s.
    2. + +
    3. Call rsForEach(), passing in the allocations and any optional user-defined data. + The output allocation will contain the output of the compute Renderscript.
    4. +
    +

    The following example, taken from the Renderscript +Balls sample, demonstrates how to do make a script to script call:

    +
    +rs_script script;
    +rs_allocation in_allocation;
    +rs_allocation out_allocation;
    +UserData_t data;
    +...
    +rsForEach(script, in_allocation, out_allocation, &data, sizeof(data));
    +
    + +

    In this example, assume that the script and memory allocations have already been +allocated and bound at the Android framework level and that UserData_t is a struct +declared previously. Passing a pointer to a struct and the size of the struct to rsForEach +is optional, but useful if your compute Renderscript requires additional information other than +the necessary memory allocations.

    diff --git a/docs/html/guide/topics/renderscript/graphics.jd b/docs/html/guide/topics/renderscript/graphics.jd index 2fefecc172ecf..1c6d0de41c678 100644 --- a/docs/html/guide/topics/renderscript/graphics.jd +++ b/docs/html/guide/topics/renderscript/graphics.jd @@ -1,6 +1,7 @@ -page.title=3D Graphics -parent.title=RenderScript +page.title=Graphics +parent.title=Renderscript parent.link=index.html + @jd:body
    @@ -11,16 +12,16 @@ parent.link=index.html
  • Creating a Graphics Renderscript
      -
    1. Creating the native Renderscript file
    2. +
    3. Creating the Renderscript file
    4. Creating the Renderscript entry point class
    5. -
    6. Creating the surface view
    7. -
    8. Creating the activity
    9. +
    10. Creating the view class
    11. +
    12. Creating the activity class
  • Drawing
      -
    1. Drawing using the rsgDraw functions
    2. +
    3. Simple drawing
    4. Drawing with a mesh
  • @@ -31,6 +32,9 @@ parent.link=index.html
  • Defining a sampler
  • +
  • + Rendering to a Framebuffer Object +
  • Related Samples

    @@ -40,8 +44,9 @@ parent.link=index.html
  • Fountain
  • -
  • Hello - World
  • +
  • FountainFbo
  • + +
  • Hello World
  • Misc Samples
  • @@ -49,310 +54,476 @@ href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samp
    -

    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 +

    Renderscript provides a number of graphics APIs for rendering, both at the Android + framework level as well as at the Renderscript runtime 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.

    + Renderscript graphics APIs let you draw the actual meshes to render your scene. You need to + be familiar with both APIs to appropriately render graphics on an Android-powered device.

    -

    Creating a Graphics RenderScript

    +

    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:

    +

    Renderscript applications require various layers of code, so it is useful to create the following + files to help keep your application organized:

    - +
    The activity .java class
    -

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

    +
    This class is the main activity class and sets your {@link android.renderscript.RSSurfaceView} as the main content + view for this activity or uses the {@link android.renderscript.RSTextureView} alongside other views.
    + +

    Figure 1 describes how these classes interact with one another in a graphics Renderscript:

    + + +

    Figure 1. Graphics Renderscript overview

    -

    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 +

    The following sections describe how to create an application that uses a graphics Renderscript by using + the Renderscript Fountain + sample that is provided in the SDK as a guide (some code has been modified from its original + form for simplicity).

    + +

    Creating the Renderscript file

    + +

    Your Renderscript code resides in .rs and .rsh (headers) files in the + <project_root>/src/ directory. This code contains the logic to render your + graphics and declares all other necessary items such as variables, structs, and pointers. Every graphics .rs file generally contains the following items:

    -

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

    +

    The following code shows how the fountain.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)
    +#pragma rs java_package_name(com.example.android.rs.fountain)
     
    -// Built-in header with graphics APIs
    +//declare shader binding
    +#pragma stateFragment(parent)
    +
    +// header with graphics APIs, must include explicitly
     #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;
    +static int newPart = 0;
     
    -// 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;
    +// the mesh to render
    +rs_mesh partMesh;
    +
    +// the point representing where a particle is rendered
    +typedef struct __attribute__((packed, aligned(4))) Point {
    +    float2 delta;
    +    float2 position;
    +    uchar4 color;
    +} Point_t;
    +Point_t *point;
    +
    +// main worker function that renders particles onto the screen
    +int root() {
    +    float dt = min(rsGetDt(), 0.1f);
    +    rsgClearColor(0.f, 0.f, 0.f, 1.f);
    +    const float height = rsgGetHeight();
    +    const int size = rsAllocationGetDimX(rsGetAllocation(point));
    +    float dy2 = dt * (10.f);
    +    Point_t * p = point;
    +    for (int ct=0; ct < size; ct++) {
    +        p->delta.y += dy2;
    +        p->position += p->delta;
    +        if ((p->position.y > height) && (p->delta.y > 0)) {
    +            p->delta.y *= -0.3f;
    +        }
    +        p++;
    +    }
    +
    +    rsgDrawMesh(partMesh);
    +    return 1;
     }
     
    -int root(int launchID) {
    +// adds particles to the screen to render
    +static float4 partColor[10];
    +void addParticles(int rate, float x, float y, int index, bool newColor)
    +{
    +    if (newColor) {
    +        partColor[index].x = rsRand(0.5f, 1.0f);
    +        partColor[index].y = rsRand(1.0f);
    +        partColor[index].z = rsRand(1.0f);
    +    }
    +    float rMax = ((float)rate) * 0.02f;
    +    int size = rsAllocationGetDimX(rsGetAllocation(point));
    +    uchar4 c = rsPackColorTo8888(partColor[index]);
     
    -    // 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;
    +    Point_t * np = &point[newPart];
    +    float2 p = {x, y};
    +    while (rate--) {
    +        float angle = rsRand(3.14f * 2.f);
    +        float len = rsRand(rMax);
    +        np->delta.x = len * sin(angle);
    +        np->delta.y = len * cos(angle);
    +        np->position = p;
    +        np->color = c;
    +        newPart++;
    +        np++;
    +        if (newPart >= size) {
    +            newPart = 0;
    +            np = &point[newPart];
    +        }
    +    }
     }
     
    -

    Creating the RenderScript entry point class

    +

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

    +

    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. + The most important thing this class does is receive a {@link android.renderscript.RenderScriptGL} rendering context + object from the view class and binds the actual Renderscript + code to the rendering context. This notifies your view class of the code that it needs + to render graphics. +

    -

    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:

    +

    In addition, this class should contain all of the things needed to set up Renderscript. + Some important things that you need to do in this class are:

    + + + +

    The following code shows how the + FountainRS class is implemented:

    +
    +package com.example.android.rs.fountain;
     
     import android.content.res.Resources;
     import android.renderscript.*;
    +import android.util.Log;
     
    -public class HelloWorldRS {
    -    //context and resources are obtained from RSSurfaceView, which calls init()
    +public class FountainRS {
    +    public static final int PART_COUNT = 50000;
    +
    +    public FountainRS() {
    +    }
    +
    +    /**
    +     * This provides us with the Renderscript context and resources
    +     * that allow us to create the Renderscript object
    +     */
         private Resources mRes;
         private RenderScriptGL mRS;
     
    -    //Declare the RenderScript object
    -    private ScriptC_helloworld mScript;
    +    // Renderscript object
    +    private ScriptC_fountain mScript;
     
    -    public HelloWorldRS() {
    -    }
    -
    -    /**
    -     * This provides us with the RenderScript context and resources
    -     * that allow us to create the RenderScript object
    -     */
    +    // Called by the view class to initialize the Renderscript context and renderer
         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
    +
    +        /**
    +         * Create a shader and bind to the Renderscript context
    +         */
    +        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
    +        pfb.setVaryingColor(true);
    +        rs.bindProgramFragment(pfb.create());
    +
    +        /**
    +         * Allocate memory for the particles to render and create the mesh to draw
    +         */
    +        ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
    +        Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
    +        smb.addVertexAllocation(points.getAllocation());
    +        smb.addIndexSetType(Mesh.Primitive.POINT);
    +        Mesh sm = smb.create();
    +
    +       /**
    +        * Create and bind the Renderscript object to the Renderscript context
    +        */
    +        mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
    +        mScript.set_partMesh(sm);
    +        mScript.bind_point(points);
             mRS.bindRootScript(mScript);
         }
    -}
     
    +    boolean holdingColor[] = new boolean[10];
    +
    +    /**
    +     * Calls Renderscript functions (invoke_addParticles)
    +     * via the Renderscript object to add particles to render
    +     * based on where a user touches the screen.
    +     */
    +    public void newTouchPosition(float x, float y, float pressure, int id) {
    +        if (id >= holdingColor.length) {
    +            return;
    +        }
    +        int rate = (int)(pressure * pressure * 500.f);
    +        if (rate > 500) {
    +            rate = 500;
    +        }
    +        if (rate > 0) {
    +            mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
    +            holdingColor[id] = true;
    +        } else {
    +            holdingColor[id] = false;
    +        }
    +
    +    }
    +}
     
    -

    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:

    +

    Creating the view class

    + + +

    To display graphics, you need a view to render on. Create a class that extends {@link + android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. This class + allows you to create a {@link android.renderscript.RenderScriptGL} context object by calling and + pass it to the Rendscript entry point class to bind the two. Once bound, the content is aware + of the code that it needs to use to render graphics with. If your Renderscript code + depends on any type of information that the view is aware of, such as touches from the user, + you can also use this class to relay that information to the Renderscript entry point class. + The following code shows how the FountainView class is implemented:

    -package com.android.rs.helloworld;
    +package com.example.android.rs.fountain;
     
    -import android.renderscript.RSSurfaceView;
    +import android.renderscript.RSTextureView;
     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 class FountainView extends RSTextureView {
     
    -    public HelloWorldView(Context context) {
    +    public FountainView(Context context) {
             super(context);
    -        initRS();
         }
    +    // Renderscript context
    +    private RenderScriptGL mRS;
    +    // Renderscript entry point object that calls Renderscript code
    +    private FountainRS mRender;
     
    -    private void initRS() {
    +    /**
    +     * Create Renderscript context and initialize Renderscript entry point
    +     */
    +    @Override
    +    protected void onAttachedToWindow() {
    +        super.onAttachedToWindow();
    +        android.util.Log.e("rs", "onAttachedToWindow");
             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 = new FountainRS();
                 mRender.init(mRS, getResources());
             }
         }
     
    -    /**
    -     * Rebind everything when the window becomes attached
    -     */
    -    protected void onAttachedToWindow() {
    -        super.onAttachedToWindow();
    -        initRS();
    -    }
    -
    -    /**
    -     * Stop rendering when window becomes detached
    -     */
    +    @Override
         protected void onDetachedFromWindow() {
    -        // Handle the system event and clean up
    -        mRender = null;
    +        super.onDetachedFromWindow();
    +        android.util.Log.e("rs", "onDetachedFromWindow");
             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;
    +    /**
    +     * Use callbacks to relay data to Renderscript entry point class
    +     */
    +    @Override
    +    public boolean onTouchEvent(MotionEvent ev)
    +    {
    +        int act = ev.getActionMasked();
    +        if (act == ev.ACTION_UP) {
    +            mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
    +            return false;
    +        } else if (act == MotionEvent.ACTION_POINTER_UP) {
    +            // only one pointer going up, we can get the index like this
    +            int pointerIndex = ev.getActionIndex();
    +            int pointerId = ev.getPointerId(pointerIndex);
    +            mRender.newTouchPosition(0, 0, 0, pointerId);
    +        }
    +        int count = ev.getHistorySize();
    +        int pcount = ev.getPointerCount();
    +
    +        for (int p=0; p < pcount; p++) {
    +            int id = ev.getPointerId(p);
    +            mRender.newTouchPosition(ev.getX(p),
    +                                     ev.getY(p),
    +                                     ev.getPressure(p),
    +                                     id);
    +
    +            for (int i=0; i < count; i++) {
    +                mRender.newTouchPosition(ev.getHistoricalX(p, i),
    +                                         ev.getHistoricalY(p, i),
    +                                         ev.getHistoricalPressure(p, i),
    +                                         id);
    +            }
    +        }
    +        return true;
         }
     }
    -
     
    -

    Creating the Activity

    +

    Creating the activity class

    -

    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:

    +

    Applications that use Renderscript still behave like normal Android applications, so you + need an activity class that handles activity lifecycle callback events appropriately. The activity class + also sets your {@link android.renderscript.RSSurfaceView} view class to be the main content view of the + activity or uses your {@link android.renderscript.RSTextureView} + in a {@link android.view.ViewGroup} alongside other views.

    + +

    The following code shows how the Fountain + sample declares its activity class:

    -public class HelloWorldActivity extends Activity {
    +package com.example.android.rs.fountain;
     
    -    //Custom view to use with RenderScript
    -    private HelloWorldView view;
    +import android.app.Activity;
    +import android.os.Bundle;
    +import android.util.Log;
     
    +public class Fountain extends Activity {
    +
    +    private static final String LOG_TAG = "libRS_jni";
    +    private static final boolean DEBUG  = false;
    +    private static final boolean LOG_ENABLED = false;
    +
    +    private FountainView mView;
    +
    +    @Override
         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);
    +
    +        // Create our Preview view and set it as 
    +        // the content of our activity
    +        mView = new FountainView(this);
    +        setContentView(mView);
         }
     
    +    @Override
         protected void onResume() {
    -        // Ideally an app should implement onResume() and onPause()
    -        // to take appropriate action when the activity loses focus
    +        Log.e("rs", "onResume");
    +
    +        // Ideally a game should implement onResume() and onPause()
    +        // to take appropriate action when the activity looses focus
             super.onResume();
    -        view.resume();
    +        mView.resume();
         }
     
    +    @Override
         protected void onPause() {
    -        // Ideally an app should implement onResume() and onPause()
    -        // to take appropriate action when the activity loses focus
    +        Log.e("rs", "onPause");
    +
    +        // Ideally a game should implement onResume() and onPause()
    +        // to take appropriate action when the activity looses focus
             super.onPause();
    -        view.pause();
    +        mView.pause();
    +
    +    }
    +
    +    static void log(String message) {
    +        if (LOG_ENABLED) {
    +            Log.v(LOG_TAG, message);
    +        }
         }
     }
     
    +

    Now that you have an idea of what is involved in a Renderscript graphics application, you can +start building your own. It might be easiest to begin with one of the +Renderscript samples as a starting +point if this is your first time using Renderscript.

    +

    Drawing

    The following sections describe how to use the graphics functions to draw with Renderscript.

    -

    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:

    +

    Simple drawing

    + +

    The native Renderscript APIs provide a few convenient functions to easily draw a polygon or text to + the screen. You call these in your root() function to have them render to the {@link + android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. 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 +

    When you want to render complex scenes to the screen, instantiate a {@link + android.renderscript.Mesh} and draw it 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:

    + normals, texture coordinates) and index data that provides information on how to draw triangles + and lines with the provided vertex data. You can build a Mesh in three different ways: