blob: b8564b60bbf2f237dbda6d2968f1f892bbecc4a9 [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;
Tim Murrayabd5db92013-02-28 11:45:22 -080029import android.graphics.Canvas;
Jason Samsb8c5a842009-07-31 20:40:47 -070030
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070031/**
Robert Ly11518ac2011-02-09 13:57:06 -080032 * <p>
33 * Memory allocation class for renderscript. An allocation combines a
34 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
35 * This implies that all memory in Renderscript is typed.
36 * </p>
Jason Samsa23d4e72011-01-04 18:59:12 -080037 *
Robert Ly11518ac2011-02-09 13:57:06 -080038 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
39 * synchronized and it's possible for allocations to exist in multiple memory spaces
40 * concurrently. Currently those spaces are:</p>
41 * <ul>
42 * <li>Script: accessable by RS scripts.</li>
43 * <li>Graphics Texture: accessable as a graphics texture.</li>
44 * <li>Graphics Vertex: accessable as graphical vertex data.</li>
45 * <li>Graphics Constants: Accessable as constants in user shaders</li>
46 * </ul>
47 * </p>
48 * <p>
49 * For example, when creating a allocation for a texture, the user can
50 * specify its memory spaces as both script and textures. This means that it can both
51 * be used as script binding and as a GPU texture for rendering. To maintain
52 * synchronization if a script modifies an allocation used by other targets it must
53 * call a synchronizing function to push the updates to the memory, otherwise the results
54 * are undefined.
55 * </p>
56 * <p>By default, Android system side updates are always applied to the script accessable
57 * memory. If this is not present, they are then applied to the various HW
58 * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()}
59 * call is necessary after the script data is updated to
60 * keep the other memory spaces in sync.</p>
Jason Samsa23d4e72011-01-04 18:59:12 -080061 *
Robert Ly11518ac2011-02-09 13:57:06 -080062 * <p>Allocation data is uploaded in one of two primary ways. For simple
63 * arrays there are copyFrom() functions that take an array from the control code and
64 * copy it to the slave memory store. Both type checked and unchecked copies are provided.
65 * The unchecked variants exist to allow apps to copy over arrays of structures from a
66 * control language that does not support structures.</p>
Jason Samsb8c5a842009-07-31 20:40:47 -070067 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080068 * <div class="special reference">
69 * <h3>Developer Guides</h3>
70 * <p>For more information about creating an application that uses Renderscript, read the
Scott Mainb47fa162013-02-05 14:23:13 -080071 * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080072 * </div>
Jason Samsb8c5a842009-07-31 20:40:47 -070073 **/
74public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070075 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080076 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080077 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070078 Allocation mAdaptedAllocation;
79
80 boolean mConstrainedLOD;
81 boolean mConstrainedFace;
82 boolean mConstrainedY;
83 boolean mConstrainedZ;
Jason Sams615e7ce2012-01-13 14:01:20 -080084 boolean mReadAllowed = true;
85 boolean mWriteAllowed = true;
Jason Samsba862d12011-07-07 15:24:42 -070086 int mSelectedY;
87 int mSelectedZ;
88 int mSelectedLOD;
89 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
90
91 int mCurrentDimX;
92 int mCurrentDimY;
93 int mCurrentDimZ;
94 int mCurrentCount;
95
Jason Sams5476b452010-12-08 16:14:36 -080096
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070097 /**
Jason Samsf7086092011-01-12 13:28:37 -080098 * The usage of the allocation. These signal to renderscript
99 * where to place the allocation in memory.
100 *
101 * SCRIPT The allocation will be bound to and accessed by
102 * scripts.
103 */
Jason Sams5476b452010-12-08 16:14:36 -0800104 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800105
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700106 /**
Jason Sams163766c2012-02-15 12:04:24 -0800107 * GRAPHICS_TEXTURE The allocation will be used as a texture
Stephen Hines836c4a52011-06-01 14:38:10 -0700108 * source by one or more graphics programs.
Jason Samsf7086092011-01-12 13:28:37 -0800109 *
110 */
Jason Sams5476b452010-12-08 16:14:36 -0800111 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800112
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700113 /**
Jason Samsf7086092011-01-12 13:28:37 -0800114 * GRAPHICS_VERTEX The allocation will be used as a graphics
115 * mesh.
116 *
117 */
Jason Sams5476b452010-12-08 16:14:36 -0800118 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800119
120
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700121 /**
Jason Samsf7086092011-01-12 13:28:37 -0800122 * GRAPHICS_CONSTANTS The allocation will be used as the source
123 * of shader constants by one or more programs.
124 *
125 */
Jason Sams5476b452010-12-08 16:14:36 -0800126 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
127
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700128 /**
Jason Sams163766c2012-02-15 12:04:24 -0800129 * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700130 * target for offscreen rendering
131 *
132 */
133 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
134
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700135 /**
Jason Sams163766c2012-02-15 12:04:24 -0800136 * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
137 * consumer. This usage will cause the allocation to be created
138 * read only.
Jason Sams615e7ce2012-01-13 14:01:20 -0800139 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800140 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700141 public static final int USAGE_IO_INPUT = 0x0020;
Stephen Hines9069ee82012-02-13 18:25:54 -0800142
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700143 /**
Jason Sams163766c2012-02-15 12:04:24 -0800144 * USAGE_IO_OUTPUT The allocation will be used as a
145 * SurfaceTexture producer. The dimensions and format of the
146 * SurfaceTexture will be forced to those of the allocation.
Jason Sams615e7ce2012-01-13 14:01:20 -0800147 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800148 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700149 public static final int USAGE_IO_OUTPUT = 0x0040;
Jason Sams43ee06852009-08-12 17:54:11 -0700150
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700151 /**
Tim Murray00bb4542012-12-17 16:35:06 -0800152 * USAGE_SHARED The allocation's backing store will be inherited
153 * from another object (usually a Bitmap); calling appropriate
154 * copy methods will be significantly faster than if the entire
155 * allocation were copied every time.
156 *
157 * This is set by default for allocations created with
158 * CreateFromBitmap(RenderScript, Bitmap) in API version 18 and
159 * higher.
160 *
161 */
162 public static final int USAGE_SHARED = 0x0080;
163
164 /**
Jason Samsf7086092011-01-12 13:28:37 -0800165 * Controls mipmap behavior when using the bitmap creation and
166 * update functions.
167 */
Jason Sams4ef66502010-12-10 16:03:15 -0800168 public enum MipmapControl {
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700169 /**
Jason Samsf7086092011-01-12 13:28:37 -0800170 * No mipmaps will be generated and the type generated from the
171 * incoming bitmap will not contain additional LODs.
172 */
Jason Sams5476b452010-12-08 16:14:36 -0800173 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800174
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700175 /**
Jason Samsf7086092011-01-12 13:28:37 -0800176 * A Full mipmap chain will be created in script memory. The
177 * type of the allocation will contain a full mipmap chain. On
178 * upload to graphics the full chain will be transfered.
179 */
Jason Sams5476b452010-12-08 16:14:36 -0800180 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800181
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700182 /**
Jason Samsf7086092011-01-12 13:28:37 -0800183 * The type of the allocation will be the same as MIPMAP_NONE.
184 * It will not contain mipmaps. On upload to graphics the
185 * graphics copy of the allocation data will contain a full
186 * mipmap chain generated from the top level in script memory.
187 */
Jason Sams5476b452010-12-08 16:14:36 -0800188 MIPMAP_ON_SYNC_TO_TEXTURE(2);
189
190 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800191 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800192 mID = id;
193 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700194 }
195
Jason Sams48fe5342011-07-08 13:52:30 -0700196
197 private int getIDSafe() {
198 if (mAdaptedAllocation != null) {
Jason Samse07694b2012-04-03 15:36:36 -0700199 return mAdaptedAllocation.getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700200 }
Jason Samse07694b2012-04-03 15:36:36 -0700201 return getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700202 }
203
Jason Sams03d2d002012-03-23 13:51:56 -0700204
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700205 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700206 * Get the element of the type of the Allocation.
207 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700208 * @return Element that describes the structure of data in the
209 * allocation
Jason Sams03d2d002012-03-23 13:51:56 -0700210 *
211 */
212 public Element getElement() {
213 return mType.getElement();
214 }
215
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700216 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700217 * Get the usage flags of the Allocation.
218 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700219 * @return usage flags associated with the allocation. e.g.
220 * script, texture, etc.
Jason Sams03d2d002012-03-23 13:51:56 -0700221 *
222 */
223 public int getUsage() {
224 return mUsage;
225 }
226
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700227 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700228 * Get the size of the Allocation in bytes.
229 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700230 * @return size of the Allocation in bytes.
Jason Sams36c0f642012-03-23 15:48:37 -0700231 *
232 */
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700233 public int getBytesSize() {
234 return mType.getCount() * mType.getElement().getBytesSize();
Jason Sams36c0f642012-03-23 15:48:37 -0700235 }
236
Jason Sams452a7662011-07-07 16:05:18 -0700237 private void updateCacheInfo(Type t) {
238 mCurrentDimX = t.getX();
239 mCurrentDimY = t.getY();
240 mCurrentDimZ = t.getZ();
241 mCurrentCount = mCurrentDimX;
242 if (mCurrentDimY > 1) {
243 mCurrentCount *= mCurrentDimY;
244 }
245 if (mCurrentDimZ > 1) {
246 mCurrentCount *= mCurrentDimZ;
247 }
248 }
Jason Samsba862d12011-07-07 15:24:42 -0700249
Tim Murraya3145512012-12-04 17:59:29 -0800250 private void setBitmap(Bitmap b) {
251 mBitmap = b;
252 }
253
Jason Sams5476b452010-12-08 16:14:36 -0800254 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700255 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800256 if ((usage & ~(USAGE_SCRIPT |
257 USAGE_GRAPHICS_TEXTURE |
258 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700259 USAGE_GRAPHICS_CONSTANTS |
Jason Sams615e7ce2012-01-13 14:01:20 -0800260 USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams615e7ce2012-01-13 14:01:20 -0800261 USAGE_IO_INPUT |
Tim Murray00bb4542012-12-17 16:35:06 -0800262 USAGE_IO_OUTPUT |
263 USAGE_SHARED)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800264 throw new RSIllegalArgumentException("Unknown usage specified.");
265 }
Jason Sams615e7ce2012-01-13 14:01:20 -0800266
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700267 if ((usage & USAGE_IO_INPUT) != 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800268 mWriteAllowed = false;
269
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700270 if ((usage & ~(USAGE_IO_INPUT |
Jason Sams615e7ce2012-01-13 14:01:20 -0800271 USAGE_GRAPHICS_TEXTURE |
272 USAGE_SCRIPT)) != 0) {
273 throw new RSIllegalArgumentException("Invalid usage combination.");
274 }
275 }
276
Jason Sams5476b452010-12-08 16:14:36 -0800277 mType = t;
Jason Sams615e7ce2012-01-13 14:01:20 -0800278 mUsage = usage;
Jason Samsba862d12011-07-07 15:24:42 -0700279
Jason Sams452a7662011-07-07 16:05:18 -0700280 if (t != null) {
281 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700282 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700283 }
284
Jason Samsb97b2512011-01-16 15:04:08 -0800285 private void validateIsInt32() {
286 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
287 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
288 return;
289 }
290 throw new RSIllegalArgumentException(
291 "32 bit integer source does not match allocation type " + mType.mElement.mType);
292 }
293
294 private void validateIsInt16() {
295 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
296 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
297 return;
298 }
299 throw new RSIllegalArgumentException(
300 "16 bit integer source does not match allocation type " + mType.mElement.mType);
301 }
302
303 private void validateIsInt8() {
304 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
305 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
306 return;
307 }
308 throw new RSIllegalArgumentException(
309 "8 bit integer source does not match allocation type " + mType.mElement.mType);
310 }
311
312 private void validateIsFloat32() {
313 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
314 return;
315 }
316 throw new RSIllegalArgumentException(
317 "32 bit float source does not match allocation type " + mType.mElement.mType);
318 }
319
320 private void validateIsObject() {
321 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
322 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
323 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
324 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
325 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
326 (mType.mElement.mType == Element.DataType.RS_MESH) ||
327 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
328 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
329 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
330 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
331 return;
332 }
333 throw new RSIllegalArgumentException(
334 "Object source does not match allocation type " + mType.mElement.mType);
335 }
336
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700337 @Override
338 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800339 super.updateFromNative();
Jason Samse07694b2012-04-03 15:36:36 -0700340 int typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700341 if(typeID != 0) {
342 mType = new Type(typeID, mRS);
343 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700344 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700345 }
346 }
347
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700348 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700349 * Get the type of the Allocation.
350 *
351 * @return Type
352 *
353 */
Jason Samsea87e962010-01-12 12:12:28 -0800354 public Type getType() {
355 return mType;
356 }
357
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700358 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700359 * Propagate changes from one usage of the allocation to the
Jason Sams03d2d002012-03-23 13:51:56 -0700360 * remaining usages of the allocation.
361 *
362 */
Jason Sams5476b452010-12-08 16:14:36 -0800363 public void syncAll(int srcLocation) {
364 switch (srcLocation) {
365 case USAGE_SCRIPT:
366 case USAGE_GRAPHICS_CONSTANTS:
367 case USAGE_GRAPHICS_TEXTURE:
368 case USAGE_GRAPHICS_VERTEX:
369 break;
370 default:
371 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
372 }
373 mRS.validate();
Jason Sams48fe5342011-07-08 13:52:30 -0700374 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
Jason Sams5476b452010-12-08 16:14:36 -0800375 }
376
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700377 /**
Jason Sams163766c2012-02-15 12:04:24 -0800378 * Send a buffer to the output stream. The contents of the
379 * Allocation will be undefined after this operation.
380 *
Jason Sams163766c2012-02-15 12:04:24 -0800381 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700382 public void ioSend() {
Jason Sams163766c2012-02-15 12:04:24 -0800383 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
384 throw new RSIllegalArgumentException(
385 "Can only send buffer if IO_OUTPUT usage specified.");
386 }
387 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700388 mRS.nAllocationIoSend(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800389 }
390
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700391 /**
Jason Samsc5f519c2012-03-29 17:58:15 -0700392 * Delete once code is updated.
393 * @hide
394 */
395 public void ioSendOutput() {
396 ioSend();
397 }
398
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700399 /**
Jason Sams163766c2012-02-15 12:04:24 -0800400 * Receive the latest input into the Allocation.
401 *
Jason Sams163766c2012-02-15 12:04:24 -0800402 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700403 public void ioReceive() {
Jason Sams163766c2012-02-15 12:04:24 -0800404 if ((mUsage & USAGE_IO_INPUT) == 0) {
405 throw new RSIllegalArgumentException(
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700406 "Can only receive if IO_INPUT usage specified.");
Jason Sams163766c2012-02-15 12:04:24 -0800407 }
408 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700409 mRS.nAllocationIoReceive(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800410 }
411
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700412 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700413 * Copy an array of RS objects to the allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700414 *
415 * @param d Source array.
416 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800417 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800418 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800419 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700420 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800421 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700422 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800423 }
424 int i[] = new int[d.length];
425 for (int ct=0; ct < d.length; ct++) {
Jason Samse07694b2012-04-03 15:36:36 -0700426 i[ct] = d[ct].getID(mRS);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800427 }
Jason Samsba862d12011-07-07 15:24:42 -0700428 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700429 }
430
Jason Samsfb9f82c2011-01-12 14:53:25 -0800431 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800432 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800433 if (bc == null) {
434 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
435 }
Jason Sams252c0782011-01-11 17:42:52 -0800436 switch (bc) {
437 case ALPHA_8:
438 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
439 throw new RSIllegalArgumentException("Allocation kind is " +
440 mType.getElement().mKind + ", type " +
441 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700442 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800443 " bytes, passed bitmap was " + bc);
444 }
445 break;
446 case ARGB_8888:
447 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700448 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800449 throw new RSIllegalArgumentException("Allocation kind is " +
450 mType.getElement().mKind + ", type " +
451 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700452 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800453 " bytes, passed bitmap was " + bc);
454 }
455 break;
456 case RGB_565:
457 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700458 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800459 throw new RSIllegalArgumentException("Allocation kind is " +
460 mType.getElement().mKind + ", type " +
461 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700462 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800463 " bytes, passed bitmap was " + bc);
464 }
465 break;
466 case ARGB_4444:
467 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700468 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800469 throw new RSIllegalArgumentException("Allocation kind is " +
470 mType.getElement().mKind + ", type " +
471 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700472 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800473 " bytes, passed bitmap was " + bc);
474 }
475 break;
476
477 }
Jason Sams4ef66502010-12-10 16:03:15 -0800478 }
479
Jason Samsfb9f82c2011-01-12 14:53:25 -0800480 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700481 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800482 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
483 }
484 }
485
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700486 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800487 * Copy an allocation from an array. This variant is not type
488 * checked which allows an application to fill in structured
489 * data from an array.
490 *
491 * @param d the source data array
492 */
493 public void copyFromUnchecked(int[] d) {
494 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800495 if (mCurrentDimY > 0) {
496 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
497 } else {
498 copy1DRangeFromUnchecked(0, mCurrentCount, d);
499 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800500 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700501 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800502 * Copy an allocation from an array. This variant is not type
503 * checked which allows an application to fill in structured
504 * data from an array.
505 *
506 * @param d the source data array
507 */
508 public void copyFromUnchecked(short[] d) {
509 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800510 if (mCurrentDimY > 0) {
511 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
512 } else {
513 copy1DRangeFromUnchecked(0, mCurrentCount, d);
514 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800515 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700516 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800517 * Copy an allocation from an array. This variant is not type
518 * checked which allows an application to fill in structured
519 * data from an array.
520 *
521 * @param d the source data array
522 */
523 public void copyFromUnchecked(byte[] d) {
524 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800525 if (mCurrentDimY > 0) {
526 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
527 } else {
528 copy1DRangeFromUnchecked(0, mCurrentCount, d);
529 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800530 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700531 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800532 * Copy an allocation from an array. This variant is not type
533 * checked which allows an application to fill in structured
534 * data from an array.
535 *
536 * @param d the source data array
537 */
538 public void copyFromUnchecked(float[] d) {
539 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800540 if (mCurrentDimY > 0) {
541 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
542 } else {
543 copy1DRangeFromUnchecked(0, mCurrentCount, d);
544 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800545 }
546
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700547 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800548 * Copy an allocation from an array. This variant is type
549 * checked and will generate exceptions if the Allocation type
550 * is not a 32 bit integer type.
551 *
552 * @param d the source data array
553 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800554 public void copyFrom(int[] d) {
555 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800556 if (mCurrentDimY > 0) {
557 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
558 } else {
559 copy1DRangeFrom(0, mCurrentCount, d);
560 }
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 16 bit integer type.
567 *
568 * @param d the source data array
569 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800570 public void copyFrom(short[] d) {
571 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800572 if (mCurrentDimY > 0) {
573 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
574 } else {
575 copy1DRangeFrom(0, mCurrentCount, d);
576 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800577 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800578
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700579 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800580 * Copy an allocation from an array. This variant is type
581 * checked and will generate exceptions if the Allocation type
582 * is not a 8 bit integer type.
583 *
584 * @param d the source data array
585 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800586 public void copyFrom(byte[] d) {
587 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800588 if (mCurrentDimY > 0) {
589 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
590 } else {
591 copy1DRangeFrom(0, mCurrentCount, d);
592 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800593 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800594
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700595 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800596 * Copy an allocation from an array. This variant is type
597 * checked and will generate exceptions if the Allocation type
598 * is not a 32 bit float type.
599 *
600 * @param d the source data array
601 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800602 public void copyFrom(float[] d) {
603 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800604 if (mCurrentDimY > 0) {
605 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
606 } else {
607 copy1DRangeFrom(0, mCurrentCount, d);
608 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800609 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800610
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700611 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800612 * Copy an allocation from a bitmap. The height, width, and
613 * format of the bitmap must match the existing allocation.
614 *
615 * @param b the source bitmap
616 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800617 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800618 mRS.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -0800619 if (b.getConfig() == null) {
620 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
621 Canvas c = new Canvas(newBitmap);
622 c.drawBitmap(b, 0, 0, null);
623 copyFrom(newBitmap);
624 return;
625 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800626 validateBitmapSize(b);
627 validateBitmapFormat(b);
Jason Samse07694b2012-04-03 15:36:36 -0700628 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700629 }
630
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700631 /**
Tim Murrayf671fb02012-10-03 13:50:05 -0700632 * Copy an allocation from an allocation. The types of both allocations
633 * must be identical.
634 *
635 * @param a the source allocation
636 */
637 public void copyFrom(Allocation a) {
638 mRS.validate();
639 if (!mType.equals(a.getType())) {
640 throw new RSIllegalArgumentException("Types of allocations must match.");
641 }
642 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
643 }
644
645
646 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800647 * This is only intended to be used by auto-generate code reflected from the
648 * renderscript script files.
649 *
650 * @param xoff
651 * @param fp
652 */
Jason Sams21b41032011-01-16 15:05:41 -0800653 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800654 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700655 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700656 final byte[] data = fp.getData();
657
658 int count = data.length / eSize;
659 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800660 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700661 " not divisible by element size " + eSize + ".");
662 }
Jason Samsba862d12011-07-07 15:24:42 -0700663 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700664 }
665
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700666 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800667 * This is only intended to be used by auto-generate code reflected from the
668 * renderscript script files.
669 *
670 * @param xoff
671 * @param component_number
672 * @param fp
673 */
Jason Sams21b41032011-01-16 15:05:41 -0800674 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800675 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700676 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800677 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700678 }
679 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800680 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700681 }
682
683 final byte[] data = fp.getData();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700684 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800685 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700686
687 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800688 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700689 " does not match component size " + eSize + ".");
690 }
691
Jason Sams48fe5342011-07-08 13:52:30 -0700692 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
Jason Samsba862d12011-07-07 15:24:42 -0700693 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700694 }
695
Jason Sams768bc022009-09-21 19:41:04 -0700696 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800697 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700698 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800699 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700700 }
701 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800702 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700703 }
Jason Samsba862d12011-07-07 15:24:42 -0700704 if((off + count) > mCurrentCount) {
705 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700706 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700707 }
Jason Samsba862d12011-07-07 15:24:42 -0700708 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800709 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700710 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700711 }
712
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700713 /**
Jason Samsf7086092011-01-12 13:28:37 -0800714 * Generate a mipmap chain. Requires the type of the allocation
715 * include mipmaps.
716 *
717 * This function will generate a complete set of mipmaps from
718 * the top level lod and place them into the script memoryspace.
719 *
720 * If the allocation is also using other memory spaces a
721 * followup sync will be required.
722 */
723 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700724 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800725 }
726
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700727 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800728 * Copy part of an allocation from an array. This variant is
729 * not type checked which allows an application to fill in
730 * structured data from an array.
731 *
732 * @param off The offset of the first element to be copied.
733 * @param count The number of elements to be copied.
734 * @param d the source data array
735 */
736 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700737 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700738 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700739 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700740 }
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 * not type checked which allows an application to fill in
744 * structured data from an array.
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 */
750 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700751 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700752 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700753 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700754 }
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 * not type checked which allows an application to fill in
758 * structured data from an array.
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 */
764 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700765 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700766 data1DChecks(off, count, d.length, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700767 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700768 }
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 * not type checked which allows an application to fill in
772 * structured data from an array.
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 */
778 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700779 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700780 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700781 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700782 }
783
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700784 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800785 * Copy part of an allocation from an array. This variant is
786 * type checked and will generate exceptions if the Allocation
787 * type is not a 32 bit integer type.
788 *
789 * @param off The offset of the first element to be copied.
790 * @param count The number of elements to be copied.
791 * @param d the source data array
792 */
Jason Samsb97b2512011-01-16 15:04:08 -0800793 public void copy1DRangeFrom(int off, int count, int[] d) {
794 validateIsInt32();
795 copy1DRangeFromUnchecked(off, count, d);
796 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800797
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700798 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800799 * Copy part of an allocation from an array. This variant is
800 * type checked and will generate exceptions if the Allocation
801 * type is not a 16 bit integer type.
802 *
803 * @param off The offset of the first element to be copied.
804 * @param count The number of elements to be copied.
805 * @param d the source data array
806 */
Jason Samsb97b2512011-01-16 15:04:08 -0800807 public void copy1DRangeFrom(int off, int count, short[] d) {
808 validateIsInt16();
809 copy1DRangeFromUnchecked(off, count, d);
810 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800811
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700812 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800813 * Copy part of an allocation from an array. This variant is
814 * type checked and will generate exceptions if the Allocation
815 * type is not a 8 bit integer type.
816 *
817 * @param off The offset of the first element to be copied.
818 * @param count The number of elements to be copied.
819 * @param d the source data array
820 */
Jason Samsb97b2512011-01-16 15:04:08 -0800821 public void copy1DRangeFrom(int off, int count, byte[] d) {
822 validateIsInt8();
823 copy1DRangeFromUnchecked(off, count, d);
824 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800825
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700826 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800827 * Copy part of an allocation from an array. This variant is
828 * type checked and will generate exceptions if the Allocation
829 * type is not a 32 bit float type.
830 *
831 * @param off The offset of the first element to be copied.
832 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700833 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800834 */
Jason Samsb97b2512011-01-16 15:04:08 -0800835 public void copy1DRangeFrom(int off, int count, float[] d) {
836 validateIsFloat32();
837 copy1DRangeFromUnchecked(off, count, d);
838 }
839
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700840 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700841 * Copy part of an allocation from another allocation.
842 *
843 * @param off The offset of the first element to be copied.
844 * @param count The number of elements to be copied.
845 * @param data the source data allocation.
846 * @param dataOff off The offset of the first element in data to
847 * be copied.
848 */
849 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Jason Sams48fe5342011-07-08 13:52:30 -0700850 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700851 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700852 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700853 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700854 }
855
Jason Samsfb9f82c2011-01-12 14:53:25 -0800856 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700857 if (mAdaptedAllocation != null) {
858
859 } else {
860
861 if (xoff < 0 || yoff < 0) {
862 throw new RSIllegalArgumentException("Offset cannot be negative.");
863 }
864 if (h < 0 || w < 0) {
865 throw new RSIllegalArgumentException("Height or width cannot be negative.");
866 }
867 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
868 throw new RSIllegalArgumentException("Updated region larger than allocation.");
869 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800870 }
871 }
Jason Sams768bc022009-09-21 19:41:04 -0700872
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800873 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) {
874 mRS.validate();
875 validate2DRange(xoff, yoff, w, h);
876 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
877 w, h, data, data.length);
878 }
879
880 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) {
881 mRS.validate();
882 validate2DRange(xoff, yoff, w, h);
883 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
884 w, h, data, data.length * 2);
885 }
886
887 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) {
888 mRS.validate();
889 validate2DRange(xoff, yoff, w, h);
890 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
891 w, h, data, data.length * 4);
892 }
893
894 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) {
895 mRS.validate();
896 validate2DRange(xoff, yoff, w, h);
897 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
898 w, h, data, data.length * 4);
899 }
900
901
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700902 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700903 * Copy a rectangular region from the array into the allocation.
904 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800905 *
906 * @param xoff X offset of the region to update
907 * @param yoff Y offset of the region to update
908 * @param w Width of the incoming region to update
909 * @param h Height of the incoming region to update
910 * @param data to be placed into the allocation
911 */
912 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800913 validateIsInt8();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800914 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800915 }
916
Jason Samsf7086092011-01-12 13:28:37 -0800917 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800918 validateIsInt16();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800919 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800920 }
921
Jason Samsf7086092011-01-12 13:28:37 -0800922 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800923 validateIsInt32();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800924 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsb8c5a842009-07-31 20:40:47 -0700925 }
926
Jason Samsf7086092011-01-12 13:28:37 -0800927 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800928 validateIsFloat32();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800929 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsb8c5a842009-07-31 20:40:47 -0700930 }
931
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700932 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700933 * Copy a rectangular region into the allocation from another
934 * allocation.
935 *
936 * @param xoff X offset of the region to update.
937 * @param yoff Y offset of the region to update.
938 * @param w Width of the incoming region to update.
939 * @param h Height of the incoming region to update.
940 * @param data source allocation.
941 * @param dataXoff X offset in data of the region to update.
942 * @param dataYoff Y offset in data of the region to update.
943 */
944 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
945 Allocation data, int dataXoff, int dataYoff) {
946 mRS.validate();
947 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700948 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700949 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700950 w, h, data.getID(mRS), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700951 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700952 }
953
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700954 /**
Jason Samsf7086092011-01-12 13:28:37 -0800955 * Copy a bitmap into an allocation. The height and width of
956 * the update will use the height and width of the incoming
957 * bitmap.
958 *
959 * @param xoff X offset of the region to update
960 * @param yoff Y offset of the region to update
961 * @param data the bitmap to be copied
962 */
963 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800964 mRS.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -0800965 if (data.getConfig() == null) {
966 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
967 Canvas c = new Canvas(newBitmap);
968 c.drawBitmap(data, 0, 0, null);
969 copy2DRangeFrom(xoff, yoff, newBitmap);
970 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800971 validateBitmapFormat(data);
972 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Sams48fe5342011-07-08 13:52:30 -0700973 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800974 }
975
976
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700977 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700978 * Copy from the Allocation into a Bitmap. The bitmap must
979 * match the dimensions of the Allocation.
980 *
981 * @param b The bitmap to be set from the Allocation.
982 */
Jason Samsfa445b92011-01-07 17:00:07 -0800983 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800984 mRS.validate();
985 validateBitmapFormat(b);
986 validateBitmapSize(b);
Jason Samse07694b2012-04-03 15:36:36 -0700987 mRS.nAllocationCopyToBitmap(getID(mRS), b);
Jason Samsfa445b92011-01-07 17:00:07 -0800988 }
989
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700990 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700991 * Copy from the Allocation into a byte array. The array must
992 * be at least as large as the Allocation. The allocation must
993 * be of an 8 bit elemental type.
994 *
995 * @param d The array to be set from the Allocation.
996 */
Jason Samsfa445b92011-01-07 17:00:07 -0800997 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800998 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800999 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001000 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -07001001 }
1002
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001003 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001004 * Copy from the Allocation into a short array. The array must
1005 * be at least as large as the Allocation. The allocation must
1006 * be of an 16 bit elemental type.
1007 *
1008 * @param d The array to be set from the Allocation.
1009 */
Jason Samsfa445b92011-01-07 17:00:07 -08001010 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001011 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -08001012 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001013 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -08001014 }
1015
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001016 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001017 * Copy from the Allocation into a int array. The array must be
1018 * at least as large as the Allocation. The allocation must be
1019 * of an 32 bit elemental type.
1020 *
1021 * @param d The array to be set from the Allocation.
1022 */
Jason Samsfa445b92011-01-07 17:00:07 -08001023 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001024 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -08001025 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001026 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -08001027 }
1028
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001029 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001030 * Copy from the Allocation into a float array. The array must
1031 * be at least as large as the Allocation. The allocation must
1032 * be of an 32 bit float elemental type.
1033 *
1034 * @param d The array to be set from the Allocation.
1035 */
Jason Samsfa445b92011-01-07 17:00:07 -08001036 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001037 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -08001038 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001039 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -07001040 }
1041
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001042 /**
Jason Samsf7086092011-01-12 13:28:37 -08001043 * Resize a 1D allocation. The contents of the allocation are
1044 * preserved. If new elements are allocated objects are created
1045 * with null contents and the new region is otherwise undefined.
1046 *
1047 * If the new region is smaller the references of any objects
1048 * outside the new region will be released.
1049 *
1050 * A new type will be created with the new dimension.
1051 *
1052 * @param dimX The new size of the allocation.
1053 */
Jason Sams31a7e422010-10-26 13:09:17 -07001054 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001055 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001056 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001057 }
Jason Samse07694b2012-04-03 15:36:36 -07001058 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001059 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001060
Jason Samse07694b2012-04-03 15:36:36 -07001061 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001062 mType = new Type(typeID, mRS);
1063 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001064 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001065 }
1066
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001067 /**
Jason Sams163766c2012-02-15 12:04:24 -08001068 * Resize a 2D allocation. The contents of the allocation are
1069 * preserved. If new elements are allocated objects are created
1070 * with null contents and the new region is otherwise undefined.
1071 *
1072 * If the new region is smaller the references of any objects
1073 * outside the new region will be released.
1074 *
1075 * A new type will be created with the new dimension.
1076 *
Jason Sams163766c2012-02-15 12:04:24 -08001077 * @param dimX The new size of the allocation.
1078 * @param dimY The new size of the allocation.
1079 */
Tim Murraybc254b92012-10-05 15:00:45 -07001080 public synchronized void resize(int dimX, int dimY) {
Jason Sams163766c2012-02-15 12:04:24 -08001081 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
1082 throw new RSInvalidStateException(
1083 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001084 }
1085 if (mType.getY() == 0) {
Jason Sams163766c2012-02-15 12:04:24 -08001086 throw new RSInvalidStateException(
1087 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001088 }
Jason Samse07694b2012-04-03 15:36:36 -07001089 mRS.nAllocationResize2D(getID(mRS), dimX, dimY);
Jason Sams163766c2012-02-15 12:04:24 -08001090 mRS.finish(); // Necessary because resize is fifoed and update is async.
1091
Jason Samse07694b2012-04-03 15:36:36 -07001092 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -08001093 mType = new Type(typeID, mRS);
1094 mType.updateFromNative();
1095 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001096 }
Jason Sams40a29e82009-08-10 14:55:26 -07001097
Jason Samsbd1c3ad2009-08-03 16:03:08 -07001098
Jason Samsb8c5a842009-07-31 20:40:47 -07001099
1100 // creation
1101
Jason Sams49a05d72010-12-29 14:31:29 -08001102 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001103 static {
1104 mBitmapOptions.inScaled = false;
1105 }
1106
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001107 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001108 *
1109 * @param type renderscript type describing data layout
1110 * @param mips specifies desired mipmap behaviour for the
1111 * allocation
1112 * @param usage bit field specifying how the allocation is
1113 * utilized
1114 */
1115 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001116 rs.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001117 if (type.getID(rs) == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001118 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -07001119 }
Jason Samse07694b2012-04-03 15:36:36 -07001120 int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
Jason Sams857d0c72011-11-23 15:02:15 -08001121 if (id == 0) {
1122 throw new RSRuntimeException("Allocation creation failed.");
1123 }
1124 return new Allocation(id, rs, type, usage);
1125 }
1126
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001127 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001128 * Creates a renderscript allocation with the size specified by
1129 * the type and no mipmaps generated by default
1130 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001131 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001132 * @param type renderscript type describing data layout
1133 * @param usage bit field specifying how the allocation is
1134 * utilized
1135 *
1136 * @return allocation
1137 */
Jason Samse5d37122010-12-16 00:33:33 -08001138 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1139 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1140 }
1141
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001142 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001143 * Creates a renderscript allocation for use by the script with
1144 * the size specified by the type and no mipmaps generated by
1145 * default
1146 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001147 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001148 * @param type renderscript type describing data layout
1149 *
1150 * @return allocation
1151 */
Jason Sams5476b452010-12-08 16:14:36 -08001152 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001153 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001154 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001155
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001156 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001157 * Creates a renderscript allocation with a specified number of
1158 * given elements
1159 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001160 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001161 * @param e describes what each element of an allocation is
1162 * @param count specifies the number of element in the allocation
1163 * @param usage bit field specifying how the allocation is
1164 * utilized
1165 *
1166 * @return allocation
1167 */
Jason Sams5476b452010-12-08 16:14:36 -08001168 static public Allocation createSized(RenderScript rs, Element e,
1169 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001170 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -07001171 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001172 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -07001173 Type t = b.create();
1174
Jason Samse07694b2012-04-03 15:36:36 -07001175 int id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
Jason Sams5476b452010-12-08 16:14:36 -08001176 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001177 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -07001178 }
Jason Sams5476b452010-12-08 16:14:36 -08001179 return new Allocation(id, rs, t, usage);
1180 }
1181
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001182 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001183 * Creates a renderscript allocation with a specified number of
1184 * given elements
1185 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001186 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001187 * @param e describes what each element of an allocation is
1188 * @param count specifies the number of element in the allocation
1189 *
1190 * @return allocation
1191 */
Jason Sams5476b452010-12-08 16:14:36 -08001192 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001193 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001194 }
1195
Jason Sams49a05d72010-12-29 14:31:29 -08001196 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08001197 final Bitmap.Config bc = b.getConfig();
1198 if (bc == Bitmap.Config.ALPHA_8) {
1199 return Element.A_8(rs);
1200 }
1201 if (bc == Bitmap.Config.ARGB_4444) {
1202 return Element.RGBA_4444(rs);
1203 }
1204 if (bc == Bitmap.Config.ARGB_8888) {
1205 return Element.RGBA_8888(rs);
1206 }
1207 if (bc == Bitmap.Config.RGB_565) {
1208 return Element.RGB_565(rs);
1209 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08001210 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08001211 }
1212
Jason Sams49a05d72010-12-29 14:31:29 -08001213 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001214 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08001215 Element e = elementFromBitmap(rs, b);
1216 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001217 tb.setX(b.getWidth());
1218 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08001219 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08001220 return tb.create();
1221 }
1222
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001223 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001224 * Creates a renderscript allocation from a bitmap
1225 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001226 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001227 * @param b bitmap source for the allocation data
1228 * @param mips specifies desired mipmap behaviour for the
1229 * allocation
1230 * @param usage bit field specifying how the allocation is
1231 * utilized
1232 *
1233 * @return renderscript allocation containing bitmap data
1234 *
1235 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001236 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001237 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001238 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001239 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08001240
1241 // WAR undocumented color formats
1242 if (b.getConfig() == null) {
1243 if ((usage & USAGE_SHARED) != 0) {
1244 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
1245 }
1246 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
1247 Canvas c = new Canvas(newBitmap);
1248 c.drawBitmap(b, 0, 0, null);
1249 return createFromBitmap(rs, newBitmap, mips, usage);
1250 }
1251
Jason Sams5476b452010-12-08 16:14:36 -08001252 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08001253
Tim Murraya3145512012-12-04 17:59:29 -08001254 // enable optimized bitmap path only with no mipmap and script-only usage
1255 if (mips == MipmapControl.MIPMAP_NONE &&
1256 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
Stephen Hinesd34dc852012-12-19 19:33:13 -08001257 usage == (USAGE_SHARED | USAGE_SCRIPT)) {
Tim Murraya3145512012-12-04 17:59:29 -08001258 int id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
1259 if (id == 0) {
1260 throw new RSRuntimeException("Load failed.");
1261 }
1262
1263 // keep a reference to the Bitmap around to prevent GC
1264 Allocation alloc = new Allocation(id, rs, t, usage);
1265 alloc.setBitmap(b);
1266 return alloc;
1267 }
1268
1269
Jason Samse07694b2012-04-03 15:36:36 -07001270 int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Jason Sams5476b452010-12-08 16:14:36 -08001271 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001272 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -08001273 }
Jason Sams5476b452010-12-08 16:14:36 -08001274 return new Allocation(id, rs, t, usage);
1275 }
1276
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001277 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001278 * For allocations used with io operations, returns the handle
1279 * onto a raw buffer that is being managed by the screen
1280 * compositor.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001281 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001282 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001283 *
1284 */
1285 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08001286 if ((mUsage & USAGE_IO_INPUT) == 0) {
1287 throw new RSInvalidStateException("Allocation is not a surface texture.");
1288 }
1289 return mRS.nAllocationGetSurface(getID(mRS));
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001290 }
1291
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001292 /**
Jason Samsc089c2f2013-02-22 13:57:36 -08001293 * @hide
1294 */
1295 public void setSurfaceTexture(SurfaceTexture st) {
1296 setSurface(new Surface(st));
1297 }
1298
1299 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001300 * Associate a surface for io output with this allocation
1301 *
1302 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08001303 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001304 public void setSurface(Surface sur) {
1305 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08001306 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
1307 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
1308 }
1309
Jason Samse07694b2012-04-03 15:36:36 -07001310 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08001311 }
1312
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001313 /**
Tim Murray00bb4542012-12-17 16:35:06 -08001314 * Creates a RenderScript allocation from a bitmap.
1315 *
1316 * With target API version 18 or greater, this allocation will be
1317 * created with USAGE_SHARED. With target API version 17 or lower,
1318 * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001319 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001320 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001321 * @param b bitmap source for the allocation data
1322 *
1323 * @return renderscript allocation containing bitmap data
1324 *
1325 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001326 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08001327 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
1328 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1329 USAGE_SHARED | USAGE_SCRIPT);
1330 }
Jason Sams6d8eb262010-12-15 01:41:00 -08001331 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1332 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001333 }
1334
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001335 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001336 * Creates a cubemap allocation from a bitmap containing the
1337 * horizontal list of cube faces. Each individual face must be
1338 * the same size and power of 2
1339 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001340 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001341 * @param b bitmap with cubemap faces layed out in the following
1342 * format: right, left, top, bottom, front, back
1343 * @param mips specifies desired mipmap behaviour for the cubemap
1344 * @param usage bit field specifying how the cubemap is utilized
1345 *
1346 * @return allocation containing cubemap data
1347 *
1348 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001349 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001350 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001351 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001352 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001353
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001354 int height = b.getHeight();
1355 int width = b.getWidth();
1356
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001357 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001358 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1359 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001360 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001361 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001362 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001363 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001364 if (!isPow2) {
1365 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1366 }
1367
1368 Element e = elementFromBitmap(rs, b);
1369 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001370 tb.setX(height);
1371 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001372 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001373 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001374 Type t = tb.create();
1375
Jason Samse07694b2012-04-03 15:36:36 -07001376 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001377 if(id == 0) {
1378 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1379 }
Jason Sams5476b452010-12-08 16:14:36 -08001380 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001381 }
1382
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001383 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001384 * Creates a non-mipmapped cubemap allocation for use as a
1385 * graphics texture from a bitmap containing the horizontal list
1386 * of cube faces. Each individual face must be the same size and
1387 * power of 2
1388 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001389 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001390 * @param b bitmap with cubemap faces layed out in the following
1391 * format: right, left, top, bottom, front, back
1392 *
1393 * @return allocation containing cubemap data
1394 *
1395 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001396 static public Allocation createCubemapFromBitmap(RenderScript rs,
1397 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001398 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001399 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001400 }
1401
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001402 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001403 * Creates a cubemap allocation from 6 bitmaps containing
1404 * the cube faces. All the faces must be the same size and
1405 * power of 2
1406 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001407 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001408 * @param xpos cubemap face in the positive x direction
1409 * @param xneg cubemap face in the negative x direction
1410 * @param ypos cubemap face in the positive y direction
1411 * @param yneg cubemap face in the negative y direction
1412 * @param zpos cubemap face in the positive z direction
1413 * @param zneg cubemap face in the negative z direction
1414 * @param mips specifies desired mipmap behaviour for the cubemap
1415 * @param usage bit field specifying how the cubemap is utilized
1416 *
1417 * @return allocation containing cubemap data
1418 *
1419 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001420 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1421 Bitmap xpos,
1422 Bitmap xneg,
1423 Bitmap ypos,
1424 Bitmap yneg,
1425 Bitmap zpos,
1426 Bitmap zneg,
1427 MipmapControl mips,
1428 int usage) {
1429 int height = xpos.getHeight();
1430 if (xpos.getWidth() != height ||
1431 xneg.getWidth() != height || xneg.getHeight() != height ||
1432 ypos.getWidth() != height || ypos.getHeight() != height ||
1433 yneg.getWidth() != height || yneg.getHeight() != height ||
1434 zpos.getWidth() != height || zpos.getHeight() != height ||
1435 zneg.getWidth() != height || zneg.getHeight() != height) {
1436 throw new RSIllegalArgumentException("Only square cube map faces supported");
1437 }
1438 boolean isPow2 = (height & (height - 1)) == 0;
1439 if (!isPow2) {
1440 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1441 }
1442
1443 Element e = elementFromBitmap(rs, xpos);
1444 Type.Builder tb = new Type.Builder(rs, e);
1445 tb.setX(height);
1446 tb.setY(height);
1447 tb.setFaces(true);
1448 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1449 Type t = tb.create();
1450 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1451
1452 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001453 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001454 adapter.copyFrom(xpos);
1455 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1456 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001457 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001458 adapter.copyFrom(ypos);
1459 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1460 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001461 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001462 adapter.copyFrom(zpos);
1463 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1464 adapter.copyFrom(zneg);
1465
1466 return cubemap;
1467 }
1468
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001469 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001470 * Creates a non-mipmapped cubemap allocation for use as a
1471 * graphics texture from 6 bitmaps containing
1472 * the cube faces. All the faces must be the same size and
1473 * power of 2
1474 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001475 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001476 * @param xpos cubemap face in the positive x direction
1477 * @param xneg cubemap face in the negative x direction
1478 * @param ypos cubemap face in the positive y direction
1479 * @param yneg cubemap face in the negative y direction
1480 * @param zpos cubemap face in the positive z direction
1481 * @param zneg cubemap face in the negative z direction
1482 *
1483 * @return allocation containing cubemap data
1484 *
1485 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001486 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1487 Bitmap xpos,
1488 Bitmap xneg,
1489 Bitmap ypos,
1490 Bitmap yneg,
1491 Bitmap zpos,
1492 Bitmap zneg) {
1493 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1494 zpos, zneg, MipmapControl.MIPMAP_NONE,
1495 USAGE_GRAPHICS_TEXTURE);
1496 }
1497
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001498 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001499 * Creates a renderscript allocation from the bitmap referenced
1500 * by resource id
1501 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001502 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001503 * @param res application resources
1504 * @param id resource id to load the data from
1505 * @param mips specifies desired mipmap behaviour for the
1506 * allocation
1507 * @param usage bit field specifying how the allocation is
1508 * utilized
1509 *
1510 * @return renderscript allocation containing resource data
1511 *
1512 */
Jason Sams5476b452010-12-08 16:14:36 -08001513 static public Allocation createFromBitmapResource(RenderScript rs,
1514 Resources res,
1515 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001516 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001517 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001518
Jason Sams771bebb2009-12-07 12:40:12 -08001519 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001520 Bitmap b = BitmapFactory.decodeResource(res, id);
1521 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1522 b.recycle();
1523 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001524 }
1525
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001526 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001527 * Creates a non-mipmapped renderscript allocation to use as a
1528 * graphics texture from the bitmap referenced by resource id
1529 *
Jason Sams455d6442013-02-05 19:20:18 -08001530 * With target API version 18 or greater, this allocation will be
1531 * created with USAGE_SHARED. With target API version 17 or lower,
1532 * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
1533 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001534 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001535 * @param res application resources
1536 * @param id resource id to load the data from
1537 *
1538 * @return renderscript allocation containing resource data
1539 *
1540 */
Jason Sams5476b452010-12-08 16:14:36 -08001541 static public Allocation createFromBitmapResource(RenderScript rs,
1542 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001543 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08001544 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
1545 return createFromBitmapResource(rs, res, id,
1546 MipmapControl.MIPMAP_NONE,
1547 USAGE_SHARED | USAGE_SCRIPT);
1548 }
Jason Sams6d8eb262010-12-15 01:41:00 -08001549 return createFromBitmapResource(rs, res, id,
1550 MipmapControl.MIPMAP_NONE,
1551 USAGE_GRAPHICS_TEXTURE);
1552 }
1553
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001554 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001555 * Creates a renderscript allocation containing string data
1556 * encoded in UTF-8 format
1557 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001558 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001559 * @param str string to create the allocation from
1560 * @param usage bit field specifying how the allocaiton is
1561 * utilized
1562 *
1563 */
Jason Sams5476b452010-12-08 16:14:36 -08001564 static public Allocation createFromString(RenderScript rs,
1565 String str,
1566 int usage) {
1567 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001568 byte[] allocArray = null;
1569 try {
1570 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001571 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001572 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001573 return alloc;
1574 }
1575 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001576 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001577 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001578 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001579}
1580
1581