blob: 9ec6e8daf429d3b182e79b7051575de899313e9c [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 }
Yang Ni6484b6b2016-03-24 09:40:32 -0700383 guard.open("destroy");
Tim Murray2f2472c2013-08-22 14:55:26 -0700384 }
385
Miao Wang8c150922015-10-26 17:44:10 -0700386 Allocation(long id, RenderScript rs, Type t, int usage, MipmapControl mips) {
387 this(id, rs, t, usage);
388 mMipmapControl = mips;
389 }
390
Tim Murray2f2472c2013-08-22 14:55:26 -0700391 protected void finalize() throws Throwable {
392 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
393 super.finalize();
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700394 }
395
Jason Sams3042d262013-11-25 18:28:33 -0800396 private void validateIsInt64() {
397 if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
398 (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
399 return;
400 }
401 throw new RSIllegalArgumentException(
402 "64 bit integer source does not match allocation type " + mType.mElement.mType);
403 }
404
Jason Samsb97b2512011-01-16 15:04:08 -0800405 private void validateIsInt32() {
406 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
407 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
408 return;
409 }
410 throw new RSIllegalArgumentException(
411 "32 bit integer source does not match allocation type " + mType.mElement.mType);
412 }
413
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800414 private void validateIsInt16OrFloat16() {
Jason Samsb97b2512011-01-16 15:04:08 -0800415 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800416 (mType.mElement.mType == Element.DataType.UNSIGNED_16) ||
417 (mType.mElement.mType == Element.DataType.FLOAT_16)) {
Jason Samsb97b2512011-01-16 15:04:08 -0800418 return;
419 }
420 throw new RSIllegalArgumentException(
421 "16 bit integer source does not match allocation type " + mType.mElement.mType);
422 }
423
424 private void validateIsInt8() {
425 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
426 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
427 return;
428 }
429 throw new RSIllegalArgumentException(
430 "8 bit integer source does not match allocation type " + mType.mElement.mType);
431 }
432
433 private void validateIsFloat32() {
434 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
435 return;
436 }
437 throw new RSIllegalArgumentException(
438 "32 bit float source does not match allocation type " + mType.mElement.mType);
439 }
440
Jason Sams3042d262013-11-25 18:28:33 -0800441 private void validateIsFloat64() {
442 if (mType.mElement.mType == Element.DataType.FLOAT_64) {
443 return;
444 }
445 throw new RSIllegalArgumentException(
446 "64 bit float source does not match allocation type " + mType.mElement.mType);
447 }
448
Jason Samsb97b2512011-01-16 15:04:08 -0800449 private void validateIsObject() {
450 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
451 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
452 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
453 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
454 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
455 (mType.mElement.mType == Element.DataType.RS_MESH) ||
456 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
457 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
458 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
459 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
460 return;
461 }
462 throw new RSIllegalArgumentException(
463 "Object source does not match allocation type " + mType.mElement.mType);
464 }
465
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700466 @Override
467 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800468 super.updateFromNative();
Tim Murray460a0492013-11-19 12:45:54 -0800469 long typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700470 if(typeID != 0) {
471 mType = new Type(typeID, mRS);
472 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700473 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700474 }
475 }
476
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700477 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700478 * Get the {@link android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700479 *
480 * @return Type
481 *
482 */
Jason Samsea87e962010-01-12 12:12:28 -0800483 public Type getType() {
484 return mType;
485 }
486
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700487 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700488 * Propagate changes from one usage of the Allocation to the
489 * other usages of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700490 *
491 */
Jason Sams5476b452010-12-08 16:14:36 -0800492 public void syncAll(int srcLocation) {
Chris Craik06d29842015-06-02 17:19:24 -0700493 try {
494 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
495 switch (srcLocation) {
496 case USAGE_GRAPHICS_TEXTURE:
497 case USAGE_SCRIPT:
498 if ((mUsage & USAGE_SHARED) != 0) {
499 copyFrom(mBitmap);
500 }
501 break;
502 case USAGE_GRAPHICS_CONSTANTS:
503 case USAGE_GRAPHICS_VERTEX:
504 break;
505 case USAGE_SHARED:
506 if ((mUsage & USAGE_SHARED) != 0) {
507 copyTo(mBitmap);
508 }
509 break;
510 default:
511 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
Tim Murray78e64942013-04-09 17:28:56 -0700512 }
Chris Craik06d29842015-06-02 17:19:24 -0700513 mRS.validate();
514 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
515 } finally {
516 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams5476b452010-12-08 16:14:36 -0800517 }
Jason Sams5476b452010-12-08 16:14:36 -0800518 }
519
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700520 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700521 * Send a buffer to the output stream. The contents of the Allocation will
522 * be undefined after this operation. This operation is only valid if {@link
523 * #USAGE_IO_OUTPUT} is set on the Allocation.
524 *
Jason Sams163766c2012-02-15 12:04:24 -0800525 *
Jason Sams163766c2012-02-15 12:04:24 -0800526 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700527 public void ioSend() {
Chris Craik06d29842015-06-02 17:19:24 -0700528 try {
529 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
530 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
531 throw new RSIllegalArgumentException(
532 "Can only send buffer if IO_OUTPUT usage specified.");
533 }
534 mRS.validate();
535 mRS.nAllocationIoSend(getID(mRS));
536 } finally {
537 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800538 }
Jason Sams163766c2012-02-15 12:04:24 -0800539 }
540
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700541 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700542 * Receive the latest input into the Allocation. This operation
543 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
Jason Sams163766c2012-02-15 12:04:24 -0800544 *
Jason Sams163766c2012-02-15 12:04:24 -0800545 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700546 public void ioReceive() {
Chris Craik06d29842015-06-02 17:19:24 -0700547 try {
548 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
549 if ((mUsage & USAGE_IO_INPUT) == 0) {
550 throw new RSIllegalArgumentException(
551 "Can only receive if IO_INPUT usage specified.");
552 }
553 mRS.validate();
Miao Wang8c150922015-10-26 17:44:10 -0700554 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
Chris Craik06d29842015-06-02 17:19:24 -0700555 } finally {
556 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800557 }
Jason Sams163766c2012-02-15 12:04:24 -0800558 }
559
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700560 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700561 * Copy an array of RS objects to the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700562 *
563 * @param d Source array.
564 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800565 public void copyFrom(BaseObj[] d) {
Chris Craik06d29842015-06-02 17:19:24 -0700566 try {
567 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
568 mRS.validate();
569 validateIsObject();
570 if (d.length != mCurrentCount) {
571 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
572 mCurrentCount + ", array length = " + d.length);
573 }
Tim Murray460a0492013-11-19 12:45:54 -0800574
Chris Craik06d29842015-06-02 17:19:24 -0700575 if (RenderScript.sPointerSize == 8) {
576 long i[] = new long[d.length * 4];
577 for (int ct=0; ct < d.length; ct++) {
578 i[ct * 4] = d[ct].getID(mRS);
579 }
580 copy1DRangeFromUnchecked(0, mCurrentCount, i);
581 } else {
582 int i[] = new int[d.length];
583 for (int ct=0; ct < d.length; ct++) {
584 i[ct] = (int) d[ct].getID(mRS);
585 }
586 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Tim Murray3de3dc72014-07-01 16:56:18 -0700587 }
Chris Craik06d29842015-06-02 17:19:24 -0700588 } finally {
589 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800590 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700591 }
592
Jason Samsfb9f82c2011-01-12 14:53:25 -0800593 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800594 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800595 if (bc == null) {
596 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
597 }
Jason Sams252c0782011-01-11 17:42:52 -0800598 switch (bc) {
599 case ALPHA_8:
600 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
601 throw new RSIllegalArgumentException("Allocation kind is " +
602 mType.getElement().mKind + ", type " +
603 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700604 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800605 " bytes, passed bitmap was " + bc);
606 }
607 break;
608 case ARGB_8888:
609 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700610 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800611 throw new RSIllegalArgumentException("Allocation kind is " +
612 mType.getElement().mKind + ", type " +
613 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700614 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800615 " bytes, passed bitmap was " + bc);
616 }
617 break;
618 case RGB_565:
619 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700620 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800621 throw new RSIllegalArgumentException("Allocation kind is " +
622 mType.getElement().mKind + ", type " +
623 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700624 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800625 " bytes, passed bitmap was " + bc);
626 }
627 break;
628 case ARGB_4444:
629 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700630 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800631 throw new RSIllegalArgumentException("Allocation kind is " +
632 mType.getElement().mKind + ", type " +
633 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700634 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800635 " bytes, passed bitmap was " + bc);
636 }
637 break;
638
639 }
Jason Sams4ef66502010-12-10 16:03:15 -0800640 }
641
Jason Samsfb9f82c2011-01-12 14:53:25 -0800642 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700643 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800644 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
645 }
646 }
647
Jason Sams3042d262013-11-25 18:28:33 -0800648 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700649 try {
650 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
651 mRS.validate();
652 if (mCurrentDimZ > 0) {
653 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
654 } else if (mCurrentDimY > 0) {
655 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
656 } else {
657 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
658 }
659 } finally {
660 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams3042d262013-11-25 18:28:33 -0800661 }
Jason Sams3042d262013-11-25 18:28:33 -0800662 }
663
664 /**
665 * Copy into this Allocation from an array. This method does not guarantee
666 * that the Allocation is compatible with the input buffer; it copies memory
667 * without reinterpretation.
668 *
669 * @param array The source data array
670 */
671 public void copyFromUnchecked(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700672 try {
673 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
674 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
675 java.lang.reflect.Array.getLength(array));
676 } finally {
677 Trace.traceEnd(RenderScript.TRACE_TAG);
678 }
Jason Sams3042d262013-11-25 18:28:33 -0800679 }
680
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700681 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700682 * Copy into this Allocation from an array. This method does not guarantee
683 * that the Allocation is compatible with the input buffer; it copies memory
684 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800685 *
686 * @param d the source data array
687 */
688 public void copyFromUnchecked(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800689 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800690 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700691
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700692 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700693 * Copy into this Allocation from an array. This method does not guarantee
694 * that the Allocation is compatible with the input buffer; it copies memory
695 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800696 *
697 * @param d the source data array
698 */
699 public void copyFromUnchecked(short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800700 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800701 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700702
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700703 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700704 * Copy into this Allocation from an array. This method does not guarantee
705 * that the Allocation is compatible with the input buffer; it copies memory
706 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800707 *
708 * @param d the source data array
709 */
710 public void copyFromUnchecked(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800711 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800712 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700713
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700714 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700715 * Copy into this Allocation from an array. This method does not guarantee
716 * that the Allocation is compatible with the input buffer; it copies memory
717 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800718 *
719 * @param d the source data array
720 */
721 public void copyFromUnchecked(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800722 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800723 }
724
Tim Murray6d7a53c2013-05-23 16:59:23 -0700725
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700726 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700727 * Copy into this Allocation from an array. This variant is type checked
728 * and will generate exceptions if the Allocation's {@link
Jason Sams3042d262013-11-25 18:28:33 -0800729 * android.renderscript.Element} does not match the array's
730 * primitive type.
731 *
Ying Wang16229812013-11-26 15:45:12 -0800732 * @param array The source data array
Jason Sams3042d262013-11-25 18:28:33 -0800733 */
734 public void copyFrom(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700735 try {
736 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
737 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
738 java.lang.reflect.Array.getLength(array));
739 } finally {
740 Trace.traceEnd(RenderScript.TRACE_TAG);
741 }
Jason Sams3042d262013-11-25 18:28:33 -0800742 }
743
744 /**
745 * Copy into this Allocation from an array. This variant is type checked
746 * and will generate exceptions if the Allocation's {@link
Tim Murrayc11e25c2013-04-09 11:01:01 -0700747 * android.renderscript.Element} is not a 32 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800748 *
749 * @param d the source data array
750 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800751 public void copyFrom(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800752 validateIsInt32();
753 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800754 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800755
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700756 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700757 * Copy into this Allocation from an array. This variant is type checked
758 * and will generate exceptions if the Allocation's {@link
759 * android.renderscript.Element} is not a 16 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800760 *
761 * @param d the source data array
762 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800763 public void copyFrom(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800764 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -0800765 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800766 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800767
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700768 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700769 * Copy into this Allocation from an array. This variant is type checked
770 * and will generate exceptions if the Allocation's {@link
771 * android.renderscript.Element} is not an 8 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800772 *
773 * @param d the source data array
774 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800775 public void copyFrom(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800776 validateIsInt8();
777 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800778 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800779
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700780 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700781 * Copy into this Allocation from an array. This variant is type checked
782 * and will generate exceptions if the Allocation's {@link
783 * android.renderscript.Element} is not a 32 bit float type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800784 *
785 * @param d the source data array
786 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800787 public void copyFrom(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800788 validateIsFloat32();
789 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800790 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800791
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700792 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700793 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
794 * height, width, and format of the bitmap must match the existing
795 * allocation.
796 *
797 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
798 * android.graphics.Bitmap} used to create the Allocation with {@link
799 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
800 * this will synchronize the Allocation with the latest data from the {@link
801 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
Jason Sams4fa3eed2011-01-19 15:44:38 -0800802 *
803 * @param b the source bitmap
804 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800805 public void copyFrom(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -0700806 try {
807 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
808 mRS.validate();
809 if (b.getConfig() == null) {
810 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
811 Canvas c = new Canvas(newBitmap);
812 c.drawBitmap(b, 0, 0, null);
813 copyFrom(newBitmap);
814 return;
815 }
816 validateBitmapSize(b);
817 validateBitmapFormat(b);
818 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
819 } finally {
820 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -0800821 }
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700822 }
823
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700824 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700825 * Copy an Allocation from an Allocation. The types of both allocations
Tim Murrayf671fb02012-10-03 13:50:05 -0700826 * must be identical.
827 *
828 * @param a the source allocation
829 */
830 public void copyFrom(Allocation a) {
Chris Craik06d29842015-06-02 17:19:24 -0700831 try {
832 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
833 mRS.validate();
834 if (!mType.equals(a.getType())) {
835 throw new RSIllegalArgumentException("Types of allocations must match.");
836 }
837 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
838 } finally {
839 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayf671fb02012-10-03 13:50:05 -0700840 }
Tim Murrayf671fb02012-10-03 13:50:05 -0700841 }
842
Tim Murrayf671fb02012-10-03 13:50:05 -0700843 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700844 * This is only intended to be used by auto-generated code reflected from
845 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800846 *
847 * @param xoff
848 * @param fp
849 */
Jason Sams21b41032011-01-16 15:05:41 -0800850 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc2012-02-22 15:22:41 -0800851 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700852 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700853 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700854 int data_length = fp.getPos();
Jason Samsa70f4162010-03-26 15:33:42 -0700855
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700856 int count = data_length / eSize;
857 if ((eSize * count) != data_length) {
858 throw new RSIllegalArgumentException("Field packer length " + data_length +
Jason Samsa70f4162010-03-26 15:33:42 -0700859 " not divisible by element size " + eSize + ".");
860 }
Jason Samsba862d12011-07-07 15:24:42 -0700861 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700862 }
863
Miao Wang45cec0a2015-03-04 16:40:21 -0800864
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700865 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700866 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800867 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800868 *
869 * @param xoff
870 * @param component_number
871 * @param fp
872 */
Jason Sams21b41032011-01-16 15:05:41 -0800873 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800874 setFromFieldPacker(xoff, 0, 0, component_number, fp);
875 }
876
877 /**
Miao Wangc8e237e2015-02-20 18:36:32 -0800878 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800879 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -0800880 *
881 * @param xoff
882 * @param yoff
Miao Wangc8e237e2015-02-20 18:36:32 -0800883 * @param zoff
884 * @param component_number
885 * @param fp
886 */
887 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc2012-02-22 15:22:41 -0800888 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700889 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800890 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700891 }
892 if(xoff < 0) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800893 throw new RSIllegalArgumentException("Offset x must be >= 0.");
894 }
895 if(yoff < 0) {
896 throw new RSIllegalArgumentException("Offset y must be >= 0.");
897 }
898 if(zoff < 0) {
899 throw new RSIllegalArgumentException("Offset z must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700900 }
901
902 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700903 int data_length = fp.getPos();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700904 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800905 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700906
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700907 if (data_length != eSize) {
908 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700909 " does not match component size " + eSize + ".");
910 }
911
Miao Wangc8e237e2015-02-20 18:36:32 -0800912 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
913 component_number, data, data_length);
Jason Samsa70f4162010-03-26 15:33:42 -0700914 }
915
Miao Wang87e908d2015-03-02 15:15:15 -0800916 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
Jason Sams771bebb2009-12-07 12:40:12 -0800917 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700918 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800919 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700920 }
921 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800922 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700923 }
Jason Samsba862d12011-07-07 15:24:42 -0700924 if((off + count) > mCurrentCount) {
925 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700926 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700927 }
Miao Wang87e908d2015-03-02 15:15:15 -0800928 if(usePadding) {
929 if(len < dataSize / 4 * 3) {
930 throw new RSIllegalArgumentException("Array too small for allocation type.");
931 }
932 } else {
933 if(len < dataSize) {
934 throw new RSIllegalArgumentException("Array too small for allocation type.");
935 }
Jason Sams768bc022009-09-21 19:41:04 -0700936 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700937 }
938
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700939 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700940 * Generate a mipmap chain. This is only valid if the Type of the Allocation
941 * includes mipmaps.
Jason Samsf7086092011-01-12 13:28:37 -0800942 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700943 * <p>This function will generate a complete set of mipmaps from the top
944 * level LOD and place them into the script memory space.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800945 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700946 * <p>If the Allocation is also using other memory spaces, a call to {@link
947 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800948 */
949 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700950 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800951 }
952
Jason Sams3042d262013-11-25 18:28:33 -0800953 private void copy1DRangeFromUnchecked(int off, int count, Object array,
954 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700955 try {
956 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
957 final int dataSize = mType.mElement.getBytesSize() * count;
958 // AutoPadding for Vec3 Element
959 boolean usePadding = false;
960 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
961 usePadding = true;
962 }
963 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
964 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
965 mType.mElement.mType.mSize, usePadding);
966 } finally {
967 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -0800968 }
Jason Sams3042d262013-11-25 18:28:33 -0800969 }
970
971 /**
972 * Copy an array into part of this Allocation. This method does not
973 * guarantee that the Allocation is compatible with the input buffer.
974 *
975 * @param off The offset of the first element to be copied.
976 * @param count The number of elements to be copied.
977 * @param array The source data array
978 */
979 public void copy1DRangeFromUnchecked(int off, int count, Object array) {
980 copy1DRangeFromUnchecked(off, count, array,
981 validateObjectIsPrimitiveArray(array, false),
982 java.lang.reflect.Array.getLength(array));
983 }
984
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700985 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700986 * Copy an array into part of this Allocation. This method does not
987 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800988 *
989 * @param off The offset of the first element to be copied.
990 * @param count The number of elements to be copied.
991 * @param d the source data array
992 */
993 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800994 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700995 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700996
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700997 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700998 * Copy an array into part of this Allocation. This method does not
999 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001000 *
1001 * @param off The offset of the first element to be copied.
1002 * @param count The number of elements to be copied.
1003 * @param d the source data array
1004 */
1005 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001006 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001007 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001008
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001009 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001010 * Copy an array into part of this Allocation. This method does not
1011 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001012 *
1013 * @param off The offset of the first element to be copied.
1014 * @param count The number of elements to be copied.
1015 * @param d the source data array
1016 */
1017 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001018 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001019 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001020
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001021 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001022 * Copy an array into part of this Allocation. This method does not
1023 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001024 *
1025 * @param off The offset of the first element to be copied.
1026 * @param count The number of elements to be copied.
1027 * @param d the source data array
1028 */
1029 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001030 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1031 }
1032
1033
1034 /**
1035 * Copy an array into part of this Allocation. This variant is type checked
1036 * and will generate exceptions if the Allocation type does not
1037 * match the component type of the array passed in.
1038 *
1039 * @param off The offset of the first element to be copied.
1040 * @param count The number of elements to be copied.
1041 * @param array The source data array.
1042 */
1043 public void copy1DRangeFrom(int off, int count, Object array) {
1044 copy1DRangeFromUnchecked(off, count, array,
1045 validateObjectIsPrimitiveArray(array, true),
1046 java.lang.reflect.Array.getLength(array));
Jason Samsb8c5a842009-07-31 20:40:47 -07001047 }
1048
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001049 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001050 * Copy an array into part of this Allocation. This variant is type checked
1051 * and will generate exceptions if the Allocation type is not a 32 bit
1052 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001053 *
1054 * @param off The offset of the first element to be copied.
1055 * @param count The number of elements to be copied.
1056 * @param d the source data array
1057 */
Jason Samsb97b2512011-01-16 15:04:08 -08001058 public void copy1DRangeFrom(int off, int count, int[] d) {
1059 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001060 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001061 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001062
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001063 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001064 * Copy an array into part of this Allocation. This variant is type checked
1065 * and will generate exceptions if the Allocation type is not a 16 bit
1066 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001067 *
1068 * @param off The offset of the first element to be copied.
1069 * @param count The number of elements to be copied.
1070 * @param d the source data array
1071 */
Jason Samsb97b2512011-01-16 15:04:08 -08001072 public void copy1DRangeFrom(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001073 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001074 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001075 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001076
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001077 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001078 * Copy an array into part of this Allocation. This variant is type checked
1079 * and will generate exceptions if the Allocation type is not an 8 bit
1080 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001081 *
1082 * @param off The offset of the first element to be copied.
1083 * @param count The number of elements to be copied.
1084 * @param d the source data array
1085 */
Jason Samsb97b2512011-01-16 15:04:08 -08001086 public void copy1DRangeFrom(int off, int count, byte[] d) {
1087 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001088 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001089 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001090
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001091 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001092 * Copy an array into part of this Allocation. This variant is type checked
1093 * and will generate exceptions if the Allocation type is not a 32 bit float
1094 * type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001095 *
1096 * @param off The offset of the first element to be copied.
1097 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001098 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001099 */
Jason Samsb97b2512011-01-16 15:04:08 -08001100 public void copy1DRangeFrom(int off, int count, float[] d) {
1101 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001102 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001103 }
Jason Sams3042d262013-11-25 18:28:33 -08001104
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001105 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001106 * Copy part of an Allocation into this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001107 *
1108 * @param off The offset of the first element to be copied.
1109 * @param count The number of elements to be copied.
1110 * @param data the source data allocation.
1111 * @param dataOff off The offset of the first element in data to
1112 * be copied.
1113 */
1114 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Tim Murray6d7a53c2013-05-23 16:59:23 -07001115 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
Jason Sams48fe5342011-07-08 13:52:30 -07001116 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001117 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -07001118 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001119 data.mSelectedLOD, data.mSelectedFace.mID);
Chris Craik5c705d62015-06-01 10:39:36 -07001120 Trace.traceEnd(RenderScript.TRACE_TAG);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001121 }
1122
Jason Samsfb9f82c2011-01-12 14:53:25 -08001123 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -07001124 if (mAdaptedAllocation != null) {
1125
1126 } else {
1127
1128 if (xoff < 0 || yoff < 0) {
1129 throw new RSIllegalArgumentException("Offset cannot be negative.");
1130 }
1131 if (h < 0 || w < 0) {
1132 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1133 }
1134 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1135 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1136 }
Jason Samsfb9f82c2011-01-12 14:53:25 -08001137 }
1138 }
Jason Sams768bc022009-09-21 19:41:04 -07001139
Jason Sams3042d262013-11-25 18:28:33 -08001140 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1141 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001142 try {
1143 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
1144 mRS.validate();
1145 validate2DRange(xoff, yoff, w, h);
1146 final int dataSize = mType.mElement.getBytesSize() * w * h;
1147 // AutoPadding for Vec3 Element
1148 boolean usePadding = false;
1149 int sizeBytes = arrayLen * dt.mSize;
1150 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1151 if (dataSize / 4 * 3 > sizeBytes) {
1152 throw new RSIllegalArgumentException("Array too small for allocation type.");
1153 }
1154 usePadding = true;
1155 sizeBytes = dataSize;
1156 } else {
1157 if (dataSize > sizeBytes) {
1158 throw new RSIllegalArgumentException("Array too small for allocation type.");
1159 }
Miao Wang87e908d2015-03-02 15:15:15 -08001160 }
Chris Craik06d29842015-06-02 17:19:24 -07001161 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1162 array, sizeBytes, dt,
1163 mType.mElement.mType.mSize, usePadding);
1164 } finally {
1165 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001166 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001167 }
1168
Jason Sams3042d262013-11-25 18:28:33 -08001169 /**
1170 * Copy from an array into a rectangular region in this Allocation. The
1171 * array is assumed to be tightly packed.
1172 *
1173 * @param xoff X offset of the region to update in this Allocation
1174 * @param yoff Y offset of the region to update in this Allocation
1175 * @param w Width of the region to update
1176 * @param h Height of the region to update
Ying Wang16229812013-11-26 15:45:12 -08001177 * @param array Data to be placed into the Allocation
Jason Sams3042d262013-11-25 18:28:33 -08001178 */
1179 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001180 try {
1181 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1182 copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1183 validateObjectIsPrimitiveArray(array, true),
1184 java.lang.reflect.Array.getLength(array));
1185 } finally {
1186 Trace.traceEnd(RenderScript.TRACE_TAG);
1187 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001188 }
1189
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001190 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001191 * Copy from an array into a rectangular region in this Allocation. The
1192 * array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -08001193 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001194 * @param xoff X offset of the region to update in this Allocation
1195 * @param yoff Y offset of the region to update in this Allocation
1196 * @param w Width of the region to update
1197 * @param h Height of the region to update
1198 * @param data to be placed into the Allocation
Jason Samsf7086092011-01-12 13:28:37 -08001199 */
1200 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001201 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001202 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1203 Element.DataType.SIGNED_8, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001204 }
1205
Tim Murrayc11e25c2013-04-09 11:01:01 -07001206 /**
1207 * Copy from an array into a rectangular region in this Allocation. The
1208 * array is assumed to be tightly packed.
1209 *
1210 * @param xoff X offset of the region to update in this Allocation
1211 * @param yoff Y offset of the region to update in this Allocation
1212 * @param w Width of the region to update
1213 * @param h Height of the region to update
1214 * @param data to be placed into the Allocation
1215 */
Jason Samsf7086092011-01-12 13:28:37 -08001216 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001217 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001218 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1219 Element.DataType.SIGNED_16, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001220 }
1221
Tim Murrayc11e25c2013-04-09 11:01:01 -07001222 /**
1223 * Copy from an array into a rectangular region in this Allocation. The
1224 * array is assumed to be tightly packed.
1225 *
1226 * @param xoff X offset of the region to update in this Allocation
1227 * @param yoff Y offset of the region to update in this Allocation
1228 * @param w Width of the region to update
1229 * @param h Height of the region to update
1230 * @param data to be placed into the Allocation
1231 */
Jason Samsf7086092011-01-12 13:28:37 -08001232 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001233 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001234 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1235 Element.DataType.SIGNED_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001236 }
1237
Tim Murrayc11e25c2013-04-09 11:01:01 -07001238 /**
1239 * Copy from an array into a rectangular region in this Allocation. The
1240 * array is assumed to be tightly packed.
1241 *
1242 * @param xoff X offset of the region to update in this Allocation
1243 * @param yoff Y offset of the region to update in this Allocation
1244 * @param w Width of the region to update
1245 * @param h Height of the region to update
1246 * @param data to be placed into the Allocation
1247 */
Jason Samsf7086092011-01-12 13:28:37 -08001248 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001249 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001250 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1251 Element.DataType.FLOAT_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001252 }
1253
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001254 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001255 * Copy a rectangular region from an Allocation into a rectangular region in
1256 * this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001257 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001258 * @param xoff X offset of the region in this Allocation
1259 * @param yoff Y offset of the region in this Allocation
1260 * @param w Width of the region to update.
1261 * @param h Height of the region to update.
1262 * @param data source Allocation.
1263 * @param dataXoff X offset in source Allocation
1264 * @param dataYoff Y offset in source Allocation
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001265 */
1266 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1267 Allocation data, int dataXoff, int dataYoff) {
Chris Craik06d29842015-06-02 17:19:24 -07001268 try {
1269 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1270 mRS.validate();
1271 validate2DRange(xoff, yoff, w, h);
1272 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1273 mSelectedLOD, mSelectedFace.mID,
1274 w, h, data.getID(mRS), dataXoff, dataYoff,
1275 data.mSelectedLOD, data.mSelectedFace.mID);
1276 } finally {
1277 Trace.traceEnd(RenderScript.TRACE_TAG);
1278 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001279 }
1280
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001281 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001282 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
1283 * and width of the update will use the height and width of the {@link
1284 * android.graphics.Bitmap}.
Jason Samsf7086092011-01-12 13:28:37 -08001285 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001286 * @param xoff X offset of the region to update in this Allocation
1287 * @param yoff Y offset of the region to update in this Allocation
1288 * @param data the Bitmap to be copied
Jason Samsf7086092011-01-12 13:28:37 -08001289 */
1290 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Chris Craik5c705d62015-06-01 10:39:36 -07001291 try {
1292 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1293 mRS.validate();
1294 if (data.getConfig() == null) {
1295 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1296 Canvas c = new Canvas(newBitmap);
1297 c.drawBitmap(data, 0, 0, null);
1298 copy2DRangeFrom(xoff, yoff, newBitmap);
1299 return;
1300 }
1301 validateBitmapFormat(data);
1302 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1303 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1304 } finally {
1305 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -08001306 }
Jason Samsfa445b92011-01-07 17:00:07 -08001307 }
1308
Jason Samsb05d6892013-04-09 15:59:24 -07001309 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1310 if (mAdaptedAllocation != null) {
1311
1312 } else {
1313
1314 if (xoff < 0 || yoff < 0 || zoff < 0) {
1315 throw new RSIllegalArgumentException("Offset cannot be negative.");
1316 }
1317 if (h < 0 || w < 0 || d < 0) {
1318 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1319 }
1320 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1321 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1322 }
1323 }
1324 }
1325
1326 /**
Miao Wang258db502015-03-03 14:05:36 -08001327 * Copy a rectangular region from the array into the allocation.
1328 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001329 *
Miao Wang258db502015-03-03 14:05:36 -08001330 * The data type of the array is not required to be the same as
1331 * the element data type.
Jason Samsb05d6892013-04-09 15:59:24 -07001332 */
Jason Sams3042d262013-11-25 18:28:33 -08001333 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1334 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001335 try {
1336 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
1337 mRS.validate();
1338 validate3DRange(xoff, yoff, zoff, w, h, d);
1339 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1340 // AutoPadding for Vec3 Element
1341 boolean usePadding = false;
1342 int sizeBytes = arrayLen * dt.mSize;
1343 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1344 if (dataSize / 4 * 3 > sizeBytes) {
1345 throw new RSIllegalArgumentException("Array too small for allocation type.");
1346 }
1347 usePadding = true;
1348 sizeBytes = dataSize;
1349 } else {
1350 if (dataSize > sizeBytes) {
1351 throw new RSIllegalArgumentException("Array too small for allocation type.");
1352 }
Miao Wang87e908d2015-03-02 15:15:15 -08001353 }
Chris Craik06d29842015-06-02 17:19:24 -07001354 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1355 array, sizeBytes, dt,
1356 mType.mElement.mType.mSize, usePadding);
1357 } finally {
1358 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001359 }
Jason Samsb05d6892013-04-09 15:59:24 -07001360 }
1361
1362 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001363 * Copy a rectangular region from the array into the allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001364 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001365 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001366 * @param xoff X offset of the region to update in this Allocation
1367 * @param yoff Y offset of the region to update in this Allocation
1368 * @param zoff Z offset of the region to update in this Allocation
1369 * @param w Width of the region to update
1370 * @param h Height of the region to update
1371 * @param d Depth of the region to update
Miao Wang87e908d2015-03-02 15:15:15 -08001372 * @param array to be placed into the allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001373 */
Jason Sams3042d262013-11-25 18:28:33 -08001374 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001375 try {
1376 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
1377 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1378 validateObjectIsPrimitiveArray(array, true),
1379 java.lang.reflect.Array.getLength(array));
1380 } finally {
1381 Trace.traceEnd(RenderScript.TRACE_TAG);
1382 }
Jason Samsb05d6892013-04-09 15:59:24 -07001383 }
1384
1385 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001386 * Copy a rectangular region into the allocation from another
1387 * allocation.
1388 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001389 * @param xoff X offset of the region to update in this Allocation
1390 * @param yoff Y offset of the region to update in this Allocation
1391 * @param zoff Z offset of the region to update in this Allocation
1392 * @param w Width of the region to update.
1393 * @param h Height of the region to update.
1394 * @param d Depth of the region to update.
Jason Samsb05d6892013-04-09 15:59:24 -07001395 * @param data source allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001396 * @param dataXoff X offset of the region in the source Allocation
1397 * @param dataYoff Y offset of the region in the source Allocation
1398 * @param dataZoff Z offset of the region in the source Allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001399 */
1400 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1401 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1402 mRS.validate();
1403 validate3DRange(xoff, yoff, zoff, w, h, d);
1404 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1405 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1406 data.mSelectedLOD);
1407 }
1408
Jason Samsfa445b92011-01-07 17:00:07 -08001409
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001410 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001411 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
1412 * bitmap must match the dimensions of the Allocation.
Jason Sams48fe5342011-07-08 13:52:30 -07001413 *
1414 * @param b The bitmap to be set from the Allocation.
1415 */
Jason Samsfa445b92011-01-07 17:00:07 -08001416 public void copyTo(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -07001417 try {
1418 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1419 mRS.validate();
1420 validateBitmapFormat(b);
1421 validateBitmapSize(b);
1422 mRS.nAllocationCopyToBitmap(getID(mRS), b);
1423 } finally {
1424 Trace.traceEnd(RenderScript.TRACE_TAG);
1425 }
Jason Samsfa445b92011-01-07 17:00:07 -08001426 }
1427
Jason Sams3042d262013-11-25 18:28:33 -08001428 private void copyTo(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001429 try {
1430 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1431 mRS.validate();
1432 boolean usePadding = false;
1433 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1434 usePadding = true;
Miao Wangd9b63282015-04-03 09:15:39 -07001435 }
Chris Craik06d29842015-06-02 17:19:24 -07001436 if (usePadding) {
1437 if (dt.mSize * arrayLen < mSize / 4 * 3) {
1438 throw new RSIllegalArgumentException(
1439 "Size of output array cannot be smaller than size of allocation.");
1440 }
1441 } else {
1442 if (dt.mSize * arrayLen < mSize) {
1443 throw new RSIllegalArgumentException(
1444 "Size of output array cannot be smaller than size of allocation.");
1445 }
Miao Wangd9b63282015-04-03 09:15:39 -07001446 }
Chris Craik06d29842015-06-02 17:19:24 -07001447 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1448 } finally {
1449 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wangd9b63282015-04-03 09:15:39 -07001450 }
Jason Sams3042d262013-11-25 18:28:33 -08001451 }
1452
1453 /**
1454 * Copy from the Allocation into an array. The array must be at
1455 * least as large as the Allocation. The
1456 * {@link android.renderscript.Element} must match the component
1457 * type of the array passed in.
1458 *
1459 * @param array The array to be set from the Allocation.
1460 */
1461 public void copyTo(Object array) {
1462 copyTo(array, validateObjectIsPrimitiveArray(array, true),
1463 java.lang.reflect.Array.getLength(array));
1464 }
1465
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001466 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001467 * Copy from the Allocation into a byte array. The array must be at least
1468 * as large as the Allocation. The allocation must be of an 8 bit integer
1469 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001470 *
1471 * @param d The array to be set from the Allocation.
1472 */
Jason Samsfa445b92011-01-07 17:00:07 -08001473 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001474 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001475 copyTo(d, Element.DataType.SIGNED_8, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001476 }
1477
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001478 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001479 * Copy from the Allocation into a short array. The array must be at least
1480 * as large as the Allocation. The allocation must be of an 16 bit integer
1481 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001482 *
1483 * @param d The array to be set from the Allocation.
1484 */
Jason Samsfa445b92011-01-07 17:00:07 -08001485 public void copyTo(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001486 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001487 copyTo(d, Element.DataType.SIGNED_16, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001488 }
1489
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001490 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001491 * Copy from the Allocation into a int array. The array must be at least as
1492 * large as the Allocation. The allocation must be of an 32 bit integer
1493 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001494 *
1495 * @param d The array to be set from the Allocation.
1496 */
Jason Samsfa445b92011-01-07 17:00:07 -08001497 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001498 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001499 copyTo(d, Element.DataType.SIGNED_32, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001500 }
1501
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001502 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001503 * Copy from the Allocation into a float array. The array must be at least
1504 * as large as the Allocation. The allocation must be of an 32 bit float
1505 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001506 *
1507 * @param d The array to be set from the Allocation.
1508 */
Jason Samsfa445b92011-01-07 17:00:07 -08001509 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001510 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001511 copyTo(d, Element.DataType.FLOAT_32, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001512 }
1513
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001514 /**
Miao Wang3c613272015-05-11 11:41:55 -07001515 * @hide
1516 *
Miao Wang45cec0a2015-03-04 16:40:21 -08001517 * This is only intended to be used by auto-generated code reflected from
1518 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -08001519 *
1520 * @param xoff
1521 * @param yoff
1522 * @param zoff
1523 * @param component_number
Miao Wang258db502015-03-03 14:05:36 -08001524 * @param fp
Miao Wangc8e237e2015-02-20 18:36:32 -08001525 */
Miao Wang45cec0a2015-03-04 16:40:21 -08001526 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -08001527 mRS.validate();
1528 if (component_number >= mType.mElement.mElements.length) {
1529 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1530 }
1531 if(xoff < 0) {
1532 throw new RSIllegalArgumentException("Offset x must be >= 0.");
1533 }
1534 if(yoff < 0) {
1535 throw new RSIllegalArgumentException("Offset y must be >= 0.");
1536 }
1537 if(zoff < 0) {
1538 throw new RSIllegalArgumentException("Offset z must be >= 0.");
1539 }
1540
Miao Wang45cec0a2015-03-04 16:40:21 -08001541 final byte[] data = fp.getData();
Miao Wangbfa5e652015-05-04 15:29:25 -07001542 int data_length = data.length;
Miao Wangc8e237e2015-02-20 18:36:32 -08001543 int eSize = mType.mElement.mElements[component_number].getBytesSize();
1544 eSize *= mType.mElement.mArraySizes[component_number];
1545
Miao Wang45cec0a2015-03-04 16:40:21 -08001546 if (data_length != eSize) {
1547 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1548 " does not match component size " + eSize + ".");
Miao Wangc8e237e2015-02-20 18:36:32 -08001549 }
1550
1551 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
Miao Wang45cec0a2015-03-04 16:40:21 -08001552 component_number, data, data_length);
Miao Wangc8e237e2015-02-20 18:36:32 -08001553 }
1554 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001555 * Resize a 1D allocation. The contents of the allocation are preserved.
1556 * If new elements are allocated objects are created with null contents and
1557 * the new region is otherwise undefined.
Jason Samsf7086092011-01-12 13:28:37 -08001558 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001559 * <p>If the new region is smaller the references of any objects outside the
1560 * new region will be released.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001561 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001562 * <p>A new type will be created with the new dimension.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001563 *
1564 * @param dimX The new size of the allocation.
Jason Samsb05d6892013-04-09 15:59:24 -07001565 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001566 * @deprecated RenderScript objects should be immutable once created. The
Tim Murraycd38b762014-08-13 13:20:25 -07001567 * replacement is to create a new allocation and copy the contents. This
1568 * function will throw an exception if API 21 or higher is used.
Jason Samsf7086092011-01-12 13:28:37 -08001569 */
Jason Sams31a7e422010-10-26 13:09:17 -07001570 public synchronized void resize(int dimX) {
Tim Murraycd38b762014-08-13 13:20:25 -07001571 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) {
1572 throw new RSRuntimeException("Resize is not allowed in API 21+.");
1573 }
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001574 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001575 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001576 }
Jason Samse07694b2012-04-03 15:36:36 -07001577 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001578 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001579
Tim Murray460a0492013-11-19 12:45:54 -08001580 long typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001581 mType = new Type(typeID, mRS);
1582 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001583 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001584 }
1585
Miao Wangc8e237e2015-02-20 18:36:32 -08001586 private void copy1DRangeToUnchecked(int off, int count, Object array,
1587 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001588 try {
1589 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked");
1590 final int dataSize = mType.mElement.getBytesSize() * count;
1591 // AutoPadding for Vec3 Element
1592 boolean usePadding = false;
1593 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1594 usePadding = true;
1595 }
1596 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1597 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1598 mType.mElement.mType.mSize, usePadding);
1599 } finally {
1600 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001601 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001602 }
1603
1604 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001605 * Copy part of this Allocation into an array. This method does not
1606 * guarantee that the Allocation is compatible with the input buffer.
1607 *
1608 * @param off The offset of the first element to be copied.
1609 * @param count The number of elements to be copied.
1610 * @param array The dest data array
1611 */
1612 public void copy1DRangeToUnchecked(int off, int count, Object array) {
1613 copy1DRangeToUnchecked(off, count, array,
1614 validateObjectIsPrimitiveArray(array, false),
1615 java.lang.reflect.Array.getLength(array));
1616 }
1617
1618 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001619 * Copy part of this Allocation into an array. This method does not
1620 * guarantee that the Allocation is compatible with the input buffer.
1621 *
1622 * @param off The offset of the first element to be copied.
1623 * @param count The number of elements to be copied.
1624 * @param d the source data array
1625 */
1626 public void copy1DRangeToUnchecked(int off, int count, int[] d) {
1627 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1628 }
1629
1630 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001631 * Copy part of this Allocation into an array. This method does not
1632 * guarantee that the Allocation is compatible with the input buffer.
1633 *
1634 * @param off The offset of the first element to be copied.
1635 * @param count The number of elements to be copied.
1636 * @param d the source data array
1637 */
1638 public void copy1DRangeToUnchecked(int off, int count, short[] d) {
1639 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1640 }
1641
1642 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001643 * Copy part of this Allocation into an array. This method does not
1644 * guarantee that the Allocation is compatible with the input buffer.
1645 *
1646 * @param off The offset of the first element to be copied.
1647 * @param count The number of elements to be copied.
1648 * @param d the source data array
1649 */
1650 public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
1651 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1652 }
1653
1654 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001655 * Copy part of this Allocation into an array. This method does not
1656 * guarantee that the Allocation is compatible with the input buffer.
1657 *
1658 * @param off The offset of the first element to be copied.
1659 * @param count The number of elements to be copied.
1660 * @param d the source data array
1661 */
1662 public void copy1DRangeToUnchecked(int off, int count, float[] d) {
1663 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1664 }
1665
1666
1667 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001668 * Copy part of this Allocation into an array. This method does not
1669 * and will generate exceptions if the Allocation type does not
1670 * match the component type of the array passed in.
1671 *
1672 * @param off The offset of the first element to be copied.
1673 * @param count The number of elements to be copied.
1674 * @param array The source data array.
1675 */
1676 public void copy1DRangeTo(int off, int count, Object array) {
1677 copy1DRangeToUnchecked(off, count, array,
1678 validateObjectIsPrimitiveArray(array, true),
1679 java.lang.reflect.Array.getLength(array));
1680 }
1681
1682 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001683 * Copy part of this Allocation into an array. This method does not
1684 * and will generate exceptions if the Allocation type is not a 32 bit
1685 * integer type.
1686 *
1687 * @param off The offset of the first element to be copied.
1688 * @param count The number of elements to be copied.
1689 * @param d the source data array
1690 */
1691 public void copy1DRangeTo(int off, int count, int[] d) {
1692 validateIsInt32();
1693 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1694 }
1695
1696 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001697 * Copy part of this Allocation into an array. This method does not
1698 * and will generate exceptions if the Allocation type is not a 16 bit
1699 * integer type.
1700 *
1701 * @param off The offset of the first element to be copied.
1702 * @param count The number of elements to be copied.
1703 * @param d the source data array
1704 */
1705 public void copy1DRangeTo(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001706 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001707 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1708 }
1709
1710 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001711 * Copy part of this Allocation into an array. This method does not
1712 * and will generate exceptions if the Allocation type is not an 8 bit
1713 * integer type.
1714 *
1715 * @param off The offset of the first element to be copied.
1716 * @param count The number of elements to be copied.
1717 * @param d the source data array
1718 */
1719 public void copy1DRangeTo(int off, int count, byte[] d) {
1720 validateIsInt8();
1721 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1722 }
1723
1724 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001725 * Copy part of this Allocation into an array. This method does not
1726 * and will generate exceptions if the Allocation type is not a 32 bit float
1727 * type.
1728 *
1729 * @param off The offset of the first element to be copied.
1730 * @param count The number of elements to be copied.
1731 * @param d the source data array.
1732 */
1733 public void copy1DRangeTo(int off, int count, float[] d) {
1734 validateIsFloat32();
1735 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1736 }
1737
1738
1739 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
1740 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001741 try {
1742 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked");
1743 mRS.validate();
1744 validate2DRange(xoff, yoff, w, h);
1745 final int dataSize = mType.mElement.getBytesSize() * w * h;
1746 // AutoPadding for Vec3 Element
1747 boolean usePadding = false;
1748 int sizeBytes = arrayLen * dt.mSize;
1749 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1750 if (dataSize / 4 * 3 > sizeBytes) {
1751 throw new RSIllegalArgumentException("Array too small for allocation type.");
1752 }
1753 usePadding = true;
1754 sizeBytes = dataSize;
1755 } else {
1756 if (dataSize > sizeBytes) {
1757 throw new RSIllegalArgumentException("Array too small for allocation type.");
1758 }
Miao Wang87e908d2015-03-02 15:15:15 -08001759 }
Chris Craik06d29842015-06-02 17:19:24 -07001760 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1761 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1762 } finally {
1763 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001764 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001765 }
1766
1767 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001768 * Copy from a rectangular region in this Allocation into an array.
1769 *
1770 * @param xoff X offset of the region to copy in this Allocation
1771 * @param yoff Y offset of the region to copy in this Allocation
1772 * @param w Width of the region to copy
1773 * @param h Height of the region to copy
1774 * @param array Dest Array to be copied into
1775 */
1776 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
1777 copy2DRangeToUnchecked(xoff, yoff, w, h, array,
1778 validateObjectIsPrimitiveArray(array, true),
1779 java.lang.reflect.Array.getLength(array));
1780 }
1781
1782 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001783 * Copy from a rectangular region in this Allocation into an array.
1784 *
1785 * @param xoff X offset of the region to copy in this Allocation
1786 * @param yoff Y offset of the region to copy in this Allocation
1787 * @param w Width of the region to copy
1788 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001789 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001790 */
1791 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
1792 validateIsInt8();
1793 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1794 Element.DataType.SIGNED_8, data.length);
1795 }
1796
1797 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001798 * Copy from a rectangular region in this Allocation into an array.
1799 *
1800 * @param xoff X offset of the region to copy in this Allocation
1801 * @param yoff Y offset of the region to copy in this Allocation
1802 * @param w Width of the region to copy
1803 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001804 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001805 */
1806 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001807 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001808 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1809 Element.DataType.SIGNED_16, data.length);
1810 }
1811
1812 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001813 * Copy from a rectangular region in this Allocation into an array.
1814 *
1815 * @param xoff X offset of the region to copy in this Allocation
1816 * @param yoff Y offset of the region to copy in this Allocation
1817 * @param w Width of the region to copy
1818 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001819 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001820 */
1821 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
1822 validateIsInt32();
1823 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1824 Element.DataType.SIGNED_32, data.length);
1825 }
1826
1827 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001828 * Copy from a rectangular region in this Allocation into an array.
1829 *
1830 * @param xoff X offset of the region to copy in this Allocation
1831 * @param yoff Y offset of the region to copy in this Allocation
1832 * @param w Width of the region to copy
1833 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001834 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001835 */
1836 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
1837 validateIsFloat32();
1838 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1839 Element.DataType.FLOAT_32, data.length);
1840 }
1841
1842
1843 /**
Miao Wang258db502015-03-03 14:05:36 -08001844 * Copy from a rectangular region in this Allocation into an array.
1845 * The array is assumed to be tightly packed.
Miao Wangc8e237e2015-02-20 18:36:32 -08001846 *
Miao Wang258db502015-03-03 14:05:36 -08001847 * The data type of the array is not required to be the same as
1848 * the element data type.
Miao Wangc8e237e2015-02-20 18:36:32 -08001849 */
1850 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1851 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001852 try {
1853 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked");
1854 mRS.validate();
1855 validate3DRange(xoff, yoff, zoff, w, h, d);
1856 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1857 // AutoPadding for Vec3 Element
1858 boolean usePadding = false;
1859 int sizeBytes = arrayLen * dt.mSize;
1860 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1861 if (dataSize / 4 * 3 > sizeBytes) {
1862 throw new RSIllegalArgumentException("Array too small for allocation type.");
1863 }
1864 usePadding = true;
1865 sizeBytes = dataSize;
1866 } else {
1867 if (dataSize > sizeBytes) {
1868 throw new RSIllegalArgumentException("Array too small for allocation type.");
1869 }
Miao Wang87e908d2015-03-02 15:15:15 -08001870 }
Chris Craik06d29842015-06-02 17:19:24 -07001871 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1872 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1873 } finally {
1874 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001875 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001876 }
1877
Miao Wang258db502015-03-03 14:05:36 -08001878 /*
Miao Wangc8e237e2015-02-20 18:36:32 -08001879 * Copy from a rectangular region in this Allocation into an array.
1880 *
1881 * @param xoff X offset of the region to copy in this Allocation
1882 * @param yoff Y offset of the region to copy in this Allocation
1883 * @param zoff Z offset of the region to copy in this Allocation
1884 * @param w Width of the region to copy
1885 * @param h Height of the region to copy
1886 * @param d Depth of the region to copy
1887 * @param array Dest Array to be copied into
1888 */
1889 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1890 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
1891 validateObjectIsPrimitiveArray(array, true),
1892 java.lang.reflect.Array.getLength(array));
1893 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001894
1895 // creation
1896
Jason Sams49a05d72010-12-29 14:31:29 -08001897 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001898 static {
1899 mBitmapOptions.inScaled = false;
1900 }
1901
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001902 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001903 * Creates a new Allocation with the given {@link
1904 * android.renderscript.Type}, mipmap flag, and usage flags.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001905 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001906 * @param type RenderScript type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001907 * @param mips specifies desired mipmap behaviour for the
1908 * allocation
Tim Murrayc11e25c2013-04-09 11:01:01 -07001909 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001910 * utilized
1911 */
1912 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001913 try {
1914 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
1915 rs.validate();
1916 if (type.getID(rs) == 0) {
1917 throw new RSInvalidStateException("Bad Type");
1918 }
Yang Ni6484b6b2016-03-24 09:40:32 -07001919 // TODO: What if there is an exception after this? The native allocation would leak.
Chris Craik06d29842015-06-02 17:19:24 -07001920 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
1921 if (id == 0) {
1922 throw new RSRuntimeException("Allocation creation failed.");
1923 }
Miao Wang8c150922015-10-26 17:44:10 -07001924 return new Allocation(id, rs, type, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07001925 } finally {
1926 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams1bada8c2009-08-09 17:01:55 -07001927 }
Jason Sams857d0c72011-11-23 15:02:15 -08001928 }
1929
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001930 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001931 * Creates an Allocation with the size specified by the type and no mipmaps
1932 * generated by default
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001933 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001934 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001935 * @param type renderscript type describing data layout
1936 * @param usage bit field specifying how the allocation is
1937 * utilized
1938 *
1939 * @return allocation
1940 */
Jason Samse5d37122010-12-16 00:33:33 -08001941 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1942 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1943 }
1944
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001945 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001946 * Creates an Allocation for use by scripts with a given {@link
1947 * android.renderscript.Type} and no mipmaps
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001948 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001949 * @param rs Context to which the Allocation will belong.
1950 * @param type RenderScript Type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001951 *
1952 * @return allocation
1953 */
Jason Sams5476b452010-12-08 16:14:36 -08001954 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001955 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001956 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001957
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001958 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001959 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001960 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001961 * @param rs Context to which the Allocation will belong.
1962 * @param e Element to use in the Allocation
1963 * @param count the number of Elements in the Allocation
1964 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001965 * utilized
1966 *
1967 * @return allocation
1968 */
Jason Sams5476b452010-12-08 16:14:36 -08001969 static public Allocation createSized(RenderScript rs, Element e,
1970 int count, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001971 try {
1972 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
1973 rs.validate();
1974 Type.Builder b = new Type.Builder(rs, e);
1975 b.setX(count);
1976 Type t = b.create();
Jason Sams768bc022009-09-21 19:41:04 -07001977
Chris Craik06d29842015-06-02 17:19:24 -07001978 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
1979 if (id == 0) {
1980 throw new RSRuntimeException("Allocation creation failed.");
1981 }
Miao Wang8c150922015-10-26 17:44:10 -07001982 return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
Chris Craik06d29842015-06-02 17:19:24 -07001983 } finally {
1984 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsb8c5a842009-07-31 20:40:47 -07001985 }
Jason Sams5476b452010-12-08 16:14:36 -08001986 }
1987
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001988 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001989 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001990 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001991 * @param rs Context to which the Allocation will belong.
1992 * @param e Element to use in the Allocation
1993 * @param count the number of Elements in the Allocation
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001994 *
1995 * @return allocation
1996 */
Jason Sams5476b452010-12-08 16:14:36 -08001997 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001998 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001999 }
2000
Jason Sams49a05d72010-12-29 14:31:29 -08002001 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08002002 final Bitmap.Config bc = b.getConfig();
2003 if (bc == Bitmap.Config.ALPHA_8) {
2004 return Element.A_8(rs);
2005 }
2006 if (bc == Bitmap.Config.ARGB_4444) {
2007 return Element.RGBA_4444(rs);
2008 }
2009 if (bc == Bitmap.Config.ARGB_8888) {
2010 return Element.RGBA_8888(rs);
2011 }
2012 if (bc == Bitmap.Config.RGB_565) {
2013 return Element.RGB_565(rs);
2014 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08002015 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08002016 }
2017
Jason Sams49a05d72010-12-29 14:31:29 -08002018 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002019 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08002020 Element e = elementFromBitmap(rs, b);
2021 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002022 tb.setX(b.getWidth());
2023 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08002024 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08002025 return tb.create();
2026 }
2027
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002028 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002029 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002030 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002031 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002032 * @param b Bitmap source for the allocation data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002033 * @param mips specifies desired mipmap behaviour for the
2034 * allocation
2035 * @param usage bit field specifying how the allocation is
2036 * utilized
2037 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002038 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002039 *
2040 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002041 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002042 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002043 int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07002044 try {
2045 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
2046 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08002047
Chris Craik06d29842015-06-02 17:19:24 -07002048 // WAR undocumented color formats
2049 if (b.getConfig() == null) {
2050 if ((usage & USAGE_SHARED) != 0) {
2051 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2052 }
2053 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2054 Canvas c = new Canvas(newBitmap);
2055 c.drawBitmap(b, 0, 0, null);
2056 return createFromBitmap(rs, newBitmap, mips, usage);
Tim Murrayabd5db92013-02-28 11:45:22 -08002057 }
Tim Murrayabd5db92013-02-28 11:45:22 -08002058
Chris Craik06d29842015-06-02 17:19:24 -07002059 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08002060
Chris Craik06d29842015-06-02 17:19:24 -07002061 // enable optimized bitmap path only with no mipmap and script-only usage
2062 if (mips == MipmapControl.MIPMAP_NONE &&
2063 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2064 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2065 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2066 if (id == 0) {
2067 throw new RSRuntimeException("Load failed.");
2068 }
2069
2070 // keep a reference to the Bitmap around to prevent GC
Miao Wang8c150922015-10-26 17:44:10 -07002071 Allocation alloc = new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002072 alloc.setBitmap(b);
2073 return alloc;
2074 }
2075
2076
2077 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Tim Murraya3145512012-12-04 17:59:29 -08002078 if (id == 0) {
2079 throw new RSRuntimeException("Load failed.");
2080 }
Miao Wang8c150922015-10-26 17:44:10 -07002081 return new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002082 } finally {
2083 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murraya3145512012-12-04 17:59:29 -08002084 }
Jason Sams5476b452010-12-08 16:14:36 -08002085 }
2086
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002087 /**
Miao Wang0facf022015-11-25 11:21:13 -08002088 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
2089 * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
2090 * would contain the up-to-date data as READ ONLY.
2091 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2092 * the Allocation has certain alignment. The size of each row including padding,
2093 * called stride, can be queried using the {@link #getStride()} method.
2094 *
2095 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
2096 *
2097 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
2098 */
2099 public ByteBuffer getByteBuffer() {
2100 // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
2101 if (mType.hasFaces()) {
2102 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
2103 }
2104 if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
2105 mType.getYuv() == android.graphics.ImageFormat.YV12 ||
2106 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
2107 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
2108 }
2109 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
2110 int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
2111 long[] stride = new long[1];
2112 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
2113 mByteBufferStride = stride[0];
2114 }
2115 if ((mUsage & USAGE_IO_INPUT) != 0) {
2116 return mByteBuffer.asReadOnlyBuffer();
2117 }
2118 return mByteBuffer;
2119 }
2120
2121 /**
Miao Wang8c150922015-10-26 17:44:10 -07002122 * Creates a new Allocation Array with the given {@link
2123 * android.renderscript.Type}, and usage flags.
2124 * Note: If the input allocation is of usage: USAGE_IO_INPUT,
2125 * the created Allocation will be sharing the same BufferQueue.
2126 *
2127 * @param rs RenderScript context
2128 * @param t RenderScript type describing data layout
2129 * @param usage bit field specifying how the Allocation is
2130 * utilized
2131 * @param numAlloc Number of Allocations in the array.
2132 * @return Allocation[]
2133 */
2134 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
2135 try {
2136 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
2137 rs.validate();
2138 if (t.getID(rs) == 0) {
2139 throw new RSInvalidStateException("Bad Type");
2140 }
2141
2142 Allocation[] mAllocationArray = new Allocation[numAlloc];
2143 mAllocationArray[0] = createTyped(rs, t, usage);
2144 if ((usage & USAGE_IO_INPUT) != 0) {
2145 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
2146 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2147 MAX_NUMBER_IO_INPUT_ALLOC);
2148 }
2149 mAllocationArray[0].setupBufferQueue(numAlloc);;
2150 }
2151
2152 for (int i=1; i<numAlloc; i++) {
2153 mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
2154 }
2155 return mAllocationArray;
2156 } finally {
2157 Trace.traceEnd(RenderScript.TRACE_TAG);
2158 }
2159 }
2160
2161 /**
2162 * Creates a new Allocation with the given {@link
2163 * android.renderscript.Allocation}. The same data layout of
2164 * the input Allocation will be applied.
2165 * If the input allocation is of usage: USAGE_IO_INPUT, the created
2166 * Allocation will be sharing the same BufferQueue.
2167 *
2168 * @param rs Context to which the allocation will belong.
2169 * @param alloc RenderScript Allocation describing data layout.
2170 * @return Allocation sharing the same data structure.
2171 */
2172 static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
2173 try {
2174 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2175 rs.validate();
2176 if (alloc.getID(rs) == 0) {
2177 throw new RSInvalidStateException("Bad input Allocation");
2178 }
2179
2180 Type type = alloc.getType();
2181 int usage = alloc.getUsage();
2182 MipmapControl mips = alloc.getMipmap();
2183 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2184 if (id == 0) {
2185 throw new RSRuntimeException("Allocation creation failed.");
2186 }
2187 Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
2188 if ((usage & USAGE_IO_INPUT) != 0) {
2189 outAlloc.shareBufferQueue(alloc);
2190 }
2191 return outAlloc;
2192 } finally {
2193 Trace.traceEnd(RenderScript.TRACE_TAG);
2194 }
2195 }
2196
2197 /**
2198 * Initialize BufferQueue with specified max number of buffers.
2199 */
2200 void setupBufferQueue(int numAlloc) {
2201 mRS.validate();
2202 if ((mUsage & USAGE_IO_INPUT) == 0) {
2203 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2204 }
2205 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2206 }
2207
2208 /**
2209 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2210 *
2211 * @param alloc Allocation to associate with allocation
2212 */
2213 void shareBufferQueue(Allocation alloc) {
2214 mRS.validate();
2215 if ((mUsage & USAGE_IO_INPUT) == 0) {
2216 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2217 }
2218 mGetSurfaceSurface = alloc.getSurface();
2219 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2220 }
2221
2222 /**
Miao Wang0facf022015-11-25 11:21:13 -08002223 * Gets the stride of the Allocation.
2224 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2225 * the Allocation has certain alignment. The size of each row including such
2226 * padding is called stride.
2227 *
2228 * @return the stride. For 1D Allocation, the stride will be the number of
2229 * bytes of this Allocation. For 2D and 3D Allocations, the stride
2230 * will be the stride in X dimension measuring in bytes.
2231 */
2232 public long getStride() {
2233 if (mByteBufferStride == -1) {
2234 getByteBuffer();
2235 }
2236 return mByteBufferStride;
2237 }
2238
2239 /**
Miao Wang8c150922015-10-26 17:44:10 -07002240 * Get the timestamp for the most recent buffer held by this Allocation.
2241 * The timestamp is guaranteed to be unique and monotonically increasing.
2242 * Default value: -1. The timestamp will be updated after each {@link
2243 * #ioReceive ioReceive()} call.
2244 *
2245 * It can be used to identify the images by comparing the unique timestamps
2246 * when used with {@link android.hardware.camera2} APIs.
2247 * Example steps:
2248 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
2249 * capture is completed.
2250 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
2251 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
2252 * alloc.getTimeStamp().
2253 * @return long Timestamp associated with the buffer held by the Allocation.
2254 */
2255 public long getTimeStamp() {
2256 return mTimeStamp;
2257 }
2258
2259 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002260 * Returns the handle to a raw buffer that is being managed by the screen
2261 * compositor. This operation is only valid for Allocations with {@link
2262 * #USAGE_IO_INPUT}.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002263 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002264 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002265 *
2266 */
2267 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08002268 if ((mUsage & USAGE_IO_INPUT) == 0) {
2269 throw new RSInvalidStateException("Allocation is not a surface texture.");
2270 }
Jason Sams1e68bac2015-03-17 16:36:55 -07002271
2272 if (mGetSurfaceSurface == null) {
2273 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
2274 }
2275
2276 return mGetSurfaceSurface;
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002277 }
2278
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002279 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002280 * Associate a {@link android.view.Surface} with this Allocation. This
2281 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002282 *
2283 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08002284 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002285 public void setSurface(Surface sur) {
2286 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08002287 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2288 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2289 }
2290
Jason Samse07694b2012-04-03 15:36:36 -07002291 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08002292 }
2293
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002294 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002295 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Tim Murray00bb4542012-12-17 16:35:06 -08002296 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002297 * <p>With target API version 18 or greater, this Allocation will be created
2298 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
2299 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
2300 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002301 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002302 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002303 * @param b bitmap source for the allocation data
2304 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002305 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002306 *
2307 */
Jason Sams6d8eb262010-12-15 01:41:00 -08002308 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08002309 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2310 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Tim Murray78e64942013-04-09 17:28:56 -07002311 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Tim Murray00bb4542012-12-17 16:35:06 -08002312 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002313 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2314 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08002315 }
2316
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002317 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002318 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2319 * containing the horizontal list of cube faces. Each face must be a square,
2320 * have the same size as all other faces, and have a width that is a power
2321 * of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002322 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002323 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002324 * @param b Bitmap with cubemap faces layed out in the following
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002325 * format: right, left, top, bottom, front, back
2326 * @param mips specifies desired mipmap behaviour for the cubemap
2327 * @param usage bit field specifying how the cubemap is utilized
2328 *
2329 * @return allocation containing cubemap data
2330 *
2331 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002332 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002333 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002334 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002335 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08002336
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002337 int height = b.getHeight();
2338 int width = b.getWidth();
2339
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002340 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002341 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2342 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002343 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002344 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002345 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002346 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002347 if (!isPow2) {
2348 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2349 }
2350
2351 Element e = elementFromBitmap(rs, b);
2352 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002353 tb.setX(height);
2354 tb.setY(height);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002355 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08002356 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002357 Type t = tb.create();
2358
Tim Murray460a0492013-11-19 12:45:54 -08002359 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002360 if(id == 0) {
2361 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2362 }
Miao Wang8c150922015-10-26 17:44:10 -07002363 return new Allocation(id, rs, t, usage, mips);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002364 }
2365
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002366 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002367 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2368 * from a {@link android.graphics.Bitmap} containing the horizontal list of
2369 * cube faces. Each face must be a square, have the same size as all other
2370 * faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002371 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002372 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002373 * @param b bitmap with cubemap faces layed out in the following
2374 * format: right, left, top, bottom, front, back
2375 *
2376 * @return allocation containing cubemap data
2377 *
2378 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002379 static public Allocation createCubemapFromBitmap(RenderScript rs,
2380 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08002381 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002382 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08002383 }
2384
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002385 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002386 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2387 * objects containing the cube faces. Each face must be a square, have the
2388 * same size as all other faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002389 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002390 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002391 * @param xpos cubemap face in the positive x direction
2392 * @param xneg cubemap face in the negative x direction
2393 * @param ypos cubemap face in the positive y direction
2394 * @param yneg cubemap face in the negative y direction
2395 * @param zpos cubemap face in the positive z direction
2396 * @param zneg cubemap face in the negative z direction
2397 * @param mips specifies desired mipmap behaviour for the cubemap
2398 * @param usage bit field specifying how the cubemap is utilized
2399 *
2400 * @return allocation containing cubemap data
2401 *
2402 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002403 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2404 Bitmap xpos,
2405 Bitmap xneg,
2406 Bitmap ypos,
2407 Bitmap yneg,
2408 Bitmap zpos,
2409 Bitmap zneg,
2410 MipmapControl mips,
2411 int usage) {
2412 int height = xpos.getHeight();
2413 if (xpos.getWidth() != height ||
2414 xneg.getWidth() != height || xneg.getHeight() != height ||
2415 ypos.getWidth() != height || ypos.getHeight() != height ||
2416 yneg.getWidth() != height || yneg.getHeight() != height ||
2417 zpos.getWidth() != height || zpos.getHeight() != height ||
2418 zneg.getWidth() != height || zneg.getHeight() != height) {
2419 throw new RSIllegalArgumentException("Only square cube map faces supported");
2420 }
2421 boolean isPow2 = (height & (height - 1)) == 0;
2422 if (!isPow2) {
2423 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2424 }
2425
2426 Element e = elementFromBitmap(rs, xpos);
2427 Type.Builder tb = new Type.Builder(rs, e);
2428 tb.setX(height);
2429 tb.setY(height);
2430 tb.setFaces(true);
2431 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2432 Type t = tb.create();
2433 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2434
2435 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07002436 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002437 adapter.copyFrom(xpos);
2438 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2439 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002440 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002441 adapter.copyFrom(ypos);
2442 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2443 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002444 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002445 adapter.copyFrom(zpos);
2446 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2447 adapter.copyFrom(zneg);
2448
2449 return cubemap;
2450 }
2451
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002452 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002453 * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2454 * from 6 {@link android.graphics.Bitmap} objects containing the cube
2455 * faces. Each face must be a square, have the same size as all other faces,
2456 * and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002457 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002458 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002459 * @param xpos cubemap face in the positive x direction
2460 * @param xneg cubemap face in the negative x direction
2461 * @param ypos cubemap face in the positive y direction
2462 * @param yneg cubemap face in the negative y direction
2463 * @param zpos cubemap face in the positive z direction
2464 * @param zneg cubemap face in the negative z direction
2465 *
2466 * @return allocation containing cubemap data
2467 *
2468 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002469 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2470 Bitmap xpos,
2471 Bitmap xneg,
2472 Bitmap ypos,
2473 Bitmap yneg,
2474 Bitmap zpos,
2475 Bitmap zneg) {
2476 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2477 zpos, zneg, MipmapControl.MIPMAP_NONE,
2478 USAGE_GRAPHICS_TEXTURE);
2479 }
2480
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002481 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002482 * Creates an Allocation from the Bitmap referenced
2483 * by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002484 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002485 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002486 * @param res application resources
2487 * @param id resource id to load the data from
2488 * @param mips specifies desired mipmap behaviour for the
2489 * allocation
2490 * @param usage bit field specifying how the allocation is
2491 * utilized
2492 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002493 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002494 *
2495 */
Jason Sams5476b452010-12-08 16:14:36 -08002496 static public Allocation createFromBitmapResource(RenderScript rs,
2497 Resources res,
2498 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08002499 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002500 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07002501
Jason Sams771bebb2009-12-07 12:40:12 -08002502 rs.validate();
Jason Sams3ece2f32013-05-31 14:00:46 -07002503 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2504 throw new RSIllegalArgumentException("Unsupported usage specified.");
2505 }
Jason Sams5476b452010-12-08 16:14:36 -08002506 Bitmap b = BitmapFactory.decodeResource(res, id);
2507 Allocation alloc = createFromBitmap(rs, b, mips, usage);
2508 b.recycle();
2509 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07002510 }
2511
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002512 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002513 * Creates a non-mipmapped Allocation to use as a graphics texture from the
2514 * {@link android.graphics.Bitmap} referenced by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002515 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002516 * <p>With target API version 18 or greater, this allocation will be created
2517 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
2518 * target API version 17 or lower, this allocation will be created with
2519 * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Jason Sams455d6442013-02-05 19:20:18 -08002520 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002521 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002522 * @param res application resources
2523 * @param id resource id to load the data from
2524 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002525 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002526 *
2527 */
Jason Sams5476b452010-12-08 16:14:36 -08002528 static public Allocation createFromBitmapResource(RenderScript rs,
2529 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08002530 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08002531 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2532 return createFromBitmapResource(rs, res, id,
2533 MipmapControl.MIPMAP_NONE,
Jason Sams3ece2f32013-05-31 14:00:46 -07002534 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Jason Sams455d6442013-02-05 19:20:18 -08002535 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002536 return createFromBitmapResource(rs, res, id,
2537 MipmapControl.MIPMAP_NONE,
2538 USAGE_GRAPHICS_TEXTURE);
2539 }
2540
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002541 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002542 * Creates an Allocation containing string data encoded in UTF-8 format.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002543 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002544 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002545 * @param str string to create the allocation from
2546 * @param usage bit field specifying how the allocaiton is
2547 * utilized
2548 *
2549 */
Jason Sams5476b452010-12-08 16:14:36 -08002550 static public Allocation createFromString(RenderScript rs,
2551 String str,
2552 int usage) {
2553 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002554 byte[] allocArray = null;
2555 try {
2556 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08002557 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08002558 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002559 return alloc;
2560 }
2561 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08002562 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002563 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002564 }
Jason Sams739c8262013-04-11 18:07:52 -07002565
2566 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002567 * Interface to handle notification when new buffers are available via
2568 * {@link #USAGE_IO_INPUT}. An application will receive one notification
2569 * when a buffer is available. Additional buffers will not trigger new
2570 * notifications until a buffer is processed.
Jason Sams739c8262013-04-11 18:07:52 -07002571 */
Jason Sams42ef2382013-08-29 13:30:59 -07002572 public interface OnBufferAvailableListener {
Jason Sams739c8262013-04-11 18:07:52 -07002573 public void onBufferAvailable(Allocation a);
2574 }
2575
2576 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002577 * Set a notification handler for {@link #USAGE_IO_INPUT}.
Jason Sams739c8262013-04-11 18:07:52 -07002578 *
Jason Sams42ef2382013-08-29 13:30:59 -07002579 * @param callback instance of the OnBufferAvailableListener
2580 * class to be called when buffer arrive.
Jason Sams739c8262013-04-11 18:07:52 -07002581 */
Jason Sams42ef2382013-08-29 13:30:59 -07002582 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
Jason Sams739c8262013-04-11 18:07:52 -07002583 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002584 mAllocationMap.put(new Long(getID(mRS)), this);
Jason Sams739c8262013-04-11 18:07:52 -07002585 mBufferNotifier = callback;
2586 }
2587 }
2588
Tim Murrayb730d862014-08-18 16:14:24 -07002589 static void sendBufferNotification(long id) {
Jason Sams739c8262013-04-11 18:07:52 -07002590 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002591 Allocation a = mAllocationMap.get(new Long(id));
Jason Sams739c8262013-04-11 18:07:52 -07002592
2593 if ((a != null) && (a.mBufferNotifier != null)) {
2594 a.mBufferNotifier.onBufferAvailable(a);
2595 }
2596 }
2597 }
2598
Miao Wangf0f6e802015-02-03 17:16:43 -08002599 /**
2600 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
2601 *
2602 */
2603 @Override
2604 public void destroy() {
2605 if((mUsage & USAGE_IO_OUTPUT) != 0) {
2606 setSurface(null);
2607 }
2608 super.destroy();
2609 }
Jason Samsb8c5a842009-07-31 20:40:47 -07002610}