blob: ea02a17041ea21ebacd703084cbf492ff3ea67bd [file] [log] [blame]
Jason Samsb8c5a842009-07-31 20:40:47 -07001/*
Stephen Hines9069ee82012-02-13 18:25:54 -08002 * Copyright (C) 2008-2012 The Android Open Source Project
Jason Samsb8c5a842009-07-31 20:40:47 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.renderscript;
18
Jason Samsb8c5a842009-07-31 20:40:47 -070019import java.io.IOException;
20import java.io.InputStream;
Jason Samsb8c5a842009-07-31 20:40:47 -070021import android.content.res.Resources;
Romain Guy650a3eb2009-08-31 14:06:43 -070022import android.content.res.AssetManager;
Jason Samsb8c5a842009-07-31 20:40:47 -070023import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
Jason Samsfb9aa9f2012-03-28 15:30:07 -070025import android.view.Surface;
Jason Sams615e7ce2012-01-13 14:01:20 -080026import android.graphics.SurfaceTexture;
Jason Samsb8c5a842009-07-31 20:40:47 -070027import android.util.Log;
Romain Guy650a3eb2009-08-31 14:06:43 -070028import android.util.TypedValue;
Jason Samsb8c5a842009-07-31 20:40:47 -070029
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070030/**
Robert Ly11518ac2011-02-09 13:57:06 -080031 * <p>
32 * Memory allocation class for renderscript. An allocation combines a
33 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
34 * This implies that all memory in Renderscript is typed.
35 * </p>
Jason Samsa23d4e72011-01-04 18:59:12 -080036 *
Robert Ly11518ac2011-02-09 13:57:06 -080037 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
38 * synchronized and it's possible for allocations to exist in multiple memory spaces
39 * concurrently. Currently those spaces are:</p>
40 * <ul>
41 * <li>Script: accessable by RS scripts.</li>
42 * <li>Graphics Texture: accessable as a graphics texture.</li>
43 * <li>Graphics Vertex: accessable as graphical vertex data.</li>
44 * <li>Graphics Constants: Accessable as constants in user shaders</li>
45 * </ul>
46 * </p>
47 * <p>
48 * For example, when creating a allocation for a texture, the user can
49 * specify its memory spaces as both script and textures. This means that it can both
50 * be used as script binding and as a GPU texture for rendering. To maintain
51 * synchronization if a script modifies an allocation used by other targets it must
52 * call a synchronizing function to push the updates to the memory, otherwise the results
53 * are undefined.
54 * </p>
55 * <p>By default, Android system side updates are always applied to the script accessable
56 * memory. If this is not present, they are then applied to the various HW
57 * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()}
58 * call is necessary after the script data is updated to
59 * keep the other memory spaces in sync.</p>
Jason Samsa23d4e72011-01-04 18:59:12 -080060 *
Robert Ly11518ac2011-02-09 13:57:06 -080061 * <p>Allocation data is uploaded in one of two primary ways. For simple
62 * arrays there are copyFrom() functions that take an array from the control code and
63 * copy it to the slave memory store. Both type checked and unchecked copies are provided.
64 * The unchecked variants exist to allow apps to copy over arrays of structures from a
65 * control language that does not support structures.</p>
Jason Samsb8c5a842009-07-31 20:40:47 -070066 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080067 * <div class="special reference">
68 * <h3>Developer Guides</h3>
69 * <p>For more information about creating an application that uses Renderscript, read the
Scott Mainb47fa162013-02-05 14:23:13 -080070 * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080071 * </div>
Jason Samsb8c5a842009-07-31 20:40:47 -070072 **/
73public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070074 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080075 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080076 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070077 Allocation mAdaptedAllocation;
78
79 boolean mConstrainedLOD;
80 boolean mConstrainedFace;
81 boolean mConstrainedY;
82 boolean mConstrainedZ;
Jason Sams615e7ce2012-01-13 14:01:20 -080083 boolean mReadAllowed = true;
84 boolean mWriteAllowed = true;
Jason Samsba862d12011-07-07 15:24:42 -070085 int mSelectedY;
86 int mSelectedZ;
87 int mSelectedLOD;
88 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
89
90 int mCurrentDimX;
91 int mCurrentDimY;
92 int mCurrentDimZ;
93 int mCurrentCount;
94
Jason Sams5476b452010-12-08 16:14:36 -080095
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070096 /**
Jason Samsf7086092011-01-12 13:28:37 -080097 * The usage of the allocation. These signal to renderscript
98 * where to place the allocation in memory.
99 *
100 * SCRIPT The allocation will be bound to and accessed by
101 * scripts.
102 */
Jason Sams5476b452010-12-08 16:14:36 -0800103 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800104
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700105 /**
Jason Sams163766c2012-02-15 12:04:24 -0800106 * GRAPHICS_TEXTURE The allocation will be used as a texture
Stephen Hines836c4a52011-06-01 14:38:10 -0700107 * source by one or more graphics programs.
Jason Samsf7086092011-01-12 13:28:37 -0800108 *
109 */
Jason Sams5476b452010-12-08 16:14:36 -0800110 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800111
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700112 /**
Jason Samsf7086092011-01-12 13:28:37 -0800113 * GRAPHICS_VERTEX The allocation will be used as a graphics
114 * mesh.
115 *
116 */
Jason Sams5476b452010-12-08 16:14:36 -0800117 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800118
119
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700120 /**
Jason Samsf7086092011-01-12 13:28:37 -0800121 * GRAPHICS_CONSTANTS The allocation will be used as the source
122 * of shader constants by one or more programs.
123 *
124 */
Jason Sams5476b452010-12-08 16:14:36 -0800125 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
126
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700127 /**
Jason Sams163766c2012-02-15 12:04:24 -0800128 * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700129 * target for offscreen rendering
130 *
131 */
132 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
133
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700134 /**
Jason Sams163766c2012-02-15 12:04:24 -0800135 * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
136 * consumer. This usage will cause the allocation to be created
137 * read only.
Jason Sams615e7ce2012-01-13 14:01:20 -0800138 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800139 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700140 public static final int USAGE_IO_INPUT = 0x0020;
Stephen Hines9069ee82012-02-13 18:25:54 -0800141
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700142 /**
Jason Sams163766c2012-02-15 12:04:24 -0800143 * USAGE_IO_OUTPUT The allocation will be used as a
144 * SurfaceTexture producer. The dimensions and format of the
145 * SurfaceTexture will be forced to those of the allocation.
Jason Sams615e7ce2012-01-13 14:01:20 -0800146 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800147 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700148 public static final int USAGE_IO_OUTPUT = 0x0040;
Jason Sams43ee06852009-08-12 17:54:11 -0700149
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700150 /**
Tim Murray00bb4542012-12-17 16:35:06 -0800151 * USAGE_SHARED The allocation's backing store will be inherited
152 * from another object (usually a Bitmap); calling appropriate
153 * copy methods will be significantly faster than if the entire
154 * allocation were copied every time.
155 *
156 * This is set by default for allocations created with
157 * CreateFromBitmap(RenderScript, Bitmap) in API version 18 and
158 * higher.
159 *
160 */
161 public static final int USAGE_SHARED = 0x0080;
162
163 /**
Jason Samsf7086092011-01-12 13:28:37 -0800164 * Controls mipmap behavior when using the bitmap creation and
165 * update functions.
166 */
Jason Sams4ef66502010-12-10 16:03:15 -0800167 public enum MipmapControl {
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700168 /**
Jason Samsf7086092011-01-12 13:28:37 -0800169 * No mipmaps will be generated and the type generated from the
170 * incoming bitmap will not contain additional LODs.
171 */
Jason Sams5476b452010-12-08 16:14:36 -0800172 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800173
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700174 /**
Jason Samsf7086092011-01-12 13:28:37 -0800175 * A Full mipmap chain will be created in script memory. The
176 * type of the allocation will contain a full mipmap chain. On
177 * upload to graphics the full chain will be transfered.
178 */
Jason Sams5476b452010-12-08 16:14:36 -0800179 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800180
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700181 /**
Jason Samsf7086092011-01-12 13:28:37 -0800182 * The type of the allocation will be the same as MIPMAP_NONE.
183 * It will not contain mipmaps. On upload to graphics the
184 * graphics copy of the allocation data will contain a full
185 * mipmap chain generated from the top level in script memory.
186 */
Jason Sams5476b452010-12-08 16:14:36 -0800187 MIPMAP_ON_SYNC_TO_TEXTURE(2);
188
189 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800190 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800191 mID = id;
192 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700193 }
194
Jason Sams48fe5342011-07-08 13:52:30 -0700195
196 private int getIDSafe() {
197 if (mAdaptedAllocation != null) {
Jason Samse07694b2012-04-03 15:36:36 -0700198 return mAdaptedAllocation.getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700199 }
Jason Samse07694b2012-04-03 15:36:36 -0700200 return getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700201 }
202
Jason Sams03d2d002012-03-23 13:51:56 -0700203
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700204 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700205 * Get the element of the type of the Allocation.
206 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700207 * @return Element that describes the structure of data in the
208 * allocation
Jason Sams03d2d002012-03-23 13:51:56 -0700209 *
210 */
211 public Element getElement() {
212 return mType.getElement();
213 }
214
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700215 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700216 * Get the usage flags of the Allocation.
217 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700218 * @return usage flags associated with the allocation. e.g.
219 * script, texture, etc.
Jason Sams03d2d002012-03-23 13:51:56 -0700220 *
221 */
222 public int getUsage() {
223 return mUsage;
224 }
225
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700226 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700227 * Get the size of the Allocation in bytes.
228 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700229 * @return size of the Allocation in bytes.
Jason Sams36c0f642012-03-23 15:48:37 -0700230 *
231 */
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700232 public int getBytesSize() {
233 return mType.getCount() * mType.getElement().getBytesSize();
Jason Sams36c0f642012-03-23 15:48:37 -0700234 }
235
Jason Sams452a7662011-07-07 16:05:18 -0700236 private void updateCacheInfo(Type t) {
237 mCurrentDimX = t.getX();
238 mCurrentDimY = t.getY();
239 mCurrentDimZ = t.getZ();
240 mCurrentCount = mCurrentDimX;
241 if (mCurrentDimY > 1) {
242 mCurrentCount *= mCurrentDimY;
243 }
244 if (mCurrentDimZ > 1) {
245 mCurrentCount *= mCurrentDimZ;
246 }
247 }
Jason Samsba862d12011-07-07 15:24:42 -0700248
Tim Murraya3145512012-12-04 17:59:29 -0800249 private void setBitmap(Bitmap b) {
250 mBitmap = b;
251 }
252
Jason Sams5476b452010-12-08 16:14:36 -0800253 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700254 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800255 if ((usage & ~(USAGE_SCRIPT |
256 USAGE_GRAPHICS_TEXTURE |
257 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700258 USAGE_GRAPHICS_CONSTANTS |
Jason Sams615e7ce2012-01-13 14:01:20 -0800259 USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams615e7ce2012-01-13 14:01:20 -0800260 USAGE_IO_INPUT |
Tim Murray00bb4542012-12-17 16:35:06 -0800261 USAGE_IO_OUTPUT |
262 USAGE_SHARED)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800263 throw new RSIllegalArgumentException("Unknown usage specified.");
264 }
Jason Sams615e7ce2012-01-13 14:01:20 -0800265
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700266 if ((usage & USAGE_IO_INPUT) != 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800267 mWriteAllowed = false;
268
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700269 if ((usage & ~(USAGE_IO_INPUT |
Jason Sams615e7ce2012-01-13 14:01:20 -0800270 USAGE_GRAPHICS_TEXTURE |
271 USAGE_SCRIPT)) != 0) {
272 throw new RSIllegalArgumentException("Invalid usage combination.");
273 }
274 }
275
Jason Sams5476b452010-12-08 16:14:36 -0800276 mType = t;
Jason Sams615e7ce2012-01-13 14:01:20 -0800277 mUsage = usage;
Jason Samsba862d12011-07-07 15:24:42 -0700278
Jason Sams452a7662011-07-07 16:05:18 -0700279 if (t != null) {
280 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700281 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700282 }
283
Jason Samsb97b2512011-01-16 15:04:08 -0800284 private void validateIsInt32() {
285 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
286 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
287 return;
288 }
289 throw new RSIllegalArgumentException(
290 "32 bit integer source does not match allocation type " + mType.mElement.mType);
291 }
292
293 private void validateIsInt16() {
294 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
295 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
296 return;
297 }
298 throw new RSIllegalArgumentException(
299 "16 bit integer source does not match allocation type " + mType.mElement.mType);
300 }
301
302 private void validateIsInt8() {
303 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
304 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
305 return;
306 }
307 throw new RSIllegalArgumentException(
308 "8 bit integer source does not match allocation type " + mType.mElement.mType);
309 }
310
311 private void validateIsFloat32() {
312 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
313 return;
314 }
315 throw new RSIllegalArgumentException(
316 "32 bit float source does not match allocation type " + mType.mElement.mType);
317 }
318
319 private void validateIsObject() {
320 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
321 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
322 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
323 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
324 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
325 (mType.mElement.mType == Element.DataType.RS_MESH) ||
326 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
327 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
328 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
329 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
330 return;
331 }
332 throw new RSIllegalArgumentException(
333 "Object source does not match allocation type " + mType.mElement.mType);
334 }
335
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700336 @Override
337 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800338 super.updateFromNative();
Jason Samse07694b2012-04-03 15:36:36 -0700339 int typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700340 if(typeID != 0) {
341 mType = new Type(typeID, mRS);
342 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700343 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700344 }
345 }
346
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700347 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700348 * Get the type of the Allocation.
349 *
350 * @return Type
351 *
352 */
Jason Samsea87e962010-01-12 12:12:28 -0800353 public Type getType() {
354 return mType;
355 }
356
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700357 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700358 * Propagate changes from one usage of the allocation to the
Jason Sams03d2d002012-03-23 13:51:56 -0700359 * remaining usages of the allocation.
360 *
361 */
Jason Sams5476b452010-12-08 16:14:36 -0800362 public void syncAll(int srcLocation) {
363 switch (srcLocation) {
364 case USAGE_SCRIPT:
365 case USAGE_GRAPHICS_CONSTANTS:
366 case USAGE_GRAPHICS_TEXTURE:
367 case USAGE_GRAPHICS_VERTEX:
368 break;
369 default:
370 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
371 }
372 mRS.validate();
Jason Sams48fe5342011-07-08 13:52:30 -0700373 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
Jason Sams5476b452010-12-08 16:14:36 -0800374 }
375
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700376 /**
Jason Sams163766c2012-02-15 12:04:24 -0800377 * Send a buffer to the output stream. The contents of the
378 * Allocation will be undefined after this operation.
379 *
Jason Sams163766c2012-02-15 12:04:24 -0800380 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700381 public void ioSend() {
Jason Sams163766c2012-02-15 12:04:24 -0800382 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
383 throw new RSIllegalArgumentException(
384 "Can only send buffer if IO_OUTPUT usage specified.");
385 }
386 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700387 mRS.nAllocationIoSend(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800388 }
389
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700390 /**
Jason Samsc5f519c2012-03-29 17:58:15 -0700391 * Delete once code is updated.
392 * @hide
393 */
394 public void ioSendOutput() {
395 ioSend();
396 }
397
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700398 /**
Jason Sams163766c2012-02-15 12:04:24 -0800399 * Receive the latest input into the Allocation.
400 *
Jason Sams163766c2012-02-15 12:04:24 -0800401 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700402 public void ioReceive() {
Jason Sams163766c2012-02-15 12:04:24 -0800403 if ((mUsage & USAGE_IO_INPUT) == 0) {
404 throw new RSIllegalArgumentException(
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700405 "Can only receive if IO_INPUT usage specified.");
Jason Sams163766c2012-02-15 12:04:24 -0800406 }
407 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700408 mRS.nAllocationIoReceive(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800409 }
410
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700411 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700412 * Copy an array of RS objects to the allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700413 *
414 * @param d Source array.
415 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800416 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800417 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800418 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700419 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800420 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700421 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800422 }
423 int i[] = new int[d.length];
424 for (int ct=0; ct < d.length; ct++) {
Jason Samse07694b2012-04-03 15:36:36 -0700425 i[ct] = d[ct].getID(mRS);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800426 }
Jason Samsba862d12011-07-07 15:24:42 -0700427 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700428 }
429
Jason Samsfb9f82c2011-01-12 14:53:25 -0800430 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800431 Bitmap.Config bc = b.getConfig();
432 switch (bc) {
433 case ALPHA_8:
434 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
435 throw new RSIllegalArgumentException("Allocation kind is " +
436 mType.getElement().mKind + ", type " +
437 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700438 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800439 " bytes, passed bitmap was " + bc);
440 }
441 break;
442 case ARGB_8888:
443 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700444 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800445 throw new RSIllegalArgumentException("Allocation kind is " +
446 mType.getElement().mKind + ", type " +
447 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700448 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800449 " bytes, passed bitmap was " + bc);
450 }
451 break;
452 case RGB_565:
453 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700454 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800455 throw new RSIllegalArgumentException("Allocation kind is " +
456 mType.getElement().mKind + ", type " +
457 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700458 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800459 " bytes, passed bitmap was " + bc);
460 }
461 break;
462 case ARGB_4444:
463 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700464 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800465 throw new RSIllegalArgumentException("Allocation kind is " +
466 mType.getElement().mKind + ", type " +
467 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700468 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800469 " bytes, passed bitmap was " + bc);
470 }
471 break;
472
473 }
Jason Sams4ef66502010-12-10 16:03:15 -0800474 }
475
Jason Samsfb9f82c2011-01-12 14:53:25 -0800476 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700477 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800478 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
479 }
480 }
481
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700482 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800483 * Copy an allocation from an array. This variant is not type
484 * checked which allows an application to fill in structured
485 * data from an array.
486 *
487 * @param d the source data array
488 */
489 public void copyFromUnchecked(int[] d) {
490 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700491 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800492 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700493 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800494 * Copy an allocation from an array. This variant is not type
495 * checked which allows an application to fill in structured
496 * data from an array.
497 *
498 * @param d the source data array
499 */
500 public void copyFromUnchecked(short[] d) {
501 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700502 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800503 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700504 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800505 * Copy an allocation from an array. This variant is not type
506 * checked which allows an application to fill in structured
507 * data from an array.
508 *
509 * @param d the source data array
510 */
511 public void copyFromUnchecked(byte[] d) {
512 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700513 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800514 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700515 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800516 * Copy an allocation from an array. This variant is not type
517 * checked which allows an application to fill in structured
518 * data from an array.
519 *
520 * @param d the source data array
521 */
522 public void copyFromUnchecked(float[] d) {
523 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700524 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800525 }
526
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700527 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800528 * Copy an allocation from an array. This variant is type
529 * checked and will generate exceptions if the Allocation type
530 * is not a 32 bit integer type.
531 *
532 * @param d the source data array
533 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800534 public void copyFrom(int[] d) {
535 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700536 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800537 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800538
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700539 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800540 * Copy an allocation from an array. This variant is type
541 * checked and will generate exceptions if the Allocation type
542 * is not a 16 bit integer type.
543 *
544 * @param d the source data array
545 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800546 public void copyFrom(short[] d) {
547 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700548 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800549 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800550
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700551 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800552 * Copy an allocation from an array. This variant is type
553 * checked and will generate exceptions if the Allocation type
554 * is not a 8 bit integer type.
555 *
556 * @param d the source data array
557 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800558 public void copyFrom(byte[] d) {
559 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700560 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800561 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800562
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700563 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800564 * Copy an allocation from an array. This variant is type
565 * checked and will generate exceptions if the Allocation type
566 * is not a 32 bit float type.
567 *
568 * @param d the source data array
569 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800570 public void copyFrom(float[] d) {
571 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700572 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800573 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800574
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700575 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800576 * Copy an allocation from a bitmap. The height, width, and
577 * format of the bitmap must match the existing allocation.
578 *
579 * @param b the source bitmap
580 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800581 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800582 mRS.validate();
583 validateBitmapSize(b);
584 validateBitmapFormat(b);
Jason Samse07694b2012-04-03 15:36:36 -0700585 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700586 }
587
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700588 /**
Tim Murrayf671fb02012-10-03 13:50:05 -0700589 * Copy an allocation from an allocation. The types of both allocations
590 * must be identical.
591 *
592 * @param a the source allocation
593 */
594 public void copyFrom(Allocation a) {
595 mRS.validate();
596 if (!mType.equals(a.getType())) {
597 throw new RSIllegalArgumentException("Types of allocations must match.");
598 }
599 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
600 }
601
602
603 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800604 * This is only intended to be used by auto-generate code reflected from the
605 * renderscript script files.
606 *
607 * @param xoff
608 * @param fp
609 */
Jason Sams21b41032011-01-16 15:05:41 -0800610 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800611 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700612 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700613 final byte[] data = fp.getData();
614
615 int count = data.length / eSize;
616 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800617 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700618 " not divisible by element size " + eSize + ".");
619 }
Jason Samsba862d12011-07-07 15:24:42 -0700620 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700621 }
622
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700623 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800624 * This is only intended to be used by auto-generate code reflected from the
625 * renderscript script files.
626 *
627 * @param xoff
628 * @param component_number
629 * @param fp
630 */
Jason Sams21b41032011-01-16 15:05:41 -0800631 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800632 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700633 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800634 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700635 }
636 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800637 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700638 }
639
640 final byte[] data = fp.getData();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700641 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800642 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700643
644 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800645 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700646 " does not match component size " + eSize + ".");
647 }
648
Jason Sams48fe5342011-07-08 13:52:30 -0700649 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
Jason Samsba862d12011-07-07 15:24:42 -0700650 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700651 }
652
Jason Sams768bc022009-09-21 19:41:04 -0700653 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800654 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700655 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800656 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700657 }
658 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800659 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700660 }
Jason Samsba862d12011-07-07 15:24:42 -0700661 if((off + count) > mCurrentCount) {
662 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700663 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700664 }
Jason Samsba862d12011-07-07 15:24:42 -0700665 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800666 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700667 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700668 }
669
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700670 /**
Jason Samsf7086092011-01-12 13:28:37 -0800671 * Generate a mipmap chain. Requires the type of the allocation
672 * include mipmaps.
673 *
674 * This function will generate a complete set of mipmaps from
675 * the top level lod and place them into the script memoryspace.
676 *
677 * If the allocation is also using other memory spaces a
678 * followup sync will be required.
679 */
680 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700681 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800682 }
683
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700684 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800685 * Copy part of an allocation from an array. This variant is
686 * not type checked which allows an application to fill in
687 * structured data from an array.
688 *
689 * @param off The offset of the first element to be copied.
690 * @param count The number of elements to be copied.
691 * @param d the source data array
692 */
693 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700694 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700695 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700696 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700697 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700698 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800699 * Copy part of an allocation from an array. This variant is
700 * not type checked which allows an application to fill in
701 * structured data from an array.
702 *
703 * @param off The offset of the first element to be copied.
704 * @param count The number of elements to be copied.
705 * @param d the source data array
706 */
707 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700708 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700709 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700710 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700711 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700712 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800713 * Copy part of an allocation from an array. This variant is
714 * not type checked which allows an application to fill in
715 * structured data from an array.
716 *
717 * @param off The offset of the first element to be copied.
718 * @param count The number of elements to be copied.
719 * @param d the source data array
720 */
721 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700722 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700723 data1DChecks(off, count, d.length, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700724 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700725 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700726 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800727 * Copy part of an allocation from an array. This variant is
728 * not type checked which allows an application to fill in
729 * structured data from an array.
730 *
731 * @param off The offset of the first element to be copied.
732 * @param count The number of elements to be copied.
733 * @param d the source data array
734 */
735 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700736 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700737 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700738 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700739 }
740
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700741 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800742 * Copy part of an allocation from an array. This variant is
743 * type checked and will generate exceptions if the Allocation
744 * type is not a 32 bit integer type.
745 *
746 * @param off The offset of the first element to be copied.
747 * @param count The number of elements to be copied.
748 * @param d the source data array
749 */
Jason Samsb97b2512011-01-16 15:04:08 -0800750 public void copy1DRangeFrom(int off, int count, int[] d) {
751 validateIsInt32();
752 copy1DRangeFromUnchecked(off, count, d);
753 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800754
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700755 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800756 * Copy part of an allocation from an array. This variant is
757 * type checked and will generate exceptions if the Allocation
758 * type is not a 16 bit integer type.
759 *
760 * @param off The offset of the first element to be copied.
761 * @param count The number of elements to be copied.
762 * @param d the source data array
763 */
Jason Samsb97b2512011-01-16 15:04:08 -0800764 public void copy1DRangeFrom(int off, int count, short[] d) {
765 validateIsInt16();
766 copy1DRangeFromUnchecked(off, count, d);
767 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800768
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700769 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800770 * Copy part of an allocation from an array. This variant is
771 * type checked and will generate exceptions if the Allocation
772 * type is not a 8 bit integer type.
773 *
774 * @param off The offset of the first element to be copied.
775 * @param count The number of elements to be copied.
776 * @param d the source data array
777 */
Jason Samsb97b2512011-01-16 15:04:08 -0800778 public void copy1DRangeFrom(int off, int count, byte[] d) {
779 validateIsInt8();
780 copy1DRangeFromUnchecked(off, count, d);
781 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800782
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700783 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800784 * Copy part of an allocation from an array. This variant is
785 * type checked and will generate exceptions if the Allocation
786 * type is not a 32 bit float type.
787 *
788 * @param off The offset of the first element to be copied.
789 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700790 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800791 */
Jason Samsb97b2512011-01-16 15:04:08 -0800792 public void copy1DRangeFrom(int off, int count, float[] d) {
793 validateIsFloat32();
794 copy1DRangeFromUnchecked(off, count, d);
795 }
796
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700797 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700798 * Copy part of an allocation from another allocation.
799 *
800 * @param off The offset of the first element to be copied.
801 * @param count The number of elements to be copied.
802 * @param data the source data allocation.
803 * @param dataOff off The offset of the first element in data to
804 * be copied.
805 */
806 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Jason Sams48fe5342011-07-08 13:52:30 -0700807 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700808 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700809 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700810 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700811 }
812
Jason Samsfb9f82c2011-01-12 14:53:25 -0800813 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700814 if (mAdaptedAllocation != null) {
815
816 } else {
817
818 if (xoff < 0 || yoff < 0) {
819 throw new RSIllegalArgumentException("Offset cannot be negative.");
820 }
821 if (h < 0 || w < 0) {
822 throw new RSIllegalArgumentException("Height or width cannot be negative.");
823 }
824 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
825 throw new RSIllegalArgumentException("Updated region larger than allocation.");
826 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800827 }
828 }
Jason Sams768bc022009-09-21 19:41:04 -0700829
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700830 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700831 * Copy a rectangular region from the array into the allocation.
832 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800833 *
834 * @param xoff X offset of the region to update
835 * @param yoff Y offset of the region to update
836 * @param w Width of the incoming region to update
837 * @param h Height of the incoming region to update
838 * @param data to be placed into the allocation
839 */
840 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800841 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800842 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700843 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700844 w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800845 }
846
Jason Samsf7086092011-01-12 13:28:37 -0800847 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800848 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800849 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700850 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700851 w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800852 }
853
Jason Samsf7086092011-01-12 13:28:37 -0800854 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800855 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800856 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700857 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700858 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700859 }
860
Jason Samsf7086092011-01-12 13:28:37 -0800861 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800862 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800863 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700864 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700865 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700866 }
867
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700868 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700869 * Copy a rectangular region into the allocation from another
870 * allocation.
871 *
872 * @param xoff X offset of the region to update.
873 * @param yoff Y offset of the region to update.
874 * @param w Width of the incoming region to update.
875 * @param h Height of the incoming region to update.
876 * @param data source allocation.
877 * @param dataXoff X offset in data of the region to update.
878 * @param dataYoff Y offset in data of the region to update.
879 */
880 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
881 Allocation data, int dataXoff, int dataYoff) {
882 mRS.validate();
883 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700884 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700885 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700886 w, h, data.getID(mRS), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700887 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700888 }
889
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700890 /**
Jason Samsf7086092011-01-12 13:28:37 -0800891 * Copy a bitmap into an allocation. The height and width of
892 * the update will use the height and width of the incoming
893 * bitmap.
894 *
895 * @param xoff X offset of the region to update
896 * @param yoff Y offset of the region to update
897 * @param data the bitmap to be copied
898 */
899 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800900 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800901 validateBitmapFormat(data);
902 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Sams48fe5342011-07-08 13:52:30 -0700903 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800904 }
905
906
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700907 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700908 * Copy from the Allocation into a Bitmap. The bitmap must
909 * match the dimensions of the Allocation.
910 *
911 * @param b The bitmap to be set from the Allocation.
912 */
Jason Samsfa445b92011-01-07 17:00:07 -0800913 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800914 mRS.validate();
915 validateBitmapFormat(b);
916 validateBitmapSize(b);
Jason Samse07694b2012-04-03 15:36:36 -0700917 mRS.nAllocationCopyToBitmap(getID(mRS), b);
Jason Samsfa445b92011-01-07 17:00:07 -0800918 }
919
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700920 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700921 * Copy from the Allocation into a byte array. The array must
922 * be at least as large as the Allocation. The allocation must
923 * be of an 8 bit elemental type.
924 *
925 * @param d The array to be set from the Allocation.
926 */
Jason Samsfa445b92011-01-07 17:00:07 -0800927 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800928 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800929 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700930 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700931 }
932
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700933 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700934 * Copy from the Allocation into a short array. The array must
935 * be at least as large as the Allocation. The allocation must
936 * be of an 16 bit elemental type.
937 *
938 * @param d The array to be set from the Allocation.
939 */
Jason Samsfa445b92011-01-07 17:00:07 -0800940 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800941 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800942 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700943 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -0800944 }
945
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700946 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700947 * Copy from the Allocation into a int array. The array must be
948 * at least as large as the Allocation. The allocation must be
949 * of an 32 bit elemental type.
950 *
951 * @param d The array to be set from the Allocation.
952 */
Jason Samsfa445b92011-01-07 17:00:07 -0800953 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800954 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800955 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700956 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -0800957 }
958
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700959 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700960 * Copy from the Allocation into a float array. The array must
961 * be at least as large as the Allocation. The allocation must
962 * be of an 32 bit float elemental type.
963 *
964 * @param d The array to be set from the Allocation.
965 */
Jason Samsfa445b92011-01-07 17:00:07 -0800966 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800967 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800968 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700969 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700970 }
971
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700972 /**
Jason Samsf7086092011-01-12 13:28:37 -0800973 * Resize a 1D allocation. The contents of the allocation are
974 * preserved. If new elements are allocated objects are created
975 * with null contents and the new region is otherwise undefined.
976 *
977 * If the new region is smaller the references of any objects
978 * outside the new region will be released.
979 *
980 * A new type will be created with the new dimension.
981 *
982 * @param dimX The new size of the allocation.
983 */
Jason Sams31a7e422010-10-26 13:09:17 -0700984 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800985 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800986 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700987 }
Jason Samse07694b2012-04-03 15:36:36 -0700988 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700989 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700990
Jason Samse07694b2012-04-03 15:36:36 -0700991 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -0700992 mType = new Type(typeID, mRS);
993 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -0700994 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -0700995 }
996
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700997 /**
Jason Sams163766c2012-02-15 12:04:24 -0800998 * Resize a 2D allocation. The contents of the allocation are
999 * preserved. If new elements are allocated objects are created
1000 * with null contents and the new region is otherwise undefined.
1001 *
1002 * If the new region is smaller the references of any objects
1003 * outside the new region will be released.
1004 *
1005 * A new type will be created with the new dimension.
1006 *
Jason Sams163766c2012-02-15 12:04:24 -08001007 * @param dimX The new size of the allocation.
1008 * @param dimY The new size of the allocation.
1009 */
Tim Murraybc254b92012-10-05 15:00:45 -07001010 public synchronized void resize(int dimX, int dimY) {
Jason Sams163766c2012-02-15 12:04:24 -08001011 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
1012 throw new RSInvalidStateException(
1013 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001014 }
1015 if (mType.getY() == 0) {
Jason Sams163766c2012-02-15 12:04:24 -08001016 throw new RSInvalidStateException(
1017 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001018 }
Jason Samse07694b2012-04-03 15:36:36 -07001019 mRS.nAllocationResize2D(getID(mRS), dimX, dimY);
Jason Sams163766c2012-02-15 12:04:24 -08001020 mRS.finish(); // Necessary because resize is fifoed and update is async.
1021
Jason Samse07694b2012-04-03 15:36:36 -07001022 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -08001023 mType = new Type(typeID, mRS);
1024 mType.updateFromNative();
1025 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001026 }
Jason Sams40a29e82009-08-10 14:55:26 -07001027
Jason Samsbd1c3ad2009-08-03 16:03:08 -07001028
Jason Samsb8c5a842009-07-31 20:40:47 -07001029
1030 // creation
1031
Jason Sams49a05d72010-12-29 14:31:29 -08001032 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001033 static {
1034 mBitmapOptions.inScaled = false;
1035 }
1036
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001037 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001038 *
1039 * @param type renderscript type describing data layout
1040 * @param mips specifies desired mipmap behaviour for the
1041 * allocation
1042 * @param usage bit field specifying how the allocation is
1043 * utilized
1044 */
1045 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001046 rs.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001047 if (type.getID(rs) == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001048 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -07001049 }
Jason Samse07694b2012-04-03 15:36:36 -07001050 int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
Jason Sams857d0c72011-11-23 15:02:15 -08001051 if (id == 0) {
1052 throw new RSRuntimeException("Allocation creation failed.");
1053 }
1054 return new Allocation(id, rs, type, usage);
1055 }
1056
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001057 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001058 * Creates a renderscript allocation with the size specified by
1059 * the type and no mipmaps generated by default
1060 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001061 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001062 * @param type renderscript type describing data layout
1063 * @param usage bit field specifying how the allocation is
1064 * utilized
1065 *
1066 * @return allocation
1067 */
Jason Samse5d37122010-12-16 00:33:33 -08001068 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1069 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1070 }
1071
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001072 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001073 * Creates a renderscript allocation for use by the script with
1074 * the size specified by the type and no mipmaps generated by
1075 * default
1076 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001077 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001078 * @param type renderscript type describing data layout
1079 *
1080 * @return allocation
1081 */
Jason Sams5476b452010-12-08 16:14:36 -08001082 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001083 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001084 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001085
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001086 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001087 * Creates a renderscript allocation with a specified number of
1088 * given elements
1089 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001090 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001091 * @param e describes what each element of an allocation is
1092 * @param count specifies the number of element in the allocation
1093 * @param usage bit field specifying how the allocation is
1094 * utilized
1095 *
1096 * @return allocation
1097 */
Jason Sams5476b452010-12-08 16:14:36 -08001098 static public Allocation createSized(RenderScript rs, Element e,
1099 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001100 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -07001101 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001102 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -07001103 Type t = b.create();
1104
Jason Samse07694b2012-04-03 15:36:36 -07001105 int id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
Jason Sams5476b452010-12-08 16:14:36 -08001106 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001107 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -07001108 }
Jason Sams5476b452010-12-08 16:14:36 -08001109 return new Allocation(id, rs, t, usage);
1110 }
1111
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001112 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001113 * Creates a renderscript allocation with a specified number of
1114 * given elements
1115 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001116 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001117 * @param e describes what each element of an allocation is
1118 * @param count specifies the number of element in the allocation
1119 *
1120 * @return allocation
1121 */
Jason Sams5476b452010-12-08 16:14:36 -08001122 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001123 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001124 }
1125
Jason Sams49a05d72010-12-29 14:31:29 -08001126 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08001127 final Bitmap.Config bc = b.getConfig();
1128 if (bc == Bitmap.Config.ALPHA_8) {
1129 return Element.A_8(rs);
1130 }
1131 if (bc == Bitmap.Config.ARGB_4444) {
1132 return Element.RGBA_4444(rs);
1133 }
1134 if (bc == Bitmap.Config.ARGB_8888) {
1135 return Element.RGBA_8888(rs);
1136 }
1137 if (bc == Bitmap.Config.RGB_565) {
1138 return Element.RGB_565(rs);
1139 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08001140 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08001141 }
1142
Jason Sams49a05d72010-12-29 14:31:29 -08001143 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001144 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08001145 Element e = elementFromBitmap(rs, b);
1146 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001147 tb.setX(b.getWidth());
1148 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08001149 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08001150 return tb.create();
1151 }
1152
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001153 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001154 * Creates a renderscript allocation from a bitmap
1155 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001156 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001157 * @param b bitmap source for the allocation data
1158 * @param mips specifies desired mipmap behaviour for the
1159 * allocation
1160 * @param usage bit field specifying how the allocation is
1161 * utilized
1162 *
1163 * @return renderscript allocation containing bitmap data
1164 *
1165 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001166 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001167 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001168 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001169 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001170 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08001171
Tim Murraya3145512012-12-04 17:59:29 -08001172 // enable optimized bitmap path only with no mipmap and script-only usage
1173 if (mips == MipmapControl.MIPMAP_NONE &&
1174 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
Stephen Hinesd34dc852012-12-19 19:33:13 -08001175 usage == (USAGE_SHARED | USAGE_SCRIPT)) {
Tim Murraya3145512012-12-04 17:59:29 -08001176 int id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
1177 if (id == 0) {
1178 throw new RSRuntimeException("Load failed.");
1179 }
1180
1181 // keep a reference to the Bitmap around to prevent GC
1182 Allocation alloc = new Allocation(id, rs, t, usage);
1183 alloc.setBitmap(b);
1184 return alloc;
1185 }
1186
1187
Jason Samse07694b2012-04-03 15:36:36 -07001188 int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Jason Sams5476b452010-12-08 16:14:36 -08001189 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001190 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -08001191 }
Jason Sams5476b452010-12-08 16:14:36 -08001192 return new Allocation(id, rs, t, usage);
1193 }
1194
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001195 /**
Jason Sams615e7ce2012-01-13 14:01:20 -08001196 *
1197 *
1198 * @hide
1199 *
1200 */
1201 public SurfaceTexture getSurfaceTexture() {
Jason Samsfe1d5ff2012-03-23 11:47:26 -07001202 if ((mUsage & USAGE_IO_INPUT) == 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -08001203 throw new RSInvalidStateException("Allocation is not a surface texture.");
1204 }
1205
Jason Samse07694b2012-04-03 15:36:36 -07001206 int id = mRS.nAllocationGetSurfaceTextureID(getID(mRS));
Jason Samsfe1d5ff2012-03-23 11:47:26 -07001207 SurfaceTexture st = new SurfaceTexture(id);
Jason Samse07694b2012-04-03 15:36:36 -07001208 mRS.nAllocationGetSurfaceTextureID2(getID(mRS), st);
Jason Sams615e7ce2012-01-13 14:01:20 -08001209
Jason Samsfe1d5ff2012-03-23 11:47:26 -07001210 return st;
Jason Sams615e7ce2012-01-13 14:01:20 -08001211 }
1212
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001213 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001214 * For allocations used with io operations, returns the handle
1215 * onto a raw buffer that is being managed by the screen
1216 * compositor.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001217 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001218 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001219 *
1220 */
1221 public Surface getSurface() {
1222 return new Surface(getSurfaceTexture());
1223 }
1224
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001225 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001226 * Associate a surface for io output with this allocation
1227 *
1228 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08001229 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001230 public void setSurface(Surface sur) {
1231 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08001232 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
1233 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
1234 }
1235
Jason Samse07694b2012-04-03 15:36:36 -07001236 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08001237 }
1238
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001239 /**
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001240 * @hide
1241 */
1242 public void setSurfaceTexture(SurfaceTexture st) {
1243 mRS.validate();
1244 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
1245 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
1246 }
1247
1248 Surface s = new Surface(st);
Jason Samse07694b2012-04-03 15:36:36 -07001249 mRS.nAllocationSetSurface(getID(mRS), s);
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001250 }
Jason Sams615e7ce2012-01-13 14:01:20 -08001251
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001252 /**
Tim Murray00bb4542012-12-17 16:35:06 -08001253 * Creates a RenderScript allocation from a bitmap.
1254 *
1255 * With target API version 18 or greater, this allocation will be
1256 * created with USAGE_SHARED. With target API version 17 or lower,
1257 * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001258 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001259 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001260 * @param b bitmap source for the allocation data
1261 *
1262 * @return renderscript allocation containing bitmap data
1263 *
1264 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001265 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08001266 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
1267 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1268 USAGE_SHARED | USAGE_SCRIPT);
1269 }
Jason Sams6d8eb262010-12-15 01:41:00 -08001270 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1271 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001272 }
1273
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001274 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001275 * Creates a cubemap allocation from a bitmap containing the
1276 * horizontal list of cube faces. Each individual face must be
1277 * the same size and power of 2
1278 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001279 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001280 * @param b bitmap with cubemap faces layed out in the following
1281 * format: right, left, top, bottom, front, back
1282 * @param mips specifies desired mipmap behaviour for the cubemap
1283 * @param usage bit field specifying how the cubemap is utilized
1284 *
1285 * @return allocation containing cubemap data
1286 *
1287 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001288 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001289 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001290 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001291 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001292
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001293 int height = b.getHeight();
1294 int width = b.getWidth();
1295
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001296 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001297 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1298 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001299 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001300 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001301 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001302 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001303 if (!isPow2) {
1304 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1305 }
1306
1307 Element e = elementFromBitmap(rs, b);
1308 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001309 tb.setX(height);
1310 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001311 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001312 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001313 Type t = tb.create();
1314
Jason Samse07694b2012-04-03 15:36:36 -07001315 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001316 if(id == 0) {
1317 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1318 }
Jason Sams5476b452010-12-08 16:14:36 -08001319 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001320 }
1321
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001322 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001323 * Creates a non-mipmapped cubemap allocation for use as a
1324 * graphics texture from a bitmap containing the horizontal list
1325 * of cube faces. Each individual face must be the same size and
1326 * power of 2
1327 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001328 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001329 * @param b bitmap with cubemap faces layed out in the following
1330 * format: right, left, top, bottom, front, back
1331 *
1332 * @return allocation containing cubemap data
1333 *
1334 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001335 static public Allocation createCubemapFromBitmap(RenderScript rs,
1336 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001337 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001338 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001339 }
1340
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001341 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001342 * Creates a cubemap allocation from 6 bitmaps containing
1343 * the cube faces. All the faces must be the same size and
1344 * power of 2
1345 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001346 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001347 * @param xpos cubemap face in the positive x direction
1348 * @param xneg cubemap face in the negative x direction
1349 * @param ypos cubemap face in the positive y direction
1350 * @param yneg cubemap face in the negative y direction
1351 * @param zpos cubemap face in the positive z direction
1352 * @param zneg cubemap face in the negative z direction
1353 * @param mips specifies desired mipmap behaviour for the cubemap
1354 * @param usage bit field specifying how the cubemap is utilized
1355 *
1356 * @return allocation containing cubemap data
1357 *
1358 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001359 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1360 Bitmap xpos,
1361 Bitmap xneg,
1362 Bitmap ypos,
1363 Bitmap yneg,
1364 Bitmap zpos,
1365 Bitmap zneg,
1366 MipmapControl mips,
1367 int usage) {
1368 int height = xpos.getHeight();
1369 if (xpos.getWidth() != height ||
1370 xneg.getWidth() != height || xneg.getHeight() != height ||
1371 ypos.getWidth() != height || ypos.getHeight() != height ||
1372 yneg.getWidth() != height || yneg.getHeight() != height ||
1373 zpos.getWidth() != height || zpos.getHeight() != height ||
1374 zneg.getWidth() != height || zneg.getHeight() != height) {
1375 throw new RSIllegalArgumentException("Only square cube map faces supported");
1376 }
1377 boolean isPow2 = (height & (height - 1)) == 0;
1378 if (!isPow2) {
1379 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1380 }
1381
1382 Element e = elementFromBitmap(rs, xpos);
1383 Type.Builder tb = new Type.Builder(rs, e);
1384 tb.setX(height);
1385 tb.setY(height);
1386 tb.setFaces(true);
1387 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1388 Type t = tb.create();
1389 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1390
1391 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001392 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001393 adapter.copyFrom(xpos);
1394 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1395 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001396 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001397 adapter.copyFrom(ypos);
1398 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1399 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001400 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001401 adapter.copyFrom(zpos);
1402 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1403 adapter.copyFrom(zneg);
1404
1405 return cubemap;
1406 }
1407
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001408 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001409 * Creates a non-mipmapped cubemap allocation for use as a
1410 * graphics texture from 6 bitmaps containing
1411 * the cube faces. All the faces must be the same size and
1412 * power of 2
1413 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001414 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001415 * @param xpos cubemap face in the positive x direction
1416 * @param xneg cubemap face in the negative x direction
1417 * @param ypos cubemap face in the positive y direction
1418 * @param yneg cubemap face in the negative y direction
1419 * @param zpos cubemap face in the positive z direction
1420 * @param zneg cubemap face in the negative z direction
1421 *
1422 * @return allocation containing cubemap data
1423 *
1424 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001425 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1426 Bitmap xpos,
1427 Bitmap xneg,
1428 Bitmap ypos,
1429 Bitmap yneg,
1430 Bitmap zpos,
1431 Bitmap zneg) {
1432 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1433 zpos, zneg, MipmapControl.MIPMAP_NONE,
1434 USAGE_GRAPHICS_TEXTURE);
1435 }
1436
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001437 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001438 * Creates a renderscript allocation from the bitmap referenced
1439 * by resource id
1440 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001441 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001442 * @param res application resources
1443 * @param id resource id to load the data from
1444 * @param mips specifies desired mipmap behaviour for the
1445 * allocation
1446 * @param usage bit field specifying how the allocation is
1447 * utilized
1448 *
1449 * @return renderscript allocation containing resource data
1450 *
1451 */
Jason Sams5476b452010-12-08 16:14:36 -08001452 static public Allocation createFromBitmapResource(RenderScript rs,
1453 Resources res,
1454 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001455 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001456 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001457
Jason Sams771bebb2009-12-07 12:40:12 -08001458 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001459 Bitmap b = BitmapFactory.decodeResource(res, id);
1460 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1461 b.recycle();
1462 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001463 }
1464
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001465 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001466 * Creates a non-mipmapped renderscript allocation to use as a
1467 * graphics texture from the bitmap referenced by resource id
1468 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001469 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001470 * @param res application resources
1471 * @param id resource id to load the data from
1472 *
1473 * @return renderscript allocation containing resource data
1474 *
1475 */
Jason Sams5476b452010-12-08 16:14:36 -08001476 static public Allocation createFromBitmapResource(RenderScript rs,
1477 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001478 int id) {
1479 return createFromBitmapResource(rs, res, id,
1480 MipmapControl.MIPMAP_NONE,
1481 USAGE_GRAPHICS_TEXTURE);
1482 }
1483
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001484 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001485 * Creates a renderscript allocation containing string data
1486 * encoded in UTF-8 format
1487 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001488 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001489 * @param str string to create the allocation from
1490 * @param usage bit field specifying how the allocaiton is
1491 * utilized
1492 *
1493 */
Jason Sams5476b452010-12-08 16:14:36 -08001494 static public Allocation createFromString(RenderScript rs,
1495 String str,
1496 int usage) {
1497 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001498 byte[] allocArray = null;
1499 try {
1500 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001501 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001502 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001503 return alloc;
1504 }
1505 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001506 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001507 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001508 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001509}
1510
1511