Home | History | Annotate | Download | only in slang
      1 ==============================================
      2 llvm-rs-cc: Compiler for Renderscript language
      3 ==============================================
      4 
      5 
      6 Introduction
      7 ------------
      8 
      9 llvm-rs-cc compiles a program in the Renderscript language to generate the
     10 following files:
     11 
     12 * Bitcode file. Note that the bitcode here denotes the LLVM (Low-Level
     13   Virtual Machine) bitcode representation, which will be consumed on
     14   an Android device by libbcc (in
     15   platform/frameworks/compile/libbcc.git) to generate device-specific
     16   executables.
     17 
     18 * Reflected APIs for Java. As a result, Android's Java developers can
     19   invoke those APIs from their code.
     20 
     21 Note that although Renderscript is C99-like, we enhance it with several
     22 distinct, effective features for Android programming. We will use
     23 some examples to illustrate these features.
     24 
     25 llvm-rs-cc is run on the host and performs many aggressive optimizations.
     26 As a result, libbcc on the device can be lightweight and focus on
     27 machine-dependent code generation for some input bitcode.
     28 
     29 llvm-rs-cc is a driver on top of libslang. The architecture of
     30 libslang and libbcc is depicted in the following figure::
     31 
     32     libslang   libbcc
     33         |   \   |
     34         |    \  |
     35      clang     llvm
     36 
     37 
     38 Usage
     39 -----
     40 
     41 * *-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw*
     42 
     43   This option specifies the directory for outputting a .bc file.
     44 
     45 * *-p $(PRIVATE_RS_OUTPUT_DIR)/src*
     46 
     47   The option *-p* denotes the directory for outputting the reflected Java files.
     48 
     49 * *-d $(PRIVATE_RS_OUTPUT_DIR)*
     50 
     51   This option *-d* sets the directory for writing dependence information.
     52 
     53 * *-MD*
     54 
     55   Note that *-MD* will tell llvm-rs-cc to output dependence information.
     56 
     57 * *-a $(EXTRA_TARGETS)*
     58 
     59   Specifies additional target dependencies.
     60 
     61 Example Command
     62 ---------------
     63 
     64 First::
     65 
     66   $ cd <Android_Root_Directory>
     67 
     68 Using frameworks/base/tests/RenderScriptTests/Fountain as a simple app in both
     69 Java and Renderscript, we can find the following command line in the build
     70 log::
     71 
     72   $ out/host/linux-x86/bin/llvm-rs-cc \
     73     -o out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/res/raw \
     74     -p out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/src \
     75     -d out/target/common/obj/APPS/Fountain_intermediates/src/renderscript \
     76     -a out/target/common/obj/APPS/Fountain_intermediates/src/RenderScript.stamp \
     77     -MD \
     78     -I frameworks/base/libs/rs/scriptc \
     79     -I external/clang/lib/Headers \
     80     frameworks/base/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
     81 
     82 This command will generate:
     83 
     84 * **fountain.bc**
     85 
     86 * **ScriptC_fountain.java**
     87 
     88 * **ScriptField_Point.java**
     89 
     90 The **Script\*.java** files above will be documented below.
     91 
     92 
     93 Example Program: fountain.rs
     94 ----------------------------
     95 
     96 fountain.rs is in the Renderscript language, which is based on the standard
     97 C99. However, llvm-rs-cc goes beyond "clang -std=c99" and provides the
     98 following important features:
     99 
    100 1. Pragma
    101 ---------
    102 
    103 * *#pragma rs java_package_name([PACKAGE_NAME])*
    104 
    105   The ScriptC_[SCRIPT_NAME].java has to be packaged so that Java
    106   developers can invoke those APIs.
    107 
    108   To do that, a Renderscript programmer should specify the package name, so
    109   that llvm-rs-cc knows the package expression and hence the directory
    110   for outputting ScriptC_[SCRIPT_NAME].java.
    111 
    112   In fountain.rs, we have::
    113 
    114     #pragma rs java_package_name(com.android.fountain)
    115 
    116   In ScriptC_fountain.java, we have::
    117 
    118     package com.android.fountain
    119 
    120   Note that the ScriptC_fountain.java will be generated inside
    121   ./com/android/fountain/.
    122 
    123 * #pragma version(1)
    124 
    125   This pragma is for evolving the language. Currently we are at
    126   version 1 of the language.
    127 
    128 
    129 2. Basic Reflection: Export Variables and Functions
    130 ---------------------------------------------------
    131 
    132 llvm-rs-cc automatically exports the "externalizable and defined" functions and
    133 variables to Android's Java side. That is, scripts are accessible from
    134 Java.
    135 
    136 For instance, for::
    137 
    138   int foo = 0;
    139 
    140 In ScriptC_fountain.java, llvm-rs-cc will reflect the following methods::
    141 
    142   void set_foo(int v)...
    143 
    144   int get_foo()...
    145 
    146 This access takes the form of generated classes which provide access
    147 to the functions and global variables within a script. In summary,
    148 global variables and functions within a script that are not declared
    149 static will generate get, set, or invoke methods.  This provides a way
    150 to set the data within a script and call its functions.
    151 
    152 Take the addParticles function in fountain.rs as an example::
    153 
    154   void addParticles(int rate, float x, float y, int index, bool newColor) {
    155     ...
    156   }
    157 
    158 llvm-rs-cc will genearte ScriptC_fountain.java as follows::
    159 
    160   void invoke_addParticles(int rate, float x, float y,
    161                            int index, bool newColor) {
    162     ...
    163   }
    164 
    165 
    166 3. Export User-Defined Structs
    167 ------------------------------
    168 
    169 In fountain.rs, we have::
    170 
    171   typedef struct __attribute__((packed, aligned(4))) Point {
    172     float2 delta;
    173     float2 position;
    174     uchar4 color;
    175   } Point_t;
    176 
    177   Point_t *point;
    178 
    179 llvm-rs-cc generates one ScriptField*.java file for each user-defined
    180 struct. In this case, llvm-rs-cc will reflect two files,
    181 ScriptC_fountain.java and ScriptField_Point.java.
    182 
    183 Note that when the type of an exportable variable is a structure, Renderscript
    184 developers should avoid using anonymous structs. This is because llvm-rs-cc
    185 uses the struct name to identify the file, instead of the typedef name.
    186 
    187 For the generated Java files, using ScriptC_fountain.java as an
    188 example we also have::
    189 
    190   void bind_point(ScriptField_Point v)
    191 
    192 This binds your object with the allocated memory.
    193 
    194 You can bind the struct(e.g., Point), using the setter and getter
    195 methods in ScriptField_Point.java.
    196 
    197 After binding, you can access the object with this method::
    198 
    199   ScriptField_Point get_point()
    200 
    201 In ScriptField_Point_s.java::
    202 
    203     ...
    204     // Copying the Item, which is the object that stores every
    205     // fields of struct, to the *index*\-th entry of byte array.
    206     //
    207     // In general, this method would not be invoked directly
    208     // but is used to implement the setter.
    209     void copyToArray(Item i, int index)
    210 
    211     // The setter of Item array,
    212     // index: the index of the Item array
    213     // copyNow: If true, it will be copied to the *index*\-th entry
    214     // of byte array.
    215     void set(Item i, int index, boolean copyNow)
    216 
    217     // The getter of Item array, which gets the *index*-th element
    218     // of byte array.
    219     Item get(int index)
    220 
    221     set_delta(int index, Float2 v, boolean copyNow)
    222 
    223     // The following is the individual setters and getters of
    224     // each field of a struct.
    225     public void set_delta(int index, Float2 v, boolean copyNow)
    226     public void set_position(int index, Float2 v, boolean copyNow)
    227     public void set_color(int index, Short4 v, boolean copyNow)
    228     public Float2 get_delta(int index)
    229     public Float2 get_position(int index)
    230     public Short4 get_color(int index)
    231 
    232     // Copying all Item array to byte array (i.e., memory allocation).
    233     void copyAll()
    234     ...
    235 
    236 
    237 4. Summary of the Java Reflection above
    238 ---------------------------------------
    239 
    240 This section summarizes the high-level design of Renderscript's reflection.
    241 
    242 * In terms of a script's global functions, they can be called from Java.
    243   These calls operate asynchronously and no assumptions should be made
    244   on whether a function called will have actually completed operation.  If it
    245   is necessary to wait for a function to complete, the Java application
    246   may call the runtime finish() method, which will wait for all the script
    247   threads to complete pending operations.  A few special functions can also
    248   exist:
    249 
    250   * The function **init** (if present) will be called once after the script
    251     is loaded.  This is useful to initialize data or anything else the
    252     script may need before it can be used.  The init function may not depend
    253     on globals initialized from Java as it will be called before these
    254     can be initialized. The function signature for init must be::
    255 
    256       void init(void);
    257 
    258   * The function **root** is a special function for graphics.  This function
    259     will be called when a script must redraw its contents.  No
    260     assumptions should be made as to when this function will be
    261     called.  It will only be called if the script is bound as a graphics root.
    262     Calls to this function will be synchronized with data updates and
    263     other invocations from Java.  Thus the script will not change due
    264     to external influence in the middle of running **root**.  The return value
    265     indicates to the runtime when the function should be called again to
    266     redraw in the future.  A return value of 0 indicates that no
    267     redraw is necessary until something changes on the Java side.  Any
    268     positive integer indicates a time in milliseconds that the runtime should
    269     wait before calling root again to render another frame.  The function
    270     signature for a graphics root functions is as follows::
    271 
    272       int root(void);
    273 
    274   * It is also possible to create a purely compute-based **root** function.
    275     Such a function has the following signature::
    276 
    277       void root(const T1 *in, T2 *out, const T3 *usrData, uint32_t x, uint32_t y);
    278 
    279     T1, T2, and T3 represent any supported Renderscript type.  Any parameters
    280     above can be omitted, although at least one of in/out must be present.
    281     If both in and out are present, root must only be invoked with types of
    282     the same exact dimensionality (i.e. matching X and Y values for dimension).
    283     This root function is accessible through the Renderscript language
    284     construct **forEach**.  We also reflect a Java version to access this
    285     function as **forEach_root** (for API levels of 14+).  An example of this
    286     can be seen in the Android SDK sample for HelloCompute.
    287 
    288   * The function **.rs.dtor** is a function that is sometimes generated by
    289     llvm-rs-cc.  This function cleans up any global variable that contains
    290     (or is) a reference counted Renderscript object type (such as an
    291     rs_allocation, rs_font, or rs_script).  This function will be invoked
    292     implicitly by the Renderscript runtime during script teardown.
    293 
    294 * In terms of a script's global data, global variables can be written
    295   from Java.  The Java instance will cache the value or object set and
    296   provide return methods to retrieve this value.  If a script updates
    297   the value, this update will not propagate back to the Java class.
    298   Initializers, if present, will also initialize the cached Java value.
    299   This provides a convenient way to declare constants within a script and
    300   make them accessible to the Java runtime.  If the script declares a
    301   variable const, only the get methods will be generated.
    302 
    303   Globals within a script are considered local to the script.  They
    304   cannot be accessed by other scripts and are in effect always 'static'
    305   in the traditional C sense.  Static here is used to control if
    306   accessors are generated.  Static continues to mean *not
    307   externally visible* and thus prevents the generation of
    308   accessors.  Globals are persistent across invocations of a script and
    309   thus may be used to hold data from run to run.
    310 
    311   Globals of two types may be reflected into the Java class.  The first
    312   type is basic non-pointer types.  Types defined in rs_types.rsh may also be
    313   used.  For the non-pointer class, get and set methods are generated for
    314   Java.  Globals of single pointer types behave differently.  These may
    315   use more complex types.  Simple structures composed of the types in
    316   rs_types.rsh may also be used.  These globals generate bind points in
    317   Java.  If the type is a structure they also generate an appropriate
    318   **Field** class that is used to pack and unpack the contents of the
    319   structure.  Binding an allocation in Java effectively sets the
    320   pointer in the script.  Bind points marked const indicate to the
    321   runtime that the script will not modify the contents of an allocation.
    322   This may allow the runtime to make more effective use of threads.
    323 
    324 
    325 5. Vector Types
    326 ---------------
    327 
    328 Vector types such as float2, float4, and uint4 are included to support
    329 vector processing in environments where the processors provide vector
    330 instructions.
    331 
    332 On non-vector systems the same code will continue to run but without
    333 the performance advantage.  Function overloading is also supported.
    334 This allows the runtime to support vector version of the basic math
    335 routines without the need for special naming.  For instance,
    336 
    337 * *float sin(float);*
    338 
    339 * *float2 sin(float2);*
    340 
    341 * *float3 sin(float3);*
    342 
    343 * *float4 sin(float4);*
    344