<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" /> <title>llvm-rs-cc: Compiler for Renderscript language</title> <style type="text/css"> /* :Author: David Goodger (goodger@python.org) :Id: $Id: html4css1.css 5951 2009-05-18 18:03:10Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } /* Uncomment (and remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin: 0 0 0.5em 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left, .figure.align-left{ clear: left ; float: left ; margin-right: 1em } img.align-right, .figure.align-right { clear: right ; float: right ; margin-left: 1em } .align-left { text-align: left } .align-center { clear: both ; text-align: center } .align-right { text-align: right } /* reset inner alignment in figures */ div.align-right { text-align: left } /* div.align-center * { */ /* text-align: left } */ ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font: inherit } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em } span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none } </style> </head> <body> <div class="document" id="llvm-rs-cc-compiler-for-renderscript-language"> <h1 class="title">llvm-rs-cc: Compiler for Renderscript language</h1> <div class="section" id="introduction"> <h1>Introduction</h1> <p>llvm-rs-cc compiles a program in the Renderscript language to generate the following files:</p> <ul class="simple"> <li>Bitcode file. Note that the bitcode here denotes the LLVM (Low-Level Virtual Machine) bitcode representation, which will be consumed on an Android device by libbcc (in platform/frameworks/compile/libbcc.git) to generate device-specific executables.</li> <li>Reflected APIs for Java. As a result, Android's Java developers can invoke those APIs from their code.</li> </ul> <p>Note that although Renderscript is C99-like, we enhance it with several distinct, effective features for Android programming. We will use some examples to illustrate these features.</p> <p>llvm-rs-cc is run on the host and performs many aggressive optimizations. As a result, libbcc on the device can be lightweight and focus on machine-dependent code generation for some input bitcode.</p> <p>llvm-rs-cc is a driver on top of libslang. The architecture of libslang and libbcc is depicted in the following figure:</p> <pre class="literal-block"> libslang libbcc | \ | | \ | clang llvm </pre> </div> <div class="section" id="usage"> <h1>Usage</h1> <ul> <li><p class="first"><em>-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw</em></p> <p>This option specifies the directory for outputting a .bc file.</p> </li> <li><p class="first"><em>-p $(PRIVATE_RS_OUTPUT_DIR)/src</em></p> <p>The option <em>-p</em> denotes the directory for outputting the reflected Java files.</p> </li> <li><p class="first"><em>-d $(PRIVATE_RS_OUTPUT_DIR)</em></p> <p>This option <em>-d</em> sets the directory for writing dependence information.</p> </li> <li><p class="first"><em>-MD</em></p> <p>Note that <em>-MD</em> will tell llvm-rs-cc to output dependence information.</p> </li> <li><p class="first"><em>-a $(EXTRA_TARGETS)</em></p> <p>Specifies additional target dependencies.</p> </li> </ul> </div> <div class="section" id="example-command"> <h1>Example Command</h1> <p>First:</p> <pre class="literal-block"> $ cd <Android_Root_Directory> </pre> <p>Using frameworks/base/tests/RenderScriptTests/Fountain as a simple app in both Java and Renderscript, we can find the following command line in the build log:</p> <pre class="literal-block"> $ out/host/linux-x86/bin/llvm-rs-cc \ -o out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/res/raw \ -p out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/src \ -d out/target/common/obj/APPS/Fountain_intermediates/src/renderscript \ -a out/target/common/obj/APPS/Fountain_intermediates/src/RenderScript.stamp \ -MD \ -I frameworks/base/libs/rs/scriptc \ -I external/clang/lib/Headers \ frameworks/base/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs </pre> <p>This command will generate:</p> <ul class="simple"> <li><strong>fountain.bc</strong></li> <li><strong>ScriptC_fountain.java</strong></li> <li><strong>ScriptField_Point.java</strong></li> </ul> <p>The <strong>Script*.java</strong> files above will be documented below.</p> </div> <div class="section" id="example-program-fountain-rs"> <h1>Example Program: fountain.rs</h1> <p>fountain.rs is in the Renderscript language, which is based on the standard C99. However, llvm-rs-cc goes beyond "clang -std=c99" and provides the following important features:</p> </div> <div class="section" id="pragma"> <h1>1. Pragma</h1> <ul> <li><p class="first"><em>#pragma rs java_package_name([PACKAGE_NAME])</em></p> <p>The ScriptC_[SCRIPT_NAME].java has to be packaged so that Java developers can invoke those APIs.</p> <p>To do that, a Renderscript programmer should specify the package name, so that llvm-rs-cc knows the package expression and hence the directory for outputting ScriptC_[SCRIPT_NAME].java.</p> <p>In fountain.rs, we have:</p> <pre class="literal-block"> #pragma rs java_package_name(com.android.fountain) </pre> <p>In ScriptC_fountain.java, we have:</p> <pre class="literal-block"> package com.android.fountain </pre> <p>Note that the ScriptC_fountain.java will be generated inside ./com/android/fountain/.</p> </li> <li><p class="first">#pragma version(1)</p> <p>This pragma is for evolving the language. Currently we are at version 1 of the language.</p> </li> </ul> </div> <div class="section" id="basic-reflection-export-variables-and-functions"> <h1>2. Basic Reflection: Export Variables and Functions</h1> <p>llvm-rs-cc automatically exports the "externalizable and defined" functions and variables to Android's Java side. That is, scripts are accessible from Java.</p> <p>For instance, for:</p> <pre class="literal-block"> int foo = 0; </pre> <p>In ScriptC_fountain.java, llvm-rs-cc will reflect the following methods:</p> <pre class="literal-block"> void set_foo(int v)... int get_foo()... </pre> <p>This access takes the form of generated classes which provide access to the functions and global variables within a script. In summary, global variables and functions within a script that are not declared static will generate get, set, or invoke methods. This provides a way to set the data within a script and call its functions.</p> <p>Take the addParticles function in fountain.rs as an example:</p> <pre class="literal-block"> void addParticles(int rate, float x, float y, int index, bool newColor) { ... } </pre> <p>llvm-rs-cc will genearte ScriptC_fountain.java as follows:</p> <pre class="literal-block"> void invoke_addParticles(int rate, float x, float y, int index, bool newColor) { ... } </pre> </div> <div class="section" id="export-user-defined-structs"> <h1>3. Export User-Defined Structs</h1> <p>In fountain.rs, we have:</p> <pre class="literal-block"> typedef struct __attribute__((packed, aligned(4))) Point { float2 delta; float2 position; uchar4 color; } Point_t; Point_t *point; </pre> <p>llvm-rs-cc generates one ScriptField*.java file for each user-defined struct. In this case, llvm-rs-cc will reflect two files, ScriptC_fountain.java and ScriptField_Point.java.</p> <p>Note that when the type of an exportable variable is a structure, Renderscript developers should avoid using anonymous structs. This is because llvm-rs-cc uses the struct name to identify the file, instead of the typedef name.</p> <p>For the generated Java files, using ScriptC_fountain.java as an example we also have:</p> <pre class="literal-block"> void bind_point(ScriptField_Point v) </pre> <p>This binds your object with the allocated memory.</p> <p>You can bind the struct(e.g., Point), using the setter and getter methods in ScriptField_Point.java.</p> <p>After binding, you can access the object with this method:</p> <pre class="literal-block"> ScriptField_Point get_point() </pre> <p>In ScriptField_Point_s.java:</p> <pre class="literal-block"> ... // Copying the Item, which is the object that stores every // fields of struct, to the *index*\-th entry of byte array. // // In general, this method would not be invoked directly // but is used to implement the setter. void copyToArray(Item i, int index) // The setter of Item array, // index: the index of the Item array // copyNow: If true, it will be copied to the *index*\-th entry // of byte array. void set(Item i, int index, boolean copyNow) // The getter of Item array, which gets the *index*-th element // of byte array. Item get(int index) set_delta(int index, Float2 v, boolean copyNow) // The following is the individual setters and getters of // each field of a struct. public void set_delta(int index, Float2 v, boolean copyNow) public void set_position(int index, Float2 v, boolean copyNow) public void set_color(int index, Short4 v, boolean copyNow) public Float2 get_delta(int index) public Float2 get_position(int index) public Short4 get_color(int index) // Copying all Item array to byte array (i.e., memory allocation). void copyAll() ... </pre> </div> <div class="section" id="summary-of-the-java-reflection-above"> <h1>4. Summary of the Java Reflection above</h1> <p>This section summarizes the high-level design of Renderscript's reflection.</p> <ul> <li><p class="first">In terms of a script's global functions, they can be called from Java. These calls operate asynchronously and no assumptions should be made on whether a function called will have actually completed operation. If it is necessary to wait for a function to complete, the Java application may call the runtime finish() method, which will wait for all the script threads to complete pending operations. A few special functions can also exist:</p> <ul> <li><p class="first">The function <strong>init</strong> (if present) will be called once after the script is loaded. This is useful to initialize data or anything else the script may need before it can be used. The init function may not depend on globals initialized from Java as it will be called before these can be initialized. The function signature for init must be:</p> <pre class="literal-block"> void init(void); </pre> </li> <li><p class="first">The function <strong>root</strong> is a special function for graphics. This function will be called when a script must redraw its contents. No assumptions should be made as to when this function will be called. It will only be called if the script is bound as a graphics root. Calls to this function will be synchronized with data updates and other invocations from Java. Thus the script will not change due to external influence in the middle of running <strong>root</strong>. The return value indicates to the runtime when the function should be called again to redraw in the future. A return value of 0 indicates that no redraw is necessary until something changes on the Java side. Any positive integer indicates a time in milliseconds that the runtime should wait before calling root again to render another frame. The function signature for a graphics root functions is as follows:</p> <pre class="literal-block"> int root(void); </pre> </li> <li><p class="first">It is also possible to create a purely compute-based <strong>root</strong> function. Such a function has the following signature:</p> <pre class="literal-block"> void root(const T1 *in, T2 *out, const T3 *usrData, uint32_t x, uint32_t y); </pre> <p>T1, T2, and T3 represent any supported Renderscript type. Any parameters above can be omitted, although at least one of in/out must be present. If both in and out are present, root must only be invoked with types of the same exact dimensionality (i.e. matching X and Y values for dimension). This root function is accessible through the Renderscript language construct <strong>forEach</strong>. We also reflect a Java version to access this function as <strong>forEach_root</strong> (for API levels of 14+). An example of this can be seen in the Android SDK sample for HelloCompute.</p> </li> <li><p class="first">The function <strong>.rs.dtor</strong> is a function that is sometimes generated by llvm-rs-cc. This function cleans up any global variable that contains (or is) a reference counted Renderscript object type (such as an rs_allocation, rs_font, or rs_script). This function will be invoked implicitly by the Renderscript runtime during script teardown.</p> </li> </ul> </li> <li><p class="first">In terms of a script's global data, global variables can be written from Java. The Java instance will cache the value or object set and provide return methods to retrieve this value. If a script updates the value, this update will not propagate back to the Java class. Initializers, if present, will also initialize the cached Java value. This provides a convenient way to declare constants within a script and make them accessible to the Java runtime. If the script declares a variable const, only the get methods will be generated.</p> <p>Globals within a script are considered local to the script. They cannot be accessed by other scripts and are in effect always 'static' in the traditional C sense. Static here is used to control if accessors are generated. Static continues to mean <em>not externally visible</em> and thus prevents the generation of accessors. Globals are persistent across invocations of a script and thus may be used to hold data from run to run.</p> <p>Globals of two types may be reflected into the Java class. The first type is basic non-pointer types. Types defined in rs_types.rsh may also be used. For the non-pointer class, get and set methods are generated for Java. Globals of single pointer types behave differently. These may use more complex types. Simple structures composed of the types in rs_types.rsh may also be used. These globals generate bind points in Java. If the type is a structure they also generate an appropriate <strong>Field</strong> class that is used to pack and unpack the contents of the structure. Binding an allocation in Java effectively sets the pointer in the script. Bind points marked const indicate to the runtime that the script will not modify the contents of an allocation. This may allow the runtime to make more effective use of threads.</p> </li> </ul> </div> <div class="section" id="vector-types"> <h1>5. Vector Types</h1> <p>Vector types such as float2, float4, and uint4 are included to support vector processing in environments where the processors provide vector instructions.</p> <p>On non-vector systems the same code will continue to run but without the performance advantage. Function overloading is also supported. This allows the runtime to support vector version of the basic math routines without the need for special naming. For instance,</p> <ul class="simple"> <li><em>float sin(float);</em></li> <li><em>float2 sin(float2);</em></li> <li><em>float3 sin(float3);</em></li> <li><em>float4 sin(float4);</em></li> </ul> </div> </div> </body> </html>