| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 1 | page.title=Advanced RenderScript |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 2 | parent.title=Computation |
| 3 | parent.link=index.html |
| 4 | |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 5 | @jd:body |
| 6 | |
| 7 | <div id="qv-wrapper"> |
| 8 | <div id="qv"> |
| 9 | <h2>In this document</h2> |
| 10 | |
| 11 | <ol> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 12 | <li><a href="#native">RenderScript Runtime Layer</a></li> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 13 | <li><a href="#reflected">Reflected Layer</a> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 14 | <ol> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 15 | <li><a href="#func">Functions</a></li> |
| 16 | <li><a href="#var">Variables</a></li> |
| 17 | <li><a href="#pointer">Pointers</a></li> |
| 18 | <li><a href="#struct">Structs</a></li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 19 | </ol> |
| 20 | </li> |
| 21 | |
| 22 | <li> |
| 23 | <a href="#mem-allocation">Memory Allocation APIs</a> |
| 24 | </li> |
| 25 | <li> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 26 | <a href="#memory">Working with Memory</a> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 27 | <ol> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 28 | <li><a href="#allocating-mem">Allocating and binding memory to the RenderScript</a></li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 29 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 30 | <li><a href="#read-write">Reading and writing to memory</a></li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 31 | |
| 32 | </ol> |
| 33 | </li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 34 | </ol> |
| 35 | </div> |
| 36 | </div> |
| 37 | |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 38 | <p></p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 39 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 40 | <p>Because applications that utilize RenderScript still run inside of the Android VM, |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 41 | you have access to all of the framework APIs that you are familiar with, but can |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 42 | utilize RenderScript when appropriate. To facilitate this interaction between |
| 43 | the framework and the RenderScript runtime, an intermediate layer of code is also |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 44 | present to facilitate communication and memory management between the two levels of code. |
| 45 | This document goes into more detail about these |
| 46 | different layers of code as well as how memory is shared between the Android VM and |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 47 | RenderScript runtime.</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 48 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 49 | <h2 id="native">RenderScript Runtime Layer</h2> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 50 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 51 | <p>Your RenderScript code is compiled and |
| 52 | executed in a compact and well-defined runtime layer. The RenderScript runtime APIs offer support for |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 53 | intensive computation that is portable and automatically scalable to the |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 54 | amount of cores available on a processor. |
| 55 | </p> |
| 56 | <p class="note"><strong>Note:</strong> The standard C functions in the NDK must be |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 57 | guaranteed to run on a CPU, so RenderScript cannot access these libraries, |
| 58 | because RenderScript is designed to run on different types of processors.</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 59 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 60 | <p>You define your RenderScript code in <code>.rs</code> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 61 | and <code>.rsh</code> files in the <code>src/</code> directory of your Android project. The code |
| 62 | is compiled to intermediate bytecode by the |
| 63 | <code>llvm</code> compiler that runs as part of an Android build. When your application |
| 64 | runs on a device, the bytecode is then compiled (just-in-time) to machine code by another |
| 65 | <code>llvm</code> compiler that resides on the device. The machine code is optimized for the |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 66 | device and also cached, so subsequent uses of the RenderScript enabled application does not |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 67 | recompile the bytecode.</p> |
| 68 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 69 | <p>Some key features of the RenderScript runtime libraries include:</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 70 | |
| 71 | <ul> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 72 | |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 73 | <li>Memory allocation request features</li> |
| 74 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 75 | <li>A large collection of math functions with both scalar and vector typed overloaded versions |
| 76 | of many common routines. Operations such as adding, multiplying, dot product, and cross product |
| 77 | are available as well as atomic arithmetic and comparison functions.</li> |
| 78 | |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 79 | <li>Conversion routines for primitive data types and vectors, matrix routines, and date and time |
| 80 | routines</li> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 81 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 82 | <li>Data types and structures to support the RenderScript system such as Vector types for |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 83 | defining two-, three-, or four-vectors.</li> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 84 | |
| 85 | <li>Logging functions</li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 86 | </ul> |
| 87 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 88 | <p>See the RenderScript runtime API reference for more information on the available functions. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 89 | |
| 90 | <h2 id="reflected">Reflected Layer</h2> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 91 | |
| 92 | <p>The reflected layer is a set of classes that the Android build tools generate to allow access |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 93 | to the RenderScript runtime from the Android framework. This layer also provides methods |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 94 | and constructors that allow you to allocate and work with memory for pointers that are defined in |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 95 | your RenderScript code. The following list describes the major |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 96 | components that are reflected:</p> |
| 97 | |
| 98 | <ul> |
| 99 | <li>Every <code>.rs</code> file that you create is generated into a class named |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 100 | <code>project_root/gen/package/name/ScriptC_<em>renderscript_filename</em></code> of |
| 101 | type {@link android.renderscript.ScriptC}. This file is the <code>.java</code> version of your |
| 102 | <code>.rs</code> file, which you can call from the Android framework. This class contains the |
| 103 | following items reflected from the <code>.rs</code> file: |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 104 | |
| 105 | <ul> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 106 | <li>Non-static functions</li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 107 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 108 | <li>Non-static, global RenderScript variables. Accessor methods are generated for each |
| 109 | variable, so you can read and write the RenderScript variables from the Android |
| 110 | framework. If a global variable is initialized at the RenderScript runtime layer, those |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 111 | values are used to initialize the corresponding values in the Android framework layer. If global |
| 112 | variables are marked as <code>const</code>, then a <code>set</code> method is not |
| 113 | generated.</p></li> |
| 114 | |
| 115 | <li>Global pointers</li> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 116 | </ul> |
| 117 | </li> |
| 118 | |
| 119 | <li>A <code>struct</code> is reflected into its own class named |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 120 | |
| 121 | <code>project_root/gen/package/name/ScriptField_struct_name</em></code>, which extends {@link |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 122 | android.renderscript.Script.FieldBase}. This class represents an array of the |
| 123 | <code>struct</code>, which allows you to allocate memory for one or more instances of this |
| 124 | <code>struct</code>.</li> |
| 125 | </ul> |
| 126 | |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 127 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 128 | <h3 id="func">Functions</h3> |
| 129 | <p>Functions are reflected into the script class itself, located in |
| 130 | <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 131 | example, if you declare the following function in your RenderScript code:</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 132 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 133 | <pre> |
| 134 | void touch(float x, float y, float pressure, int id) { |
| 135 | if (id >= 10) { |
| 136 | return; |
| 137 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 138 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 139 | touchPos[id].x = x; |
| 140 | touchPos[id].y = y; |
| 141 | touchPressure[id] = pressure; |
| 142 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 143 | </pre> |
| 144 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 145 | <p>then the following code is generated:</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 146 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 147 | <pre> |
| 148 | public void invoke_touch(float x, float y, float pressure, int id) { |
| 149 | FieldPacker touch_fp = new FieldPacker(16); |
| 150 | touch_fp.addF32(x); |
| 151 | touch_fp.addF32(y); |
| 152 | touch_fp.addF32(pressure); |
| 153 | touch_fp.addI32(id); |
| 154 | invoke(mExportFuncIdx_touch, touch_fp); |
| 155 | } |
| 156 | </pre> |
| 157 | <p> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 158 | Functions cannot have a return value, because the RenderScript system is designed to be |
| 159 | asynchronous. When your Android framework code calls into RenderScript, the call is queued and is |
| 160 | executed when possible. This restriction allows the RenderScript system to function without constant |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 161 | interruption and increases efficiency. If functions were allowed to have return values, the call |
| 162 | would block until the value was returned.</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 163 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 164 | <p> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 165 | If you want the RenderScript code to send a value back to the Android framework, use the |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 166 | <a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> |
| 167 | function. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 168 | </p> |
| 169 | |
| 170 | <h3 id="var">Variables</h3> |
| 171 | |
| 172 | <p>Variables of supported types are reflected into the script class itself, located in |
| 173 | <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor |
| 174 | methods are generated for each variable. For example, if you declare the following variable in |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 175 | your RenderScript code:</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 176 | <pre>uint32_t unsignedInteger = 1;</pre> |
| 177 | |
| 178 | <p>then the following code is generated:</p> |
| 179 | |
| 180 | <pre> |
| 181 | private long mExportVar_unsignedInteger; |
| 182 | public void set_unsignedInteger(long v){ |
| 183 | mExportVar_unsignedInteger = v; |
| 184 | setVar(mExportVarIdx_unsignedInteger, v); |
| 185 | } |
| 186 | |
| 187 | public long get_unsignedInteger(){ |
| 188 | return mExportVar_unsignedInteger; |
| 189 | } |
| 190 | </pre> |
| 191 | |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 192 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 193 | <h3 id="struct">Structs</h3> |
| 194 | <p>Structs are reflected into their own classes, located in |
| 195 | <code><project_root>/gen/com/example/renderscript/ScriptField_struct_name</code>. This |
| 196 | class represents an array of the <code>struct</code> and allows you to allocate memory for a |
| 197 | specified number of <code>struct</code>s. For example, if you declare the following struct:</p> |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 198 | <pre> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 199 | typedef struct Point { |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 200 | float2 position; |
| 201 | float size; |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 202 | } Point_t; |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 203 | </pre> |
| 204 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 205 | <p>then the following code is generated in <code>ScriptField_Point.java</code>: |
| 206 | <pre> |
| 207 | package com.example.android.rs.hellocompute; |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 208 | |
| 209 | import android.renderscript.*; |
| 210 | import android.content.res.Resources; |
| 211 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 212 | /** |
| 213 | * @hide |
| 214 | */ |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 215 | public class ScriptField_Point extends android.renderscript.Script.FieldBase { |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 216 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 217 | static public class Item { |
| 218 | public static final int sizeof = 12; |
| 219 | |
| 220 | Float2 position; |
| 221 | float size; |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 222 | |
| 223 | Item() { |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 224 | position = new Float2(); |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 225 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 226 | } |
| 227 | |
| 228 | private Item mItemArray[]; |
| 229 | private FieldPacker mIOBuffer; |
| 230 | public static Element createElement(RenderScript rs) { |
| 231 | Element.Builder eb = new Element.Builder(rs); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 232 | eb.add(Element.F32_2(rs), "position"); |
| 233 | eb.add(Element.F32(rs), "size"); |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 234 | return eb.create(); |
| 235 | } |
| 236 | |
| 237 | public ScriptField_Point(RenderScript rs, int count) { |
| 238 | mItemArray = null; |
| 239 | mIOBuffer = null; |
| 240 | mElement = createElement(rs); |
| 241 | init(rs, count); |
| 242 | } |
| 243 | |
| 244 | public ScriptField_Point(RenderScript rs, int count, int usages) { |
| 245 | mItemArray = null; |
| 246 | mIOBuffer = null; |
| 247 | mElement = createElement(rs); |
| 248 | init(rs, count, usages); |
| 249 | } |
| 250 | |
| 251 | private void copyToArray(Item i, int index) { |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 252 | if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count |
| 253 | */); |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 254 | mIOBuffer.reset(index * Item.sizeof); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 255 | mIOBuffer.addF32(i.position); |
| 256 | mIOBuffer.addF32(i.size); |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | public void set(Item i, int index, boolean copyNow) { |
| 260 | if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; |
| 261 | mItemArray[index] = i; |
| 262 | if (copyNow) { |
| 263 | copyToArray(i, index); |
| 264 | mAllocation.setFromFieldPacker(index, mIOBuffer); |
| 265 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | public Item get(int index) { |
| 269 | if (mItemArray == null) return null; |
| 270 | return mItemArray[index]; |
| 271 | } |
| 272 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 273 | public void set_position(int index, Float2 v, boolean copyNow) { |
| 274 | if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 275 | if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; |
| 276 | if (mItemArray[index] == null) mItemArray[index] = new Item(); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 277 | mItemArray[index].position = v; |
| 278 | if (copyNow) { |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 279 | mIOBuffer.reset(index * Item.sizeof); |
| 280 | mIOBuffer.addF32(v); |
| 281 | FieldPacker fp = new FieldPacker(8); |
| 282 | fp.addF32(v); |
| 283 | mAllocation.setFromFieldPacker(index, 0, fp); |
| 284 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 285 | } |
| 286 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 287 | public void set_size(int index, float v, boolean copyNow) { |
| 288 | if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); |
| 289 | if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; |
| 290 | if (mItemArray[index] == null) mItemArray[index] = new Item(); |
| 291 | mItemArray[index].size = v; |
| 292 | if (copyNow) { |
| 293 | mIOBuffer.reset(index * Item.sizeof + 8); |
| 294 | mIOBuffer.addF32(v); |
| 295 | FieldPacker fp = new FieldPacker(4); |
| 296 | fp.addF32(v); |
| 297 | mAllocation.setFromFieldPacker(index, 1, fp); |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | public Float2 get_position(int index) { |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 302 | if (mItemArray == null) return null; |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 303 | return mItemArray[index].position; |
| 304 | } |
| 305 | |
| 306 | public float get_size(int index) { |
| 307 | if (mItemArray == null) return 0; |
| 308 | return mItemArray[index].size; |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | public void copyAll() { |
| 312 | for (int ct = 0; ct < mItemArray.length; ct++) copyToArray(mItemArray[ct], ct); |
| 313 | mAllocation.setFromFieldPacker(0, mIOBuffer); |
| 314 | } |
| 315 | |
| 316 | public void resize(int newSize) { |
| 317 | if (mItemArray != null) { |
| 318 | int oldSize = mItemArray.length; |
| 319 | int copySize = Math.min(oldSize, newSize); |
| 320 | if (newSize == oldSize) return; |
| 321 | Item ni[] = new Item[newSize]; |
| 322 | System.arraycopy(mItemArray, 0, ni, 0, copySize); |
| 323 | mItemArray = ni; |
| 324 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 325 | mAllocation.resize(newSize); |
| 326 | if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); |
| 327 | } |
| Robert Ly | f197b63 | 2011-06-08 22:23:42 -0700 | [diff] [blame] | 328 | } |
| 329 | </pre> |
| 330 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 331 | <p>The generated code is provided to you as a convenience to allocate memory for structs requested |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 332 | by the RenderScript runtime and to interact with <code>struct</code>s |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 333 | in memory. Each <code>struct</code>'s class defines the following methods and constructors:</p> |
| 334 | |
| 335 | <ul> |
| 336 | <li>Overloaded constructors that allow you to allocate memory. The |
| 337 | <code>ScriptField_<em>struct_name</em>(RenderScript rs, int count)</code> constructor allows |
| 338 | you to define the number of structures that you want to allocate memory for with the |
| 339 | <code>count</code> parameter. The <code>ScriptField_<em>struct_name</em>(RenderScript rs, int |
| 340 | count, int usages)</code> constructor defines an extra parameter, <code>usages</code>, that |
| 341 | lets you specify the memory space of this memory allocation. There are four memory space |
| 342 | possibilities: |
| 343 | |
| 344 | <ul> |
| 345 | <li>{@link android.renderscript.Allocation#USAGE_SCRIPT}: Allocates in the script memory |
| 346 | space. This is the default memory space if you do not specify a memory space.</li> |
| 347 | |
| 348 | <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}: Allocates in the |
| 349 | texture memory space of the GPU.</li> |
| 350 | |
| 351 | <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_VERTEX}: Allocates in the vertex |
| 352 | memory space of the GPU.</li> |
| 353 | |
| 354 | <li>{@link android.renderscript.Allocation#USAGE_GRAPHICS_CONSTANTS}: Allocates in the |
| 355 | constants memory space of the GPU that is used by the various program objects.</li> |
| 356 | </ul> |
| 357 | |
| 358 | <p>You can specify multiple memory spaces by using the bitwise <code>OR</code> operator. Doing so |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 359 | notifies the RenderScript runtime that you intend on accessing the data in the |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 360 | specified memory spaces. The following example allocates memory for a custom data type |
| 361 | in both the script and vertex memory spaces:</p> |
| 362 | <pre> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 363 | ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2, |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 364 | Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX); |
| 365 | </pre> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 366 | </li> |
| 367 | |
| 368 | <li>A static nested class, <code>Item</code>, allows you to create an instance of the |
| 369 | <code>struct</code>, in the form of an object. This nested class is useful if it makes more sense to work |
| 370 | with the <code>struct</code> in your Android code. When you are done manipulating the object, |
| 371 | you can push the object to the allocated memory by calling <code>set(Item i, int index, |
| 372 | boolean copyNow)</code> and setting the <code>Item</code> to the desired position in |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 373 | the array. The RenderScript runtime automatically has access to the newly written memory. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 374 | |
| 375 | <li>Accessor methods to get and set the values of each field in a struct. Each of these |
| 376 | accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in |
| 377 | the array that you want to read or write to. Each setter method also has a |
| 378 | <code>copyNow</code> parameter that specifies whether or not to immediately sync this memory |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 379 | to the RenderScript runtime. To sync any memory that has not been synced, call |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 380 | <code>copyAll()</code>.</li> |
| 381 | |
| 382 | <li>The <code>createElement()</code> method creates a description of the struct in memory. This |
| 383 | description is used to allocate memory consisting of one or many elements.</li> |
| 384 | |
| 385 | <li><code>resize()</code> works much like a <code>realloc()</code> in C, allowing you to |
| 386 | expand previously allocated memory, maintaining the current values that were previously |
| 387 | created.</li> |
| 388 | |
| 389 | <li><code>copyAll()</code> synchronizes memory that was set on the framework level to the |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 390 | RenderScript runtime. When you call a set accessor method on a member, there is an optional |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 391 | <code>copyNow</code> boolean parameter that you can specify. Specifying |
| 392 | <code>true</code> synchronizes the memory when you call the method. If you specify false, |
| 393 | you can call <code>copyAll()</code> once, and it synchronizes memory for all the |
| 394 | properties that are not yet synchronized.</li> |
| 395 | </ul> |
| 396 | |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 397 | <h3 id="pointer">Pointers</h3> |
| 398 | <p>Pointers are reflected into the script class itself, located in |
| 399 | <code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 400 | can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 401 | <code>struct</code> cannot contain pointers or nested arrays. For example, if you declare the |
| 402 | following pointers to a <code>struct</code> and <code>int32_t</code></p> |
| 403 | |
| 404 | <pre> |
| 405 | typedef struct Point { |
| 406 | float2 position; |
| 407 | float size; |
| 408 | } Point_t; |
| 409 | |
| 410 | Point_t *touchPoints; |
| 411 | int32_t *intPointer; |
| 412 | </pre> |
| 413 | <p>then the following code is generated in:</p> |
| 414 | |
| 415 | <pre> |
| 416 | private ScriptField_Point mExportVar_touchPoints; |
| 417 | public void bind_touchPoints(ScriptField_Point v) { |
| 418 | mExportVar_touchPoints = v; |
| 419 | if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); |
| 420 | else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints); |
| 421 | } |
| 422 | |
| 423 | public ScriptField_Point get_touchPoints() { |
| 424 | return mExportVar_touchPoints; |
| 425 | } |
| 426 | |
| 427 | private Allocation mExportVar_intPointer; |
| 428 | public void bind_intPointer(Allocation v) { |
| 429 | mExportVar_intPointer = v; |
| 430 | if (v == null) bindAllocation(null, mExportVarIdx_intPointer); |
| 431 | else bindAllocation(v, mExportVarIdx_intPointer); |
| 432 | } |
| 433 | |
| 434 | public Allocation get_intPointer() { |
| 435 | return mExportVar_intPointer; |
| 436 | } |
| 437 | </pre> |
| 438 | |
| 439 | <p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code> |
| 440 | (instead of a <code>set()</code> method) is generated. This method allows you to bind the memory |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 441 | that is allocated in the Android VM to the RenderScript runtime (you cannot allocate |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 442 | memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working |
| 443 | with Allocated Memory</a>. |
| 444 | </p> |
| 445 | |
| 446 | |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 447 | <h2 id="mem-allocation">Memory Allocation APIs</h2> |
| 448 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 449 | <p>Applications that use RenderScript still run in the Android VM. The actual RenderScript code, however, runs natively and |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 450 | needs access to the memory allocated in the Android VM. To accomplish this, you must |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 451 | attach the memory that is allocated in the VM to the RenderScript runtime. This |
| 452 | process, called binding, allows the RenderScript runtime to seamlessly work with memory that it |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 453 | requests but cannot explicitly allocate. The end result is essentially the same as if you had |
| 454 | called <code>malloc</code> in C. The added benefit is that the Android VM can carry out garbage collection as well as |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 455 | share memory with the RenderScript runtime layer. Binding is only necessary for dynamically allocated memory. Statically |
| 456 | allocated memory is automatically created for your RenderScript code at compile time. See <a href="#figure1">Figure 1</a> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 457 | for more information on how memory allocation occurs. |
| 458 | </p> |
| 459 | |
| 460 | <p>To support this memory allocation system, there are a set of APIs that allow the Android VM to |
| 461 | allocate memory and offer similar functionality to a <code>malloc</code> call. These classes |
| 462 | essentially describe how memory should be allocated and also carry out the allocation. To better |
| 463 | understand how these classes work, it is useful to think of them in relation to a simple |
| 464 | <code>malloc</code> call that can look like this: </p> |
| 465 | |
| 466 | <pre>array = (int *)malloc(sizeof(int)*10);</pre> |
| 467 | |
| 468 | <p>The <code>malloc</code> call can be broken up into two parts: the size of the memory being allocated (<code>sizeof(int)</code>), |
| 469 | along with how many units of that memory should be allocated (10). The Android framework provides classes for these two parts as |
| 470 | well as a class to represent <code>malloc</code> itself.</p> |
| 471 | |
| 472 | <p>The {@link android.renderscript.Element} class represents the (<code>sizeof(int)</code>) portion |
| 473 | of the <code>malloc</code> call and encapsulates one cell of a memory allocation, such as a single |
| 474 | float value or a struct. The {@link android.renderscript.Type} class encapsulates the {@link android.renderscript.Element} |
| 475 | and the amount of elements to allocate (10 in our example). You can think of a {@link android.renderscript.Type} as |
| 476 | an array of {@link android.renderscript.Element}s. The {@link android.renderscript.Allocation} class does the actual |
| 477 | memory allocation based on a given {@link android.renderscript.Type} and represents the actual allocated memory.</p> |
| 478 | |
| 479 | <p>In most situations, you do not need to call these memory allocation APIs directly. The reflected layer |
| 480 | classes generate code to use these APIs automatically and all you need to do to allocate memory is call a |
| 481 | constructor that is declared in one of the reflected layer classes and then bind |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 482 | the resulting memory {@link android.renderscript.Allocation} to the RenderScript. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 483 | There are some situations where you would want to use these classes directly to allocate memory on your |
| 484 | own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to |
| 485 | primitive types. You can see how to do this in the |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 486 | <a href="#allocating-mem">Allocating and binding memory to the RenderScript</a> section. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 487 | The following table describes the three memory management classes in more detail:</p> |
| 488 | |
| 489 | <table id="mem-mgmt-table"> |
| 490 | <tr> |
| 491 | <th>Android Object Type</th> |
| 492 | |
| 493 | <th>Description</th> |
| 494 | </tr> |
| 495 | |
| 496 | <tr> |
| 497 | <td>{@link android.renderscript.Element}</td> |
| 498 | |
| 499 | <td> |
| 500 | <p>An element describes one cell of a memory allocation and can have two forms: basic or |
| 501 | complex.</p> |
| 502 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 503 | <p>A basic element contains a single component of data of any valid RenderScript data type. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 504 | Examples of basic element data types include a single <code>float</code> value, a <code>float4</code> vector, or a |
| 505 | single RGB-565 color.</p> |
| 506 | |
| 507 | <p>Complex elements contain a list of basic elements and are created from |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 508 | <code>struct</code>s that you declare in your RenderScript code. For instance an allocation |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 509 | can contain multiple <code>struct</code>s arranged in order in memory. Each struct is considered as its |
| 510 | own element, rather than each data type within that struct.</p> |
| 511 | </td> |
| 512 | </tr> |
| 513 | |
| 514 | <tr> |
| 515 | <td>{@link android.renderscript.Type}</td> |
| 516 | |
| 517 | <td> |
| 518 | <p>A type is a memory allocation template and consists of an element and one or more |
| 519 | dimensions. It describes the layout of the memory (basically an array of {@link |
| 520 | android.renderscript.Element}s) but does not allocate the memory for the data that it |
| 521 | describes.</p> |
| 522 | |
| 523 | <p>A type consists of five dimensions: X, Y, Z, LOD (level of detail), and Faces (of a cube |
| 524 | map). You can assign the X,Y,Z dimensions to any positive integer value within the |
| 525 | constraints of available memory. A single dimension allocation has an X dimension of |
| 526 | greater than zero while the Y and Z dimensions are zero to indicate not present. For |
| 527 | example, an allocation of x=10, y=1 is considered two dimensional and x=10, y=0 is |
| 528 | considered one dimensional. The LOD and Faces dimensions are booleans to indicate present |
| 529 | or not present.</p> |
| 530 | </td> |
| 531 | </tr> |
| 532 | |
| 533 | <tr> |
| 534 | <td>{@link android.renderscript.Allocation}</td> |
| 535 | |
| 536 | <td> |
| 537 | <p>An allocation provides the memory for applications based on a description of the memory |
| 538 | that is represented by a {@link android.renderscript.Type}. Allocated memory can exist in |
| 539 | many memory spaces concurrently. If memory is modified in one space, you must explicitly |
| 540 | synchronize the memory, so that it is updated in all the other spaces in which it exists. |
| 541 | </p> |
| 542 | |
| 543 | <p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked. |
| 544 | For simple arrays there are <code>copyFrom()</code> functions that take an array from the |
| 545 | Android system and copy it to the native layer memory store. The unchecked variants allow |
| 546 | the Android system to copy over arrays of structures because it does not support |
| 547 | structures. For example, if there is an allocation that is an array of n floats, the data |
| 548 | contained in a float[n] array or a <code>byte[n*4]</code> array can be copied.</p> |
| 549 | </td> |
| 550 | </tr> |
| 551 | </table> |
| 552 | |
| 553 | <h2 id="memory">Working with Memory</h2> |
| 554 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 555 | <p>Non-static, global variables that you declare in your RenderScript are allocated memory at compile time. |
| 556 | You can work with these variables directly in your RenderScript code without having to allocate |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 557 | memory for them at the Android framework level. The Android framework layer also has access to these variables |
| 558 | with the provided accessor methods that are generated in the reflected layer classes. If these variables are |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 559 | initialized at the RenderScript runtime layer, those values are used to initialize the corresponding |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 560 | values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is |
| 561 | not generated.</p> |
| 562 | |
| 563 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 564 | <p class="note"><strong>Note:</strong> If you are using certain RenderScript structures that contain pointers, such as |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 565 | <code>rs_program_fragment</code> and <code>rs_allocation</code>, you have to obtain an object of the |
| 566 | corresponding Android framework class first and then call the <code>set</code> method for that |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 567 | structure to bind the memory to the RenderScript runtime. You cannot directly manipulate these structures |
| 568 | at the RenderScript runtime layer. This restriction is not applicable to user-defined structures |
| Robert Ly | af16675 | 2012-04-10 10:57:33 -0700 | [diff] [blame] | 569 | that contain pointers, because they cannot be exported to a reflected layer class |
| 570 | in the first place. A compiler error is generated if you try to declare a non-static, global |
| 571 | struct that contains a pointer. |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 572 | </p> |
| 573 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 574 | <p>RenderScript also has support for pointers, but you must explicitly allocate the memory in your |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 575 | Android framework code. When you declare a global pointer in your <code>.rs</code> file, you |
| 576 | allocate memory through the appropriate reflected layer class and bind that memory to the native |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 577 | RenderScript layer. You can interact with this memory from the Android framework layer as well as |
| 578 | the RenderScript layer, which offers you the flexibility to modify variables in the most |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 579 | appropriate layer.</p> |
| 580 | |
| 581 | |
| 582 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 583 | <h3 id="allocating-mem">Allocating and binding dynamic memory to the RenderScript</h3> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 584 | |
| 585 | <p>To allocate dynamic memory, you need to call the constructor of a |
| 586 | {@link android.renderscript.Script.FieldBase} class, which is the most common way. An alternative is to create an |
| 587 | {@link android.renderscript.Allocation} manually, which is required for things such as primitive type pointers. You should |
| 588 | use a {@link android.renderscript.Script.FieldBase} class constructor whenever available for simplicity. |
| 589 | After obtaining a memory allocation, call the reflected <code>bind</code> method of the pointer to bind the allocated memory to the |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 590 | RenderScript runtime.</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 591 | <p>The example below allocates memory for both a primitive type pointer, |
| 592 | <code>intPointer</code>, and a pointer to a struct, <code>touchPoints</code>. It also binds the memory to the |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 593 | RenderScript:</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 594 | <pre> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 595 | private RenderScript myRenderScript; |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 596 | private ScriptC_example script; |
| 597 | private Resources resources; |
| 598 | |
| Robert Ly | 864090e | 2012-06-17 18:22:17 -0700 | [diff] [blame] | 599 | public void init(RenderScript rs, Resources res) { |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 600 | myRenderScript = rs; |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 601 | resources = res; |
| 602 | |
| 603 | //allocate memory for the struct pointer, calling the constructor |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 604 | ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 605 | |
| 606 | //Create an element manually and allocate memory for the int pointer |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 607 | intPointer = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 608 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 609 | //create an instance of the RenderScript, pointing it to the bytecode resource |
| 610 | mScript = new ScriptC_example(myRenderScript, resources, R.raw.example); |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 611 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 612 | //bind the struct and int pointers to the RenderScript |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 613 | mScript.bind_touchPoints(touchPoints); |
| 614 | script.bind_intPointer(intPointer); |
| 615 | |
| 616 | ... |
| 617 | } |
| 618 | </pre> |
| 619 | |
| 620 | <h3>Reading and writing to memory</h3> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 621 | <p>You can read and write to statically and dynamically allocated memory both at the RenderScript runtime |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 622 | and Android framework layer.</p> |
| 623 | |
| 624 | <p>Statically allocated memory comes with a one-way communication restriction |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 625 | at the RenderScript runtime level. When RenderScript code changes the value of a variable, it is not |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 626 | communicated back to the Android framework layer for efficiency purposes. The last value |
| 627 | that is set from the Android framework is always returned during a call to a <code>get</code> |
| 628 | method. However, when Android framework code modifies a variable, that change can be communicated to |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 629 | the RenderScript runtime automatically or synchronized at a later time. If you need to send data |
| 630 | from the RenderScript runtime to the Android framework layer, you can use the |
| Robert Ly | f11ffc11 | 2012-02-22 10:59:12 -0800 | [diff] [blame] | 631 | <a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> function |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 632 | to overcome this limitation. |
| 633 | </p> |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 634 | <p>When working with dynamically allocated memory, any changes at the RenderScript runtime layer are propagated |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 635 | back to the Android framework layer if you modified the memory allocation using its associated pointer. |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 636 | Modifying an object at the Android framework layer immediately propagates that change back to the RenderScript |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 637 | runtime layer.</p> |
| 638 | |
| 639 | <h4>Reading and writing to global variables</h4> |
| 640 | |
| 641 | <p>Reading and writing to global variables is a straightforward process. You can use the accessor methods |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 642 | at the Android framework level or set them directly in the RenderScript code. Keep in mind that any |
| 643 | changes that you make in your RenderScript code are not propagated back to the Android framework layer.</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 644 | |
| 645 | <p>For example, given the following struct declared in a file named <code>rsfile.rs</code>:</p> |
| 646 | <pre> |
| 647 | typedef struct Point { |
| 648 | int x; |
| 649 | int y; |
| 650 | } Point_t; |
| 651 | |
| 652 | Point_t point; |
| 653 | |
| 654 | </pre> |
| 655 | <p>You can assign values to the struct like this directly in <code>rsfile.rs</code>. These values are not |
| 656 | propagated back to the Android framework level:</p> |
| 657 | <pre> |
| 658 | point.x = 1; |
| 659 | point.y = 1; |
| 660 | </pre> |
| 661 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 662 | <p>You can assign values to the struct at the Android framework layer like this. These values are |
| 663 | propagated back to the RenderScript runtime level:</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 664 | <pre> |
| 665 | ScriptC_rsfile mScript; |
| 666 | |
| 667 | ... |
| 668 | |
| 669 | Item i = new ScriptField_Point.Item(); |
| 670 | i.x = 1; |
| 671 | i.y = 1; |
| 672 | mScript.set_point(i); |
| 673 | </pre> |
| 674 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 675 | <p>You can read the values in your RenderScript code like this:</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 676 | |
| 677 | <pre> |
| 678 | rsDebug("Printing out a Point", point.x, point.y); |
| 679 | </pre> |
| 680 | |
| 681 | <p>You can read the values in the Android framework layer with the following code. Keep in mind that this |
| 682 | code only returns a value if one was set at the Android framework level. You will get a null pointer |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 683 | exception if you only set the value at the RenderScript runtime level:</p> |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 684 | |
| 685 | <pre> |
| 686 | Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y); |
| 687 | System.out.println(point.get_x() + " " + point.get_y()); |
| 688 | </pre> |
| 689 | |
| 690 | <h4>Reading and writing global pointers</h4> |
| 691 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 692 | <p>Assuming that memory has been allocated in the Android framework level and bound to the RenderScript runtime, |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 693 | you can read and write memory from the Android framework level by using the <code>get</code> and <code>set</code> methods for that pointer. |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 694 | In the RenderScript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 695 | back to the Android framework layer, unlike with statically allocated memory.</p> |
| 696 | |
| 697 | <p>For example, given the following pointer to a <code>struct</code> in a file named <code>rsfile.rs</code>:</p> |
| 698 | <pre> |
| 699 | typedef struct Point { |
| 700 | int x; |
| 701 | int y; |
| 702 | } Point_t; |
| 703 | |
| 704 | Point_t *point; |
| 705 | </pre> |
| 706 | |
| 707 | <p>Assuming you already allocated memory at the Android framework layer, you can access values in |
| 708 | the <code>struct</code> as normal. Any changes you make to the struct via its pointer variable |
| 709 | are automatically available to the Android framework layer:</p> |
| 710 | |
| 711 | <pre> |
| 712 | point[index].x = 1; |
| 713 | point[index].y = 1; |
| 714 | </pre> |
| 715 | |
| 716 | <p>You can read and write values to the pointer at the Android framework layer as well: |
| 717 | <pre> |
| 718 | ScriptField_Point p = new ScriptField_Point(mRS, 1); |
| 719 | Item i = new ScriptField_Point.Item(); |
| 720 | i.x=100; |
| 721 | i.y = 100; |
| 722 | p.set(i, 0, true); |
| 723 | mScript.bind_point(p); |
| 724 | |
| 725 | points.get_x(0); //read x and y from index 0 |
| 726 | points.get_x(0); |
| 727 | </pre> |
| 728 | |
| Tim Murray | 015d268 | 2013-05-30 12:34:40 -0700 | [diff] [blame] | 729 | <p>Once memory is already bound, you do not have to rebind the memory to the RenderScript |
| Robert Ly | b078d94 | 2012-01-05 10:50:39 -0800 | [diff] [blame] | 730 | runtime every time you make a change to a value.</p> |