blob: fc9296674d89192c00d08014ce44d931ec1ce4c4 [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 }
145 return null;
146 }
147
148
Tim Murrayc11e25c2013-04-09 11:01:01 -0700149 /**
150 * The usage of the Allocation. These signal to RenderScript where to place
151 * the Allocation in memory.
152 *
153 */
Jason Sams5476b452010-12-08 16:14:36 -0800154
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700155 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700156 * The Allocation will be bound to and accessed by scripts.
Jason Samsf7086092011-01-12 13:28:37 -0800157 */
Jason Sams5476b452010-12-08 16:14:36 -0800158 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800159
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700160 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700161 * The Allocation will be used as a texture source by one or more graphics
162 * programs.
Jason Samsf7086092011-01-12 13:28:37 -0800163 *
164 */
Jason Sams5476b452010-12-08 16:14:36 -0800165 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800166
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700167 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700168 * The Allocation will be used as a graphics mesh.
169 *
170 * This was deprecated in API level 16.
Jason Samsf7086092011-01-12 13:28:37 -0800171 *
172 */
Jason Sams5476b452010-12-08 16:14:36 -0800173 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800174
175
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700176 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700177 * The Allocation will be used as the source of shader constants by one or
178 * more programs.
179 *
180 * This was deprecated in API level 16.
Jason Samsf7086092011-01-12 13:28:37 -0800181 *
182 */
Jason Sams5476b452010-12-08 16:14:36 -0800183 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
184
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700185 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700186 * The Allocation will be used as a target for offscreen rendering
187 *
188 * This was deprecated in API level 16.
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700189 *
190 */
191 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
192
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700193 /**
Jason Sams3a1b8e42013-09-24 15:18:52 -0700194 * The Allocation will be used as a {@link android.view.Surface}
195 * consumer. This usage will cause the Allocation to be created
196 * as read-only.
Jason Sams615e7ce2012-01-13 14:01:20 -0800197 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800198 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700199 public static final int USAGE_IO_INPUT = 0x0020;
Stephen Hines9069ee82012-02-13 18:25:54 -0800200
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700201 /**
Jason Sams3a1b8e42013-09-24 15:18:52 -0700202 * The Allocation will be used as a {@link android.view.Surface}
Tim Murrayc11e25c2013-04-09 11:01:01 -0700203 * producer. The dimensions and format of the {@link
Jason Sams3a1b8e42013-09-24 15:18:52 -0700204 * android.view.Surface} will be forced to those of the
Tim Murrayc11e25c2013-04-09 11:01:01 -0700205 * Allocation.
Jason Sams615e7ce2012-01-13 14:01:20 -0800206 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800207 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700208 public static final int USAGE_IO_OUTPUT = 0x0040;
Jason Sams43ee06852009-08-12 17:54:11 -0700209
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700210 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700211 * The Allocation's backing store will be inherited from another object
212 * (usually a {@link android.graphics.Bitmap}); copying to or from the
213 * original source Bitmap will cause a synchronization rather than a full
214 * copy. {@link #syncAll} may also be used to synchronize the Allocation
215 * and the source Bitmap.
Tim Murray00bb4542012-12-17 16:35:06 -0800216 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700217 * <p>This is set by default for allocations created with {@link
218 * #createFromBitmap} in API version 18 and higher.</p>
Tim Murray00bb4542012-12-17 16:35:06 -0800219 *
220 */
221 public static final int USAGE_SHARED = 0x0080;
222
223 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700224 * Controls mipmap behavior when using the bitmap creation and update
225 * functions.
Jason Samsf7086092011-01-12 13:28:37 -0800226 */
Jason Sams4ef66502010-12-10 16:03:15 -0800227 public enum MipmapControl {
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700228 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700229 * No mipmaps will be generated and the type generated from the incoming
230 * bitmap will not contain additional LODs.
Jason Samsf7086092011-01-12 13:28:37 -0800231 */
Jason Sams5476b452010-12-08 16:14:36 -0800232 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800233
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700234 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700235 * A full mipmap chain will be created in script memory. The Type of
236 * the Allocation will contain a full mipmap chain. On upload, the full
237 * chain will be transferred.
Jason Samsf7086092011-01-12 13:28:37 -0800238 */
Jason Sams5476b452010-12-08 16:14:36 -0800239 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800240
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700241 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700242 * The Type of the Allocation will be the same as MIPMAP_NONE. It will
243 * not contain mipmaps. On upload, the allocation data will contain a
244 * full mipmap chain generated from the top level in script memory.
Jason Samsf7086092011-01-12 13:28:37 -0800245 */
Jason Sams5476b452010-12-08 16:14:36 -0800246 MIPMAP_ON_SYNC_TO_TEXTURE(2);
247
248 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800249 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800250 mID = id;
251 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700252 }
253
Jason Sams48fe5342011-07-08 13:52:30 -0700254
Tim Murray460a0492013-11-19 12:45:54 -0800255 private long getIDSafe() {
Jason Sams48fe5342011-07-08 13:52:30 -0700256 if (mAdaptedAllocation != null) {
Jason Samse07694b2012-04-03 15:36:36 -0700257 return mAdaptedAllocation.getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700258 }
Jason Samse07694b2012-04-03 15:36:36 -0700259 return getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700260 }
261
Jason Sams03d2d002012-03-23 13:51:56 -0700262
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700263 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700264 * Get the {@link android.renderscript.Element} of the {@link
265 * android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700266 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700267 * @return Element
Jason Sams03d2d002012-03-23 13:51:56 -0700268 *
269 */
270 public Element getElement() {
271 return mType.getElement();
272 }
273
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700274 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700275 * Get the usage flags of the Allocation.
276 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700277 * @return usage this Allocation's set of the USAGE_* flags OR'd together
Jason Sams03d2d002012-03-23 13:51:56 -0700278 *
279 */
280 public int getUsage() {
281 return mUsage;
282 }
283
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700284 /**
Miao Wang8c150922015-10-26 17:44:10 -0700285 * @hide
286 * Get the Mipmap control flag of the Allocation.
287 *
288 * @return the Mipmap control flag of the Allocation
289 *
290 */
291 public MipmapControl getMipmap() {
292 return mMipmapControl;
293 }
294
295 /**
Miao Wang87e908d2015-03-02 15:15:15 -0800296 * Enable/Disable AutoPadding for Vec3 elements.
Miao Wangd7ecab12015-03-26 18:00:15 -0700297 * By default: Diabled.
Miao Wang87e908d2015-03-02 15:15:15 -0800298 *
Miao Wang179e8b52015-04-15 17:44:32 -0700299 * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
Miao Wang87e908d2015-03-02 15:15:15 -0800300 *
301 */
302 public void setAutoPadding(boolean useAutoPadding) {
303 mAutoPadding = useAutoPadding;
304 }
305
306 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700307 * Get the size of the Allocation in bytes.
308 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700309 * @return size of the Allocation in bytes.
Jason Sams36c0f642012-03-23 15:48:37 -0700310 *
311 */
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700312 public int getBytesSize() {
Tim Murray04f0d6e2013-12-17 17:15:25 -0800313 if (mType.mDimYuv != 0) {
314 return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
315 }
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700316 return mType.getCount() * mType.getElement().getBytesSize();
Jason Sams36c0f642012-03-23 15:48:37 -0700317 }
318
Jason Sams452a7662011-07-07 16:05:18 -0700319 private void updateCacheInfo(Type t) {
320 mCurrentDimX = t.getX();
321 mCurrentDimY = t.getY();
322 mCurrentDimZ = t.getZ();
323 mCurrentCount = mCurrentDimX;
324 if (mCurrentDimY > 1) {
325 mCurrentCount *= mCurrentDimY;
326 }
327 if (mCurrentDimZ > 1) {
328 mCurrentCount *= mCurrentDimZ;
329 }
330 }
Jason Samsba862d12011-07-07 15:24:42 -0700331
Tim Murraya3145512012-12-04 17:59:29 -0800332 private void setBitmap(Bitmap b) {
333 mBitmap = b;
334 }
335
Tim Murray460a0492013-11-19 12:45:54 -0800336 Allocation(long id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700337 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800338 if ((usage & ~(USAGE_SCRIPT |
339 USAGE_GRAPHICS_TEXTURE |
340 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700341 USAGE_GRAPHICS_CONSTANTS |
Jason Sams615e7ce2012-01-13 14:01:20 -0800342 USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams615e7ce2012-01-13 14:01:20 -0800343 USAGE_IO_INPUT |
Tim Murray00bb4542012-12-17 16:35:06 -0800344 USAGE_IO_OUTPUT |
345 USAGE_SHARED)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800346 throw new RSIllegalArgumentException("Unknown usage specified.");
347 }
Jason Sams615e7ce2012-01-13 14:01:20 -0800348
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700349 if ((usage & USAGE_IO_INPUT) != 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800350 mWriteAllowed = false;
351
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700352 if ((usage & ~(USAGE_IO_INPUT |
Jason Sams615e7ce2012-01-13 14:01:20 -0800353 USAGE_GRAPHICS_TEXTURE |
354 USAGE_SCRIPT)) != 0) {
355 throw new RSIllegalArgumentException("Invalid usage combination.");
356 }
357 }
Jason Sams9bf18922013-04-13 19:48:36 -0700358
Jason Sams5476b452010-12-08 16:14:36 -0800359 mType = t;
Jason Sams615e7ce2012-01-13 14:01:20 -0800360 mUsage = usage;
Jason Samsba862d12011-07-07 15:24:42 -0700361
Jason Sams452a7662011-07-07 16:05:18 -0700362 if (t != null) {
Stephen Hines88990da2013-09-09 17:56:07 -0700363 // TODO: A3D doesn't have Type info during creation, so we can't
364 // calculate the size ahead of time. We can possibly add a method
365 // to update the size in the future if it seems reasonable.
366 mSize = mType.getCount() * mType.getElement().getBytesSize();
Jason Sams452a7662011-07-07 16:05:18 -0700367 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700368 }
Tim Murray2f2472c2013-08-22 14:55:26 -0700369 try {
370 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
371 } catch (Exception e) {
372 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
373 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
374 }
375 }
376
Miao Wang8c150922015-10-26 17:44:10 -0700377 Allocation(long id, RenderScript rs, Type t, int usage, MipmapControl mips) {
378 this(id, rs, t, usage);
379 mMipmapControl = mips;
380 }
381
Tim Murray2f2472c2013-08-22 14:55:26 -0700382 protected void finalize() throws Throwable {
383 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
384 super.finalize();
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700385 }
386
Jason Sams3042d262013-11-25 18:28:33 -0800387 private void validateIsInt64() {
388 if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
389 (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
390 return;
391 }
392 throw new RSIllegalArgumentException(
393 "64 bit integer source does not match allocation type " + mType.mElement.mType);
394 }
395
Jason Samsb97b2512011-01-16 15:04:08 -0800396 private void validateIsInt32() {
397 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
398 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
399 return;
400 }
401 throw new RSIllegalArgumentException(
402 "32 bit integer source does not match allocation type " + mType.mElement.mType);
403 }
404
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800405 private void validateIsInt16OrFloat16() {
Jason Samsb97b2512011-01-16 15:04:08 -0800406 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800407 (mType.mElement.mType == Element.DataType.UNSIGNED_16) ||
408 (mType.mElement.mType == Element.DataType.FLOAT_16)) {
Jason Samsb97b2512011-01-16 15:04:08 -0800409 return;
410 }
411 throw new RSIllegalArgumentException(
412 "16 bit integer source does not match allocation type " + mType.mElement.mType);
413 }
414
415 private void validateIsInt8() {
416 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
417 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
418 return;
419 }
420 throw new RSIllegalArgumentException(
421 "8 bit integer source does not match allocation type " + mType.mElement.mType);
422 }
423
424 private void validateIsFloat32() {
425 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
426 return;
427 }
428 throw new RSIllegalArgumentException(
429 "32 bit float source does not match allocation type " + mType.mElement.mType);
430 }
431
Jason Sams3042d262013-11-25 18:28:33 -0800432 private void validateIsFloat64() {
433 if (mType.mElement.mType == Element.DataType.FLOAT_64) {
434 return;
435 }
436 throw new RSIllegalArgumentException(
437 "64 bit float source does not match allocation type " + mType.mElement.mType);
438 }
439
Jason Samsb97b2512011-01-16 15:04:08 -0800440 private void validateIsObject() {
441 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
442 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
443 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
444 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
445 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
446 (mType.mElement.mType == Element.DataType.RS_MESH) ||
447 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
448 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
449 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
450 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
451 return;
452 }
453 throw new RSIllegalArgumentException(
454 "Object source does not match allocation type " + mType.mElement.mType);
455 }
456
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700457 @Override
458 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800459 super.updateFromNative();
Tim Murray460a0492013-11-19 12:45:54 -0800460 long typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700461 if(typeID != 0) {
462 mType = new Type(typeID, mRS);
463 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700464 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700465 }
466 }
467
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700468 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700469 * Get the {@link android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700470 *
471 * @return Type
472 *
473 */
Jason Samsea87e962010-01-12 12:12:28 -0800474 public Type getType() {
475 return mType;
476 }
477
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700478 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700479 * Propagate changes from one usage of the Allocation to the
480 * other usages of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700481 *
482 */
Jason Sams5476b452010-12-08 16:14:36 -0800483 public void syncAll(int srcLocation) {
Chris Craik06d29842015-06-02 17:19:24 -0700484 try {
485 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
486 switch (srcLocation) {
487 case USAGE_GRAPHICS_TEXTURE:
488 case USAGE_SCRIPT:
489 if ((mUsage & USAGE_SHARED) != 0) {
490 copyFrom(mBitmap);
491 }
492 break;
493 case USAGE_GRAPHICS_CONSTANTS:
494 case USAGE_GRAPHICS_VERTEX:
495 break;
496 case USAGE_SHARED:
497 if ((mUsage & USAGE_SHARED) != 0) {
498 copyTo(mBitmap);
499 }
500 break;
501 default:
502 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
Tim Murray78e64942013-04-09 17:28:56 -0700503 }
Chris Craik06d29842015-06-02 17:19:24 -0700504 mRS.validate();
505 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
506 } finally {
507 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams5476b452010-12-08 16:14:36 -0800508 }
Jason Sams5476b452010-12-08 16:14:36 -0800509 }
510
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700511 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700512 * Send a buffer to the output stream. The contents of the Allocation will
513 * be undefined after this operation. This operation is only valid if {@link
514 * #USAGE_IO_OUTPUT} is set on the Allocation.
515 *
Jason Sams163766c2012-02-15 12:04:24 -0800516 *
Jason Sams163766c2012-02-15 12:04:24 -0800517 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700518 public void ioSend() {
Chris Craik06d29842015-06-02 17:19:24 -0700519 try {
520 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
521 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
522 throw new RSIllegalArgumentException(
523 "Can only send buffer if IO_OUTPUT usage specified.");
524 }
525 mRS.validate();
526 mRS.nAllocationIoSend(getID(mRS));
527 } finally {
528 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800529 }
Jason Sams163766c2012-02-15 12:04:24 -0800530 }
531
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700532 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700533 * Receive the latest input into the Allocation. This operation
534 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
Jason Sams163766c2012-02-15 12:04:24 -0800535 *
Jason Sams163766c2012-02-15 12:04:24 -0800536 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700537 public void ioReceive() {
Chris Craik06d29842015-06-02 17:19:24 -0700538 try {
539 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
540 if ((mUsage & USAGE_IO_INPUT) == 0) {
541 throw new RSIllegalArgumentException(
542 "Can only receive if IO_INPUT usage specified.");
543 }
544 mRS.validate();
Miao Wang8c150922015-10-26 17:44:10 -0700545 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
Chris Craik06d29842015-06-02 17:19:24 -0700546 } finally {
547 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800548 }
Jason Sams163766c2012-02-15 12:04:24 -0800549 }
550
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700551 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700552 * Copy an array of RS objects to the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700553 *
554 * @param d Source array.
555 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800556 public void copyFrom(BaseObj[] d) {
Chris Craik06d29842015-06-02 17:19:24 -0700557 try {
558 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
559 mRS.validate();
560 validateIsObject();
561 if (d.length != mCurrentCount) {
562 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
563 mCurrentCount + ", array length = " + d.length);
564 }
Tim Murray460a0492013-11-19 12:45:54 -0800565
Chris Craik06d29842015-06-02 17:19:24 -0700566 if (RenderScript.sPointerSize == 8) {
567 long i[] = new long[d.length * 4];
568 for (int ct=0; ct < d.length; ct++) {
569 i[ct * 4] = d[ct].getID(mRS);
570 }
571 copy1DRangeFromUnchecked(0, mCurrentCount, i);
572 } else {
573 int i[] = new int[d.length];
574 for (int ct=0; ct < d.length; ct++) {
575 i[ct] = (int) d[ct].getID(mRS);
576 }
577 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Tim Murray3de3dc72014-07-01 16:56:18 -0700578 }
Chris Craik06d29842015-06-02 17:19:24 -0700579 } finally {
580 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800581 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700582 }
583
Jason Samsfb9f82c2011-01-12 14:53:25 -0800584 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800585 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800586 if (bc == null) {
587 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
588 }
Jason Sams252c0782011-01-11 17:42:52 -0800589 switch (bc) {
590 case ALPHA_8:
591 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
592 throw new RSIllegalArgumentException("Allocation kind is " +
593 mType.getElement().mKind + ", type " +
594 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700595 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800596 " bytes, passed bitmap was " + bc);
597 }
598 break;
599 case ARGB_8888:
600 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700601 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800602 throw new RSIllegalArgumentException("Allocation kind is " +
603 mType.getElement().mKind + ", type " +
604 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700605 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800606 " bytes, passed bitmap was " + bc);
607 }
608 break;
609 case RGB_565:
610 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700611 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800612 throw new RSIllegalArgumentException("Allocation kind is " +
613 mType.getElement().mKind + ", type " +
614 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700615 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800616 " bytes, passed bitmap was " + bc);
617 }
618 break;
619 case ARGB_4444:
620 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700621 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800622 throw new RSIllegalArgumentException("Allocation kind is " +
623 mType.getElement().mKind + ", type " +
624 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700625 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800626 " bytes, passed bitmap was " + bc);
627 }
628 break;
629
630 }
Jason Sams4ef66502010-12-10 16:03:15 -0800631 }
632
Jason Samsfb9f82c2011-01-12 14:53:25 -0800633 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700634 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800635 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
636 }
637 }
638
Jason Sams3042d262013-11-25 18:28:33 -0800639 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700640 try {
641 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
642 mRS.validate();
643 if (mCurrentDimZ > 0) {
644 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
645 } else if (mCurrentDimY > 0) {
646 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
647 } else {
648 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
649 }
650 } finally {
651 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams3042d262013-11-25 18:28:33 -0800652 }
Jason Sams3042d262013-11-25 18:28:33 -0800653 }
654
655 /**
656 * Copy into this Allocation from an array. This method does not guarantee
657 * that the Allocation is compatible with the input buffer; it copies memory
658 * without reinterpretation.
659 *
660 * @param array The source data array
661 */
662 public void copyFromUnchecked(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700663 try {
664 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
665 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
666 java.lang.reflect.Array.getLength(array));
667 } finally {
668 Trace.traceEnd(RenderScript.TRACE_TAG);
669 }
Jason Sams3042d262013-11-25 18:28:33 -0800670 }
671
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700672 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700673 * Copy into this Allocation from an array. This method does not guarantee
674 * that the Allocation is compatible with the input buffer; it copies memory
675 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800676 *
677 * @param d the source data array
678 */
679 public void copyFromUnchecked(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800680 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800681 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700682
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700683 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700684 * Copy into this Allocation from an array. This method does not guarantee
685 * that the Allocation is compatible with the input buffer; it copies memory
686 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800687 *
688 * @param d the source data array
689 */
690 public void copyFromUnchecked(short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800691 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800692 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700693
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700694 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700695 * Copy into this Allocation from an array. This method does not guarantee
696 * that the Allocation is compatible with the input buffer; it copies memory
697 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800698 *
699 * @param d the source data array
700 */
701 public void copyFromUnchecked(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800702 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800703 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700704
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700705 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700706 * Copy into this Allocation from an array. This method does not guarantee
707 * that the Allocation is compatible with the input buffer; it copies memory
708 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800709 *
710 * @param d the source data array
711 */
712 public void copyFromUnchecked(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800713 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800714 }
715
Tim Murray6d7a53c2013-05-23 16:59:23 -0700716
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700717 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700718 * Copy into this Allocation from an array. This variant is type checked
719 * and will generate exceptions if the Allocation's {@link
Jason Sams3042d262013-11-25 18:28:33 -0800720 * android.renderscript.Element} does not match the array's
721 * primitive type.
722 *
Ying Wang16229812013-11-26 15:45:12 -0800723 * @param array The source data array
Jason Sams3042d262013-11-25 18:28:33 -0800724 */
725 public void copyFrom(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700726 try {
727 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
728 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
729 java.lang.reflect.Array.getLength(array));
730 } finally {
731 Trace.traceEnd(RenderScript.TRACE_TAG);
732 }
Jason Sams3042d262013-11-25 18:28:33 -0800733 }
734
735 /**
736 * Copy into this Allocation from an array. This variant is type checked
737 * and will generate exceptions if the Allocation's {@link
Tim Murrayc11e25c2013-04-09 11:01:01 -0700738 * android.renderscript.Element} is not a 32 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800739 *
740 * @param d the source data array
741 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800742 public void copyFrom(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800743 validateIsInt32();
744 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800745 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800746
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700747 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700748 * Copy into this Allocation from an array. This variant is type checked
749 * and will generate exceptions if the Allocation's {@link
750 * android.renderscript.Element} is not a 16 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800751 *
752 * @param d the source data array
753 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800754 public void copyFrom(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -0800755 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -0800756 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800757 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800758
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700759 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700760 * Copy into this Allocation from an array. This variant is type checked
761 * and will generate exceptions if the Allocation's {@link
762 * android.renderscript.Element} is not an 8 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800763 *
764 * @param d the source data array
765 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800766 public void copyFrom(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800767 validateIsInt8();
768 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800769 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800770
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700771 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700772 * Copy into this Allocation from an array. This variant is type checked
773 * and will generate exceptions if the Allocation's {@link
774 * android.renderscript.Element} is not a 32 bit float type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800775 *
776 * @param d the source data array
777 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800778 public void copyFrom(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800779 validateIsFloat32();
780 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800781 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800782
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700783 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700784 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
785 * height, width, and format of the bitmap must match the existing
786 * allocation.
787 *
788 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
789 * android.graphics.Bitmap} used to create the Allocation with {@link
790 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
791 * this will synchronize the Allocation with the latest data from the {@link
792 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
Jason Sams4fa3eed2011-01-19 15:44:38 -0800793 *
794 * @param b the source bitmap
795 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800796 public void copyFrom(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -0700797 try {
798 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
799 mRS.validate();
800 if (b.getConfig() == null) {
801 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
802 Canvas c = new Canvas(newBitmap);
803 c.drawBitmap(b, 0, 0, null);
804 copyFrom(newBitmap);
805 return;
806 }
807 validateBitmapSize(b);
808 validateBitmapFormat(b);
809 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
810 } finally {
811 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -0800812 }
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700813 }
814
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700815 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700816 * Copy an Allocation from an Allocation. The types of both allocations
Tim Murrayf671fb02012-10-03 13:50:05 -0700817 * must be identical.
818 *
819 * @param a the source allocation
820 */
821 public void copyFrom(Allocation a) {
Chris Craik06d29842015-06-02 17:19:24 -0700822 try {
823 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
824 mRS.validate();
825 if (!mType.equals(a.getType())) {
826 throw new RSIllegalArgumentException("Types of allocations must match.");
827 }
828 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
829 } finally {
830 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayf671fb02012-10-03 13:50:05 -0700831 }
Tim Murrayf671fb02012-10-03 13:50:05 -0700832 }
833
Tim Murrayf671fb02012-10-03 13:50:05 -0700834 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700835 * This is only intended to be used by auto-generated code reflected from
836 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800837 *
838 * @param xoff
839 * @param fp
840 */
Jason Sams21b41032011-01-16 15:05:41 -0800841 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800842 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700843 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700844 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700845 int data_length = fp.getPos();
Jason Samsa70f4162010-03-26 15:33:42 -0700846
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700847 int count = data_length / eSize;
848 if ((eSize * count) != data_length) {
849 throw new RSIllegalArgumentException("Field packer length " + data_length +
Jason Samsa70f4162010-03-26 15:33:42 -0700850 " not divisible by element size " + eSize + ".");
851 }
Jason Samsba862d12011-07-07 15:24:42 -0700852 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700853 }
854
Miao Wang45cec0a2015-03-04 16:40:21 -0800855
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700856 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700857 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800858 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800859 *
860 * @param xoff
861 * @param component_number
862 * @param fp
863 */
Jason Sams21b41032011-01-16 15:05:41 -0800864 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800865 setFromFieldPacker(xoff, 0, 0, component_number, fp);
866 }
867
868 /**
Miao Wangc8e237e2015-02-20 18:36:32 -0800869 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800870 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -0800871 *
872 * @param xoff
873 * @param yoff
Miao Wangc8e237e2015-02-20 18:36:32 -0800874 * @param zoff
875 * @param component_number
876 * @param fp
877 */
878 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800879 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700880 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800881 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700882 }
883 if(xoff < 0) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800884 throw new RSIllegalArgumentException("Offset x must be >= 0.");
885 }
886 if(yoff < 0) {
887 throw new RSIllegalArgumentException("Offset y must be >= 0.");
888 }
889 if(zoff < 0) {
890 throw new RSIllegalArgumentException("Offset z must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700891 }
892
893 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700894 int data_length = fp.getPos();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700895 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800896 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700897
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700898 if (data_length != eSize) {
899 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700900 " does not match component size " + eSize + ".");
901 }
902
Miao Wangc8e237e2015-02-20 18:36:32 -0800903 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
904 component_number, data, data_length);
Jason Samsa70f4162010-03-26 15:33:42 -0700905 }
906
Miao Wang87e908d2015-03-02 15:15:15 -0800907 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
Jason Sams771bebb2009-12-07 12:40:12 -0800908 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700909 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800910 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700911 }
912 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800913 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700914 }
Jason Samsba862d12011-07-07 15:24:42 -0700915 if((off + count) > mCurrentCount) {
916 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700917 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700918 }
Miao Wang87e908d2015-03-02 15:15:15 -0800919 if(usePadding) {
920 if(len < dataSize / 4 * 3) {
921 throw new RSIllegalArgumentException("Array too small for allocation type.");
922 }
923 } else {
924 if(len < dataSize) {
925 throw new RSIllegalArgumentException("Array too small for allocation type.");
926 }
Jason Sams768bc022009-09-21 19:41:04 -0700927 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700928 }
929
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700930 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700931 * Generate a mipmap chain. This is only valid if the Type of the Allocation
932 * includes mipmaps.
Jason Samsf7086092011-01-12 13:28:37 -0800933 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700934 * <p>This function will generate a complete set of mipmaps from the top
935 * level LOD and place them into the script memory space.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800936 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700937 * <p>If the Allocation is also using other memory spaces, a call to {@link
938 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800939 */
940 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700941 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800942 }
943
Jason Sams3042d262013-11-25 18:28:33 -0800944 private void copy1DRangeFromUnchecked(int off, int count, Object array,
945 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700946 try {
947 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
948 final int dataSize = mType.mElement.getBytesSize() * count;
949 // AutoPadding for Vec3 Element
950 boolean usePadding = false;
951 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
952 usePadding = true;
953 }
954 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
955 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
956 mType.mElement.mType.mSize, usePadding);
957 } finally {
958 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -0800959 }
Jason Sams3042d262013-11-25 18:28:33 -0800960 }
961
962 /**
963 * Copy an array into part of this Allocation. This method does not
964 * guarantee that the Allocation is compatible with the input buffer.
965 *
966 * @param off The offset of the first element to be copied.
967 * @param count The number of elements to be copied.
968 * @param array The source data array
969 */
970 public void copy1DRangeFromUnchecked(int off, int count, Object array) {
971 copy1DRangeFromUnchecked(off, count, array,
972 validateObjectIsPrimitiveArray(array, false),
973 java.lang.reflect.Array.getLength(array));
974 }
975
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700976 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700977 * Copy an array into part of this Allocation. This method does not
978 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800979 *
980 * @param off The offset of the first element to be copied.
981 * @param count The number of elements to be copied.
982 * @param d the source data array
983 */
984 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800985 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700986 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700987
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700988 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700989 * Copy an array into part of this Allocation. This method does not
990 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800991 *
992 * @param off The offset of the first element to be copied.
993 * @param count The number of elements to be copied.
994 * @param d the source data array
995 */
996 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800997 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700998 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700999
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001000 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001001 * Copy an array into part of this Allocation. This method does not
1002 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001003 *
1004 * @param off The offset of the first element to be copied.
1005 * @param count The number of elements to be copied.
1006 * @param d the source data array
1007 */
1008 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001009 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001010 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001011
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001012 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001013 * Copy an array into part of this Allocation. This method does not
1014 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001015 *
1016 * @param off The offset of the first element to be copied.
1017 * @param count The number of elements to be copied.
1018 * @param d the source data array
1019 */
1020 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001021 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1022 }
1023
1024
1025 /**
1026 * Copy an array into part of this Allocation. This variant is type checked
1027 * and will generate exceptions if the Allocation type does not
1028 * match the component type of the array passed in.
1029 *
1030 * @param off The offset of the first element to be copied.
1031 * @param count The number of elements to be copied.
1032 * @param array The source data array.
1033 */
1034 public void copy1DRangeFrom(int off, int count, Object array) {
1035 copy1DRangeFromUnchecked(off, count, array,
1036 validateObjectIsPrimitiveArray(array, true),
1037 java.lang.reflect.Array.getLength(array));
Jason Samsb8c5a842009-07-31 20:40:47 -07001038 }
1039
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001040 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001041 * Copy an array into part of this Allocation. This variant is type checked
1042 * and will generate exceptions if the Allocation type is not a 32 bit
1043 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001044 *
1045 * @param off The offset of the first element to be copied.
1046 * @param count The number of elements to be copied.
1047 * @param d the source data array
1048 */
Jason Samsb97b2512011-01-16 15:04:08 -08001049 public void copy1DRangeFrom(int off, int count, int[] d) {
1050 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001051 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001052 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001053
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001054 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001055 * Copy an array into part of this Allocation. This variant is type checked
1056 * and will generate exceptions if the Allocation type is not a 16 bit
1057 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001058 *
1059 * @param off The offset of the first element to be copied.
1060 * @param count The number of elements to be copied.
1061 * @param d the source data array
1062 */
Jason Samsb97b2512011-01-16 15:04:08 -08001063 public void copy1DRangeFrom(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001064 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001065 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001066 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001067
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001068 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001069 * Copy an array into part of this Allocation. This variant is type checked
1070 * and will generate exceptions if the Allocation type is not an 8 bit
1071 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001072 *
1073 * @param off The offset of the first element to be copied.
1074 * @param count The number of elements to be copied.
1075 * @param d the source data array
1076 */
Jason Samsb97b2512011-01-16 15:04:08 -08001077 public void copy1DRangeFrom(int off, int count, byte[] d) {
1078 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001079 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001080 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001081
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001082 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001083 * Copy an array into part of this Allocation. This variant is type checked
1084 * and will generate exceptions if the Allocation type is not a 32 bit float
1085 * type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001086 *
1087 * @param off The offset of the first element to be copied.
1088 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001089 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001090 */
Jason Samsb97b2512011-01-16 15:04:08 -08001091 public void copy1DRangeFrom(int off, int count, float[] d) {
1092 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001093 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001094 }
Jason Sams3042d262013-11-25 18:28:33 -08001095
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001096 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001097 * Copy part of an Allocation into this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001098 *
1099 * @param off The offset of the first element to be copied.
1100 * @param count The number of elements to be copied.
1101 * @param data the source data allocation.
1102 * @param dataOff off The offset of the first element in data to
1103 * be copied.
1104 */
1105 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Tim Murray6d7a53c2013-05-23 16:59:23 -07001106 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
Jason Sams48fe5342011-07-08 13:52:30 -07001107 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001108 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -07001109 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001110 data.mSelectedLOD, data.mSelectedFace.mID);
Chris Craik5c705d62015-06-01 10:39:36 -07001111 Trace.traceEnd(RenderScript.TRACE_TAG);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001112 }
1113
Jason Samsfb9f82c2011-01-12 14:53:25 -08001114 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -07001115 if (mAdaptedAllocation != null) {
1116
1117 } else {
1118
1119 if (xoff < 0 || yoff < 0) {
1120 throw new RSIllegalArgumentException("Offset cannot be negative.");
1121 }
1122 if (h < 0 || w < 0) {
1123 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1124 }
1125 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1126 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1127 }
Jason Samsfb9f82c2011-01-12 14:53:25 -08001128 }
1129 }
Jason Sams768bc022009-09-21 19:41:04 -07001130
Jason Sams3042d262013-11-25 18:28:33 -08001131 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1132 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001133 try {
1134 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
1135 mRS.validate();
1136 validate2DRange(xoff, yoff, w, h);
1137 final int dataSize = mType.mElement.getBytesSize() * w * h;
1138 // AutoPadding for Vec3 Element
1139 boolean usePadding = false;
1140 int sizeBytes = arrayLen * dt.mSize;
1141 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1142 if (dataSize / 4 * 3 > sizeBytes) {
1143 throw new RSIllegalArgumentException("Array too small for allocation type.");
1144 }
1145 usePadding = true;
1146 sizeBytes = dataSize;
1147 } else {
1148 if (dataSize > sizeBytes) {
1149 throw new RSIllegalArgumentException("Array too small for allocation type.");
1150 }
Miao Wang87e908d2015-03-02 15:15:15 -08001151 }
Chris Craik06d29842015-06-02 17:19:24 -07001152 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1153 array, sizeBytes, dt,
1154 mType.mElement.mType.mSize, usePadding);
1155 } finally {
1156 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001157 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001158 }
1159
Jason Sams3042d262013-11-25 18:28:33 -08001160 /**
1161 * Copy from an array into a rectangular region in this Allocation. The
1162 * array is assumed to be tightly packed.
1163 *
1164 * @param xoff X offset of the region to update in this Allocation
1165 * @param yoff Y offset of the region to update in this Allocation
1166 * @param w Width of the region to update
1167 * @param h Height of the region to update
Ying Wang16229812013-11-26 15:45:12 -08001168 * @param array Data to be placed into the Allocation
Jason Sams3042d262013-11-25 18:28:33 -08001169 */
1170 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001171 try {
1172 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1173 copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1174 validateObjectIsPrimitiveArray(array, true),
1175 java.lang.reflect.Array.getLength(array));
1176 } finally {
1177 Trace.traceEnd(RenderScript.TRACE_TAG);
1178 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001179 }
1180
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001181 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001182 * Copy from an array into a rectangular region in this Allocation. The
1183 * array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -08001184 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001185 * @param xoff X offset of the region to update in this Allocation
1186 * @param yoff Y offset of the region to update in this Allocation
1187 * @param w Width of the region to update
1188 * @param h Height of the region to update
1189 * @param data to be placed into the Allocation
Jason Samsf7086092011-01-12 13:28:37 -08001190 */
1191 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001192 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001193 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1194 Element.DataType.SIGNED_8, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001195 }
1196
Tim Murrayc11e25c2013-04-09 11:01:01 -07001197 /**
1198 * Copy from an array into a rectangular region in this Allocation. The
1199 * array is assumed to be tightly packed.
1200 *
1201 * @param xoff X offset of the region to update in this Allocation
1202 * @param yoff Y offset of the region to update in this Allocation
1203 * @param w Width of the region to update
1204 * @param h Height of the region to update
1205 * @param data to be placed into the Allocation
1206 */
Jason Samsf7086092011-01-12 13:28:37 -08001207 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001208 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001209 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1210 Element.DataType.SIGNED_16, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001211 }
1212
Tim Murrayc11e25c2013-04-09 11:01:01 -07001213 /**
1214 * Copy from an array into a rectangular region in this Allocation. The
1215 * array is assumed to be tightly packed.
1216 *
1217 * @param xoff X offset of the region to update in this Allocation
1218 * @param yoff Y offset of the region to update in this Allocation
1219 * @param w Width of the region to update
1220 * @param h Height of the region to update
1221 * @param data to be placed into the Allocation
1222 */
Jason Samsf7086092011-01-12 13:28:37 -08001223 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001224 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001225 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1226 Element.DataType.SIGNED_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001227 }
1228
Tim Murrayc11e25c2013-04-09 11:01:01 -07001229 /**
1230 * Copy from an array into a rectangular region in this Allocation. The
1231 * array is assumed to be tightly packed.
1232 *
1233 * @param xoff X offset of the region to update in this Allocation
1234 * @param yoff Y offset of the region to update in this Allocation
1235 * @param w Width of the region to update
1236 * @param h Height of the region to update
1237 * @param data to be placed into the Allocation
1238 */
Jason Samsf7086092011-01-12 13:28:37 -08001239 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001240 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001241 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1242 Element.DataType.FLOAT_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001243 }
1244
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001245 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001246 * Copy a rectangular region from an Allocation into a rectangular region in
1247 * this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001248 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001249 * @param xoff X offset of the region in this Allocation
1250 * @param yoff Y offset of the region in this Allocation
1251 * @param w Width of the region to update.
1252 * @param h Height of the region to update.
1253 * @param data source Allocation.
1254 * @param dataXoff X offset in source Allocation
1255 * @param dataYoff Y offset in source Allocation
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001256 */
1257 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1258 Allocation data, int dataXoff, int dataYoff) {
Chris Craik06d29842015-06-02 17:19:24 -07001259 try {
1260 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1261 mRS.validate();
1262 validate2DRange(xoff, yoff, w, h);
1263 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1264 mSelectedLOD, mSelectedFace.mID,
1265 w, h, data.getID(mRS), dataXoff, dataYoff,
1266 data.mSelectedLOD, data.mSelectedFace.mID);
1267 } finally {
1268 Trace.traceEnd(RenderScript.TRACE_TAG);
1269 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001270 }
1271
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001272 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001273 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
1274 * and width of the update will use the height and width of the {@link
1275 * android.graphics.Bitmap}.
Jason Samsf7086092011-01-12 13:28:37 -08001276 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001277 * @param xoff X offset of the region to update in this Allocation
1278 * @param yoff Y offset of the region to update in this Allocation
1279 * @param data the Bitmap to be copied
Jason Samsf7086092011-01-12 13:28:37 -08001280 */
1281 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Chris Craik5c705d62015-06-01 10:39:36 -07001282 try {
1283 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1284 mRS.validate();
1285 if (data.getConfig() == null) {
1286 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1287 Canvas c = new Canvas(newBitmap);
1288 c.drawBitmap(data, 0, 0, null);
1289 copy2DRangeFrom(xoff, yoff, newBitmap);
1290 return;
1291 }
1292 validateBitmapFormat(data);
1293 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1294 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1295 } finally {
1296 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -08001297 }
Jason Samsfa445b92011-01-07 17:00:07 -08001298 }
1299
Jason Samsb05d6892013-04-09 15:59:24 -07001300 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1301 if (mAdaptedAllocation != null) {
1302
1303 } else {
1304
1305 if (xoff < 0 || yoff < 0 || zoff < 0) {
1306 throw new RSIllegalArgumentException("Offset cannot be negative.");
1307 }
1308 if (h < 0 || w < 0 || d < 0) {
1309 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1310 }
1311 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1312 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1313 }
1314 }
1315 }
1316
1317 /**
Miao Wang258db502015-03-03 14:05:36 -08001318 * Copy a rectangular region from the array into the allocation.
1319 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001320 *
Miao Wang258db502015-03-03 14:05:36 -08001321 * The data type of the array is not required to be the same as
1322 * the element data type.
Jason Samsb05d6892013-04-09 15:59:24 -07001323 */
Jason Sams3042d262013-11-25 18:28:33 -08001324 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1325 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001326 try {
1327 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
1328 mRS.validate();
1329 validate3DRange(xoff, yoff, zoff, w, h, d);
1330 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1331 // AutoPadding for Vec3 Element
1332 boolean usePadding = false;
1333 int sizeBytes = arrayLen * dt.mSize;
1334 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1335 if (dataSize / 4 * 3 > sizeBytes) {
1336 throw new RSIllegalArgumentException("Array too small for allocation type.");
1337 }
1338 usePadding = true;
1339 sizeBytes = dataSize;
1340 } else {
1341 if (dataSize > sizeBytes) {
1342 throw new RSIllegalArgumentException("Array too small for allocation type.");
1343 }
Miao Wang87e908d2015-03-02 15:15:15 -08001344 }
Chris Craik06d29842015-06-02 17:19:24 -07001345 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1346 array, sizeBytes, dt,
1347 mType.mElement.mType.mSize, usePadding);
1348 } finally {
1349 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001350 }
Jason Samsb05d6892013-04-09 15:59:24 -07001351 }
1352
1353 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001354 * Copy a rectangular region from the array into the allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001355 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001356 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001357 * @param xoff X offset of the region to update in this Allocation
1358 * @param yoff Y offset of the region to update in this Allocation
1359 * @param zoff Z offset of the region to update in this Allocation
1360 * @param w Width of the region to update
1361 * @param h Height of the region to update
1362 * @param d Depth of the region to update
Miao Wang87e908d2015-03-02 15:15:15 -08001363 * @param array to be placed into the allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001364 */
Jason Sams3042d262013-11-25 18:28:33 -08001365 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001366 try {
1367 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
1368 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1369 validateObjectIsPrimitiveArray(array, true),
1370 java.lang.reflect.Array.getLength(array));
1371 } finally {
1372 Trace.traceEnd(RenderScript.TRACE_TAG);
1373 }
Jason Samsb05d6892013-04-09 15:59:24 -07001374 }
1375
1376 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001377 * Copy a rectangular region into the allocation from another
1378 * allocation.
1379 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001380 * @param xoff X offset of the region to update in this Allocation
1381 * @param yoff Y offset of the region to update in this Allocation
1382 * @param zoff Z offset of the region to update in this Allocation
1383 * @param w Width of the region to update.
1384 * @param h Height of the region to update.
1385 * @param d Depth of the region to update.
Jason Samsb05d6892013-04-09 15:59:24 -07001386 * @param data source allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001387 * @param dataXoff X offset of the region in the source Allocation
1388 * @param dataYoff Y offset of the region in the source Allocation
1389 * @param dataZoff Z offset of the region in the source Allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001390 */
1391 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1392 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1393 mRS.validate();
1394 validate3DRange(xoff, yoff, zoff, w, h, d);
1395 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1396 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1397 data.mSelectedLOD);
1398 }
1399
Jason Samsfa445b92011-01-07 17:00:07 -08001400
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001401 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001402 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
1403 * bitmap must match the dimensions of the Allocation.
Jason Sams48fe5342011-07-08 13:52:30 -07001404 *
1405 * @param b The bitmap to be set from the Allocation.
1406 */
Jason Samsfa445b92011-01-07 17:00:07 -08001407 public void copyTo(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -07001408 try {
1409 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1410 mRS.validate();
1411 validateBitmapFormat(b);
1412 validateBitmapSize(b);
1413 mRS.nAllocationCopyToBitmap(getID(mRS), b);
1414 } finally {
1415 Trace.traceEnd(RenderScript.TRACE_TAG);
1416 }
Jason Samsfa445b92011-01-07 17:00:07 -08001417 }
1418
Jason Sams3042d262013-11-25 18:28:33 -08001419 private void copyTo(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001420 try {
1421 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1422 mRS.validate();
1423 boolean usePadding = false;
1424 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1425 usePadding = true;
Miao Wangd9b63282015-04-03 09:15:39 -07001426 }
Chris Craik06d29842015-06-02 17:19:24 -07001427 if (usePadding) {
1428 if (dt.mSize * arrayLen < mSize / 4 * 3) {
1429 throw new RSIllegalArgumentException(
1430 "Size of output array cannot be smaller than size of allocation.");
1431 }
1432 } else {
1433 if (dt.mSize * arrayLen < mSize) {
1434 throw new RSIllegalArgumentException(
1435 "Size of output array cannot be smaller than size of allocation.");
1436 }
Miao Wangd9b63282015-04-03 09:15:39 -07001437 }
Chris Craik06d29842015-06-02 17:19:24 -07001438 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1439 } finally {
1440 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wangd9b63282015-04-03 09:15:39 -07001441 }
Jason Sams3042d262013-11-25 18:28:33 -08001442 }
1443
1444 /**
1445 * Copy from the Allocation into an array. The array must be at
1446 * least as large as the Allocation. The
1447 * {@link android.renderscript.Element} must match the component
1448 * type of the array passed in.
1449 *
1450 * @param array The array to be set from the Allocation.
1451 */
1452 public void copyTo(Object array) {
1453 copyTo(array, validateObjectIsPrimitiveArray(array, true),
1454 java.lang.reflect.Array.getLength(array));
1455 }
1456
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001457 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001458 * Copy from the Allocation into a byte array. The array must be at least
1459 * as large as the Allocation. The allocation must be of an 8 bit integer
1460 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001461 *
1462 * @param d The array to be set from the Allocation.
1463 */
Jason Samsfa445b92011-01-07 17:00:07 -08001464 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001465 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001466 copyTo(d, Element.DataType.SIGNED_8, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001467 }
1468
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001469 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001470 * Copy from the Allocation into a short array. The array must be at least
1471 * as large as the Allocation. The allocation must be of an 16 bit integer
1472 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001473 *
1474 * @param d The array to be set from the Allocation.
1475 */
Jason Samsfa445b92011-01-07 17:00:07 -08001476 public void copyTo(short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001477 validateIsInt16OrFloat16();
Jason Sams3042d262013-11-25 18:28:33 -08001478 copyTo(d, Element.DataType.SIGNED_16, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001479 }
1480
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001481 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001482 * Copy from the Allocation into a int array. The array must be at least as
1483 * large as the Allocation. The allocation must be of an 32 bit integer
1484 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001485 *
1486 * @param d The array to be set from the Allocation.
1487 */
Jason Samsfa445b92011-01-07 17:00:07 -08001488 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001489 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001490 copyTo(d, Element.DataType.SIGNED_32, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001491 }
1492
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001493 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001494 * Copy from the Allocation into a float array. The array must be at least
1495 * as large as the Allocation. The allocation must be of an 32 bit float
1496 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001497 *
1498 * @param d The array to be set from the Allocation.
1499 */
Jason Samsfa445b92011-01-07 17:00:07 -08001500 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001501 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001502 copyTo(d, Element.DataType.FLOAT_32, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001503 }
1504
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001505 /**
Miao Wang3c613272015-05-11 11:41:55 -07001506 * @hide
1507 *
Miao Wang45cec0a2015-03-04 16:40:21 -08001508 * This is only intended to be used by auto-generated code reflected from
1509 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -08001510 *
1511 * @param xoff
1512 * @param yoff
1513 * @param zoff
1514 * @param component_number
Miao Wang258db502015-03-03 14:05:36 -08001515 * @param fp
Miao Wangc8e237e2015-02-20 18:36:32 -08001516 */
Miao Wang45cec0a2015-03-04 16:40:21 -08001517 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -08001518 mRS.validate();
1519 if (component_number >= mType.mElement.mElements.length) {
1520 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1521 }
1522 if(xoff < 0) {
1523 throw new RSIllegalArgumentException("Offset x must be >= 0.");
1524 }
1525 if(yoff < 0) {
1526 throw new RSIllegalArgumentException("Offset y must be >= 0.");
1527 }
1528 if(zoff < 0) {
1529 throw new RSIllegalArgumentException("Offset z must be >= 0.");
1530 }
1531
Miao Wang45cec0a2015-03-04 16:40:21 -08001532 final byte[] data = fp.getData();
Miao Wangbfa5e652015-05-04 15:29:25 -07001533 int data_length = data.length;
Miao Wangc8e237e2015-02-20 18:36:32 -08001534 int eSize = mType.mElement.mElements[component_number].getBytesSize();
1535 eSize *= mType.mElement.mArraySizes[component_number];
1536
Miao Wang45cec0a2015-03-04 16:40:21 -08001537 if (data_length != eSize) {
1538 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1539 " does not match component size " + eSize + ".");
Miao Wangc8e237e2015-02-20 18:36:32 -08001540 }
1541
1542 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
Miao Wang45cec0a2015-03-04 16:40:21 -08001543 component_number, data, data_length);
Miao Wangc8e237e2015-02-20 18:36:32 -08001544 }
1545 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001546 * Resize a 1D allocation. The contents of the allocation are preserved.
1547 * If new elements are allocated objects are created with null contents and
1548 * the new region is otherwise undefined.
Jason Samsf7086092011-01-12 13:28:37 -08001549 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001550 * <p>If the new region is smaller the references of any objects outside the
1551 * new region will be released.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001552 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001553 * <p>A new type will be created with the new dimension.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001554 *
1555 * @param dimX The new size of the allocation.
Jason Samsb05d6892013-04-09 15:59:24 -07001556 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001557 * @deprecated RenderScript objects should be immutable once created. The
Tim Murraycd38b762014-08-13 13:20:25 -07001558 * replacement is to create a new allocation and copy the contents. This
1559 * function will throw an exception if API 21 or higher is used.
Jason Samsf7086092011-01-12 13:28:37 -08001560 */
Jason Sams31a7e422010-10-26 13:09:17 -07001561 public synchronized void resize(int dimX) {
Tim Murraycd38b762014-08-13 13:20:25 -07001562 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) {
1563 throw new RSRuntimeException("Resize is not allowed in API 21+.");
1564 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001565 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001566 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001567 }
Jason Samse07694b2012-04-03 15:36:36 -07001568 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001569 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001570
Tim Murray460a0492013-11-19 12:45:54 -08001571 long typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001572 mType = new Type(typeID, mRS);
1573 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001574 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001575 }
1576
Miao Wangc8e237e2015-02-20 18:36:32 -08001577 private void copy1DRangeToUnchecked(int off, int count, Object array,
1578 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001579 try {
1580 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked");
1581 final int dataSize = mType.mElement.getBytesSize() * count;
1582 // AutoPadding for Vec3 Element
1583 boolean usePadding = false;
1584 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1585 usePadding = true;
1586 }
1587 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1588 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1589 mType.mElement.mType.mSize, usePadding);
1590 } finally {
1591 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001592 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001593 }
1594
1595 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001596 * Copy part of this Allocation into an array. This method does not
1597 * guarantee that the Allocation is compatible with the input buffer.
1598 *
1599 * @param off The offset of the first element to be copied.
1600 * @param count The number of elements to be copied.
1601 * @param array The dest data array
1602 */
1603 public void copy1DRangeToUnchecked(int off, int count, Object array) {
1604 copy1DRangeToUnchecked(off, count, array,
1605 validateObjectIsPrimitiveArray(array, false),
1606 java.lang.reflect.Array.getLength(array));
1607 }
1608
1609 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001610 * Copy part of this Allocation into an array. This method does not
1611 * guarantee that the Allocation is compatible with the input buffer.
1612 *
1613 * @param off The offset of the first element to be copied.
1614 * @param count The number of elements to be copied.
1615 * @param d the source data array
1616 */
1617 public void copy1DRangeToUnchecked(int off, int count, int[] d) {
1618 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1619 }
1620
1621 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001622 * Copy part of this Allocation into an array. This method does not
1623 * guarantee that the Allocation is compatible with the input buffer.
1624 *
1625 * @param off The offset of the first element to be copied.
1626 * @param count The number of elements to be copied.
1627 * @param d the source data array
1628 */
1629 public void copy1DRangeToUnchecked(int off, int count, short[] d) {
1630 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1631 }
1632
1633 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001634 * Copy part of this Allocation into an array. This method does not
1635 * guarantee that the Allocation is compatible with the input buffer.
1636 *
1637 * @param off The offset of the first element to be copied.
1638 * @param count The number of elements to be copied.
1639 * @param d the source data array
1640 */
1641 public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
1642 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1643 }
1644
1645 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001646 * Copy part of this Allocation into an array. This method does not
1647 * guarantee that the Allocation is compatible with the input buffer.
1648 *
1649 * @param off The offset of the first element to be copied.
1650 * @param count The number of elements to be copied.
1651 * @param d the source data array
1652 */
1653 public void copy1DRangeToUnchecked(int off, int count, float[] d) {
1654 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1655 }
1656
1657
1658 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001659 * Copy part of this Allocation into an array. This method does not
1660 * and will generate exceptions if the Allocation type does not
1661 * match the component type of the array passed in.
1662 *
1663 * @param off The offset of the first element to be copied.
1664 * @param count The number of elements to be copied.
1665 * @param array The source data array.
1666 */
1667 public void copy1DRangeTo(int off, int count, Object array) {
1668 copy1DRangeToUnchecked(off, count, array,
1669 validateObjectIsPrimitiveArray(array, true),
1670 java.lang.reflect.Array.getLength(array));
1671 }
1672
1673 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001674 * Copy part of this Allocation into an array. This method does not
1675 * and will generate exceptions if the Allocation type is not a 32 bit
1676 * integer type.
1677 *
1678 * @param off The offset of the first element to be copied.
1679 * @param count The number of elements to be copied.
1680 * @param d the source data array
1681 */
1682 public void copy1DRangeTo(int off, int count, int[] d) {
1683 validateIsInt32();
1684 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1685 }
1686
1687 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001688 * Copy part of this Allocation into an array. This method does not
1689 * and will generate exceptions if the Allocation type is not a 16 bit
1690 * integer type.
1691 *
1692 * @param off The offset of the first element to be copied.
1693 * @param count The number of elements to be copied.
1694 * @param d the source data array
1695 */
1696 public void copy1DRangeTo(int off, int count, short[] d) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001697 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001698 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1699 }
1700
1701 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001702 * Copy part of this Allocation into an array. This method does not
1703 * and will generate exceptions if the Allocation type is not an 8 bit
1704 * integer type.
1705 *
1706 * @param off The offset of the first element to be copied.
1707 * @param count The number of elements to be copied.
1708 * @param d the source data array
1709 */
1710 public void copy1DRangeTo(int off, int count, byte[] d) {
1711 validateIsInt8();
1712 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1713 }
1714
1715 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001716 * Copy part of this Allocation into an array. This method does not
1717 * and will generate exceptions if the Allocation type is not a 32 bit float
1718 * type.
1719 *
1720 * @param off The offset of the first element to be copied.
1721 * @param count The number of elements to be copied.
1722 * @param d the source data array.
1723 */
1724 public void copy1DRangeTo(int off, int count, float[] d) {
1725 validateIsFloat32();
1726 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1727 }
1728
1729
1730 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
1731 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001732 try {
1733 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked");
1734 mRS.validate();
1735 validate2DRange(xoff, yoff, w, h);
1736 final int dataSize = mType.mElement.getBytesSize() * w * h;
1737 // AutoPadding for Vec3 Element
1738 boolean usePadding = false;
1739 int sizeBytes = arrayLen * dt.mSize;
1740 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1741 if (dataSize / 4 * 3 > sizeBytes) {
1742 throw new RSIllegalArgumentException("Array too small for allocation type.");
1743 }
1744 usePadding = true;
1745 sizeBytes = dataSize;
1746 } else {
1747 if (dataSize > sizeBytes) {
1748 throw new RSIllegalArgumentException("Array too small for allocation type.");
1749 }
Miao Wang87e908d2015-03-02 15:15:15 -08001750 }
Chris Craik06d29842015-06-02 17:19:24 -07001751 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1752 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1753 } finally {
1754 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001755 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001756 }
1757
1758 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001759 * Copy from a rectangular region in this Allocation into an array.
1760 *
1761 * @param xoff X offset of the region to copy in this Allocation
1762 * @param yoff Y offset of the region to copy in this Allocation
1763 * @param w Width of the region to copy
1764 * @param h Height of the region to copy
1765 * @param array Dest Array to be copied into
1766 */
1767 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
1768 copy2DRangeToUnchecked(xoff, yoff, w, h, array,
1769 validateObjectIsPrimitiveArray(array, true),
1770 java.lang.reflect.Array.getLength(array));
1771 }
1772
1773 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001774 * Copy from a rectangular region in this Allocation into an array.
1775 *
1776 * @param xoff X offset of the region to copy in this Allocation
1777 * @param yoff Y offset of the region to copy in this Allocation
1778 * @param w Width of the region to copy
1779 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001780 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001781 */
1782 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
1783 validateIsInt8();
1784 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1785 Element.DataType.SIGNED_8, data.length);
1786 }
1787
1788 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001789 * Copy from a rectangular region in this Allocation into an array.
1790 *
1791 * @param xoff X offset of the region to copy in this Allocation
1792 * @param yoff Y offset of the region to copy in this Allocation
1793 * @param w Width of the region to copy
1794 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001795 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001796 */
1797 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
Pirama Arumuga Nainarf51bb352016-02-26 09:16:17 -08001798 validateIsInt16OrFloat16();
Miao Wangc8e237e2015-02-20 18:36:32 -08001799 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1800 Element.DataType.SIGNED_16, data.length);
1801 }
1802
1803 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001804 * Copy from a rectangular region in this Allocation into an array.
1805 *
1806 * @param xoff X offset of the region to copy in this Allocation
1807 * @param yoff Y offset of the region to copy in this Allocation
1808 * @param w Width of the region to copy
1809 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001810 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001811 */
1812 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
1813 validateIsInt32();
1814 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1815 Element.DataType.SIGNED_32, data.length);
1816 }
1817
1818 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001819 * Copy from a rectangular region in this Allocation into an array.
1820 *
1821 * @param xoff X offset of the region to copy in this Allocation
1822 * @param yoff Y offset of the region to copy in this Allocation
1823 * @param w Width of the region to copy
1824 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001825 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001826 */
1827 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
1828 validateIsFloat32();
1829 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1830 Element.DataType.FLOAT_32, data.length);
1831 }
1832
1833
1834 /**
Miao Wang258db502015-03-03 14:05:36 -08001835 * Copy from a rectangular region in this Allocation into an array.
1836 * The array is assumed to be tightly packed.
Miao Wangc8e237e2015-02-20 18:36:32 -08001837 *
Miao Wang258db502015-03-03 14:05:36 -08001838 * The data type of the array is not required to be the same as
1839 * the element data type.
Miao Wangc8e237e2015-02-20 18:36:32 -08001840 */
1841 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1842 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001843 try {
1844 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked");
1845 mRS.validate();
1846 validate3DRange(xoff, yoff, zoff, w, h, d);
1847 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1848 // AutoPadding for Vec3 Element
1849 boolean usePadding = false;
1850 int sizeBytes = arrayLen * dt.mSize;
1851 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1852 if (dataSize / 4 * 3 > sizeBytes) {
1853 throw new RSIllegalArgumentException("Array too small for allocation type.");
1854 }
1855 usePadding = true;
1856 sizeBytes = dataSize;
1857 } else {
1858 if (dataSize > sizeBytes) {
1859 throw new RSIllegalArgumentException("Array too small for allocation type.");
1860 }
Miao Wang87e908d2015-03-02 15:15:15 -08001861 }
Chris Craik06d29842015-06-02 17:19:24 -07001862 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1863 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1864 } finally {
1865 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001866 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001867 }
1868
Miao Wang258db502015-03-03 14:05:36 -08001869 /*
Miao Wangc8e237e2015-02-20 18:36:32 -08001870 * Copy from a rectangular region in this Allocation into an array.
1871 *
1872 * @param xoff X offset of the region to copy in this Allocation
1873 * @param yoff Y offset of the region to copy in this Allocation
1874 * @param zoff Z offset of the region to copy in this Allocation
1875 * @param w Width of the region to copy
1876 * @param h Height of the region to copy
1877 * @param d Depth of the region to copy
1878 * @param array Dest Array to be copied into
1879 */
1880 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1881 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
1882 validateObjectIsPrimitiveArray(array, true),
1883 java.lang.reflect.Array.getLength(array));
1884 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001885
1886 // creation
1887
Jason Sams49a05d72010-12-29 14:31:29 -08001888 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001889 static {
1890 mBitmapOptions.inScaled = false;
1891 }
1892
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001893 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001894 * Creates a new Allocation with the given {@link
1895 * android.renderscript.Type}, mipmap flag, and usage flags.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001896 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001897 * @param type RenderScript type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001898 * @param mips specifies desired mipmap behaviour for the
1899 * allocation
Tim Murrayc11e25c2013-04-09 11:01:01 -07001900 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001901 * utilized
1902 */
1903 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001904 try {
1905 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
1906 rs.validate();
1907 if (type.getID(rs) == 0) {
1908 throw new RSInvalidStateException("Bad Type");
1909 }
1910 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
1911 if (id == 0) {
1912 throw new RSRuntimeException("Allocation creation failed.");
1913 }
Miao Wang8c150922015-10-26 17:44:10 -07001914 return new Allocation(id, rs, type, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07001915 } finally {
1916 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams1bada8c2009-08-09 17:01:55 -07001917 }
Jason Sams857d0c72011-11-23 15:02:15 -08001918 }
1919
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001920 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001921 * Creates an Allocation with the size specified by the type and no mipmaps
1922 * generated by default
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001923 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001924 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001925 * @param type renderscript type describing data layout
1926 * @param usage bit field specifying how the allocation is
1927 * utilized
1928 *
1929 * @return allocation
1930 */
Jason Samse5d37122010-12-16 00:33:33 -08001931 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1932 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1933 }
1934
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001935 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001936 * Creates an Allocation for use by scripts with a given {@link
1937 * android.renderscript.Type} and no mipmaps
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001938 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001939 * @param rs Context to which the Allocation will belong.
1940 * @param type RenderScript Type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001941 *
1942 * @return allocation
1943 */
Jason Sams5476b452010-12-08 16:14:36 -08001944 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001945 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001946 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001947
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001948 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001949 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001950 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001951 * @param rs Context to which the Allocation will belong.
1952 * @param e Element to use in the Allocation
1953 * @param count the number of Elements in the Allocation
1954 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001955 * utilized
1956 *
1957 * @return allocation
1958 */
Jason Sams5476b452010-12-08 16:14:36 -08001959 static public Allocation createSized(RenderScript rs, Element e,
1960 int count, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001961 try {
1962 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
1963 rs.validate();
1964 Type.Builder b = new Type.Builder(rs, e);
1965 b.setX(count);
1966 Type t = b.create();
Jason Sams768bc022009-09-21 19:41:04 -07001967
Chris Craik06d29842015-06-02 17:19:24 -07001968 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
1969 if (id == 0) {
1970 throw new RSRuntimeException("Allocation creation failed.");
1971 }
Miao Wang8c150922015-10-26 17:44:10 -07001972 return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
Chris Craik06d29842015-06-02 17:19:24 -07001973 } finally {
1974 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsb8c5a842009-07-31 20:40:47 -07001975 }
Jason Sams5476b452010-12-08 16:14:36 -08001976 }
1977
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001978 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001979 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001980 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001981 * @param rs Context to which the Allocation will belong.
1982 * @param e Element to use in the Allocation
1983 * @param count the number of Elements in the Allocation
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001984 *
1985 * @return allocation
1986 */
Jason Sams5476b452010-12-08 16:14:36 -08001987 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001988 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001989 }
1990
Jason Sams49a05d72010-12-29 14:31:29 -08001991 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08001992 final Bitmap.Config bc = b.getConfig();
1993 if (bc == Bitmap.Config.ALPHA_8) {
1994 return Element.A_8(rs);
1995 }
1996 if (bc == Bitmap.Config.ARGB_4444) {
1997 return Element.RGBA_4444(rs);
1998 }
1999 if (bc == Bitmap.Config.ARGB_8888) {
2000 return Element.RGBA_8888(rs);
2001 }
2002 if (bc == Bitmap.Config.RGB_565) {
2003 return Element.RGB_565(rs);
2004 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08002005 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08002006 }
2007
Jason Sams49a05d72010-12-29 14:31:29 -08002008 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002009 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08002010 Element e = elementFromBitmap(rs, b);
2011 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002012 tb.setX(b.getWidth());
2013 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08002014 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08002015 return tb.create();
2016 }
2017
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002018 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002019 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002020 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002021 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002022 * @param b Bitmap source for the allocation data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002023 * @param mips specifies desired mipmap behaviour for the
2024 * allocation
2025 * @param usage bit field specifying how the allocation is
2026 * utilized
2027 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002028 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002029 *
2030 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002031 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002032 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002033 int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07002034 try {
2035 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
2036 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08002037
Chris Craik06d29842015-06-02 17:19:24 -07002038 // WAR undocumented color formats
2039 if (b.getConfig() == null) {
2040 if ((usage & USAGE_SHARED) != 0) {
2041 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2042 }
2043 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2044 Canvas c = new Canvas(newBitmap);
2045 c.drawBitmap(b, 0, 0, null);
2046 return createFromBitmap(rs, newBitmap, mips, usage);
Tim Murrayabd5db92013-02-28 11:45:22 -08002047 }
Tim Murrayabd5db92013-02-28 11:45:22 -08002048
Chris Craik06d29842015-06-02 17:19:24 -07002049 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08002050
Chris Craik06d29842015-06-02 17:19:24 -07002051 // enable optimized bitmap path only with no mipmap and script-only usage
2052 if (mips == MipmapControl.MIPMAP_NONE &&
2053 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2054 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2055 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2056 if (id == 0) {
2057 throw new RSRuntimeException("Load failed.");
2058 }
2059
2060 // keep a reference to the Bitmap around to prevent GC
Miao Wang8c150922015-10-26 17:44:10 -07002061 Allocation alloc = new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002062 alloc.setBitmap(b);
2063 return alloc;
2064 }
2065
2066
2067 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Tim Murraya3145512012-12-04 17:59:29 -08002068 if (id == 0) {
2069 throw new RSRuntimeException("Load failed.");
2070 }
Miao Wang8c150922015-10-26 17:44:10 -07002071 return new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002072 } finally {
2073 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murraya3145512012-12-04 17:59:29 -08002074 }
Jason Sams5476b452010-12-08 16:14:36 -08002075 }
2076
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002077 /**
Miao Wang0facf022015-11-25 11:21:13 -08002078 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
2079 * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
2080 * would contain the up-to-date data as READ ONLY.
2081 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2082 * the Allocation has certain alignment. The size of each row including padding,
2083 * called stride, can be queried using the {@link #getStride()} method.
2084 *
2085 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
2086 *
2087 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
2088 */
2089 public ByteBuffer getByteBuffer() {
2090 // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
2091 if (mType.hasFaces()) {
2092 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
2093 }
2094 if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
2095 mType.getYuv() == android.graphics.ImageFormat.YV12 ||
2096 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
2097 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
2098 }
2099 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
2100 int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
2101 long[] stride = new long[1];
2102 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
2103 mByteBufferStride = stride[0];
2104 }
2105 if ((mUsage & USAGE_IO_INPUT) != 0) {
2106 return mByteBuffer.asReadOnlyBuffer();
2107 }
2108 return mByteBuffer;
2109 }
2110
2111 /**
Miao Wang8c150922015-10-26 17:44:10 -07002112 * Creates a new Allocation Array with the given {@link
2113 * android.renderscript.Type}, and usage flags.
2114 * Note: If the input allocation is of usage: USAGE_IO_INPUT,
2115 * the created Allocation will be sharing the same BufferQueue.
2116 *
2117 * @param rs RenderScript context
2118 * @param t RenderScript type describing data layout
2119 * @param usage bit field specifying how the Allocation is
2120 * utilized
2121 * @param numAlloc Number of Allocations in the array.
2122 * @return Allocation[]
2123 */
2124 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
2125 try {
2126 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
2127 rs.validate();
2128 if (t.getID(rs) == 0) {
2129 throw new RSInvalidStateException("Bad Type");
2130 }
2131
2132 Allocation[] mAllocationArray = new Allocation[numAlloc];
2133 mAllocationArray[0] = createTyped(rs, t, usage);
2134 if ((usage & USAGE_IO_INPUT) != 0) {
2135 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
2136 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2137 MAX_NUMBER_IO_INPUT_ALLOC);
2138 }
2139 mAllocationArray[0].setupBufferQueue(numAlloc);;
2140 }
2141
2142 for (int i=1; i<numAlloc; i++) {
2143 mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
2144 }
2145 return mAllocationArray;
2146 } finally {
2147 Trace.traceEnd(RenderScript.TRACE_TAG);
2148 }
2149 }
2150
2151 /**
2152 * Creates a new Allocation with the given {@link
2153 * android.renderscript.Allocation}. The same data layout of
2154 * the input Allocation will be applied.
2155 * If the input allocation is of usage: USAGE_IO_INPUT, the created
2156 * Allocation will be sharing the same BufferQueue.
2157 *
2158 * @param rs Context to which the allocation will belong.
2159 * @param alloc RenderScript Allocation describing data layout.
2160 * @return Allocation sharing the same data structure.
2161 */
2162 static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
2163 try {
2164 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2165 rs.validate();
2166 if (alloc.getID(rs) == 0) {
2167 throw new RSInvalidStateException("Bad input Allocation");
2168 }
2169
2170 Type type = alloc.getType();
2171 int usage = alloc.getUsage();
2172 MipmapControl mips = alloc.getMipmap();
2173 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2174 if (id == 0) {
2175 throw new RSRuntimeException("Allocation creation failed.");
2176 }
2177 Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
2178 if ((usage & USAGE_IO_INPUT) != 0) {
2179 outAlloc.shareBufferQueue(alloc);
2180 }
2181 return outAlloc;
2182 } finally {
2183 Trace.traceEnd(RenderScript.TRACE_TAG);
2184 }
2185 }
2186
2187 /**
2188 * Initialize BufferQueue with specified max number of buffers.
2189 */
2190 void setupBufferQueue(int numAlloc) {
2191 mRS.validate();
2192 if ((mUsage & USAGE_IO_INPUT) == 0) {
2193 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2194 }
2195 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2196 }
2197
2198 /**
2199 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2200 *
2201 * @param alloc Allocation to associate with allocation
2202 */
2203 void shareBufferQueue(Allocation alloc) {
2204 mRS.validate();
2205 if ((mUsage & USAGE_IO_INPUT) == 0) {
2206 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2207 }
2208 mGetSurfaceSurface = alloc.getSurface();
2209 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2210 }
2211
2212 /**
Miao Wang0facf022015-11-25 11:21:13 -08002213 * Gets the stride of the Allocation.
2214 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2215 * the Allocation has certain alignment. The size of each row including such
2216 * padding is called stride.
2217 *
2218 * @return the stride. For 1D Allocation, the stride will be the number of
2219 * bytes of this Allocation. For 2D and 3D Allocations, the stride
2220 * will be the stride in X dimension measuring in bytes.
2221 */
2222 public long getStride() {
2223 if (mByteBufferStride == -1) {
2224 getByteBuffer();
2225 }
2226 return mByteBufferStride;
2227 }
2228
2229 /**
Miao Wang8c150922015-10-26 17:44:10 -07002230 * Get the timestamp for the most recent buffer held by this Allocation.
2231 * The timestamp is guaranteed to be unique and monotonically increasing.
2232 * Default value: -1. The timestamp will be updated after each {@link
2233 * #ioReceive ioReceive()} call.
2234 *
2235 * It can be used to identify the images by comparing the unique timestamps
2236 * when used with {@link android.hardware.camera2} APIs.
2237 * Example steps:
2238 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
2239 * capture is completed.
2240 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
2241 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
2242 * alloc.getTimeStamp().
2243 * @return long Timestamp associated with the buffer held by the Allocation.
2244 */
2245 public long getTimeStamp() {
2246 return mTimeStamp;
2247 }
2248
2249 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002250 * Returns the handle to a raw buffer that is being managed by the screen
2251 * compositor. This operation is only valid for Allocations with {@link
2252 * #USAGE_IO_INPUT}.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002253 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002254 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002255 *
2256 */
2257 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08002258 if ((mUsage & USAGE_IO_INPUT) == 0) {
2259 throw new RSInvalidStateException("Allocation is not a surface texture.");
2260 }
Jason Sams1e68bac2015-03-17 16:36:55 -07002261
2262 if (mGetSurfaceSurface == null) {
2263 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
2264 }
2265
2266 return mGetSurfaceSurface;
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002267 }
2268
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002269 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002270 * Associate a {@link android.view.Surface} with this Allocation. This
2271 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002272 *
2273 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08002274 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002275 public void setSurface(Surface sur) {
2276 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08002277 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2278 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2279 }
2280
Jason Samse07694b2012-04-03 15:36:36 -07002281 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08002282 }
2283
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002284 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002285 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Tim Murray00bb4542012-12-17 16:35:06 -08002286 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002287 * <p>With target API version 18 or greater, this Allocation will be created
2288 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
2289 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
2290 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002291 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002292 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002293 * @param b bitmap source for the allocation data
2294 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002295 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002296 *
2297 */
Jason Sams6d8eb262010-12-15 01:41:00 -08002298 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08002299 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2300 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Tim Murray78e64942013-04-09 17:28:56 -07002301 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Tim Murray00bb4542012-12-17 16:35:06 -08002302 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002303 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2304 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08002305 }
2306
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002307 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002308 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2309 * containing the horizontal list of cube faces. Each face must be a square,
2310 * have the same size as all other faces, and have a width that is a power
2311 * of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002312 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002313 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002314 * @param b Bitmap with cubemap faces layed out in the following
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002315 * format: right, left, top, bottom, front, back
2316 * @param mips specifies desired mipmap behaviour for the cubemap
2317 * @param usage bit field specifying how the cubemap is utilized
2318 *
2319 * @return allocation containing cubemap data
2320 *
2321 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002322 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002323 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002324 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002325 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08002326
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002327 int height = b.getHeight();
2328 int width = b.getWidth();
2329
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002330 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002331 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2332 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002333 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002334 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002335 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002336 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002337 if (!isPow2) {
2338 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2339 }
2340
2341 Element e = elementFromBitmap(rs, b);
2342 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002343 tb.setX(height);
2344 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002345 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08002346 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002347 Type t = tb.create();
2348
Tim Murray460a0492013-11-19 12:45:54 -08002349 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002350 if(id == 0) {
2351 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2352 }
Miao Wang8c150922015-10-26 17:44:10 -07002353 return new Allocation(id, rs, t, usage, mips);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002354 }
2355
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002356 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002357 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2358 * from a {@link android.graphics.Bitmap} containing the horizontal list of
2359 * cube faces. Each face must be a square, have the same size as all other
2360 * faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002361 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002362 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002363 * @param b bitmap with cubemap faces layed out in the following
2364 * format: right, left, top, bottom, front, back
2365 *
2366 * @return allocation containing cubemap data
2367 *
2368 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002369 static public Allocation createCubemapFromBitmap(RenderScript rs,
2370 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08002371 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002372 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08002373 }
2374
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002375 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002376 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2377 * objects containing the cube faces. Each face must be a square, have the
2378 * same size as all other faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002379 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002380 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002381 * @param xpos cubemap face in the positive x direction
2382 * @param xneg cubemap face in the negative x direction
2383 * @param ypos cubemap face in the positive y direction
2384 * @param yneg cubemap face in the negative y direction
2385 * @param zpos cubemap face in the positive z direction
2386 * @param zneg cubemap face in the negative z direction
2387 * @param mips specifies desired mipmap behaviour for the cubemap
2388 * @param usage bit field specifying how the cubemap is utilized
2389 *
2390 * @return allocation containing cubemap data
2391 *
2392 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002393 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2394 Bitmap xpos,
2395 Bitmap xneg,
2396 Bitmap ypos,
2397 Bitmap yneg,
2398 Bitmap zpos,
2399 Bitmap zneg,
2400 MipmapControl mips,
2401 int usage) {
2402 int height = xpos.getHeight();
2403 if (xpos.getWidth() != height ||
2404 xneg.getWidth() != height || xneg.getHeight() != height ||
2405 ypos.getWidth() != height || ypos.getHeight() != height ||
2406 yneg.getWidth() != height || yneg.getHeight() != height ||
2407 zpos.getWidth() != height || zpos.getHeight() != height ||
2408 zneg.getWidth() != height || zneg.getHeight() != height) {
2409 throw new RSIllegalArgumentException("Only square cube map faces supported");
2410 }
2411 boolean isPow2 = (height & (height - 1)) == 0;
2412 if (!isPow2) {
2413 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2414 }
2415
2416 Element e = elementFromBitmap(rs, xpos);
2417 Type.Builder tb = new Type.Builder(rs, e);
2418 tb.setX(height);
2419 tb.setY(height);
2420 tb.setFaces(true);
2421 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2422 Type t = tb.create();
2423 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2424
2425 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07002426 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002427 adapter.copyFrom(xpos);
2428 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2429 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002430 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002431 adapter.copyFrom(ypos);
2432 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2433 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002434 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002435 adapter.copyFrom(zpos);
2436 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2437 adapter.copyFrom(zneg);
2438
2439 return cubemap;
2440 }
2441
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002442 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002443 * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2444 * from 6 {@link android.graphics.Bitmap} objects containing the cube
2445 * faces. Each face must be a square, have the same size as all other faces,
2446 * and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002447 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002448 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002449 * @param xpos cubemap face in the positive x direction
2450 * @param xneg cubemap face in the negative x direction
2451 * @param ypos cubemap face in the positive y direction
2452 * @param yneg cubemap face in the negative y direction
2453 * @param zpos cubemap face in the positive z direction
2454 * @param zneg cubemap face in the negative z direction
2455 *
2456 * @return allocation containing cubemap data
2457 *
2458 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002459 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2460 Bitmap xpos,
2461 Bitmap xneg,
2462 Bitmap ypos,
2463 Bitmap yneg,
2464 Bitmap zpos,
2465 Bitmap zneg) {
2466 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2467 zpos, zneg, MipmapControl.MIPMAP_NONE,
2468 USAGE_GRAPHICS_TEXTURE);
2469 }
2470
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002471 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002472 * Creates an Allocation from the Bitmap referenced
2473 * by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002474 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002475 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002476 * @param res application resources
2477 * @param id resource id to load the data from
2478 * @param mips specifies desired mipmap behaviour for the
2479 * allocation
2480 * @param usage bit field specifying how the allocation is
2481 * utilized
2482 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002483 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002484 *
2485 */
Jason Sams5476b452010-12-08 16:14:36 -08002486 static public Allocation createFromBitmapResource(RenderScript rs,
2487 Resources res,
2488 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08002489 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002490 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07002491
Jason Sams771bebb2009-12-07 12:40:12 -08002492 rs.validate();
Jason Sams3ece2f32013-05-31 14:00:46 -07002493 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2494 throw new RSIllegalArgumentException("Unsupported usage specified.");
2495 }
Jason Sams5476b452010-12-08 16:14:36 -08002496 Bitmap b = BitmapFactory.decodeResource(res, id);
2497 Allocation alloc = createFromBitmap(rs, b, mips, usage);
2498 b.recycle();
2499 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07002500 }
2501
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002502 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002503 * Creates a non-mipmapped Allocation to use as a graphics texture from the
2504 * {@link android.graphics.Bitmap} referenced by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002505 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002506 * <p>With target API version 18 or greater, this allocation will be created
2507 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
2508 * target API version 17 or lower, this allocation will be created with
2509 * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Jason Sams455d6442013-02-05 19:20:18 -08002510 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002511 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002512 * @param res application resources
2513 * @param id resource id to load the data from
2514 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002515 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002516 *
2517 */
Jason Sams5476b452010-12-08 16:14:36 -08002518 static public Allocation createFromBitmapResource(RenderScript rs,
2519 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08002520 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08002521 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2522 return createFromBitmapResource(rs, res, id,
2523 MipmapControl.MIPMAP_NONE,
Jason Sams3ece2f32013-05-31 14:00:46 -07002524 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Jason Sams455d6442013-02-05 19:20:18 -08002525 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002526 return createFromBitmapResource(rs, res, id,
2527 MipmapControl.MIPMAP_NONE,
2528 USAGE_GRAPHICS_TEXTURE);
2529 }
2530
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002531 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002532 * Creates an Allocation containing string data encoded in UTF-8 format.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002533 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002534 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002535 * @param str string to create the allocation from
2536 * @param usage bit field specifying how the allocaiton is
2537 * utilized
2538 *
2539 */
Jason Sams5476b452010-12-08 16:14:36 -08002540 static public Allocation createFromString(RenderScript rs,
2541 String str,
2542 int usage) {
2543 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002544 byte[] allocArray = null;
2545 try {
2546 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08002547 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002548 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002549 return alloc;
2550 }
2551 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08002552 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002553 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002554 }
Jason Sams739c8262013-04-11 18:07:52 -07002555
2556 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002557 * Interface to handle notification when new buffers are available via
2558 * {@link #USAGE_IO_INPUT}. An application will receive one notification
2559 * when a buffer is available. Additional buffers will not trigger new
2560 * notifications until a buffer is processed.
Jason Sams739c8262013-04-11 18:07:52 -07002561 */
Jason Sams42ef2382013-08-29 13:30:59 -07002562 public interface OnBufferAvailableListener {
Jason Sams739c8262013-04-11 18:07:52 -07002563 public void onBufferAvailable(Allocation a);
2564 }
2565
2566 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002567 * Set a notification handler for {@link #USAGE_IO_INPUT}.
Jason Sams739c8262013-04-11 18:07:52 -07002568 *
Jason Sams42ef2382013-08-29 13:30:59 -07002569 * @param callback instance of the OnBufferAvailableListener
2570 * class to be called when buffer arrive.
Jason Sams739c8262013-04-11 18:07:52 -07002571 */
Jason Sams42ef2382013-08-29 13:30:59 -07002572 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
Jason Sams739c8262013-04-11 18:07:52 -07002573 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002574 mAllocationMap.put(new Long(getID(mRS)), this);
Jason Sams739c8262013-04-11 18:07:52 -07002575 mBufferNotifier = callback;
2576 }
2577 }
2578
Tim Murrayb730d862014-08-18 16:14:24 -07002579 static void sendBufferNotification(long id) {
Jason Sams739c8262013-04-11 18:07:52 -07002580 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002581 Allocation a = mAllocationMap.get(new Long(id));
Jason Sams739c8262013-04-11 18:07:52 -07002582
2583 if ((a != null) && (a.mBufferNotifier != null)) {
2584 a.mBufferNotifier.onBufferAvailable(a);
2585 }
2586 }
2587 }
2588
Miao Wangf0f6e802015-02-03 17:16:43 -08002589 /**
2590 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
2591 *
2592 */
2593 @Override
2594 public void destroy() {
2595 if((mUsage & USAGE_IO_OUTPUT) != 0) {
2596 setSurface(null);
2597 }
2598 super.destroy();
2599 }
Jason Samsb8c5a842009-07-31 20:40:47 -07002600}