blob: 81f63aeab0a5e76a9b74e7f247200d963ebccdfa [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
Miao Wang0facf022015-11-25 11:21:13 -080019import java.nio.ByteBuffer;
Jason Sams739c8262013-04-11 18:07:52 -070020import java.util.HashMap;
Miao Wang0facf022015-11-25 11:21:13 -080021
Jason Samsb8c5a842009-07-31 20:40:47 -070022import android.content.res.Resources;
23import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
Tim Murrayabd5db92013-02-28 11:45:22 -080025import android.graphics.Canvas;
Tim Murray6d7a53c2013-05-23 16:59:23 -070026import android.os.Trace;
Miao Wang0facf022015-11-25 11:21:13 -080027import android.util.Log;
28import android.view.Surface;
Jason Samsb8c5a842009-07-31 20:40:47 -070029
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070030/**
Tim Murrayc11e25c2013-04-09 11:01:01 -070031 * <p> This class provides the primary method through which data is passed to
32 * and from RenderScript kernels. An Allocation provides the backing store for
33 * a given {@link android.renderscript.Type}. </p>
Jason Samsa23d4e72011-01-04 18:59:12 -080034 *
Tim Murrayc11e25c2013-04-09 11:01:01 -070035 * <p>An Allocation also contains a set of usage flags that denote how the
36 * Allocation could be used. For example, an Allocation may have usage flags
37 * specifying that it can be used from a script as well as input to a {@link
38 * android.renderscript.Sampler}. A developer must synchronize across these
39 * different usages using {@link android.renderscript.Allocation#syncAll} in
40 * order to ensure that different users of the Allocation have a consistent view
41 * of memory. For example, in the case where an Allocation is used as the output
42 * of one kernel and as Sampler input in a later kernel, a developer must call
43 * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
44 * second kernel to ensure correctness.
Jason Samsa23d4e72011-01-04 18:59:12 -080045 *
Tim Murrayc11e25c2013-04-09 11:01:01 -070046 * <p>An Allocation can be populated with the {@link #copyFrom} routines. For
47 * more complex Element types, the {@link #copyFromUnchecked} methods can be
48 * used to copy from byte arrays or similar constructs.</p>
Jason Samsb8c5a842009-07-31 20:40:47 -070049 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080050 * <div class="special reference">
51 * <h3>Developer Guides</h3>
Tim Murrayc11e25c2013-04-09 11:01:01 -070052 * <p>For more information about creating an application that uses RenderScript, read the
53 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080054 * </div>
Jason Samsb8c5a842009-07-31 20:40:47 -070055 **/
Chris Craik06d29842015-06-02 17:19:24 -070056
Jason Samsb8c5a842009-07-31 20:40:47 -070057public class Allocation extends BaseObj {
Miao Wang8c150922015-10-26 17:44:10 -070058 private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16;
59
Jason Sams43ee06852009-08-12 17:54:11 -070060 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080061 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080062 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070063 Allocation mAdaptedAllocation;
Tim Murray2f2472c2013-08-22 14:55:26 -070064 int mSize;
Miao Wang8c150922015-10-26 17:44:10 -070065 MipmapControl mMipmapControl;
Jason Samsba862d12011-07-07 15:24:42 -070066
Miao Wang8c150922015-10-26 17:44:10 -070067 long mTimeStamp = -1;
Jason Sams615e7ce2012-01-13 14:01:20 -080068 boolean mReadAllowed = true;
69 boolean mWriteAllowed = true;
Miao Wang87e908d2015-03-02 15:15:15 -080070 boolean mAutoPadding = false;
Jason Sams46ba27e32015-02-06 17:45:15 -080071 int mSelectedX;
Jason Samsba862d12011-07-07 15:24:42 -070072 int mSelectedY;
73 int mSelectedZ;
74 int mSelectedLOD;
Jason Sams46ba27e32015-02-06 17:45:15 -080075 int mSelectedArray[];
Jason Samsba862d12011-07-07 15:24:42 -070076 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
77
78 int mCurrentDimX;
79 int mCurrentDimY;
80 int mCurrentDimZ;
81 int mCurrentCount;
Tim Murray460a0492013-11-19 12:45:54 -080082 static HashMap<Long, Allocation> mAllocationMap =
83 new HashMap<Long, Allocation>();
Jason Sams42ef2382013-08-29 13:30:59 -070084 OnBufferAvailableListener mBufferNotifier;
Jason Samsba862d12011-07-07 15:24:42 -070085
Jason Sams1e68bac2015-03-17 16:36:55 -070086 private Surface mGetSurfaceSurface = null;
Miao Wang0facf022015-11-25 11:21:13 -080087 private ByteBuffer mByteBuffer = null;
88 private long mByteBufferStride = -1;
Jason Sams1e68bac2015-03-17 16:36:55 -070089
Jason Sams3042d262013-11-25 18:28:33 -080090 private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
91 final Class c = d.getClass();
92 if (!c.isArray()) {
93 throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
94 }
95 final Class cmp = c.getComponentType();
96 if (!cmp.isPrimitive()) {
97 throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
98 }
99
100 if (cmp == Long.TYPE) {
101 if (checkType) {
102 validateIsInt64();
103 return mType.mElement.mType;
104 }
105 return Element.DataType.SIGNED_64;
106 }
107
108 if (cmp == Integer.TYPE) {
109 if (checkType) {
110 validateIsInt32();
111 return mType.mElement.mType;
112 }
113 return Element.DataType.SIGNED_32;
114 }
115
116 if (cmp == Short.TYPE) {
117 if (checkType) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800118 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -0800119 return mType.mElement.mType;
120 }
121 return Element.DataType.SIGNED_16;
122 }
123
124 if (cmp == Byte.TYPE) {
125 if (checkType) {
126 validateIsInt8();
127 return mType.mElement.mType;
128 }
129 return Element.DataType.SIGNED_8;
130 }
131
132 if (cmp == Float.TYPE) {
133 if (checkType) {
134 validateIsFloat32();
135 }
136 return Element.DataType.FLOAT_32;
137 }
138
139 if (cmp == Double.TYPE) {
140 if (checkType) {
141 validateIsFloat64();
142 }
143 return Element.DataType.FLOAT_64;
144 }
Pirama Arumuga Nainar3934dad2016-03-28 12:00:00 -0700145
146 throw new RSIllegalArgumentException("Parameter of type " + cmp.getSimpleName() +
147 "[] is not compatible with data type " + mType.mElement.mType.name() +
148 " of allocation");
Jason Sams3042d262013-11-25 18:28:33 -0800149 }
150
151
Tim Murrayc11e25c2013-04-09 11:01:01 -0700152 /**
153 * The usage of the Allocation. These signal to RenderScript where to place
154 * the Allocation in memory.
155 *
156 */
Jason Sams5476b452010-12-08 16:14:36 -0800157
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700158 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700159 * The Allocation will be bound to and accessed by scripts.
Jason Samsf7086092011-01-12 13:28:37 -0800160 */
Jason Sams5476b452010-12-08 16:14:36 -0800161 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800162
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700163 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700164 * The Allocation will be used as a texture source by one or more graphics
165 * programs.
Jason Samsf7086092011-01-12 13:28:37 -0800166 *
167 */
Jason Sams5476b452010-12-08 16:14:36 -0800168 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800169
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700170 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700171 * The Allocation will be used as a graphics mesh.
172 *
173 * This was deprecated in API level 16.
Jason Samsf7086092011-01-12 13:28:37 -0800174 *
175 */
Jason Sams5476b452010-12-08 16:14:36 -0800176 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800177
178
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700179 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700180 * The Allocation will be used as the source of shader constants by one or
181 * more programs.
182 *
183 * This was deprecated in API level 16.
Jason Samsf7086092011-01-12 13:28:37 -0800184 *
185 */
Jason Sams5476b452010-12-08 16:14:36 -0800186 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
187
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700188 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700189 * The Allocation will be used as a target for offscreen rendering
190 *
191 * This was deprecated in API level 16.
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700192 *
193 */
194 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
195
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700196 /**
Jason Sams3a1b8e42013-09-24 15:18:52 -0700197 * The Allocation will be used as a {@link android.view.Surface}
198 * consumer. This usage will cause the Allocation to be created
199 * as read-only.
Jason Sams615e7ce2012-01-13 14:01:20 -0800200 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800201 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700202 public static final int USAGE_IO_INPUT = 0x0020;
Stephen Hines9069ee82012-02-13 18:25:54 -0800203
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700204 /**
Jason Sams3a1b8e42013-09-24 15:18:52 -0700205 * The Allocation will be used as a {@link android.view.Surface}
Tim Murrayc11e25c2013-04-09 11:01:01 -0700206 * producer. The dimensions and format of the {@link
Jason Sams3a1b8e42013-09-24 15:18:52 -0700207 * android.view.Surface} will be forced to those of the
Tim Murrayc11e25c2013-04-09 11:01:01 -0700208 * Allocation.
Jason Sams615e7ce2012-01-13 14:01:20 -0800209 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800210 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700211 public static final int USAGE_IO_OUTPUT = 0x0040;
Jason Sams43ee06852009-08-12 17:54:11 -0700212
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700213 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700214 * The Allocation's backing store will be inherited from another object
215 * (usually a {@link android.graphics.Bitmap}); copying to or from the
216 * original source Bitmap will cause a synchronization rather than a full
217 * copy. {@link #syncAll} may also be used to synchronize the Allocation
218 * and the source Bitmap.
Tim Murray00bb4542012-12-17 16:35:06 -0800219 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700220 * <p>This is set by default for allocations created with {@link
221 * #createFromBitmap} in API version 18 and higher.</p>
Tim Murray00bb4542012-12-17 16:35:06 -0800222 *
223 */
224 public static final int USAGE_SHARED = 0x0080;
225
226 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700227 * Controls mipmap behavior when using the bitmap creation and update
228 * functions.
Jason Samsf7086092011-01-12 13:28:37 -0800229 */
Jason Sams4ef66502010-12-10 16:03:15 -0800230 public enum MipmapControl {
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700231 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700232 * No mipmaps will be generated and the type generated from the incoming
233 * bitmap will not contain additional LODs.
Jason Samsf7086092011-01-12 13:28:37 -0800234 */
Jason Sams5476b452010-12-08 16:14:36 -0800235 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800236
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700237 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700238 * A full mipmap chain will be created in script memory. The Type of
239 * the Allocation will contain a full mipmap chain. On upload, the full
240 * chain will be transferred.
Jason Samsf7086092011-01-12 13:28:37 -0800241 */
Jason Sams5476b452010-12-08 16:14:36 -0800242 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800243
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700244 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700245 * The Type of the Allocation will be the same as MIPMAP_NONE. It will
246 * not contain mipmaps. On upload, the allocation data will contain a
247 * full mipmap chain generated from the top level in script memory.
Jason Samsf7086092011-01-12 13:28:37 -0800248 */
Jason Sams5476b452010-12-08 16:14:36 -0800249 MIPMAP_ON_SYNC_TO_TEXTURE(2);
250
251 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800252 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800253 mID = id;
254 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700255 }
256
Jason Sams48fe5342011-07-08 13:52:30 -0700257
Tim Murray460a0492013-11-19 12:45:54 -0800258 private long getIDSafe() {
Jason Sams48fe5342011-07-08 13:52:30 -0700259 if (mAdaptedAllocation != null) {
Jason Samse07694b2012-04-03 15:36:36 -0700260 return mAdaptedAllocation.getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700261 }
Jason Samse07694b2012-04-03 15:36:36 -0700262 return getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700263 }
264
Jason Sams03d2d002012-03-23 13:51:56 -0700265
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700266 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700267 * Get the {@link android.renderscript.Element} of the {@link
268 * android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700269 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700270 * @return Element
Jason Sams03d2d002012-03-23 13:51:56 -0700271 *
272 */
273 public Element getElement() {
274 return mType.getElement();
275 }
276
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700277 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700278 * Get the usage flags of the Allocation.
279 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700280 * @return usage this Allocation's set of the USAGE_* flags OR'd together
Jason Sams03d2d002012-03-23 13:51:56 -0700281 *
282 */
283 public int getUsage() {
284 return mUsage;
285 }
286
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700287 /**
Miao Wang8c150922015-10-26 17:44:10 -0700288 * @hide
289 * Get the Mipmap control flag of the Allocation.
290 *
291 * @return the Mipmap control flag of the Allocation
292 *
293 */
294 public MipmapControl getMipmap() {
295 return mMipmapControl;
296 }
297
298 /**
Miao Wang9ee76072016-03-29 15:56:55 -0700299 * Enable/Disable AutoPadding for Vec3 Elements.
300 *
301 * <p> Vec3 Elements, such as {@link Element#U8_3} are treated as Vec4 Elements
302 * with the fourth vector element used as padding. Enabling the AutoPadding feature
303 * will automatically add/remove the padding when you copy to/from an Allocation
304 * with a Vec3 Element.
305 * <p> By default: Disabled.
Miao Wang87e908d2015-03-02 15:15:15 -0800306 *
Miao Wang179e8b52015-04-15 17:44:32 -0700307 * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
Miao Wang87e908d2015-03-02 15:15:15 -0800308 *
309 */
310 public void setAutoPadding(boolean useAutoPadding) {
311 mAutoPadding = useAutoPadding;
312 }
313
314 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700315 * Get the size of the Allocation in bytes.
316 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700317 * @return size of the Allocation in bytes.
Jason Sams36c0f642012-03-23 15:48:37 -0700318 *
319 */
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700320 public int getBytesSize() {
Tim Murray04f0d6e2013-12-17 17:15:25 -0800321 if (mType.mDimYuv != 0) {
322 return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
323 }
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700324 return mType.getCount() * mType.getElement().getBytesSize();
Jason Sams36c0f642012-03-23 15:48:37 -0700325 }
326
Jason Sams452a7662011-07-07 16:05:18 -0700327 private void updateCacheInfo(Type t) {
328 mCurrentDimX = t.getX();
329 mCurrentDimY = t.getY();
330 mCurrentDimZ = t.getZ();
331 mCurrentCount = mCurrentDimX;
332 if (mCurrentDimY > 1) {
333 mCurrentCount *= mCurrentDimY;
334 }
335 if (mCurrentDimZ > 1) {
336 mCurrentCount *= mCurrentDimZ;
337 }
338 }
Jason Samsba862d12011-07-07 15:24:42 -0700339
Tim Murraya3145512012-12-04 17:59:29 -0800340 private void setBitmap(Bitmap b) {
341 mBitmap = b;
342 }
343
Tim Murray460a0492013-11-19 12:45:54 -0800344 Allocation(long id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700345 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800346 if ((usage & ~(USAGE_SCRIPT |
347 USAGE_GRAPHICS_TEXTURE |
348 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700349 USAGE_GRAPHICS_CONSTANTS |
Jason Sams615e7ce2012-01-13 14:01:20 -0800350 USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams615e7ce2012-01-13 14:01:20 -0800351 USAGE_IO_INPUT |
Tim Murray00bb4542012-12-17 16:35:06 -0800352 USAGE_IO_OUTPUT |
353 USAGE_SHARED)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800354 throw new RSIllegalArgumentException("Unknown usage specified.");
355 }
Jason Sams615e7ce2012-01-13 14:01:20 -0800356
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700357 if ((usage & USAGE_IO_INPUT) != 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800358 mWriteAllowed = false;
359
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700360 if ((usage & ~(USAGE_IO_INPUT |
Jason Sams615e7ce2012-01-13 14:01:20 -0800361 USAGE_GRAPHICS_TEXTURE |
362 USAGE_SCRIPT)) != 0) {
363 throw new RSIllegalArgumentException("Invalid usage combination.");
364 }
365 }
Jason Sams9bf18922013-04-13 19:48:36 -0700366
Jason Sams5476b452010-12-08 16:14:36 -0800367 mType = t;
Jason Sams615e7ce2012-01-13 14:01:20 -0800368 mUsage = usage;
Jason Samsba862d12011-07-07 15:24:42 -0700369
Jason Sams452a7662011-07-07 16:05:18 -0700370 if (t != null) {
Stephen Hines88990da2013-09-09 17:56:07 -0700371 // TODO: A3D doesn't have Type info during creation, so we can't
372 // calculate the size ahead of time. We can possibly add a method
373 // to update the size in the future if it seems reasonable.
374 mSize = mType.getCount() * mType.getElement().getBytesSize();
Jason Sams452a7662011-07-07 16:05:18 -0700375 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700376 }
Tim Murray2f2472c2013-08-22 14:55:26 -0700377 try {
378 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
379 } catch (Exception e) {
380 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
381 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
382 }
383 }
384
Miao Wang8c150922015-10-26 17:44:10 -0700385 Allocation(long id, RenderScript rs, Type t, int usage, MipmapControl mips) {
386 this(id, rs, t, usage);
387 mMipmapControl = mips;
388 }
389
Tim Murray2f2472c2013-08-22 14:55:26 -0700390 protected void finalize() throws Throwable {
391 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
392 super.finalize();
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700393 }
394
Jason Sams3042d262013-11-25 18:28:33 -0800395 private void validateIsInt64() {
396 if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
397 (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
398 return;
399 }
400 throw new RSIllegalArgumentException(
401 "64 bit integer source does not match allocation type " + mType.mElement.mType);
402 }
403
Jason Samsb97b2512011-01-16 15:04:08 -0800404 private void validateIsInt32() {
405 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
406 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
407 return;
408 }
409 throw new RSIllegalArgumentException(
410 "32 bit integer source does not match allocation type " + mType.mElement.mType);
411 }
412
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800413 private void validateIsInt16OrFloat16() {
Jason Samsb97b2512011-01-16 15:04:08 -0800414 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800415 (mType.mElement.mType == Element.DataType.UNSIGNED_16) ||
416 (mType.mElement.mType == Element.DataType.FLOAT_16)) {
Jason Samsb97b2512011-01-16 15:04:08 -0800417 return;
418 }
419 throw new RSIllegalArgumentException(
420 "16 bit integer source does not match allocation type " + mType.mElement.mType);
421 }
422
423 private void validateIsInt8() {
424 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
425 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
426 return;
427 }
428 throw new RSIllegalArgumentException(
429 "8 bit integer source does not match allocation type " + mType.mElement.mType);
430 }
431
432 private void validateIsFloat32() {
433 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
434 return;
435 }
436 throw new RSIllegalArgumentException(
437 "32 bit float source does not match allocation type " + mType.mElement.mType);
438 }
439
Jason Sams3042d262013-11-25 18:28:33 -0800440 private void validateIsFloat64() {
441 if (mType.mElement.mType == Element.DataType.FLOAT_64) {
442 return;
443 }
444 throw new RSIllegalArgumentException(
445 "64 bit float source does not match allocation type " + mType.mElement.mType);
446 }
447
Jason Samsb97b2512011-01-16 15:04:08 -0800448 private void validateIsObject() {
449 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
450 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
451 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
452 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
453 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
454 (mType.mElement.mType == Element.DataType.RS_MESH) ||
455 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
456 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
457 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
458 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
459 return;
460 }
461 throw new RSIllegalArgumentException(
462 "Object source does not match allocation type " + mType.mElement.mType);
463 }
464
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700465 @Override
466 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800467 super.updateFromNative();
Tim Murray460a0492013-11-19 12:45:54 -0800468 long typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700469 if(typeID != 0) {
470 mType = new Type(typeID, mRS);
471 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700472 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700473 }
474 }
475
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700476 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700477 * Get the {@link android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700478 *
479 * @return Type
480 *
481 */
Jason Samsea87e962010-01-12 12:12:28 -0800482 public Type getType() {
483 return mType;
484 }
485
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700486 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700487 * Propagate changes from one usage of the Allocation to the
488 * other usages of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700489 *
490 */
Jason Sams5476b452010-12-08 16:14:36 -0800491 public void syncAll(int srcLocation) {
Chris Craik06d29842015-06-02 17:19:24 -0700492 try {
493 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
494 switch (srcLocation) {
495 case USAGE_GRAPHICS_TEXTURE:
496 case USAGE_SCRIPT:
497 if ((mUsage & USAGE_SHARED) != 0) {
498 copyFrom(mBitmap);
499 }
500 break;
501 case USAGE_GRAPHICS_CONSTANTS:
502 case USAGE_GRAPHICS_VERTEX:
503 break;
504 case USAGE_SHARED:
505 if ((mUsage & USAGE_SHARED) != 0) {
506 copyTo(mBitmap);
507 }
508 break;
509 default:
510 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
Tim Murray78e64942013-04-09 17:28:56 -0700511 }
Chris Craik06d29842015-06-02 17:19:24 -0700512 mRS.validate();
513 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
514 } finally {
515 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams5476b452010-12-08 16:14:36 -0800516 }
Jason Sams5476b452010-12-08 16:14:36 -0800517 }
518
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700519 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700520 * Send a buffer to the output stream. The contents of the Allocation will
521 * be undefined after this operation. This operation is only valid if {@link
522 * #USAGE_IO_OUTPUT} is set on the Allocation.
523 *
Jason Sams163766c2012-02-15 12:04:24 -0800524 *
Jason Sams163766c2012-02-15 12:04:24 -0800525 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700526 public void ioSend() {
Chris Craik06d29842015-06-02 17:19:24 -0700527 try {
528 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
529 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
530 throw new RSIllegalArgumentException(
531 "Can only send buffer if IO_OUTPUT usage specified.");
532 }
533 mRS.validate();
534 mRS.nAllocationIoSend(getID(mRS));
535 } finally {
536 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800537 }
Jason Sams163766c2012-02-15 12:04:24 -0800538 }
539
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700540 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700541 * Receive the latest input into the Allocation. This operation
542 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
Jason Sams163766c2012-02-15 12:04:24 -0800543 *
Jason Sams163766c2012-02-15 12:04:24 -0800544 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700545 public void ioReceive() {
Chris Craik06d29842015-06-02 17:19:24 -0700546 try {
547 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
548 if ((mUsage & USAGE_IO_INPUT) == 0) {
549 throw new RSIllegalArgumentException(
550 "Can only receive if IO_INPUT usage specified.");
551 }
552 mRS.validate();
Miao Wang8c150922015-10-26 17:44:10 -0700553 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
Chris Craik06d29842015-06-02 17:19:24 -0700554 } finally {
555 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800556 }
Jason Sams163766c2012-02-15 12:04:24 -0800557 }
558
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700559 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700560 * Copy an array of RS objects to the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700561 *
562 * @param d Source array.
563 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800564 public void copyFrom(BaseObj[] d) {
Chris Craik06d29842015-06-02 17:19:24 -0700565 try {
566 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
567 mRS.validate();
568 validateIsObject();
569 if (d.length != mCurrentCount) {
570 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
571 mCurrentCount + ", array length = " + d.length);
572 }
Tim Murray460a0492013-11-19 12:45:54 -0800573
Chris Craik06d29842015-06-02 17:19:24 -0700574 if (RenderScript.sPointerSize == 8) {
575 long i[] = new long[d.length * 4];
576 for (int ct=0; ct < d.length; ct++) {
577 i[ct * 4] = d[ct].getID(mRS);
578 }
579 copy1DRangeFromUnchecked(0, mCurrentCount, i);
580 } else {
581 int i[] = new int[d.length];
582 for (int ct=0; ct < d.length; ct++) {
583 i[ct] = (int) d[ct].getID(mRS);
584 }
585 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Tim Murray3de3dc72014-07-01 16:56:18 -0700586 }
Chris Craik06d29842015-06-02 17:19:24 -0700587 } finally {
588 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800589 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700590 }
591
Jason Samsfb9f82c2011-01-12 14:53:25 -0800592 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800593 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800594 if (bc == null) {
595 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
596 }
Jason Sams252c0782011-01-11 17:42:52 -0800597 switch (bc) {
598 case ALPHA_8:
599 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
600 throw new RSIllegalArgumentException("Allocation kind is " +
601 mType.getElement().mKind + ", type " +
602 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700603 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800604 " bytes, passed bitmap was " + bc);
605 }
606 break;
607 case ARGB_8888:
608 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700609 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800610 throw new RSIllegalArgumentException("Allocation kind is " +
611 mType.getElement().mKind + ", type " +
612 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700613 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800614 " bytes, passed bitmap was " + bc);
615 }
616 break;
617 case RGB_565:
618 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700619 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800620 throw new RSIllegalArgumentException("Allocation kind is " +
621 mType.getElement().mKind + ", type " +
622 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700623 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800624 " bytes, passed bitmap was " + bc);
625 }
626 break;
627 case ARGB_4444:
628 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700629 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800630 throw new RSIllegalArgumentException("Allocation kind is " +
631 mType.getElement().mKind + ", type " +
632 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700633 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800634 " bytes, passed bitmap was " + bc);
635 }
636 break;
637
638 }
Jason Sams4ef66502010-12-10 16:03:15 -0800639 }
640
Jason Samsfb9f82c2011-01-12 14:53:25 -0800641 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700642 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800643 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
644 }
645 }
646
Jason Sams3042d262013-11-25 18:28:33 -0800647 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700648 try {
649 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
650 mRS.validate();
651 if (mCurrentDimZ > 0) {
652 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
653 } else if (mCurrentDimY > 0) {
654 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
655 } else {
656 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
657 }
658 } finally {
659 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams3042d262013-11-25 18:28:33 -0800660 }
Jason Sams3042d262013-11-25 18:28:33 -0800661 }
662
663 /**
664 * Copy into this Allocation from an array. This method does not guarantee
665 * that the Allocation is compatible with the input buffer; it copies memory
666 * without reinterpretation.
667 *
668 * @param array The source data array
669 */
670 public void copyFromUnchecked(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700671 try {
672 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
673 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
674 java.lang.reflect.Array.getLength(array));
675 } finally {
676 Trace.traceEnd(RenderScript.TRACE_TAG);
677 }
Jason Sams3042d262013-11-25 18:28:33 -0800678 }
679
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700680 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700681 * Copy into this Allocation from an array. This method does not guarantee
682 * that the Allocation is compatible with the input buffer; it copies memory
683 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800684 *
685 * @param d the source data array
686 */
687 public void copyFromUnchecked(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800688 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800689 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700690
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700691 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700692 * Copy into this Allocation from an array. This method does not guarantee
693 * that the Allocation is compatible with the input buffer; it copies memory
694 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800695 *
696 * @param d the source data array
697 */
698 public void copyFromUnchecked(short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800699 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800700 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700701
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700702 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700703 * Copy into this Allocation from an array. This method does not guarantee
704 * that the Allocation is compatible with the input buffer; it copies memory
705 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800706 *
707 * @param d the source data array
708 */
709 public void copyFromUnchecked(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800710 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800711 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700712
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700713 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700714 * Copy into this Allocation from an array. This method does not guarantee
715 * that the Allocation is compatible with the input buffer; it copies memory
716 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800717 *
718 * @param d the source data array
719 */
720 public void copyFromUnchecked(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800721 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800722 }
723
Tim Murray6d7a53c2013-05-23 16:59:23 -0700724
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700725 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700726 * Copy into this Allocation from an array. This variant is type checked
727 * and will generate exceptions if the Allocation's {@link
Jason Sams3042d262013-11-25 18:28:33 -0800728 * android.renderscript.Element} does not match the array's
729 * primitive type.
730 *
Ying Wang16229812013-11-26 15:45:12 -0800731 * @param array The source data array
Jason Sams3042d262013-11-25 18:28:33 -0800732 */
733 public void copyFrom(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700734 try {
735 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
736 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
737 java.lang.reflect.Array.getLength(array));
738 } finally {
739 Trace.traceEnd(RenderScript.TRACE_TAG);
740 }
Jason Sams3042d262013-11-25 18:28:33 -0800741 }
742
743 /**
744 * Copy into this Allocation from an array. This variant is type checked
745 * and will generate exceptions if the Allocation's {@link
Tim Murrayc11e25c2013-04-09 11:01:01 -0700746 * android.renderscript.Element} is not a 32 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800747 *
748 * @param d the source data array
749 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800750 public void copyFrom(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800751 validateIsInt32();
752 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800753 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800754
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700755 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700756 * Copy into this Allocation from an array. This variant is type checked
757 * and will generate exceptions if the Allocation's {@link
758 * android.renderscript.Element} is not a 16 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800759 *
760 * @param d the source data array
761 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800762 public void copyFrom(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800763 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -0800764 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800765 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800766
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700767 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700768 * Copy into this Allocation from an array. This variant is type checked
769 * and will generate exceptions if the Allocation's {@link
770 * android.renderscript.Element} is not an 8 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800771 *
772 * @param d the source data array
773 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800774 public void copyFrom(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800775 validateIsInt8();
776 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800777 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800778
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700779 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700780 * Copy into this Allocation from an array. This variant is type checked
781 * and will generate exceptions if the Allocation's {@link
782 * android.renderscript.Element} is not a 32 bit float type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800783 *
784 * @param d the source data array
785 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800786 public void copyFrom(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800787 validateIsFloat32();
788 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800789 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800790
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700791 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700792 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
793 * height, width, and format of the bitmap must match the existing
794 * allocation.
795 *
796 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
797 * android.graphics.Bitmap} used to create the Allocation with {@link
798 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
799 * this will synchronize the Allocation with the latest data from the {@link
800 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
Jason Sams4fa3eed2011-01-19 15:44:38 -0800801 *
802 * @param b the source bitmap
803 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800804 public void copyFrom(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -0700805 try {
806 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
807 mRS.validate();
808 if (b.getConfig() == null) {
809 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
810 Canvas c = new Canvas(newBitmap);
811 c.drawBitmap(b, 0, 0, null);
812 copyFrom(newBitmap);
813 return;
814 }
815 validateBitmapSize(b);
816 validateBitmapFormat(b);
817 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
818 } finally {
819 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -0800820 }
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700821 }
822
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700823 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700824 * Copy an Allocation from an Allocation. The types of both allocations
Tim Murrayf671fb02012-10-03 13:50:05 -0700825 * must be identical.
826 *
827 * @param a the source allocation
828 */
829 public void copyFrom(Allocation a) {
Chris Craik06d29842015-06-02 17:19:24 -0700830 try {
831 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
832 mRS.validate();
833 if (!mType.equals(a.getType())) {
834 throw new RSIllegalArgumentException("Types of allocations must match.");
835 }
836 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
837 } finally {
838 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayf671fb02012-10-03 13:50:05 -0700839 }
Tim Murrayf671fb02012-10-03 13:50:05 -0700840 }
841
Tim Murrayf671fb02012-10-03 13:50:05 -0700842 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700843 * This is only intended to be used by auto-generated code reflected from
844 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800845 *
846 * @param xoff
847 * @param fp
848 */
Jason Sams21b41032011-01-16 15:05:41 -0800849 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc2012-02-22 15:22:41 -0800850 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700851 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700852 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700853 int data_length = fp.getPos();
Jason Samsa70f4162010-03-26 15:33:42 -0700854
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700855 int count = data_length / eSize;
856 if ((eSize * count) != data_length) {
857 throw new RSIllegalArgumentException("Field packer length " + data_length +
Jason Samsa70f4162010-03-26 15:33:42 -0700858 " not divisible by element size " + eSize + ".");
859 }
Jason Samsba862d12011-07-07 15:24:42 -0700860 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700861 }
862
Miao Wang45cec0a2015-03-04 16:40:21 -0800863
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700864 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700865 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800866 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800867 *
868 * @param xoff
869 * @param component_number
870 * @param fp
871 */
Jason Sams21b41032011-01-16 15:05:41 -0800872 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800873 setFromFieldPacker(xoff, 0, 0, component_number, fp);
874 }
875
876 /**
Miao Wangc8e237e2015-02-20 18:36:32 -0800877 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800878 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -0800879 *
880 * @param xoff
881 * @param yoff
Miao Wangc8e237e2015-02-20 18:36:32 -0800882 * @param zoff
883 * @param component_number
884 * @param fp
885 */
886 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc2012-02-22 15:22:41 -0800887 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700888 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800889 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700890 }
891 if(xoff < 0) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800892 throw new RSIllegalArgumentException("Offset x must be >= 0.");
893 }
894 if(yoff < 0) {
895 throw new RSIllegalArgumentException("Offset y must be >= 0.");
896 }
897 if(zoff < 0) {
898 throw new RSIllegalArgumentException("Offset z must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700899 }
900
901 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700902 int data_length = fp.getPos();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700903 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800904 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700905
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700906 if (data_length != eSize) {
907 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700908 " does not match component size " + eSize + ".");
909 }
910
Miao Wangc8e237e2015-02-20 18:36:32 -0800911 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
912 component_number, data, data_length);
Jason Samsa70f4162010-03-26 15:33:42 -0700913 }
914
Miao Wang87e908d2015-03-02 15:15:15 -0800915 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
Jason Sams771bebb2009-12-07 12:40:12 -0800916 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700917 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800918 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700919 }
920 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800921 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700922 }
Jason Samsba862d12011-07-07 15:24:42 -0700923 if((off + count) > mCurrentCount) {
924 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700925 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700926 }
Miao Wang87e908d2015-03-02 15:15:15 -0800927 if(usePadding) {
928 if(len < dataSize / 4 * 3) {
929 throw new RSIllegalArgumentException("Array too small for allocation type.");
930 }
931 } else {
932 if(len < dataSize) {
933 throw new RSIllegalArgumentException("Array too small for allocation type.");
934 }
Jason Sams768bc022009-09-21 19:41:04 -0700935 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700936 }
937
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700938 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700939 * Generate a mipmap chain. This is only valid if the Type of the Allocation
940 * includes mipmaps.
Jason Samsf7086092011-01-12 13:28:37 -0800941 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700942 * <p>This function will generate a complete set of mipmaps from the top
943 * level LOD and place them into the script memory space.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800944 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700945 * <p>If the Allocation is also using other memory spaces, a call to {@link
946 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800947 */
948 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700949 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800950 }
951
Jason Sams3042d262013-11-25 18:28:33 -0800952 private void copy1DRangeFromUnchecked(int off, int count, Object array,
953 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700954 try {
955 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
956 final int dataSize = mType.mElement.getBytesSize() * count;
957 // AutoPadding for Vec3 Element
958 boolean usePadding = false;
959 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
960 usePadding = true;
961 }
962 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
963 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
964 mType.mElement.mType.mSize, usePadding);
965 } finally {
966 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -0800967 }
Jason Sams3042d262013-11-25 18:28:33 -0800968 }
969
970 /**
971 * Copy an array into part of this Allocation. This method does not
972 * guarantee that the Allocation is compatible with the input buffer.
973 *
974 * @param off The offset of the first element to be copied.
975 * @param count The number of elements to be copied.
976 * @param array The source data array
977 */
978 public void copy1DRangeFromUnchecked(int off, int count, Object array) {
979 copy1DRangeFromUnchecked(off, count, array,
980 validateObjectIsPrimitiveArray(array, false),
981 java.lang.reflect.Array.getLength(array));
982 }
983
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700984 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700985 * Copy an array into part of this Allocation. This method does not
986 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800987 *
988 * @param off The offset of the first element to be copied.
989 * @param count The number of elements to be copied.
990 * @param d the source data array
991 */
992 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800993 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700994 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700995
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700996 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700997 * Copy an array into part of this Allocation. This method does not
998 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800999 *
1000 * @param off The offset of the first element to be copied.
1001 * @param count The number of elements to be copied.
1002 * @param d the source data array
1003 */
1004 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001005 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001006 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001007
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001008 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001009 * Copy an array into part of this Allocation. This method does not
1010 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001011 *
1012 * @param off The offset of the first element to be copied.
1013 * @param count The number of elements to be copied.
1014 * @param d the source data array
1015 */
1016 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001017 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001018 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001019
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001020 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001021 * Copy an array into part of this Allocation. This method does not
1022 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001023 *
1024 * @param off The offset of the first element to be copied.
1025 * @param count The number of elements to be copied.
1026 * @param d the source data array
1027 */
1028 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001029 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1030 }
1031
1032
1033 /**
1034 * Copy an array into part of this Allocation. This variant is type checked
1035 * and will generate exceptions if the Allocation type does not
1036 * match the component type of the array passed in.
1037 *
1038 * @param off The offset of the first element to be copied.
1039 * @param count The number of elements to be copied.
1040 * @param array The source data array.
1041 */
1042 public void copy1DRangeFrom(int off, int count, Object array) {
1043 copy1DRangeFromUnchecked(off, count, array,
1044 validateObjectIsPrimitiveArray(array, true),
1045 java.lang.reflect.Array.getLength(array));
Jason Samsb8c5a842009-07-31 20:40:47 -07001046 }
1047
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001048 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001049 * Copy an array into part of this Allocation. This variant is type checked
1050 * and will generate exceptions if the Allocation type is not a 32 bit
1051 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001052 *
1053 * @param off The offset of the first element to be copied.
1054 * @param count The number of elements to be copied.
1055 * @param d the source data array
1056 */
Jason Samsb97b2512011-01-16 15:04:08 -08001057 public void copy1DRangeFrom(int off, int count, int[] d) {
1058 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001059 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001060 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001061
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001062 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001063 * Copy an array into part of this Allocation. This variant is type checked
1064 * and will generate exceptions if the Allocation type is not a 16 bit
1065 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001066 *
1067 * @param off The offset of the first element to be copied.
1068 * @param count The number of elements to be copied.
1069 * @param d the source data array
1070 */
Jason Samsb97b2512011-01-16 15:04:08 -08001071 public void copy1DRangeFrom(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001072 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001073 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001074 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001075
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001076 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001077 * Copy an array into part of this Allocation. This variant is type checked
1078 * and will generate exceptions if the Allocation type is not an 8 bit
1079 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001080 *
1081 * @param off The offset of the first element to be copied.
1082 * @param count The number of elements to be copied.
1083 * @param d the source data array
1084 */
Jason Samsb97b2512011-01-16 15:04:08 -08001085 public void copy1DRangeFrom(int off, int count, byte[] d) {
1086 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001087 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001088 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001089
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001090 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001091 * Copy an array into part of this Allocation. This variant is type checked
1092 * and will generate exceptions if the Allocation type is not a 32 bit float
1093 * type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001094 *
1095 * @param off The offset of the first element to be copied.
1096 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001097 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001098 */
Jason Samsb97b2512011-01-16 15:04:08 -08001099 public void copy1DRangeFrom(int off, int count, float[] d) {
1100 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001101 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001102 }
Jason Sams3042d262013-11-25 18:28:33 -08001103
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001104 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001105 * Copy part of an Allocation into this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001106 *
1107 * @param off The offset of the first element to be copied.
1108 * @param count The number of elements to be copied.
1109 * @param data the source data allocation.
1110 * @param dataOff off The offset of the first element in data to
1111 * be copied.
1112 */
1113 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Tim Murray6d7a53c2013-05-23 16:59:23 -07001114 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
Jason Sams48fe5342011-07-08 13:52:30 -07001115 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001116 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -07001117 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001118 data.mSelectedLOD, data.mSelectedFace.mID);
Chris Craik5c705d62015-06-01 10:39:36 -07001119 Trace.traceEnd(RenderScript.TRACE_TAG);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001120 }
1121
Jason Samsfb9f82c2011-01-12 14:53:25 -08001122 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -07001123 if (mAdaptedAllocation != null) {
1124
1125 } else {
1126
1127 if (xoff < 0 || yoff < 0) {
1128 throw new RSIllegalArgumentException("Offset cannot be negative.");
1129 }
1130 if (h < 0 || w < 0) {
1131 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1132 }
1133 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1134 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1135 }
Jason Samsfb9f82c2011-01-12 14:53:25 -08001136 }
1137 }
Jason Sams768bc022009-09-21 19:41:04 -07001138
Jason Sams3042d262013-11-25 18:28:33 -08001139 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1140 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001141 try {
1142 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
1143 mRS.validate();
1144 validate2DRange(xoff, yoff, w, h);
1145 final int dataSize = mType.mElement.getBytesSize() * w * h;
1146 // AutoPadding for Vec3 Element
1147 boolean usePadding = false;
1148 int sizeBytes = arrayLen * dt.mSize;
1149 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1150 if (dataSize / 4 * 3 > sizeBytes) {
1151 throw new RSIllegalArgumentException("Array too small for allocation type.");
1152 }
1153 usePadding = true;
1154 sizeBytes = dataSize;
1155 } else {
1156 if (dataSize > sizeBytes) {
1157 throw new RSIllegalArgumentException("Array too small for allocation type.");
1158 }
Miao Wang87e908d2015-03-02 15:15:15 -08001159 }
Chris Craik06d29842015-06-02 17:19:24 -07001160 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1161 array, sizeBytes, dt,
1162 mType.mElement.mType.mSize, usePadding);
1163 } finally {
1164 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001165 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001166 }
1167
Jason Sams3042d262013-11-25 18:28:33 -08001168 /**
1169 * Copy from an array into a rectangular region in this Allocation. The
1170 * array is assumed to be tightly packed.
1171 *
1172 * @param xoff X offset of the region to update in this Allocation
1173 * @param yoff Y offset of the region to update in this Allocation
1174 * @param w Width of the region to update
1175 * @param h Height of the region to update
Ying Wang16229812013-11-26 15:45:12 -08001176 * @param array Data to be placed into the Allocation
Jason Sams3042d262013-11-25 18:28:33 -08001177 */
1178 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001179 try {
1180 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1181 copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1182 validateObjectIsPrimitiveArray(array, true),
1183 java.lang.reflect.Array.getLength(array));
1184 } finally {
1185 Trace.traceEnd(RenderScript.TRACE_TAG);
1186 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001187 }
1188
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001189 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001190 * Copy from an array into a rectangular region in this Allocation. The
1191 * array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -08001192 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001193 * @param xoff X offset of the region to update in this Allocation
1194 * @param yoff Y offset of the region to update in this Allocation
1195 * @param w Width of the region to update
1196 * @param h Height of the region to update
1197 * @param data to be placed into the Allocation
Jason Samsf7086092011-01-12 13:28:37 -08001198 */
1199 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001200 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001201 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1202 Element.DataType.SIGNED_8, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001203 }
1204
Tim Murrayc11e25c2013-04-09 11:01:01 -07001205 /**
1206 * Copy from an array into a rectangular region in this Allocation. The
1207 * array is assumed to be tightly packed.
1208 *
1209 * @param xoff X offset of the region to update in this Allocation
1210 * @param yoff Y offset of the region to update in this Allocation
1211 * @param w Width of the region to update
1212 * @param h Height of the region to update
1213 * @param data to be placed into the Allocation
1214 */
Jason Samsf7086092011-01-12 13:28:37 -08001215 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001216 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001217 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1218 Element.DataType.SIGNED_16, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001219 }
1220
Tim Murrayc11e25c2013-04-09 11:01:01 -07001221 /**
1222 * Copy from an array into a rectangular region in this Allocation. The
1223 * array is assumed to be tightly packed.
1224 *
1225 * @param xoff X offset of the region to update in this Allocation
1226 * @param yoff Y offset of the region to update in this Allocation
1227 * @param w Width of the region to update
1228 * @param h Height of the region to update
1229 * @param data to be placed into the Allocation
1230 */
Jason Samsf7086092011-01-12 13:28:37 -08001231 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001232 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001233 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1234 Element.DataType.SIGNED_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001235 }
1236
Tim Murrayc11e25c2013-04-09 11:01:01 -07001237 /**
1238 * Copy from an array into a rectangular region in this Allocation. The
1239 * array is assumed to be tightly packed.
1240 *
1241 * @param xoff X offset of the region to update in this Allocation
1242 * @param yoff Y offset of the region to update in this Allocation
1243 * @param w Width of the region to update
1244 * @param h Height of the region to update
1245 * @param data to be placed into the Allocation
1246 */
Jason Samsf7086092011-01-12 13:28:37 -08001247 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001248 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001249 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1250 Element.DataType.FLOAT_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001251 }
1252
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001253 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001254 * Copy a rectangular region from an Allocation into a rectangular region in
1255 * this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001256 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001257 * @param xoff X offset of the region in this Allocation
1258 * @param yoff Y offset of the region in this Allocation
1259 * @param w Width of the region to update.
1260 * @param h Height of the region to update.
1261 * @param data source Allocation.
1262 * @param dataXoff X offset in source Allocation
1263 * @param dataYoff Y offset in source Allocation
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001264 */
1265 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1266 Allocation data, int dataXoff, int dataYoff) {
Chris Craik06d29842015-06-02 17:19:24 -07001267 try {
1268 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1269 mRS.validate();
1270 validate2DRange(xoff, yoff, w, h);
1271 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1272 mSelectedLOD, mSelectedFace.mID,
1273 w, h, data.getID(mRS), dataXoff, dataYoff,
1274 data.mSelectedLOD, data.mSelectedFace.mID);
1275 } finally {
1276 Trace.traceEnd(RenderScript.TRACE_TAG);
1277 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001278 }
1279
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001280 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001281 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
1282 * and width of the update will use the height and width of the {@link
1283 * android.graphics.Bitmap}.
Jason Samsf7086092011-01-12 13:28:37 -08001284 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001285 * @param xoff X offset of the region to update in this Allocation
1286 * @param yoff Y offset of the region to update in this Allocation
1287 * @param data the Bitmap to be copied
Jason Samsf7086092011-01-12 13:28:37 -08001288 */
1289 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Chris Craik5c705d62015-06-01 10:39:36 -07001290 try {
1291 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1292 mRS.validate();
1293 if (data.getConfig() == null) {
1294 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1295 Canvas c = new Canvas(newBitmap);
1296 c.drawBitmap(data, 0, 0, null);
1297 copy2DRangeFrom(xoff, yoff, newBitmap);
1298 return;
1299 }
1300 validateBitmapFormat(data);
1301 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1302 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1303 } finally {
1304 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -08001305 }
Jason Samsfa445b92011-01-07 17:00:07 -08001306 }
1307
Jason Samsb05d6892013-04-09 15:59:24 -07001308 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1309 if (mAdaptedAllocation != null) {
1310
1311 } else {
1312
1313 if (xoff < 0 || yoff < 0 || zoff < 0) {
1314 throw new RSIllegalArgumentException("Offset cannot be negative.");
1315 }
1316 if (h < 0 || w < 0 || d < 0) {
1317 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1318 }
1319 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1320 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1321 }
1322 }
1323 }
1324
1325 /**
Miao Wang258db502015-03-03 14:05:36 -08001326 * Copy a rectangular region from the array into the allocation.
1327 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001328 *
Miao Wang258db502015-03-03 14:05:36 -08001329 * The data type of the array is not required to be the same as
1330 * the element data type.
Jason Samsb05d6892013-04-09 15:59:24 -07001331 */
Jason Sams3042d262013-11-25 18:28:33 -08001332 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1333 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001334 try {
1335 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
1336 mRS.validate();
1337 validate3DRange(xoff, yoff, zoff, w, h, d);
1338 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1339 // AutoPadding for Vec3 Element
1340 boolean usePadding = false;
1341 int sizeBytes = arrayLen * dt.mSize;
1342 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1343 if (dataSize / 4 * 3 > sizeBytes) {
1344 throw new RSIllegalArgumentException("Array too small for allocation type.");
1345 }
1346 usePadding = true;
1347 sizeBytes = dataSize;
1348 } else {
1349 if (dataSize > sizeBytes) {
1350 throw new RSIllegalArgumentException("Array too small for allocation type.");
1351 }
Miao Wang87e908d2015-03-02 15:15:15 -08001352 }
Chris Craik06d29842015-06-02 17:19:24 -07001353 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1354 array, sizeBytes, dt,
1355 mType.mElement.mType.mSize, usePadding);
1356 } finally {
1357 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001358 }
Jason Samsb05d6892013-04-09 15:59:24 -07001359 }
1360
1361 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001362 * Copy a rectangular region from the array into the allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001363 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001364 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001365 * @param xoff X offset of the region to update in this Allocation
1366 * @param yoff Y offset of the region to update in this Allocation
1367 * @param zoff Z offset of the region to update in this Allocation
1368 * @param w Width of the region to update
1369 * @param h Height of the region to update
1370 * @param d Depth of the region to update
Miao Wang87e908d2015-03-02 15:15:15 -08001371 * @param array to be placed into the allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001372 */
Jason Sams3042d262013-11-25 18:28:33 -08001373 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001374 try {
1375 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
1376 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1377 validateObjectIsPrimitiveArray(array, true),
1378 java.lang.reflect.Array.getLength(array));
1379 } finally {
1380 Trace.traceEnd(RenderScript.TRACE_TAG);
1381 }
Jason Samsb05d6892013-04-09 15:59:24 -07001382 }
1383
1384 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001385 * Copy a rectangular region into the allocation from another
1386 * allocation.
1387 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001388 * @param xoff X offset of the region to update in this Allocation
1389 * @param yoff Y offset of the region to update in this Allocation
1390 * @param zoff Z offset of the region to update in this Allocation
1391 * @param w Width of the region to update.
1392 * @param h Height of the region to update.
1393 * @param d Depth of the region to update.
Jason Samsb05d6892013-04-09 15:59:24 -07001394 * @param data source allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001395 * @param dataXoff X offset of the region in the source Allocation
1396 * @param dataYoff Y offset of the region in the source Allocation
1397 * @param dataZoff Z offset of the region in the source Allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001398 */
1399 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1400 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1401 mRS.validate();
1402 validate3DRange(xoff, yoff, zoff, w, h, d);
1403 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1404 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1405 data.mSelectedLOD);
1406 }
1407
Jason Samsfa445b92011-01-07 17:00:07 -08001408
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001409 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001410 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
1411 * bitmap must match the dimensions of the Allocation.
Jason Sams48fe5342011-07-08 13:52:30 -07001412 *
1413 * @param b The bitmap to be set from the Allocation.
1414 */
Jason Samsfa445b92011-01-07 17:00:07 -08001415 public void copyTo(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -07001416 try {
1417 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1418 mRS.validate();
1419 validateBitmapFormat(b);
1420 validateBitmapSize(b);
1421 mRS.nAllocationCopyToBitmap(getID(mRS), b);
1422 } finally {
1423 Trace.traceEnd(RenderScript.TRACE_TAG);
1424 }
Jason Samsfa445b92011-01-07 17:00:07 -08001425 }
1426
Jason Sams3042d262013-11-25 18:28:33 -08001427 private void copyTo(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001428 try {
1429 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1430 mRS.validate();
1431 boolean usePadding = false;
1432 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1433 usePadding = true;
Miao Wangd9b63282015-04-03 09:15:39 -07001434 }
Chris Craik06d29842015-06-02 17:19:24 -07001435 if (usePadding) {
1436 if (dt.mSize * arrayLen < mSize / 4 * 3) {
1437 throw new RSIllegalArgumentException(
1438 "Size of output array cannot be smaller than size of allocation.");
1439 }
1440 } else {
1441 if (dt.mSize * arrayLen < mSize) {
1442 throw new RSIllegalArgumentException(
1443 "Size of output array cannot be smaller than size of allocation.");
1444 }
Miao Wangd9b63282015-04-03 09:15:39 -07001445 }
Chris Craik06d29842015-06-02 17:19:24 -07001446 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1447 } finally {
1448 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wangd9b63282015-04-03 09:15:39 -07001449 }
Jason Sams3042d262013-11-25 18:28:33 -08001450 }
1451
1452 /**
1453 * Copy from the Allocation into an array. The array must be at
1454 * least as large as the Allocation. The
1455 * {@link android.renderscript.Element} must match the component
1456 * type of the array passed in.
1457 *
1458 * @param array The array to be set from the Allocation.
1459 */
1460 public void copyTo(Object array) {
1461 copyTo(array, validateObjectIsPrimitiveArray(array, true),
1462 java.lang.reflect.Array.getLength(array));
1463 }
1464
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001465 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001466 * Copy from the Allocation into a byte array. The array must be at least
1467 * as large as the Allocation. The allocation must be of an 8 bit integer
1468 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001469 *
1470 * @param d The array to be set from the Allocation.
1471 */
Jason Samsfa445b92011-01-07 17:00:07 -08001472 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001473 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001474 copyTo(d, Element.DataType.SIGNED_8, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001475 }
1476
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001477 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001478 * Copy from the Allocation into a short array. The array must be at least
1479 * as large as the Allocation. The allocation must be of an 16 bit integer
1480 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001481 *
1482 * @param d The array to be set from the Allocation.
1483 */
Jason Samsfa445b92011-01-07 17:00:07 -08001484 public void copyTo(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001485 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001486 copyTo(d, Element.DataType.SIGNED_16, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001487 }
1488
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001489 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001490 * Copy from the Allocation into a int array. The array must be at least as
1491 * large as the Allocation. The allocation must be of an 32 bit integer
1492 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001493 *
1494 * @param d The array to be set from the Allocation.
1495 */
Jason Samsfa445b92011-01-07 17:00:07 -08001496 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001497 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001498 copyTo(d, Element.DataType.SIGNED_32, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001499 }
1500
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001501 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001502 * Copy from the Allocation into a float array. The array must be at least
1503 * as large as the Allocation. The allocation must be of an 32 bit float
1504 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001505 *
1506 * @param d The array to be set from the Allocation.
1507 */
Jason Samsfa445b92011-01-07 17:00:07 -08001508 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001509 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001510 copyTo(d, Element.DataType.FLOAT_32, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001511 }
1512
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001513 /**
Miao Wang3c613272015-05-11 11:41:55 -07001514 * @hide
1515 *
Miao Wang45cec0a2015-03-04 16:40:21 -08001516 * This is only intended to be used by auto-generated code reflected from
1517 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -08001518 *
1519 * @param xoff
1520 * @param yoff
1521 * @param zoff
1522 * @param component_number
Miao Wang258db502015-03-03 14:05:36 -08001523 * @param fp
Miao Wangc8e237e2015-02-20 18:36:32 -08001524 */
Miao Wang45cec0a2015-03-04 16:40:21 -08001525 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -08001526 mRS.validate();
1527 if (component_number >= mType.mElement.mElements.length) {
1528 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1529 }
1530 if(xoff < 0) {
1531 throw new RSIllegalArgumentException("Offset x must be >= 0.");
1532 }
1533 if(yoff < 0) {
1534 throw new RSIllegalArgumentException("Offset y must be >= 0.");
1535 }
1536 if(zoff < 0) {
1537 throw new RSIllegalArgumentException("Offset z must be >= 0.");
1538 }
1539
Miao Wang45cec0a2015-03-04 16:40:21 -08001540 final byte[] data = fp.getData();
Miao Wangbfa5e652015-05-04 15:29:25 -07001541 int data_length = data.length;
Miao Wangc8e237e2015-02-20 18:36:32 -08001542 int eSize = mType.mElement.mElements[component_number].getBytesSize();
1543 eSize *= mType.mElement.mArraySizes[component_number];
1544
Miao Wang45cec0a2015-03-04 16:40:21 -08001545 if (data_length != eSize) {
1546 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1547 " does not match component size " + eSize + ".");
Miao Wangc8e237e2015-02-20 18:36:32 -08001548 }
1549
1550 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
Miao Wang45cec0a2015-03-04 16:40:21 -08001551 component_number, data, data_length);
Miao Wangc8e237e2015-02-20 18:36:32 -08001552 }
1553 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001554 * Resize a 1D allocation. The contents of the allocation are preserved.
1555 * If new elements are allocated objects are created with null contents and
1556 * the new region is otherwise undefined.
Jason Samsf7086092011-01-12 13:28:37 -08001557 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001558 * <p>If the new region is smaller the references of any objects outside the
1559 * new region will be released.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001560 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001561 * <p>A new type will be created with the new dimension.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001562 *
1563 * @param dimX The new size of the allocation.
Jason Samsb05d6892013-04-09 15:59:24 -07001564 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001565 * @deprecated RenderScript objects should be immutable once created. The
Tim Murraycd38b762014-08-13 13:20:25 -07001566 * replacement is to create a new allocation and copy the contents. This
1567 * function will throw an exception if API 21 or higher is used.
Jason Samsf7086092011-01-12 13:28:37 -08001568 */
Jason Sams31a7e422010-10-26 13:09:17 -07001569 public synchronized void resize(int dimX) {
Tim Murraycd38b762014-08-13 13:20:25 -07001570 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) {
1571 throw new RSRuntimeException("Resize is not allowed in API 21+.");
1572 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001573 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001574 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001575 }
Jason Samse07694b2012-04-03 15:36:36 -07001576 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001577 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001578
Tim Murray460a0492013-11-19 12:45:54 -08001579 long typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001580 mType = new Type(typeID, mRS);
1581 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001582 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001583 }
1584
Miao Wangc8e237e2015-02-20 18:36:32 -08001585 private void copy1DRangeToUnchecked(int off, int count, Object array,
1586 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001587 try {
1588 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked");
1589 final int dataSize = mType.mElement.getBytesSize() * count;
1590 // AutoPadding for Vec3 Element
1591 boolean usePadding = false;
1592 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1593 usePadding = true;
1594 }
1595 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1596 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1597 mType.mElement.mType.mSize, usePadding);
1598 } finally {
1599 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001600 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001601 }
1602
1603 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001604 * Copy part of this Allocation into an array. This method does not
1605 * guarantee that the Allocation is compatible with the input buffer.
1606 *
1607 * @param off The offset of the first element to be copied.
1608 * @param count The number of elements to be copied.
1609 * @param array The dest data array
1610 */
1611 public void copy1DRangeToUnchecked(int off, int count, Object array) {
1612 copy1DRangeToUnchecked(off, count, array,
1613 validateObjectIsPrimitiveArray(array, false),
1614 java.lang.reflect.Array.getLength(array));
1615 }
1616
1617 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001618 * Copy part of this Allocation into an array. This method does not
1619 * guarantee that the Allocation is compatible with the input buffer.
1620 *
1621 * @param off The offset of the first element to be copied.
1622 * @param count The number of elements to be copied.
1623 * @param d the source data array
1624 */
1625 public void copy1DRangeToUnchecked(int off, int count, int[] d) {
1626 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1627 }
1628
1629 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001630 * Copy part of this Allocation into an array. This method does not
1631 * guarantee that the Allocation is compatible with the input buffer.
1632 *
1633 * @param off The offset of the first element to be copied.
1634 * @param count The number of elements to be copied.
1635 * @param d the source data array
1636 */
1637 public void copy1DRangeToUnchecked(int off, int count, short[] d) {
1638 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1639 }
1640
1641 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001642 * Copy part of this Allocation into an array. This method does not
1643 * guarantee that the Allocation is compatible with the input buffer.
1644 *
1645 * @param off The offset of the first element to be copied.
1646 * @param count The number of elements to be copied.
1647 * @param d the source data array
1648 */
1649 public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
1650 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1651 }
1652
1653 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001654 * Copy part of this Allocation into an array. This method does not
1655 * guarantee that the Allocation is compatible with the input buffer.
1656 *
1657 * @param off The offset of the first element to be copied.
1658 * @param count The number of elements to be copied.
1659 * @param d the source data array
1660 */
1661 public void copy1DRangeToUnchecked(int off, int count, float[] d) {
1662 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1663 }
1664
1665
1666 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001667 * Copy part of this Allocation into an array. This method does not
1668 * and will generate exceptions if the Allocation type does not
1669 * match the component type of the array passed in.
1670 *
1671 * @param off The offset of the first element to be copied.
1672 * @param count The number of elements to be copied.
1673 * @param array The source data array.
1674 */
1675 public void copy1DRangeTo(int off, int count, Object array) {
1676 copy1DRangeToUnchecked(off, count, array,
1677 validateObjectIsPrimitiveArray(array, true),
1678 java.lang.reflect.Array.getLength(array));
1679 }
1680
1681 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001682 * Copy part of this Allocation into an array. This method does not
1683 * and will generate exceptions if the Allocation type is not a 32 bit
1684 * integer type.
1685 *
1686 * @param off The offset of the first element to be copied.
1687 * @param count The number of elements to be copied.
1688 * @param d the source data array
1689 */
1690 public void copy1DRangeTo(int off, int count, int[] d) {
1691 validateIsInt32();
1692 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1693 }
1694
1695 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001696 * Copy part of this Allocation into an array. This method does not
1697 * and will generate exceptions if the Allocation type is not a 16 bit
1698 * integer type.
1699 *
1700 * @param off The offset of the first element to be copied.
1701 * @param count The number of elements to be copied.
1702 * @param d the source data array
1703 */
1704 public void copy1DRangeTo(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001705 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001706 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1707 }
1708
1709 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001710 * Copy part of this Allocation into an array. This method does not
1711 * and will generate exceptions if the Allocation type is not an 8 bit
1712 * integer type.
1713 *
1714 * @param off The offset of the first element to be copied.
1715 * @param count The number of elements to be copied.
1716 * @param d the source data array
1717 */
1718 public void copy1DRangeTo(int off, int count, byte[] d) {
1719 validateIsInt8();
1720 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1721 }
1722
1723 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001724 * Copy part of this Allocation into an array. This method does not
1725 * and will generate exceptions if the Allocation type is not a 32 bit float
1726 * type.
1727 *
1728 * @param off The offset of the first element to be copied.
1729 * @param count The number of elements to be copied.
1730 * @param d the source data array.
1731 */
1732 public void copy1DRangeTo(int off, int count, float[] d) {
1733 validateIsFloat32();
1734 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1735 }
1736
1737
1738 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
1739 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001740 try {
1741 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked");
1742 mRS.validate();
1743 validate2DRange(xoff, yoff, w, h);
1744 final int dataSize = mType.mElement.getBytesSize() * w * h;
1745 // AutoPadding for Vec3 Element
1746 boolean usePadding = false;
1747 int sizeBytes = arrayLen * dt.mSize;
1748 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1749 if (dataSize / 4 * 3 > sizeBytes) {
1750 throw new RSIllegalArgumentException("Array too small for allocation type.");
1751 }
1752 usePadding = true;
1753 sizeBytes = dataSize;
1754 } else {
1755 if (dataSize > sizeBytes) {
1756 throw new RSIllegalArgumentException("Array too small for allocation type.");
1757 }
Miao Wang87e908d2015-03-02 15:15:15 -08001758 }
Chris Craik06d29842015-06-02 17:19:24 -07001759 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1760 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1761 } finally {
1762 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001763 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001764 }
1765
1766 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001767 * Copy from a rectangular region in this Allocation into an array.
1768 *
1769 * @param xoff X offset of the region to copy in this Allocation
1770 * @param yoff Y offset of the region to copy in this Allocation
1771 * @param w Width of the region to copy
1772 * @param h Height of the region to copy
1773 * @param array Dest Array to be copied into
1774 */
1775 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
1776 copy2DRangeToUnchecked(xoff, yoff, w, h, array,
1777 validateObjectIsPrimitiveArray(array, true),
1778 java.lang.reflect.Array.getLength(array));
1779 }
1780
1781 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001782 * Copy from a rectangular region in this Allocation into an array.
1783 *
1784 * @param xoff X offset of the region to copy in this Allocation
1785 * @param yoff Y offset of the region to copy in this Allocation
1786 * @param w Width of the region to copy
1787 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001788 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001789 */
1790 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
1791 validateIsInt8();
1792 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1793 Element.DataType.SIGNED_8, data.length);
1794 }
1795
1796 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001797 * Copy from a rectangular region in this Allocation into an array.
1798 *
1799 * @param xoff X offset of the region to copy in this Allocation
1800 * @param yoff Y offset of the region to copy in this Allocation
1801 * @param w Width of the region to copy
1802 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001803 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001804 */
1805 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001806 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001807 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1808 Element.DataType.SIGNED_16, data.length);
1809 }
1810
1811 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001812 * Copy from a rectangular region in this Allocation into an array.
1813 *
1814 * @param xoff X offset of the region to copy in this Allocation
1815 * @param yoff Y offset of the region to copy in this Allocation
1816 * @param w Width of the region to copy
1817 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001818 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001819 */
1820 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
1821 validateIsInt32();
1822 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1823 Element.DataType.SIGNED_32, data.length);
1824 }
1825
1826 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001827 * Copy from a rectangular region in this Allocation into an array.
1828 *
1829 * @param xoff X offset of the region to copy in this Allocation
1830 * @param yoff Y offset of the region to copy in this Allocation
1831 * @param w Width of the region to copy
1832 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001833 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001834 */
1835 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
1836 validateIsFloat32();
1837 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1838 Element.DataType.FLOAT_32, data.length);
1839 }
1840
1841
1842 /**
Miao Wang258db502015-03-03 14:05:36 -08001843 * Copy from a rectangular region in this Allocation into an array.
1844 * The array is assumed to be tightly packed.
Miao Wangc8e237e2015-02-20 18:36:32 -08001845 *
Miao Wang258db502015-03-03 14:05:36 -08001846 * The data type of the array is not required to be the same as
1847 * the element data type.
Miao Wangc8e237e2015-02-20 18:36:32 -08001848 */
1849 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1850 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001851 try {
1852 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked");
1853 mRS.validate();
1854 validate3DRange(xoff, yoff, zoff, w, h, d);
1855 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1856 // AutoPadding for Vec3 Element
1857 boolean usePadding = false;
1858 int sizeBytes = arrayLen * dt.mSize;
1859 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1860 if (dataSize / 4 * 3 > sizeBytes) {
1861 throw new RSIllegalArgumentException("Array too small for allocation type.");
1862 }
1863 usePadding = true;
1864 sizeBytes = dataSize;
1865 } else {
1866 if (dataSize > sizeBytes) {
1867 throw new RSIllegalArgumentException("Array too small for allocation type.");
1868 }
Miao Wang87e908d2015-03-02 15:15:15 -08001869 }
Chris Craik06d29842015-06-02 17:19:24 -07001870 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1871 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1872 } finally {
1873 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001874 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001875 }
1876
Miao Wang258db502015-03-03 14:05:36 -08001877 /*
Miao Wangc8e237e2015-02-20 18:36:32 -08001878 * Copy from a rectangular region in this Allocation into an array.
1879 *
1880 * @param xoff X offset of the region to copy in this Allocation
1881 * @param yoff Y offset of the region to copy in this Allocation
1882 * @param zoff Z offset of the region to copy in this Allocation
1883 * @param w Width of the region to copy
1884 * @param h Height of the region to copy
1885 * @param d Depth of the region to copy
1886 * @param array Dest Array to be copied into
1887 */
1888 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1889 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
1890 validateObjectIsPrimitiveArray(array, true),
1891 java.lang.reflect.Array.getLength(array));
1892 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001893
1894 // creation
1895
Jason Sams49a05d72010-12-29 14:31:29 -08001896 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001897 static {
1898 mBitmapOptions.inScaled = false;
1899 }
1900
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001901 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001902 * Creates a new Allocation with the given {@link
1903 * android.renderscript.Type}, mipmap flag, and usage flags.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001904 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001905 * @param type RenderScript type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001906 * @param mips specifies desired mipmap behaviour for the
1907 * allocation
Tim Murrayc11e25c2013-04-09 11:01:01 -07001908 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001909 * utilized
1910 */
1911 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001912 try {
1913 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
1914 rs.validate();
1915 if (type.getID(rs) == 0) {
1916 throw new RSInvalidStateException("Bad Type");
1917 }
1918 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
1919 if (id == 0) {
1920 throw new RSRuntimeException("Allocation creation failed.");
1921 }
Miao Wang8c150922015-10-26 17:44:10 -07001922 return new Allocation(id, rs, type, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07001923 } finally {
1924 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams1bada8c2009-08-09 17:01:55 -07001925 }
Jason Sams857d0c72011-11-23 15:02:15 -08001926 }
1927
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001928 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001929 * Creates an Allocation with the size specified by the type and no mipmaps
1930 * generated by default
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001931 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001932 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001933 * @param type renderscript type describing data layout
1934 * @param usage bit field specifying how the allocation is
1935 * utilized
1936 *
1937 * @return allocation
1938 */
Jason Samse5d37122010-12-16 00:33:33 -08001939 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1940 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1941 }
1942
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001943 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001944 * Creates an Allocation for use by scripts with a given {@link
1945 * android.renderscript.Type} and no mipmaps
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001946 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001947 * @param rs Context to which the Allocation will belong.
1948 * @param type RenderScript Type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001949 *
1950 * @return allocation
1951 */
Jason Sams5476b452010-12-08 16:14:36 -08001952 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001953 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001954 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001955
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001956 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001957 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001958 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001959 * @param rs Context to which the Allocation will belong.
1960 * @param e Element to use in the Allocation
1961 * @param count the number of Elements in the Allocation
1962 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001963 * utilized
1964 *
1965 * @return allocation
1966 */
Jason Sams5476b452010-12-08 16:14:36 -08001967 static public Allocation createSized(RenderScript rs, Element e,
1968 int count, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001969 try {
1970 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
1971 rs.validate();
1972 Type.Builder b = new Type.Builder(rs, e);
1973 b.setX(count);
1974 Type t = b.create();
Jason Sams768bc022009-09-21 19:41:04 -07001975
Chris Craik06d29842015-06-02 17:19:24 -07001976 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
1977 if (id == 0) {
1978 throw new RSRuntimeException("Allocation creation failed.");
1979 }
Miao Wang8c150922015-10-26 17:44:10 -07001980 return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
Chris Craik06d29842015-06-02 17:19:24 -07001981 } finally {
1982 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsb8c5a842009-07-31 20:40:47 -07001983 }
Jason Sams5476b452010-12-08 16:14:36 -08001984 }
1985
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001986 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001987 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001988 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001989 * @param rs Context to which the Allocation will belong.
1990 * @param e Element to use in the Allocation
1991 * @param count the number of Elements in the Allocation
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001992 *
1993 * @return allocation
1994 */
Jason Sams5476b452010-12-08 16:14:36 -08001995 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001996 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001997 }
1998
Jason Sams49a05d72010-12-29 14:31:29 -08001999 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08002000 final Bitmap.Config bc = b.getConfig();
2001 if (bc == Bitmap.Config.ALPHA_8) {
2002 return Element.A_8(rs);
2003 }
2004 if (bc == Bitmap.Config.ARGB_4444) {
2005 return Element.RGBA_4444(rs);
2006 }
2007 if (bc == Bitmap.Config.ARGB_8888) {
2008 return Element.RGBA_8888(rs);
2009 }
2010 if (bc == Bitmap.Config.RGB_565) {
2011 return Element.RGB_565(rs);
2012 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08002013 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08002014 }
2015
Jason Sams49a05d72010-12-29 14:31:29 -08002016 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002017 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08002018 Element e = elementFromBitmap(rs, b);
2019 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002020 tb.setX(b.getWidth());
2021 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08002022 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08002023 return tb.create();
2024 }
2025
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002026 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002027 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002028 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002029 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002030 * @param b Bitmap source for the allocation data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002031 * @param mips specifies desired mipmap behaviour for the
2032 * allocation
2033 * @param usage bit field specifying how the allocation is
2034 * utilized
2035 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002036 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002037 *
2038 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002039 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002040 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002041 int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07002042 try {
2043 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
2044 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08002045
Chris Craik06d29842015-06-02 17:19:24 -07002046 // WAR undocumented color formats
2047 if (b.getConfig() == null) {
2048 if ((usage & USAGE_SHARED) != 0) {
2049 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2050 }
2051 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2052 Canvas c = new Canvas(newBitmap);
2053 c.drawBitmap(b, 0, 0, null);
2054 return createFromBitmap(rs, newBitmap, mips, usage);
Tim Murrayabd5db92013-02-28 11:45:22 -08002055 }
Tim Murrayabd5db92013-02-28 11:45:22 -08002056
Chris Craik06d29842015-06-02 17:19:24 -07002057 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08002058
Chris Craik06d29842015-06-02 17:19:24 -07002059 // enable optimized bitmap path only with no mipmap and script-only usage
2060 if (mips == MipmapControl.MIPMAP_NONE &&
2061 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2062 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2063 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2064 if (id == 0) {
2065 throw new RSRuntimeException("Load failed.");
2066 }
2067
2068 // keep a reference to the Bitmap around to prevent GC
Miao Wang8c150922015-10-26 17:44:10 -07002069 Allocation alloc = new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002070 alloc.setBitmap(b);
2071 return alloc;
2072 }
2073
2074
2075 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Tim Murraya3145512012-12-04 17:59:29 -08002076 if (id == 0) {
2077 throw new RSRuntimeException("Load failed.");
2078 }
Miao Wang8c150922015-10-26 17:44:10 -07002079 return new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002080 } finally {
2081 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murraya3145512012-12-04 17:59:29 -08002082 }
Jason Sams5476b452010-12-08 16:14:36 -08002083 }
2084
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002085 /**
Miao Wang0facf022015-11-25 11:21:13 -08002086 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
2087 * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
2088 * would contain the up-to-date data as READ ONLY.
2089 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2090 * the Allocation has certain alignment. The size of each row including padding,
2091 * called stride, can be queried using the {@link #getStride()} method.
2092 *
2093 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
2094 *
2095 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
2096 */
2097 public ByteBuffer getByteBuffer() {
2098 // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
2099 if (mType.hasFaces()) {
2100 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
2101 }
2102 if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
2103 mType.getYuv() == android.graphics.ImageFormat.YV12 ||
2104 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
2105 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
2106 }
2107 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
2108 int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
2109 long[] stride = new long[1];
2110 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
2111 mByteBufferStride = stride[0];
2112 }
2113 if ((mUsage & USAGE_IO_INPUT) != 0) {
2114 return mByteBuffer.asReadOnlyBuffer();
2115 }
2116 return mByteBuffer;
2117 }
2118
2119 /**
Miao Wang8c150922015-10-26 17:44:10 -07002120 * Creates a new Allocation Array with the given {@link
2121 * android.renderscript.Type}, and usage flags.
2122 * Note: If the input allocation is of usage: USAGE_IO_INPUT,
2123 * the created Allocation will be sharing the same BufferQueue.
2124 *
2125 * @param rs RenderScript context
2126 * @param t RenderScript type describing data layout
2127 * @param usage bit field specifying how the Allocation is
2128 * utilized
2129 * @param numAlloc Number of Allocations in the array.
2130 * @return Allocation[]
2131 */
2132 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
2133 try {
2134 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
2135 rs.validate();
2136 if (t.getID(rs) == 0) {
2137 throw new RSInvalidStateException("Bad Type");
2138 }
2139
2140 Allocation[] mAllocationArray = new Allocation[numAlloc];
2141 mAllocationArray[0] = createTyped(rs, t, usage);
2142 if ((usage & USAGE_IO_INPUT) != 0) {
2143 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
2144 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2145 MAX_NUMBER_IO_INPUT_ALLOC);
2146 }
2147 mAllocationArray[0].setupBufferQueue(numAlloc);;
2148 }
2149
2150 for (int i=1; i<numAlloc; i++) {
2151 mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
2152 }
2153 return mAllocationArray;
2154 } finally {
2155 Trace.traceEnd(RenderScript.TRACE_TAG);
2156 }
2157 }
2158
2159 /**
2160 * Creates a new Allocation with the given {@link
2161 * android.renderscript.Allocation}. The same data layout of
2162 * the input Allocation will be applied.
2163 * If the input allocation is of usage: USAGE_IO_INPUT, the created
2164 * Allocation will be sharing the same BufferQueue.
2165 *
2166 * @param rs Context to which the allocation will belong.
2167 * @param alloc RenderScript Allocation describing data layout.
2168 * @return Allocation sharing the same data structure.
2169 */
2170 static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
2171 try {
2172 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2173 rs.validate();
2174 if (alloc.getID(rs) == 0) {
2175 throw new RSInvalidStateException("Bad input Allocation");
2176 }
2177
2178 Type type = alloc.getType();
2179 int usage = alloc.getUsage();
2180 MipmapControl mips = alloc.getMipmap();
2181 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2182 if (id == 0) {
2183 throw new RSRuntimeException("Allocation creation failed.");
2184 }
2185 Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
2186 if ((usage & USAGE_IO_INPUT) != 0) {
2187 outAlloc.shareBufferQueue(alloc);
2188 }
2189 return outAlloc;
2190 } finally {
2191 Trace.traceEnd(RenderScript.TRACE_TAG);
2192 }
2193 }
2194
2195 /**
2196 * Initialize BufferQueue with specified max number of buffers.
2197 */
2198 void setupBufferQueue(int numAlloc) {
2199 mRS.validate();
2200 if ((mUsage & USAGE_IO_INPUT) == 0) {
2201 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2202 }
2203 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2204 }
2205
2206 /**
2207 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2208 *
2209 * @param alloc Allocation to associate with allocation
2210 */
2211 void shareBufferQueue(Allocation alloc) {
2212 mRS.validate();
2213 if ((mUsage & USAGE_IO_INPUT) == 0) {
2214 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2215 }
2216 mGetSurfaceSurface = alloc.getSurface();
2217 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2218 }
2219
2220 /**
Miao Wang0facf022015-11-25 11:21:13 -08002221 * Gets the stride of the Allocation.
2222 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2223 * the Allocation has certain alignment. The size of each row including such
2224 * padding is called stride.
2225 *
2226 * @return the stride. For 1D Allocation, the stride will be the number of
2227 * bytes of this Allocation. For 2D and 3D Allocations, the stride
2228 * will be the stride in X dimension measuring in bytes.
2229 */
2230 public long getStride() {
2231 if (mByteBufferStride == -1) {
2232 getByteBuffer();
2233 }
2234 return mByteBufferStride;
2235 }
2236
2237 /**
Miao Wang8c150922015-10-26 17:44:10 -07002238 * Get the timestamp for the most recent buffer held by this Allocation.
2239 * The timestamp is guaranteed to be unique and monotonically increasing.
2240 * Default value: -1. The timestamp will be updated after each {@link
2241 * #ioReceive ioReceive()} call.
2242 *
2243 * It can be used to identify the images by comparing the unique timestamps
2244 * when used with {@link android.hardware.camera2} APIs.
2245 * Example steps:
2246 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
2247 * capture is completed.
2248 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
2249 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
2250 * alloc.getTimeStamp().
2251 * @return long Timestamp associated with the buffer held by the Allocation.
2252 */
2253 public long getTimeStamp() {
2254 return mTimeStamp;
2255 }
2256
2257 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002258 * Returns the handle to a raw buffer that is being managed by the screen
2259 * compositor. This operation is only valid for Allocations with {@link
2260 * #USAGE_IO_INPUT}.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002261 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002262 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002263 *
2264 */
2265 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08002266 if ((mUsage & USAGE_IO_INPUT) == 0) {
2267 throw new RSInvalidStateException("Allocation is not a surface texture.");
2268 }
Jason Sams1e68bac2015-03-17 16:36:55 -07002269
2270 if (mGetSurfaceSurface == null) {
2271 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
2272 }
2273
2274 return mGetSurfaceSurface;
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002275 }
2276
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002277 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002278 * Associate a {@link android.view.Surface} with this Allocation. This
2279 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002280 *
2281 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08002282 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002283 public void setSurface(Surface sur) {
2284 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08002285 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2286 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2287 }
2288
Jason Samse07694b2012-04-03 15:36:36 -07002289 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08002290 }
2291
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002292 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002293 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Tim Murray00bb4542012-12-17 16:35:06 -08002294 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002295 * <p>With target API version 18 or greater, this Allocation will be created
2296 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
2297 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
2298 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002299 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002300 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002301 * @param b bitmap source for the allocation data
2302 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002303 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002304 *
2305 */
Jason Sams6d8eb262010-12-15 01:41:00 -08002306 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08002307 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2308 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Tim Murray78e64942013-04-09 17:28:56 -07002309 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Tim Murray00bb4542012-12-17 16:35:06 -08002310 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002311 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2312 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08002313 }
2314
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002315 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002316 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2317 * containing the horizontal list of cube faces. Each face must be a square,
2318 * have the same size as all other faces, and have a width that is a power
2319 * of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002320 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002321 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002322 * @param b Bitmap with cubemap faces layed out in the following
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002323 * format: right, left, top, bottom, front, back
2324 * @param mips specifies desired mipmap behaviour for the cubemap
2325 * @param usage bit field specifying how the cubemap is utilized
2326 *
2327 * @return allocation containing cubemap data
2328 *
2329 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002330 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002331 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002332 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002333 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08002334
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002335 int height = b.getHeight();
2336 int width = b.getWidth();
2337
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002338 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002339 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2340 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002341 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002342 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002343 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002344 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002345 if (!isPow2) {
2346 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2347 }
2348
2349 Element e = elementFromBitmap(rs, b);
2350 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002351 tb.setX(height);
2352 tb.setY(height);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002353 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08002354 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002355 Type t = tb.create();
2356
Tim Murray460a0492013-11-19 12:45:54 -08002357 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002358 if(id == 0) {
2359 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2360 }
Miao Wang8c150922015-10-26 17:44:10 -07002361 return new Allocation(id, rs, t, usage, mips);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002362 }
2363
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002364 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002365 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2366 * from a {@link android.graphics.Bitmap} containing the horizontal list of
2367 * cube faces. Each face must be a square, have the same size as all other
2368 * faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002369 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002370 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002371 * @param b bitmap with cubemap faces layed out in the following
2372 * format: right, left, top, bottom, front, back
2373 *
2374 * @return allocation containing cubemap data
2375 *
2376 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002377 static public Allocation createCubemapFromBitmap(RenderScript rs,
2378 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08002379 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002380 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08002381 }
2382
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002383 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002384 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2385 * objects containing the cube faces. Each face must be a square, have the
2386 * same size as all other faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002387 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002388 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002389 * @param xpos cubemap face in the positive x direction
2390 * @param xneg cubemap face in the negative x direction
2391 * @param ypos cubemap face in the positive y direction
2392 * @param yneg cubemap face in the negative y direction
2393 * @param zpos cubemap face in the positive z direction
2394 * @param zneg cubemap face in the negative z direction
2395 * @param mips specifies desired mipmap behaviour for the cubemap
2396 * @param usage bit field specifying how the cubemap is utilized
2397 *
2398 * @return allocation containing cubemap data
2399 *
2400 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002401 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2402 Bitmap xpos,
2403 Bitmap xneg,
2404 Bitmap ypos,
2405 Bitmap yneg,
2406 Bitmap zpos,
2407 Bitmap zneg,
2408 MipmapControl mips,
2409 int usage) {
2410 int height = xpos.getHeight();
2411 if (xpos.getWidth() != height ||
2412 xneg.getWidth() != height || xneg.getHeight() != height ||
2413 ypos.getWidth() != height || ypos.getHeight() != height ||
2414 yneg.getWidth() != height || yneg.getHeight() != height ||
2415 zpos.getWidth() != height || zpos.getHeight() != height ||
2416 zneg.getWidth() != height || zneg.getHeight() != height) {
2417 throw new RSIllegalArgumentException("Only square cube map faces supported");
2418 }
2419 boolean isPow2 = (height & (height - 1)) == 0;
2420 if (!isPow2) {
2421 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2422 }
2423
2424 Element e = elementFromBitmap(rs, xpos);
2425 Type.Builder tb = new Type.Builder(rs, e);
2426 tb.setX(height);
2427 tb.setY(height);
2428 tb.setFaces(true);
2429 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2430 Type t = tb.create();
2431 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2432
2433 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07002434 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002435 adapter.copyFrom(xpos);
2436 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2437 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002438 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002439 adapter.copyFrom(ypos);
2440 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2441 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002442 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002443 adapter.copyFrom(zpos);
2444 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2445 adapter.copyFrom(zneg);
2446
2447 return cubemap;
2448 }
2449
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002450 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002451 * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2452 * from 6 {@link android.graphics.Bitmap} objects containing the cube
2453 * faces. Each face must be a square, have the same size as all other faces,
2454 * and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002455 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002456 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002457 * @param xpos cubemap face in the positive x direction
2458 * @param xneg cubemap face in the negative x direction
2459 * @param ypos cubemap face in the positive y direction
2460 * @param yneg cubemap face in the negative y direction
2461 * @param zpos cubemap face in the positive z direction
2462 * @param zneg cubemap face in the negative z direction
2463 *
2464 * @return allocation containing cubemap data
2465 *
2466 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002467 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2468 Bitmap xpos,
2469 Bitmap xneg,
2470 Bitmap ypos,
2471 Bitmap yneg,
2472 Bitmap zpos,
2473 Bitmap zneg) {
2474 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2475 zpos, zneg, MipmapControl.MIPMAP_NONE,
2476 USAGE_GRAPHICS_TEXTURE);
2477 }
2478
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002479 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002480 * Creates an Allocation from the Bitmap referenced
2481 * by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002482 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002483 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002484 * @param res application resources
2485 * @param id resource id to load the data from
2486 * @param mips specifies desired mipmap behaviour for the
2487 * allocation
2488 * @param usage bit field specifying how the allocation is
2489 * utilized
2490 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002491 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002492 *
2493 */
Jason Sams5476b452010-12-08 16:14:36 -08002494 static public Allocation createFromBitmapResource(RenderScript rs,
2495 Resources res,
2496 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08002497 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002498 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07002499
Jason Sams771bebb2009-12-07 12:40:12 -08002500 rs.validate();
Jason Sams3ece2f32013-05-31 14:00:46 -07002501 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2502 throw new RSIllegalArgumentException("Unsupported usage specified.");
2503 }
Jason Sams5476b452010-12-08 16:14:36 -08002504 Bitmap b = BitmapFactory.decodeResource(res, id);
2505 Allocation alloc = createFromBitmap(rs, b, mips, usage);
2506 b.recycle();
2507 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07002508 }
2509
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002510 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002511 * Creates a non-mipmapped Allocation to use as a graphics texture from the
2512 * {@link android.graphics.Bitmap} referenced by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002513 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002514 * <p>With target API version 18 or greater, this allocation will be created
2515 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
2516 * target API version 17 or lower, this allocation will be created with
2517 * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Jason Sams455d6442013-02-05 19:20:18 -08002518 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002519 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002520 * @param res application resources
2521 * @param id resource id to load the data from
2522 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002523 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002524 *
2525 */
Jason Sams5476b452010-12-08 16:14:36 -08002526 static public Allocation createFromBitmapResource(RenderScript rs,
2527 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08002528 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08002529 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2530 return createFromBitmapResource(rs, res, id,
2531 MipmapControl.MIPMAP_NONE,
Jason Sams3ece2f32013-05-31 14:00:46 -07002532 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Jason Sams455d6442013-02-05 19:20:18 -08002533 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002534 return createFromBitmapResource(rs, res, id,
2535 MipmapControl.MIPMAP_NONE,
2536 USAGE_GRAPHICS_TEXTURE);
2537 }
2538
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002539 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002540 * Creates an Allocation containing string data encoded in UTF-8 format.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002541 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002542 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002543 * @param str string to create the allocation from
2544 * @param usage bit field specifying how the allocaiton is
2545 * utilized
2546 *
2547 */
Jason Sams5476b452010-12-08 16:14:36 -08002548 static public Allocation createFromString(RenderScript rs,
2549 String str,
2550 int usage) {
2551 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002552 byte[] allocArray = null;
2553 try {
2554 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08002555 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002556 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002557 return alloc;
2558 }
2559 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08002560 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002561 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002562 }
Jason Sams739c8262013-04-11 18:07:52 -07002563
2564 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002565 * Interface to handle notification when new buffers are available via
2566 * {@link #USAGE_IO_INPUT}. An application will receive one notification
2567 * when a buffer is available. Additional buffers will not trigger new
2568 * notifications until a buffer is processed.
Jason Sams739c8262013-04-11 18:07:52 -07002569 */
Jason Sams42ef2382013-08-29 13:30:59 -07002570 public interface OnBufferAvailableListener {
Jason Sams739c8262013-04-11 18:07:52 -07002571 public void onBufferAvailable(Allocation a);
2572 }
2573
2574 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002575 * Set a notification handler for {@link #USAGE_IO_INPUT}.
Jason Sams739c8262013-04-11 18:07:52 -07002576 *
Jason Sams42ef2382013-08-29 13:30:59 -07002577 * @param callback instance of the OnBufferAvailableListener
2578 * class to be called when buffer arrive.
Jason Sams739c8262013-04-11 18:07:52 -07002579 */
Jason Sams42ef2382013-08-29 13:30:59 -07002580 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
Jason Sams739c8262013-04-11 18:07:52 -07002581 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002582 mAllocationMap.put(new Long(getID(mRS)), this);
Jason Sams739c8262013-04-11 18:07:52 -07002583 mBufferNotifier = callback;
2584 }
2585 }
2586
Tim Murrayb730d862014-08-18 16:14:24 -07002587 static void sendBufferNotification(long id) {
Jason Sams739c8262013-04-11 18:07:52 -07002588 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002589 Allocation a = mAllocationMap.get(new Long(id));
Jason Sams739c8262013-04-11 18:07:52 -07002590
2591 if ((a != null) && (a.mBufferNotifier != null)) {
2592 a.mBufferNotifier.onBufferAvailable(a);
2593 }
2594 }
2595 }
2596
Miao Wangf0f6e802015-02-03 17:16:43 -08002597 /**
2598 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
2599 *
2600 */
2601 @Override
2602 public void destroy() {
2603 if((mUsage & USAGE_IO_OUTPUT) != 0) {
2604 setSurface(null);
2605 }
2606 super.destroy();
2607 }
Jason Samsb8c5a842009-07-31 20:40:47 -07002608}