blob: 8c78a3ac2aad88a741daaad2bfe963db5e98ee42 [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) {
118 validateIsInt16();
119 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
405 private void validateIsInt16() {
406 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
407 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
408 return;
409 }
410 throw new RSIllegalArgumentException(
411 "16 bit integer source does not match allocation type " + mType.mElement.mType);
412 }
413
414 private void validateIsInt8() {
415 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
416 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
417 return;
418 }
419 throw new RSIllegalArgumentException(
420 "8 bit integer source does not match allocation type " + mType.mElement.mType);
421 }
422
423 private void validateIsFloat32() {
424 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
425 return;
426 }
427 throw new RSIllegalArgumentException(
428 "32 bit float source does not match allocation type " + mType.mElement.mType);
429 }
430
Jason Sams3042d262013-11-25 18:28:33 -0800431 private void validateIsFloat64() {
432 if (mType.mElement.mType == Element.DataType.FLOAT_64) {
433 return;
434 }
435 throw new RSIllegalArgumentException(
436 "64 bit float source does not match allocation type " + mType.mElement.mType);
437 }
438
Jason Samsb97b2512011-01-16 15:04:08 -0800439 private void validateIsObject() {
440 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
441 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
442 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
443 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
444 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
445 (mType.mElement.mType == Element.DataType.RS_MESH) ||
446 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
447 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
448 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
449 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
450 return;
451 }
452 throw new RSIllegalArgumentException(
453 "Object source does not match allocation type " + mType.mElement.mType);
454 }
455
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700456 @Override
457 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800458 super.updateFromNative();
Tim Murray460a0492013-11-19 12:45:54 -0800459 long typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700460 if(typeID != 0) {
461 mType = new Type(typeID, mRS);
462 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700463 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700464 }
465 }
466
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700467 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700468 * Get the {@link android.renderscript.Type} of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700469 *
470 * @return Type
471 *
472 */
Jason Samsea87e962010-01-12 12:12:28 -0800473 public Type getType() {
474 return mType;
475 }
476
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700477 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700478 * Propagate changes from one usage of the Allocation to the
479 * other usages of the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700480 *
481 */
Jason Sams5476b452010-12-08 16:14:36 -0800482 public void syncAll(int srcLocation) {
Chris Craik06d29842015-06-02 17:19:24 -0700483 try {
484 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
485 switch (srcLocation) {
486 case USAGE_GRAPHICS_TEXTURE:
487 case USAGE_SCRIPT:
488 if ((mUsage & USAGE_SHARED) != 0) {
489 copyFrom(mBitmap);
490 }
491 break;
492 case USAGE_GRAPHICS_CONSTANTS:
493 case USAGE_GRAPHICS_VERTEX:
494 break;
495 case USAGE_SHARED:
496 if ((mUsage & USAGE_SHARED) != 0) {
497 copyTo(mBitmap);
498 }
499 break;
500 default:
501 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
Tim Murray78e64942013-04-09 17:28:56 -0700502 }
Chris Craik06d29842015-06-02 17:19:24 -0700503 mRS.validate();
504 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
505 } finally {
506 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams5476b452010-12-08 16:14:36 -0800507 }
Jason Sams5476b452010-12-08 16:14:36 -0800508 }
509
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700510 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700511 * Send a buffer to the output stream. The contents of the Allocation will
512 * be undefined after this operation. This operation is only valid if {@link
513 * #USAGE_IO_OUTPUT} is set on the Allocation.
514 *
Jason Sams163766c2012-02-15 12:04:24 -0800515 *
Jason Sams163766c2012-02-15 12:04:24 -0800516 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700517 public void ioSend() {
Chris Craik06d29842015-06-02 17:19:24 -0700518 try {
519 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
520 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
521 throw new RSIllegalArgumentException(
522 "Can only send buffer if IO_OUTPUT usage specified.");
523 }
524 mRS.validate();
525 mRS.nAllocationIoSend(getID(mRS));
526 } finally {
527 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800528 }
Jason Sams163766c2012-02-15 12:04:24 -0800529 }
530
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700531 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700532 * Receive the latest input into the Allocation. This operation
533 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
Jason Sams163766c2012-02-15 12:04:24 -0800534 *
Jason Sams163766c2012-02-15 12:04:24 -0800535 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700536 public void ioReceive() {
Chris Craik06d29842015-06-02 17:19:24 -0700537 try {
538 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
539 if ((mUsage & USAGE_IO_INPUT) == 0) {
540 throw new RSIllegalArgumentException(
541 "Can only receive if IO_INPUT usage specified.");
542 }
543 mRS.validate();
Miao Wang8c150922015-10-26 17:44:10 -0700544 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
Chris Craik06d29842015-06-02 17:19:24 -0700545 } finally {
546 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams163766c2012-02-15 12:04:24 -0800547 }
Jason Sams163766c2012-02-15 12:04:24 -0800548 }
549
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700550 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700551 * Copy an array of RS objects to the Allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700552 *
553 * @param d Source array.
554 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800555 public void copyFrom(BaseObj[] d) {
Chris Craik06d29842015-06-02 17:19:24 -0700556 try {
557 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
558 mRS.validate();
559 validateIsObject();
560 if (d.length != mCurrentCount) {
561 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
562 mCurrentCount + ", array length = " + d.length);
563 }
Tim Murray460a0492013-11-19 12:45:54 -0800564
Chris Craik06d29842015-06-02 17:19:24 -0700565 if (RenderScript.sPointerSize == 8) {
566 long i[] = new long[d.length * 4];
567 for (int ct=0; ct < d.length; ct++) {
568 i[ct * 4] = d[ct].getID(mRS);
569 }
570 copy1DRangeFromUnchecked(0, mCurrentCount, i);
571 } else {
572 int i[] = new int[d.length];
573 for (int ct=0; ct < d.length; ct++) {
574 i[ct] = (int) d[ct].getID(mRS);
575 }
576 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Tim Murray3de3dc72014-07-01 16:56:18 -0700577 }
Chris Craik06d29842015-06-02 17:19:24 -0700578 } finally {
579 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800580 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700581 }
582
Jason Samsfb9f82c2011-01-12 14:53:25 -0800583 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800584 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800585 if (bc == null) {
586 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
587 }
Jason Sams252c0782011-01-11 17:42:52 -0800588 switch (bc) {
589 case ALPHA_8:
590 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
591 throw new RSIllegalArgumentException("Allocation kind is " +
592 mType.getElement().mKind + ", type " +
593 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700594 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800595 " bytes, passed bitmap was " + bc);
596 }
597 break;
598 case ARGB_8888:
599 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700600 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800601 throw new RSIllegalArgumentException("Allocation kind is " +
602 mType.getElement().mKind + ", type " +
603 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700604 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800605 " bytes, passed bitmap was " + bc);
606 }
607 break;
608 case RGB_565:
609 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700610 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800611 throw new RSIllegalArgumentException("Allocation kind is " +
612 mType.getElement().mKind + ", type " +
613 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700614 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800615 " bytes, passed bitmap was " + bc);
616 }
617 break;
618 case ARGB_4444:
619 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700620 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800621 throw new RSIllegalArgumentException("Allocation kind is " +
622 mType.getElement().mKind + ", type " +
623 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700624 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800625 " bytes, passed bitmap was " + bc);
626 }
627 break;
628
629 }
Jason Sams4ef66502010-12-10 16:03:15 -0800630 }
631
Jason Samsfb9f82c2011-01-12 14:53:25 -0800632 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700633 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800634 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
635 }
636 }
637
Jason Sams3042d262013-11-25 18:28:33 -0800638 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700639 try {
640 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
641 mRS.validate();
642 if (mCurrentDimZ > 0) {
643 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
644 } else if (mCurrentDimY > 0) {
645 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
646 } else {
647 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
648 }
649 } finally {
650 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams3042d262013-11-25 18:28:33 -0800651 }
Jason Sams3042d262013-11-25 18:28:33 -0800652 }
653
654 /**
655 * Copy into this Allocation from an array. This method does not guarantee
656 * that the Allocation is compatible with the input buffer; it copies memory
657 * without reinterpretation.
658 *
659 * @param array The source data array
660 */
661 public void copyFromUnchecked(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700662 try {
663 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
664 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
665 java.lang.reflect.Array.getLength(array));
666 } finally {
667 Trace.traceEnd(RenderScript.TRACE_TAG);
668 }
Jason Sams3042d262013-11-25 18:28:33 -0800669 }
670
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700671 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700672 * Copy into this Allocation from an array. This method does not guarantee
673 * that the Allocation is compatible with the input buffer; it copies memory
674 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800675 *
676 * @param d the source data array
677 */
678 public void copyFromUnchecked(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800679 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800680 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700681
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700682 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700683 * Copy into this Allocation from an array. This method does not guarantee
684 * that the Allocation is compatible with the input buffer; it copies memory
685 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800686 *
687 * @param d the source data array
688 */
689 public void copyFromUnchecked(short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800690 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800691 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700692
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700693 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700694 * Copy into this Allocation from an array. This method does not guarantee
695 * that the Allocation is compatible with the input buffer; it copies memory
696 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800697 *
698 * @param d the source data array
699 */
700 public void copyFromUnchecked(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800701 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800702 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700703
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700704 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700705 * Copy into this Allocation from an array. This method does not guarantee
706 * that the Allocation is compatible with the input buffer; it copies memory
707 * without reinterpretation.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800708 *
709 * @param d the source data array
710 */
711 public void copyFromUnchecked(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800712 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800713 }
714
Tim Murray6d7a53c2013-05-23 16:59:23 -0700715
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700716 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700717 * Copy into this Allocation from an array. This variant is type checked
718 * and will generate exceptions if the Allocation's {@link
Jason Sams3042d262013-11-25 18:28:33 -0800719 * android.renderscript.Element} does not match the array's
720 * primitive type.
721 *
Ying Wang16229812013-11-26 15:45:12 -0800722 * @param array The source data array
Jason Sams3042d262013-11-25 18:28:33 -0800723 */
724 public void copyFrom(Object array) {
Chris Craik06d29842015-06-02 17:19:24 -0700725 try {
726 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
727 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
728 java.lang.reflect.Array.getLength(array));
729 } finally {
730 Trace.traceEnd(RenderScript.TRACE_TAG);
731 }
Jason Sams3042d262013-11-25 18:28:33 -0800732 }
733
734 /**
735 * Copy into this Allocation from an array. This variant is type checked
736 * and will generate exceptions if the Allocation's {@link
Tim Murrayc11e25c2013-04-09 11:01:01 -0700737 * android.renderscript.Element} is not a 32 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800738 *
739 * @param d the source data array
740 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800741 public void copyFrom(int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800742 validateIsInt32();
743 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800744 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800745
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700746 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700747 * Copy into this Allocation from an array. This variant is type checked
748 * and will generate exceptions if the Allocation's {@link
749 * android.renderscript.Element} is not a 16 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800750 *
751 * @param d the source data array
752 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800753 public void copyFrom(short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800754 validateIsInt16();
755 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800756 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800757
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700758 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700759 * Copy into this Allocation from an array. This variant is type checked
760 * and will generate exceptions if the Allocation's {@link
761 * android.renderscript.Element} is not an 8 bit integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800762 *
763 * @param d the source data array
764 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800765 public void copyFrom(byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800766 validateIsInt8();
767 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800768 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800769
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700770 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700771 * Copy into this Allocation from an array. This variant is type checked
772 * and will generate exceptions if the Allocation's {@link
773 * android.renderscript.Element} is not a 32 bit float type.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800774 *
775 * @param d the source data array
776 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800777 public void copyFrom(float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800778 validateIsFloat32();
779 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800780 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800781
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700782 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700783 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
784 * height, width, and format of the bitmap must match the existing
785 * allocation.
786 *
787 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
788 * android.graphics.Bitmap} used to create the Allocation with {@link
789 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
790 * this will synchronize the Allocation with the latest data from the {@link
791 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
Jason Sams4fa3eed2011-01-19 15:44:38 -0800792 *
793 * @param b the source bitmap
794 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800795 public void copyFrom(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -0700796 try {
797 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
798 mRS.validate();
799 if (b.getConfig() == null) {
800 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
801 Canvas c = new Canvas(newBitmap);
802 c.drawBitmap(b, 0, 0, null);
803 copyFrom(newBitmap);
804 return;
805 }
806 validateBitmapSize(b);
807 validateBitmapFormat(b);
808 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
809 } finally {
810 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -0800811 }
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700812 }
813
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700814 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700815 * Copy an Allocation from an Allocation. The types of both allocations
Tim Murrayf671fb02012-10-03 13:50:05 -0700816 * must be identical.
817 *
818 * @param a the source allocation
819 */
820 public void copyFrom(Allocation a) {
Chris Craik06d29842015-06-02 17:19:24 -0700821 try {
822 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
823 mRS.validate();
824 if (!mType.equals(a.getType())) {
825 throw new RSIllegalArgumentException("Types of allocations must match.");
826 }
827 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
828 } finally {
829 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayf671fb02012-10-03 13:50:05 -0700830 }
Tim Murrayf671fb02012-10-03 13:50:05 -0700831 }
832
Tim Murrayf671fb02012-10-03 13:50:05 -0700833 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700834 * This is only intended to be used by auto-generated code reflected from
835 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800836 *
837 * @param xoff
838 * @param fp
839 */
Jason Sams21b41032011-01-16 15:05:41 -0800840 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800841 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700842 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700843 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700844 int data_length = fp.getPos();
Jason Samsa70f4162010-03-26 15:33:42 -0700845
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700846 int count = data_length / eSize;
847 if ((eSize * count) != data_length) {
848 throw new RSIllegalArgumentException("Field packer length " + data_length +
Jason Samsa70f4162010-03-26 15:33:42 -0700849 " not divisible by element size " + eSize + ".");
850 }
Jason Samsba862d12011-07-07 15:24:42 -0700851 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700852 }
853
Miao Wang45cec0a2015-03-04 16:40:21 -0800854
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700855 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700856 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800857 * the RenderScript script files and should not be used by developers.
Jason Samsfa445b92011-01-07 17:00:07 -0800858 *
859 * @param xoff
860 * @param component_number
861 * @param fp
862 */
Jason Sams21b41032011-01-16 15:05:41 -0800863 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800864 setFromFieldPacker(xoff, 0, 0, component_number, fp);
865 }
866
867 /**
Miao Wangc8e237e2015-02-20 18:36:32 -0800868 * This is only intended to be used by auto-generated code reflected from
Miao Wang258db502015-03-03 14:05:36 -0800869 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -0800870 *
871 * @param xoff
872 * @param yoff
Miao Wangc8e237e2015-02-20 18:36:32 -0800873 * @param zoff
874 * @param component_number
875 * @param fp
876 */
877 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800878 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700879 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800880 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700881 }
882 if(xoff < 0) {
Miao Wangc8e237e2015-02-20 18:36:32 -0800883 throw new RSIllegalArgumentException("Offset x must be >= 0.");
884 }
885 if(yoff < 0) {
886 throw new RSIllegalArgumentException("Offset y must be >= 0.");
887 }
888 if(zoff < 0) {
889 throw new RSIllegalArgumentException("Offset z must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700890 }
891
892 final byte[] data = fp.getData();
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700893 int data_length = fp.getPos();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700894 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800895 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700896
Stephen Hinesfa1275a2014-06-17 17:25:04 -0700897 if (data_length != eSize) {
898 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700899 " does not match component size " + eSize + ".");
900 }
901
Miao Wangc8e237e2015-02-20 18:36:32 -0800902 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
903 component_number, data, data_length);
Jason Samsa70f4162010-03-26 15:33:42 -0700904 }
905
Miao Wang87e908d2015-03-02 15:15:15 -0800906 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
Jason Sams771bebb2009-12-07 12:40:12 -0800907 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700908 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800909 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700910 }
911 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800912 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700913 }
Jason Samsba862d12011-07-07 15:24:42 -0700914 if((off + count) > mCurrentCount) {
915 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700916 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700917 }
Miao Wang87e908d2015-03-02 15:15:15 -0800918 if(usePadding) {
919 if(len < dataSize / 4 * 3) {
920 throw new RSIllegalArgumentException("Array too small for allocation type.");
921 }
922 } else {
923 if(len < dataSize) {
924 throw new RSIllegalArgumentException("Array too small for allocation type.");
925 }
Jason Sams768bc022009-09-21 19:41:04 -0700926 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700927 }
928
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700929 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700930 * Generate a mipmap chain. This is only valid if the Type of the Allocation
931 * includes mipmaps.
Jason Samsf7086092011-01-12 13:28:37 -0800932 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700933 * <p>This function will generate a complete set of mipmaps from the top
934 * level LOD and place them into the script memory space.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800935 *
Tim Murrayc11e25c2013-04-09 11:01:01 -0700936 * <p>If the Allocation is also using other memory spaces, a call to {@link
937 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
Jason Samsf7086092011-01-12 13:28:37 -0800938 */
939 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700940 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800941 }
942
Jason Sams3042d262013-11-25 18:28:33 -0800943 private void copy1DRangeFromUnchecked(int off, int count, Object array,
944 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -0700945 try {
946 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
947 final int dataSize = mType.mElement.getBytesSize() * count;
948 // AutoPadding for Vec3 Element
949 boolean usePadding = false;
950 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
951 usePadding = true;
952 }
953 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
954 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
955 mType.mElement.mType.mSize, usePadding);
956 } finally {
957 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -0800958 }
Jason Sams3042d262013-11-25 18:28:33 -0800959 }
960
961 /**
962 * Copy an array into part of this Allocation. This method does not
963 * guarantee that the Allocation is compatible with the input buffer.
964 *
965 * @param off The offset of the first element to be copied.
966 * @param count The number of elements to be copied.
967 * @param array The source data array
968 */
969 public void copy1DRangeFromUnchecked(int off, int count, Object array) {
970 copy1DRangeFromUnchecked(off, count, array,
971 validateObjectIsPrimitiveArray(array, false),
972 java.lang.reflect.Array.getLength(array));
973 }
974
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700975 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700976 * Copy an array into part of this Allocation. This method does not
977 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800978 *
979 * @param off The offset of the first element to be copied.
980 * @param count The number of elements to be copied.
981 * @param d the source data array
982 */
983 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800984 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700985 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700986
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700987 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -0700988 * Copy an array into part of this Allocation. This method does not
989 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800990 *
991 * @param off The offset of the first element to be copied.
992 * @param count The number of elements to be copied.
993 * @param d the source data array
994 */
995 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams3042d262013-11-25 18:28:33 -0800996 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
Jason Sams768bc022009-09-21 19:41:04 -0700997 }
Tim Murray6d7a53c2013-05-23 16:59:23 -0700998
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700999 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001000 * Copy an array into part of this Allocation. This method does not
1001 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001002 *
1003 * @param off The offset of the first element to be copied.
1004 * @param count The number of elements to be copied.
1005 * @param d the source data array
1006 */
1007 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001008 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
Jason Sams768bc022009-09-21 19:41:04 -07001009 }
Tim Murray6d7a53c2013-05-23 16:59:23 -07001010
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001011 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001012 * Copy an array into part of this Allocation. This method does not
1013 * guarantee that the Allocation is compatible with the input buffer.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001014 *
1015 * @param off The offset of the first element to be copied.
1016 * @param count The number of elements to be copied.
1017 * @param d the source data array
1018 */
1019 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams3042d262013-11-25 18:28:33 -08001020 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1021 }
1022
1023
1024 /**
1025 * Copy an array into part of this Allocation. This variant is type checked
1026 * and will generate exceptions if the Allocation type does not
1027 * match the component type of the array passed in.
1028 *
1029 * @param off The offset of the first element to be copied.
1030 * @param count The number of elements to be copied.
1031 * @param array The source data array.
1032 */
1033 public void copy1DRangeFrom(int off, int count, Object array) {
1034 copy1DRangeFromUnchecked(off, count, array,
1035 validateObjectIsPrimitiveArray(array, true),
1036 java.lang.reflect.Array.getLength(array));
Jason Samsb8c5a842009-07-31 20:40:47 -07001037 }
1038
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001039 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001040 * Copy an array into part of this Allocation. This variant is type checked
1041 * and will generate exceptions if the Allocation type is not a 32 bit
1042 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001043 *
1044 * @param off The offset of the first element to be copied.
1045 * @param count The number of elements to be copied.
1046 * @param d the source data array
1047 */
Jason Samsb97b2512011-01-16 15:04:08 -08001048 public void copy1DRangeFrom(int off, int count, int[] d) {
1049 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001050 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001051 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001052
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001053 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001054 * Copy an array into part of this Allocation. This variant is type checked
1055 * and will generate exceptions if the Allocation type is not a 16 bit
1056 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001057 *
1058 * @param off The offset of the first element to be copied.
1059 * @param count The number of elements to be copied.
1060 * @param d the source data array
1061 */
Jason Samsb97b2512011-01-16 15:04:08 -08001062 public void copy1DRangeFrom(int off, int count, short[] d) {
1063 validateIsInt16();
Jason Sams3042d262013-11-25 18:28:33 -08001064 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001065 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001066
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001067 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001068 * Copy an array into part of this Allocation. This variant is type checked
1069 * and will generate exceptions if the Allocation type is not an 8 bit
1070 * integer type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001071 *
1072 * @param off The offset of the first element to be copied.
1073 * @param count The number of elements to be copied.
1074 * @param d the source data array
1075 */
Jason Samsb97b2512011-01-16 15:04:08 -08001076 public void copy1DRangeFrom(int off, int count, byte[] d) {
1077 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001078 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001079 }
Jason Sams4fa3eed2011-01-19 15:44:38 -08001080
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001081 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001082 * Copy an array into part of this Allocation. This variant is type checked
1083 * and will generate exceptions if the Allocation type is not a 32 bit float
1084 * type.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001085 *
1086 * @param off The offset of the first element to be copied.
1087 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001088 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -08001089 */
Jason Samsb97b2512011-01-16 15:04:08 -08001090 public void copy1DRangeFrom(int off, int count, float[] d) {
1091 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001092 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
Jason Samsb97b2512011-01-16 15:04:08 -08001093 }
Jason Sams3042d262013-11-25 18:28:33 -08001094
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001095 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001096 * Copy part of an Allocation into this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001097 *
1098 * @param off The offset of the first element to be copied.
1099 * @param count The number of elements to be copied.
1100 * @param data the source data allocation.
1101 * @param dataOff off The offset of the first element in data to
1102 * be copied.
1103 */
1104 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Tim Murray6d7a53c2013-05-23 16:59:23 -07001105 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
Jason Sams48fe5342011-07-08 13:52:30 -07001106 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001107 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -07001108 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -07001109 data.mSelectedLOD, data.mSelectedFace.mID);
Chris Craik5c705d62015-06-01 10:39:36 -07001110 Trace.traceEnd(RenderScript.TRACE_TAG);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001111 }
1112
Jason Samsfb9f82c2011-01-12 14:53:25 -08001113 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -07001114 if (mAdaptedAllocation != null) {
1115
1116 } else {
1117
1118 if (xoff < 0 || yoff < 0) {
1119 throw new RSIllegalArgumentException("Offset cannot be negative.");
1120 }
1121 if (h < 0 || w < 0) {
1122 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1123 }
1124 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1125 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1126 }
Jason Samsfb9f82c2011-01-12 14:53:25 -08001127 }
1128 }
Jason Sams768bc022009-09-21 19:41:04 -07001129
Jason Sams3042d262013-11-25 18:28:33 -08001130 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1131 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001132 try {
1133 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
1134 mRS.validate();
1135 validate2DRange(xoff, yoff, w, h);
1136 final int dataSize = mType.mElement.getBytesSize() * w * h;
1137 // AutoPadding for Vec3 Element
1138 boolean usePadding = false;
1139 int sizeBytes = arrayLen * dt.mSize;
1140 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1141 if (dataSize / 4 * 3 > sizeBytes) {
1142 throw new RSIllegalArgumentException("Array too small for allocation type.");
1143 }
1144 usePadding = true;
1145 sizeBytes = dataSize;
1146 } else {
1147 if (dataSize > sizeBytes) {
1148 throw new RSIllegalArgumentException("Array too small for allocation type.");
1149 }
Miao Wang87e908d2015-03-02 15:15:15 -08001150 }
Chris Craik06d29842015-06-02 17:19:24 -07001151 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1152 array, sizeBytes, dt,
1153 mType.mElement.mType.mSize, usePadding);
1154 } finally {
1155 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001156 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001157 }
1158
Jason Sams3042d262013-11-25 18:28:33 -08001159 /**
1160 * Copy from an array into a rectangular region in this Allocation. The
1161 * array is assumed to be tightly packed.
1162 *
1163 * @param xoff X offset of the region to update in this Allocation
1164 * @param yoff Y offset of the region to update in this Allocation
1165 * @param w Width of the region to update
1166 * @param h Height of the region to update
Ying Wang16229812013-11-26 15:45:12 -08001167 * @param array Data to be placed into the Allocation
Jason Sams3042d262013-11-25 18:28:33 -08001168 */
1169 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001170 try {
1171 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1172 copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1173 validateObjectIsPrimitiveArray(array, true),
1174 java.lang.reflect.Array.getLength(array));
1175 } finally {
1176 Trace.traceEnd(RenderScript.TRACE_TAG);
1177 }
Stephen Hinesa9a7b372013-02-08 17:11:31 -08001178 }
1179
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001180 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001181 * Copy from an array into a rectangular region in this Allocation. The
1182 * array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -08001183 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001184 * @param xoff X offset of the region to update in this Allocation
1185 * @param yoff Y offset of the region to update in this Allocation
1186 * @param w Width of the region to update
1187 * @param h Height of the region to update
1188 * @param data to be placed into the Allocation
Jason Samsf7086092011-01-12 13:28:37 -08001189 */
1190 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001191 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001192 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1193 Element.DataType.SIGNED_8, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001194 }
1195
Tim Murrayc11e25c2013-04-09 11:01:01 -07001196 /**
1197 * Copy from an array into a rectangular region in this Allocation. The
1198 * array is assumed to be tightly packed.
1199 *
1200 * @param xoff X offset of the region to update in this Allocation
1201 * @param yoff Y offset of the region to update in this Allocation
1202 * @param w Width of the region to update
1203 * @param h Height of the region to update
1204 * @param data to be placed into the Allocation
1205 */
Jason Samsf7086092011-01-12 13:28:37 -08001206 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001207 validateIsInt16();
Jason Sams3042d262013-11-25 18:28:33 -08001208 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1209 Element.DataType.SIGNED_16, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001210 }
1211
Tim Murrayc11e25c2013-04-09 11:01:01 -07001212 /**
1213 * Copy from an array into a rectangular region in this Allocation. The
1214 * array is assumed to be tightly packed.
1215 *
1216 * @param xoff X offset of the region to update in this Allocation
1217 * @param yoff Y offset of the region to update in this Allocation
1218 * @param w Width of the region to update
1219 * @param h Height of the region to update
1220 * @param data to be placed into the Allocation
1221 */
Jason Samsf7086092011-01-12 13:28:37 -08001222 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001223 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001224 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1225 Element.DataType.SIGNED_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001226 }
1227
Tim Murrayc11e25c2013-04-09 11:01:01 -07001228 /**
1229 * Copy from an array into a rectangular region in this Allocation. The
1230 * array is assumed to be tightly packed.
1231 *
1232 * @param xoff X offset of the region to update in this Allocation
1233 * @param yoff Y offset of the region to update in this Allocation
1234 * @param w Width of the region to update
1235 * @param h Height of the region to update
1236 * @param data to be placed into the Allocation
1237 */
Jason Samsf7086092011-01-12 13:28:37 -08001238 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -08001239 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001240 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1241 Element.DataType.FLOAT_32, data.length);
Jason Samsb8c5a842009-07-31 20:40:47 -07001242 }
1243
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001244 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001245 * Copy a rectangular region from an Allocation into a rectangular region in
1246 * this Allocation.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001247 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001248 * @param xoff X offset of the region in this Allocation
1249 * @param yoff Y offset of the region in this Allocation
1250 * @param w Width of the region to update.
1251 * @param h Height of the region to update.
1252 * @param data source Allocation.
1253 * @param dataXoff X offset in source Allocation
1254 * @param dataYoff Y offset in source Allocation
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001255 */
1256 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1257 Allocation data, int dataXoff, int dataYoff) {
Chris Craik06d29842015-06-02 17:19:24 -07001258 try {
1259 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1260 mRS.validate();
1261 validate2DRange(xoff, yoff, w, h);
1262 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1263 mSelectedLOD, mSelectedFace.mID,
1264 w, h, data.getID(mRS), dataXoff, dataYoff,
1265 data.mSelectedLOD, data.mSelectedFace.mID);
1266 } finally {
1267 Trace.traceEnd(RenderScript.TRACE_TAG);
1268 }
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -07001269 }
1270
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001271 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001272 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
1273 * and width of the update will use the height and width of the {@link
1274 * android.graphics.Bitmap}.
Jason Samsf7086092011-01-12 13:28:37 -08001275 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001276 * @param xoff X offset of the region to update in this Allocation
1277 * @param yoff Y offset of the region to update in this Allocation
1278 * @param data the Bitmap to be copied
Jason Samsf7086092011-01-12 13:28:37 -08001279 */
1280 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Chris Craik5c705d62015-06-01 10:39:36 -07001281 try {
1282 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1283 mRS.validate();
1284 if (data.getConfig() == null) {
1285 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1286 Canvas c = new Canvas(newBitmap);
1287 c.drawBitmap(data, 0, 0, null);
1288 copy2DRangeFrom(xoff, yoff, newBitmap);
1289 return;
1290 }
1291 validateBitmapFormat(data);
1292 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1293 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1294 } finally {
1295 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murrayabd5db92013-02-28 11:45:22 -08001296 }
Jason Samsfa445b92011-01-07 17:00:07 -08001297 }
1298
Jason Samsb05d6892013-04-09 15:59:24 -07001299 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1300 if (mAdaptedAllocation != null) {
1301
1302 } else {
1303
1304 if (xoff < 0 || yoff < 0 || zoff < 0) {
1305 throw new RSIllegalArgumentException("Offset cannot be negative.");
1306 }
1307 if (h < 0 || w < 0 || d < 0) {
1308 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1309 }
1310 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1311 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1312 }
1313 }
1314 }
1315
1316 /**
Miao Wang258db502015-03-03 14:05:36 -08001317 * Copy a rectangular region from the array into the allocation.
1318 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001319 *
Miao Wang258db502015-03-03 14:05:36 -08001320 * The data type of the array is not required to be the same as
1321 * the element data type.
Jason Samsb05d6892013-04-09 15:59:24 -07001322 */
Jason Sams3042d262013-11-25 18:28:33 -08001323 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1324 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001325 try {
1326 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
1327 mRS.validate();
1328 validate3DRange(xoff, yoff, zoff, w, h, d);
1329 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1330 // AutoPadding for Vec3 Element
1331 boolean usePadding = false;
1332 int sizeBytes = arrayLen * dt.mSize;
1333 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1334 if (dataSize / 4 * 3 > sizeBytes) {
1335 throw new RSIllegalArgumentException("Array too small for allocation type.");
1336 }
1337 usePadding = true;
1338 sizeBytes = dataSize;
1339 } else {
1340 if (dataSize > sizeBytes) {
1341 throw new RSIllegalArgumentException("Array too small for allocation type.");
1342 }
Miao Wang87e908d2015-03-02 15:15:15 -08001343 }
Chris Craik06d29842015-06-02 17:19:24 -07001344 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1345 array, sizeBytes, dt,
1346 mType.mElement.mType.mSize, usePadding);
1347 } finally {
1348 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001349 }
Jason Samsb05d6892013-04-09 15:59:24 -07001350 }
1351
1352 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001353 * Copy a rectangular region from the array into the allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001354 * The array is assumed to be tightly packed.
Jason Samsb05d6892013-04-09 15:59:24 -07001355 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001356 * @param xoff X offset of the region to update in this Allocation
1357 * @param yoff Y offset of the region to update in this Allocation
1358 * @param zoff Z offset of the region to update in this Allocation
1359 * @param w Width of the region to update
1360 * @param h Height of the region to update
1361 * @param d Depth of the region to update
Miao Wang87e908d2015-03-02 15:15:15 -08001362 * @param array to be placed into the allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001363 */
Jason Sams3042d262013-11-25 18:28:33 -08001364 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
Chris Craik06d29842015-06-02 17:19:24 -07001365 try {
1366 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
1367 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1368 validateObjectIsPrimitiveArray(array, true),
1369 java.lang.reflect.Array.getLength(array));
1370 } finally {
1371 Trace.traceEnd(RenderScript.TRACE_TAG);
1372 }
Jason Samsb05d6892013-04-09 15:59:24 -07001373 }
1374
1375 /**
Jason Samsb05d6892013-04-09 15:59:24 -07001376 * Copy a rectangular region into the allocation from another
1377 * allocation.
1378 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001379 * @param xoff X offset of the region to update in this Allocation
1380 * @param yoff Y offset of the region to update in this Allocation
1381 * @param zoff Z offset of the region to update in this Allocation
1382 * @param w Width of the region to update.
1383 * @param h Height of the region to update.
1384 * @param d Depth of the region to update.
Jason Samsb05d6892013-04-09 15:59:24 -07001385 * @param data source allocation.
Tim Murrayc11e25c2013-04-09 11:01:01 -07001386 * @param dataXoff X offset of the region in the source Allocation
1387 * @param dataYoff Y offset of the region in the source Allocation
1388 * @param dataZoff Z offset of the region in the source Allocation
Jason Samsb05d6892013-04-09 15:59:24 -07001389 */
1390 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1391 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1392 mRS.validate();
1393 validate3DRange(xoff, yoff, zoff, w, h, d);
1394 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1395 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1396 data.mSelectedLOD);
1397 }
1398
Jason Samsfa445b92011-01-07 17:00:07 -08001399
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001400 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001401 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
1402 * bitmap must match the dimensions of the Allocation.
Jason Sams48fe5342011-07-08 13:52:30 -07001403 *
1404 * @param b The bitmap to be set from the Allocation.
1405 */
Jason Samsfa445b92011-01-07 17:00:07 -08001406 public void copyTo(Bitmap b) {
Chris Craik06d29842015-06-02 17:19:24 -07001407 try {
1408 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1409 mRS.validate();
1410 validateBitmapFormat(b);
1411 validateBitmapSize(b);
1412 mRS.nAllocationCopyToBitmap(getID(mRS), b);
1413 } finally {
1414 Trace.traceEnd(RenderScript.TRACE_TAG);
1415 }
Jason Samsfa445b92011-01-07 17:00:07 -08001416 }
1417
Jason Sams3042d262013-11-25 18:28:33 -08001418 private void copyTo(Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001419 try {
1420 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1421 mRS.validate();
1422 boolean usePadding = false;
1423 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1424 usePadding = true;
Miao Wangd9b63282015-04-03 09:15:39 -07001425 }
Chris Craik06d29842015-06-02 17:19:24 -07001426 if (usePadding) {
1427 if (dt.mSize * arrayLen < mSize / 4 * 3) {
1428 throw new RSIllegalArgumentException(
1429 "Size of output array cannot be smaller than size of allocation.");
1430 }
1431 } else {
1432 if (dt.mSize * arrayLen < mSize) {
1433 throw new RSIllegalArgumentException(
1434 "Size of output array cannot be smaller than size of allocation.");
1435 }
Miao Wangd9b63282015-04-03 09:15:39 -07001436 }
Chris Craik06d29842015-06-02 17:19:24 -07001437 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1438 } finally {
1439 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wangd9b63282015-04-03 09:15:39 -07001440 }
Jason Sams3042d262013-11-25 18:28:33 -08001441 }
1442
1443 /**
1444 * Copy from the Allocation into an array. The array must be at
1445 * least as large as the Allocation. The
1446 * {@link android.renderscript.Element} must match the component
1447 * type of the array passed in.
1448 *
1449 * @param array The array to be set from the Allocation.
1450 */
1451 public void copyTo(Object array) {
1452 copyTo(array, validateObjectIsPrimitiveArray(array, true),
1453 java.lang.reflect.Array.getLength(array));
1454 }
1455
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001456 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001457 * Copy from the Allocation into a byte array. The array must be at least
1458 * as large as the Allocation. The allocation must be of an 8 bit integer
1459 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001460 *
1461 * @param d The array to be set from the Allocation.
1462 */
Jason Samsfa445b92011-01-07 17:00:07 -08001463 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001464 validateIsInt8();
Jason Sams3042d262013-11-25 18:28:33 -08001465 copyTo(d, Element.DataType.SIGNED_8, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001466 }
1467
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001468 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001469 * Copy from the Allocation into a short array. The array must be at least
1470 * as large as the Allocation. The allocation must be of an 16 bit integer
1471 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001472 *
1473 * @param d The array to be set from the Allocation.
1474 */
Jason Samsfa445b92011-01-07 17:00:07 -08001475 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001476 validateIsInt16();
Jason Sams3042d262013-11-25 18:28:33 -08001477 copyTo(d, Element.DataType.SIGNED_16, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001478 }
1479
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001480 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001481 * Copy from the Allocation into a int array. The array must be at least as
1482 * large as the Allocation. The allocation must be of an 32 bit integer
1483 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001484 *
1485 * @param d The array to be set from the Allocation.
1486 */
Jason Samsfa445b92011-01-07 17:00:07 -08001487 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001488 validateIsInt32();
Jason Sams3042d262013-11-25 18:28:33 -08001489 copyTo(d, Element.DataType.SIGNED_32, d.length);
Jason Samsfa445b92011-01-07 17:00:07 -08001490 }
1491
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001492 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001493 * Copy from the Allocation into a float array. The array must be at least
1494 * as large as the Allocation. The allocation must be of an 32 bit float
1495 * {@link android.renderscript.Element} type.
Jason Sams48fe5342011-07-08 13:52:30 -07001496 *
1497 * @param d The array to be set from the Allocation.
1498 */
Jason Samsfa445b92011-01-07 17:00:07 -08001499 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001500 validateIsFloat32();
Jason Sams3042d262013-11-25 18:28:33 -08001501 copyTo(d, Element.DataType.FLOAT_32, d.length);
Jason Sams40a29e82009-08-10 14:55:26 -07001502 }
1503
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001504 /**
Miao Wang3c613272015-05-11 11:41:55 -07001505 * @hide
1506 *
Miao Wang45cec0a2015-03-04 16:40:21 -08001507 * This is only intended to be used by auto-generated code reflected from
1508 * the RenderScript script files and should not be used by developers.
Miao Wangc8e237e2015-02-20 18:36:32 -08001509 *
1510 * @param xoff
1511 * @param yoff
1512 * @param zoff
1513 * @param component_number
Miao Wang258db502015-03-03 14:05:36 -08001514 * @param fp
Miao Wangc8e237e2015-02-20 18:36:32 -08001515 */
Miao Wang45cec0a2015-03-04 16:40:21 -08001516 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
Miao Wangc8e237e2015-02-20 18:36:32 -08001517 mRS.validate();
1518 if (component_number >= mType.mElement.mElements.length) {
1519 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1520 }
1521 if(xoff < 0) {
1522 throw new RSIllegalArgumentException("Offset x must be >= 0.");
1523 }
1524 if(yoff < 0) {
1525 throw new RSIllegalArgumentException("Offset y must be >= 0.");
1526 }
1527 if(zoff < 0) {
1528 throw new RSIllegalArgumentException("Offset z must be >= 0.");
1529 }
1530
Miao Wang45cec0a2015-03-04 16:40:21 -08001531 final byte[] data = fp.getData();
Miao Wangbfa5e652015-05-04 15:29:25 -07001532 int data_length = data.length;
Miao Wangc8e237e2015-02-20 18:36:32 -08001533 int eSize = mType.mElement.mElements[component_number].getBytesSize();
1534 eSize *= mType.mElement.mArraySizes[component_number];
1535
Miao Wang45cec0a2015-03-04 16:40:21 -08001536 if (data_length != eSize) {
1537 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1538 " does not match component size " + eSize + ".");
Miao Wangc8e237e2015-02-20 18:36:32 -08001539 }
1540
1541 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
Miao Wang45cec0a2015-03-04 16:40:21 -08001542 component_number, data, data_length);
Miao Wangc8e237e2015-02-20 18:36:32 -08001543 }
1544 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001545 * Resize a 1D allocation. The contents of the allocation are preserved.
1546 * If new elements are allocated objects are created with null contents and
1547 * the new region is otherwise undefined.
Jason Samsf7086092011-01-12 13:28:37 -08001548 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001549 * <p>If the new region is smaller the references of any objects outside the
1550 * new region will be released.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001551 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001552 * <p>A new type will be created with the new dimension.</p>
Jason Samsf7086092011-01-12 13:28:37 -08001553 *
1554 * @param dimX The new size of the allocation.
Jason Samsb05d6892013-04-09 15:59:24 -07001555 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001556 * @deprecated RenderScript objects should be immutable once created. The
Tim Murraycd38b762014-08-13 13:20:25 -07001557 * replacement is to create a new allocation and copy the contents. This
1558 * function will throw an exception if API 21 or higher is used.
Jason Samsf7086092011-01-12 13:28:37 -08001559 */
Jason Sams31a7e422010-10-26 13:09:17 -07001560 public synchronized void resize(int dimX) {
Tim Murraycd38b762014-08-13 13:20:25 -07001561 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) {
1562 throw new RSRuntimeException("Resize is not allowed in API 21+.");
1563 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001564 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001565 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001566 }
Jason Samse07694b2012-04-03 15:36:36 -07001567 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001568 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001569
Tim Murray460a0492013-11-19 12:45:54 -08001570 long typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001571 mType = new Type(typeID, mRS);
1572 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001573 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001574 }
1575
Miao Wangc8e237e2015-02-20 18:36:32 -08001576 private void copy1DRangeToUnchecked(int off, int count, Object array,
1577 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001578 try {
1579 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked");
1580 final int dataSize = mType.mElement.getBytesSize() * count;
1581 // AutoPadding for Vec3 Element
1582 boolean usePadding = false;
1583 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1584 usePadding = true;
1585 }
1586 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1587 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1588 mType.mElement.mType.mSize, usePadding);
1589 } finally {
1590 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001591 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001592 }
1593
1594 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001595 * Copy part of this Allocation into an array. This method does not
1596 * guarantee that the Allocation is compatible with the input buffer.
1597 *
1598 * @param off The offset of the first element to be copied.
1599 * @param count The number of elements to be copied.
1600 * @param array The dest data array
1601 */
1602 public void copy1DRangeToUnchecked(int off, int count, Object array) {
1603 copy1DRangeToUnchecked(off, count, array,
1604 validateObjectIsPrimitiveArray(array, false),
1605 java.lang.reflect.Array.getLength(array));
1606 }
1607
1608 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001609 * Copy part of this Allocation into an array. This method does not
1610 * guarantee that the Allocation is compatible with the input buffer.
1611 *
1612 * @param off The offset of the first element to be copied.
1613 * @param count The number of elements to be copied.
1614 * @param d the source data array
1615 */
1616 public void copy1DRangeToUnchecked(int off, int count, int[] d) {
1617 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1618 }
1619
1620 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001621 * Copy part of this Allocation into an array. This method does not
1622 * guarantee that the Allocation is compatible with the input buffer.
1623 *
1624 * @param off The offset of the first element to be copied.
1625 * @param count The number of elements to be copied.
1626 * @param d the source data array
1627 */
1628 public void copy1DRangeToUnchecked(int off, int count, short[] d) {
1629 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1630 }
1631
1632 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001633 * Copy part of this Allocation into an array. This method does not
1634 * guarantee that the Allocation is compatible with the input buffer.
1635 *
1636 * @param off The offset of the first element to be copied.
1637 * @param count The number of elements to be copied.
1638 * @param d the source data array
1639 */
1640 public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
1641 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1642 }
1643
1644 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001645 * Copy part of this Allocation into an array. This method does not
1646 * guarantee that the Allocation is compatible with the input buffer.
1647 *
1648 * @param off The offset of the first element to be copied.
1649 * @param count The number of elements to be copied.
1650 * @param d the source data array
1651 */
1652 public void copy1DRangeToUnchecked(int off, int count, float[] d) {
1653 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1654 }
1655
1656
1657 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001658 * Copy part of this Allocation into an array. This method does not
1659 * and will generate exceptions if the Allocation type does not
1660 * match the component type of the array passed in.
1661 *
1662 * @param off The offset of the first element to be copied.
1663 * @param count The number of elements to be copied.
1664 * @param array The source data array.
1665 */
1666 public void copy1DRangeTo(int off, int count, Object array) {
1667 copy1DRangeToUnchecked(off, count, array,
1668 validateObjectIsPrimitiveArray(array, true),
1669 java.lang.reflect.Array.getLength(array));
1670 }
1671
1672 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001673 * Copy part of this Allocation into an array. This method does not
1674 * and will generate exceptions if the Allocation type is not a 32 bit
1675 * integer type.
1676 *
1677 * @param off The offset of the first element to be copied.
1678 * @param count The number of elements to be copied.
1679 * @param d the source data array
1680 */
1681 public void copy1DRangeTo(int off, int count, int[] d) {
1682 validateIsInt32();
1683 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1684 }
1685
1686 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001687 * Copy part of this Allocation into an array. This method does not
1688 * and will generate exceptions if the Allocation type is not a 16 bit
1689 * integer type.
1690 *
1691 * @param off The offset of the first element to be copied.
1692 * @param count The number of elements to be copied.
1693 * @param d the source data array
1694 */
1695 public void copy1DRangeTo(int off, int count, short[] d) {
1696 validateIsInt16();
1697 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1698 }
1699
1700 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001701 * Copy part of this Allocation into an array. This method does not
1702 * and will generate exceptions if the Allocation type is not an 8 bit
1703 * integer type.
1704 *
1705 * @param off The offset of the first element to be copied.
1706 * @param count The number of elements to be copied.
1707 * @param d the source data array
1708 */
1709 public void copy1DRangeTo(int off, int count, byte[] d) {
1710 validateIsInt8();
1711 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1712 }
1713
1714 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001715 * Copy part of this Allocation into an array. This method does not
1716 * and will generate exceptions if the Allocation type is not a 32 bit float
1717 * type.
1718 *
1719 * @param off The offset of the first element to be copied.
1720 * @param count The number of elements to be copied.
1721 * @param d the source data array.
1722 */
1723 public void copy1DRangeTo(int off, int count, float[] d) {
1724 validateIsFloat32();
1725 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1726 }
1727
1728
1729 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
1730 Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001731 try {
1732 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked");
1733 mRS.validate();
1734 validate2DRange(xoff, yoff, w, h);
1735 final int dataSize = mType.mElement.getBytesSize() * w * h;
1736 // AutoPadding for Vec3 Element
1737 boolean usePadding = false;
1738 int sizeBytes = arrayLen * dt.mSize;
1739 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1740 if (dataSize / 4 * 3 > sizeBytes) {
1741 throw new RSIllegalArgumentException("Array too small for allocation type.");
1742 }
1743 usePadding = true;
1744 sizeBytes = dataSize;
1745 } else {
1746 if (dataSize > sizeBytes) {
1747 throw new RSIllegalArgumentException("Array too small for allocation type.");
1748 }
Miao Wang87e908d2015-03-02 15:15:15 -08001749 }
Chris Craik06d29842015-06-02 17:19:24 -07001750 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1751 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1752 } finally {
1753 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001754 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001755 }
1756
1757 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001758 * Copy from a rectangular region in this Allocation into an array.
1759 *
1760 * @param xoff X offset of the region to copy in this Allocation
1761 * @param yoff Y offset of the region to copy in this Allocation
1762 * @param w Width of the region to copy
1763 * @param h Height of the region to copy
1764 * @param array Dest Array to be copied into
1765 */
1766 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
1767 copy2DRangeToUnchecked(xoff, yoff, w, h, array,
1768 validateObjectIsPrimitiveArray(array, true),
1769 java.lang.reflect.Array.getLength(array));
1770 }
1771
1772 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001773 * Copy from a rectangular region in this Allocation into an array.
1774 *
1775 * @param xoff X offset of the region to copy in this Allocation
1776 * @param yoff Y offset of the region to copy in this Allocation
1777 * @param w Width of the region to copy
1778 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001779 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001780 */
1781 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
1782 validateIsInt8();
1783 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1784 Element.DataType.SIGNED_8, data.length);
1785 }
1786
1787 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001788 * Copy from a rectangular region in this Allocation into an array.
1789 *
1790 * @param xoff X offset of the region to copy in this Allocation
1791 * @param yoff Y offset of the region to copy in this Allocation
1792 * @param w Width of the region to copy
1793 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001794 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001795 */
1796 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
1797 validateIsInt16();
1798 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1799 Element.DataType.SIGNED_16, data.length);
1800 }
1801
1802 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001803 * Copy from a rectangular region in this Allocation into an array.
1804 *
1805 * @param xoff X offset of the region to copy in this Allocation
1806 * @param yoff Y offset of the region to copy in this Allocation
1807 * @param w Width of the region to copy
1808 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001809 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001810 */
1811 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
1812 validateIsInt32();
1813 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1814 Element.DataType.SIGNED_32, data.length);
1815 }
1816
1817 /**
Miao Wangc8e237e2015-02-20 18:36:32 -08001818 * Copy from a rectangular region in this Allocation into an array.
1819 *
1820 * @param xoff X offset of the region to copy in this Allocation
1821 * @param yoff Y offset of the region to copy in this Allocation
1822 * @param w Width of the region to copy
1823 * @param h Height of the region to copy
Miao Wang87e908d2015-03-02 15:15:15 -08001824 * @param data Dest Array to be copied into
Miao Wangc8e237e2015-02-20 18:36:32 -08001825 */
1826 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
1827 validateIsFloat32();
1828 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1829 Element.DataType.FLOAT_32, data.length);
1830 }
1831
1832
1833 /**
Miao Wang258db502015-03-03 14:05:36 -08001834 * Copy from a rectangular region in this Allocation into an array.
1835 * The array is assumed to be tightly packed.
Miao Wangc8e237e2015-02-20 18:36:32 -08001836 *
Miao Wang258db502015-03-03 14:05:36 -08001837 * The data type of the array is not required to be the same as
1838 * the element data type.
Miao Wangc8e237e2015-02-20 18:36:32 -08001839 */
1840 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1841 Object array, Element.DataType dt, int arrayLen) {
Chris Craik06d29842015-06-02 17:19:24 -07001842 try {
1843 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked");
1844 mRS.validate();
1845 validate3DRange(xoff, yoff, zoff, w, h, d);
1846 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1847 // AutoPadding for Vec3 Element
1848 boolean usePadding = false;
1849 int sizeBytes = arrayLen * dt.mSize;
1850 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1851 if (dataSize / 4 * 3 > sizeBytes) {
1852 throw new RSIllegalArgumentException("Array too small for allocation type.");
1853 }
1854 usePadding = true;
1855 sizeBytes = dataSize;
1856 } else {
1857 if (dataSize > sizeBytes) {
1858 throw new RSIllegalArgumentException("Array too small for allocation type.");
1859 }
Miao Wang87e908d2015-03-02 15:15:15 -08001860 }
Chris Craik06d29842015-06-02 17:19:24 -07001861 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1862 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1863 } finally {
1864 Trace.traceEnd(RenderScript.TRACE_TAG);
Miao Wang87e908d2015-03-02 15:15:15 -08001865 }
Miao Wangc8e237e2015-02-20 18:36:32 -08001866 }
1867
Miao Wang258db502015-03-03 14:05:36 -08001868 /*
Miao Wangc8e237e2015-02-20 18:36:32 -08001869 * Copy from a rectangular region in this Allocation into an array.
1870 *
1871 * @param xoff X offset of the region to copy in this Allocation
1872 * @param yoff Y offset of the region to copy in this Allocation
1873 * @param zoff Z offset of the region to copy in this Allocation
1874 * @param w Width of the region to copy
1875 * @param h Height of the region to copy
1876 * @param d Depth of the region to copy
1877 * @param array Dest Array to be copied into
1878 */
1879 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1880 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
1881 validateObjectIsPrimitiveArray(array, true),
1882 java.lang.reflect.Array.getLength(array));
1883 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001884
1885 // creation
1886
Jason Sams49a05d72010-12-29 14:31:29 -08001887 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001888 static {
1889 mBitmapOptions.inScaled = false;
1890 }
1891
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001892 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001893 * Creates a new Allocation with the given {@link
1894 * android.renderscript.Type}, mipmap flag, and usage flags.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001895 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001896 * @param type RenderScript type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001897 * @param mips specifies desired mipmap behaviour for the
1898 * allocation
Tim Murrayc11e25c2013-04-09 11:01:01 -07001899 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001900 * utilized
1901 */
1902 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001903 try {
1904 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
1905 rs.validate();
1906 if (type.getID(rs) == 0) {
1907 throw new RSInvalidStateException("Bad Type");
1908 }
1909 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
1910 if (id == 0) {
1911 throw new RSRuntimeException("Allocation creation failed.");
1912 }
Miao Wang8c150922015-10-26 17:44:10 -07001913 return new Allocation(id, rs, type, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07001914 } finally {
1915 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Sams1bada8c2009-08-09 17:01:55 -07001916 }
Jason Sams857d0c72011-11-23 15:02:15 -08001917 }
1918
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001919 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001920 * Creates an Allocation with the size specified by the type and no mipmaps
1921 * generated by default
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001922 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001923 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001924 * @param type renderscript type describing data layout
1925 * @param usage bit field specifying how the allocation is
1926 * utilized
1927 *
1928 * @return allocation
1929 */
Jason Samse5d37122010-12-16 00:33:33 -08001930 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1931 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1932 }
1933
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001934 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001935 * Creates an Allocation for use by scripts with a given {@link
1936 * android.renderscript.Type} and no mipmaps
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001937 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001938 * @param rs Context to which the Allocation will belong.
1939 * @param type RenderScript Type describing data layout
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001940 *
1941 * @return allocation
1942 */
Jason Sams5476b452010-12-08 16:14:36 -08001943 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001944 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001945 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001946
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001947 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001948 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001949 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001950 * @param rs Context to which the Allocation will belong.
1951 * @param e Element to use in the Allocation
1952 * @param count the number of Elements in the Allocation
1953 * @param usage bit field specifying how the Allocation is
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001954 * utilized
1955 *
1956 * @return allocation
1957 */
Jason Sams5476b452010-12-08 16:14:36 -08001958 static public Allocation createSized(RenderScript rs, Element e,
1959 int count, int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07001960 try {
1961 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
1962 rs.validate();
1963 Type.Builder b = new Type.Builder(rs, e);
1964 b.setX(count);
1965 Type t = b.create();
Jason Sams768bc022009-09-21 19:41:04 -07001966
Chris Craik06d29842015-06-02 17:19:24 -07001967 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
1968 if (id == 0) {
1969 throw new RSRuntimeException("Allocation creation failed.");
1970 }
Miao Wang8c150922015-10-26 17:44:10 -07001971 return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
Chris Craik06d29842015-06-02 17:19:24 -07001972 } finally {
1973 Trace.traceEnd(RenderScript.TRACE_TAG);
Jason Samsb8c5a842009-07-31 20:40:47 -07001974 }
Jason Sams5476b452010-12-08 16:14:36 -08001975 }
1976
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001977 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07001978 * Creates an Allocation with a specified number of given elements
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001979 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07001980 * @param rs Context to which the Allocation will belong.
1981 * @param e Element to use in the Allocation
1982 * @param count the number of Elements in the Allocation
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001983 *
1984 * @return allocation
1985 */
Jason Sams5476b452010-12-08 16:14:36 -08001986 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001987 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001988 }
1989
Jason Sams49a05d72010-12-29 14:31:29 -08001990 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08001991 final Bitmap.Config bc = b.getConfig();
1992 if (bc == Bitmap.Config.ALPHA_8) {
1993 return Element.A_8(rs);
1994 }
1995 if (bc == Bitmap.Config.ARGB_4444) {
1996 return Element.RGBA_4444(rs);
1997 }
1998 if (bc == Bitmap.Config.ARGB_8888) {
1999 return Element.RGBA_8888(rs);
2000 }
2001 if (bc == Bitmap.Config.RGB_565) {
2002 return Element.RGB_565(rs);
2003 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08002004 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08002005 }
2006
Jason Sams49a05d72010-12-29 14:31:29 -08002007 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002008 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08002009 Element e = elementFromBitmap(rs, b);
2010 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002011 tb.setX(b.getWidth());
2012 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08002013 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08002014 return tb.create();
2015 }
2016
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002017 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002018 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002019 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002020 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002021 * @param b Bitmap source for the allocation data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002022 * @param mips specifies desired mipmap behaviour for the
2023 * allocation
2024 * @param usage bit field specifying how the allocation is
2025 * utilized
2026 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002027 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002028 *
2029 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002030 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002031 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002032 int usage) {
Chris Craik06d29842015-06-02 17:19:24 -07002033 try {
2034 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
2035 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08002036
Chris Craik06d29842015-06-02 17:19:24 -07002037 // WAR undocumented color formats
2038 if (b.getConfig() == null) {
2039 if ((usage & USAGE_SHARED) != 0) {
2040 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2041 }
2042 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2043 Canvas c = new Canvas(newBitmap);
2044 c.drawBitmap(b, 0, 0, null);
2045 return createFromBitmap(rs, newBitmap, mips, usage);
Tim Murrayabd5db92013-02-28 11:45:22 -08002046 }
Tim Murrayabd5db92013-02-28 11:45:22 -08002047
Chris Craik06d29842015-06-02 17:19:24 -07002048 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08002049
Chris Craik06d29842015-06-02 17:19:24 -07002050 // enable optimized bitmap path only with no mipmap and script-only usage
2051 if (mips == MipmapControl.MIPMAP_NONE &&
2052 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2053 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2054 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2055 if (id == 0) {
2056 throw new RSRuntimeException("Load failed.");
2057 }
2058
2059 // keep a reference to the Bitmap around to prevent GC
Miao Wang8c150922015-10-26 17:44:10 -07002060 Allocation alloc = new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002061 alloc.setBitmap(b);
2062 return alloc;
2063 }
2064
2065
2066 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Tim Murraya3145512012-12-04 17:59:29 -08002067 if (id == 0) {
2068 throw new RSRuntimeException("Load failed.");
2069 }
Miao Wang8c150922015-10-26 17:44:10 -07002070 return new Allocation(id, rs, t, usage, mips);
Chris Craik06d29842015-06-02 17:19:24 -07002071 } finally {
2072 Trace.traceEnd(RenderScript.TRACE_TAG);
Tim Murraya3145512012-12-04 17:59:29 -08002073 }
Jason Sams5476b452010-12-08 16:14:36 -08002074 }
2075
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002076 /**
Miao Wang0facf022015-11-25 11:21:13 -08002077 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
2078 * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
2079 * would contain the up-to-date data as READ ONLY.
2080 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2081 * the Allocation has certain alignment. The size of each row including padding,
2082 * called stride, can be queried using the {@link #getStride()} method.
2083 *
2084 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
2085 *
2086 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
2087 */
2088 public ByteBuffer getByteBuffer() {
2089 // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
2090 if (mType.hasFaces()) {
2091 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
2092 }
2093 if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
2094 mType.getYuv() == android.graphics.ImageFormat.YV12 ||
2095 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
2096 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
2097 }
2098 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
2099 int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
2100 long[] stride = new long[1];
2101 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
2102 mByteBufferStride = stride[0];
2103 }
2104 if ((mUsage & USAGE_IO_INPUT) != 0) {
2105 return mByteBuffer.asReadOnlyBuffer();
2106 }
2107 return mByteBuffer;
2108 }
2109
2110 /**
Miao Wang8c150922015-10-26 17:44:10 -07002111 * Creates a new Allocation Array with the given {@link
2112 * android.renderscript.Type}, and usage flags.
2113 * Note: If the input allocation is of usage: USAGE_IO_INPUT,
2114 * the created Allocation will be sharing the same BufferQueue.
2115 *
2116 * @param rs RenderScript context
2117 * @param t RenderScript type describing data layout
2118 * @param usage bit field specifying how the Allocation is
2119 * utilized
2120 * @param numAlloc Number of Allocations in the array.
2121 * @return Allocation[]
2122 */
2123 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
2124 try {
2125 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
2126 rs.validate();
2127 if (t.getID(rs) == 0) {
2128 throw new RSInvalidStateException("Bad Type");
2129 }
2130
2131 Allocation[] mAllocationArray = new Allocation[numAlloc];
2132 mAllocationArray[0] = createTyped(rs, t, usage);
2133 if ((usage & USAGE_IO_INPUT) != 0) {
2134 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
2135 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2136 MAX_NUMBER_IO_INPUT_ALLOC);
2137 }
2138 mAllocationArray[0].setupBufferQueue(numAlloc);;
2139 }
2140
2141 for (int i=1; i<numAlloc; i++) {
2142 mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
2143 }
2144 return mAllocationArray;
2145 } finally {
2146 Trace.traceEnd(RenderScript.TRACE_TAG);
2147 }
2148 }
2149
2150 /**
2151 * Creates a new Allocation with the given {@link
2152 * android.renderscript.Allocation}. The same data layout of
2153 * the input Allocation will be applied.
2154 * If the input allocation is of usage: USAGE_IO_INPUT, the created
2155 * Allocation will be sharing the same BufferQueue.
2156 *
2157 * @param rs Context to which the allocation will belong.
2158 * @param alloc RenderScript Allocation describing data layout.
2159 * @return Allocation sharing the same data structure.
2160 */
2161 static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
2162 try {
2163 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2164 rs.validate();
2165 if (alloc.getID(rs) == 0) {
2166 throw new RSInvalidStateException("Bad input Allocation");
2167 }
2168
2169 Type type = alloc.getType();
2170 int usage = alloc.getUsage();
2171 MipmapControl mips = alloc.getMipmap();
2172 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2173 if (id == 0) {
2174 throw new RSRuntimeException("Allocation creation failed.");
2175 }
2176 Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
2177 if ((usage & USAGE_IO_INPUT) != 0) {
2178 outAlloc.shareBufferQueue(alloc);
2179 }
2180 return outAlloc;
2181 } finally {
2182 Trace.traceEnd(RenderScript.TRACE_TAG);
2183 }
2184 }
2185
2186 /**
2187 * Initialize BufferQueue with specified max number of buffers.
2188 */
2189 void setupBufferQueue(int numAlloc) {
2190 mRS.validate();
2191 if ((mUsage & USAGE_IO_INPUT) == 0) {
2192 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2193 }
2194 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2195 }
2196
2197 /**
2198 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2199 *
2200 * @param alloc Allocation to associate with allocation
2201 */
2202 void shareBufferQueue(Allocation alloc) {
2203 mRS.validate();
2204 if ((mUsage & USAGE_IO_INPUT) == 0) {
2205 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2206 }
2207 mGetSurfaceSurface = alloc.getSurface();
2208 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2209 }
2210
2211 /**
Miao Wang0facf022015-11-25 11:21:13 -08002212 * Gets the stride of the Allocation.
2213 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2214 * the Allocation has certain alignment. The size of each row including such
2215 * padding is called stride.
2216 *
2217 * @return the stride. For 1D Allocation, the stride will be the number of
2218 * bytes of this Allocation. For 2D and 3D Allocations, the stride
2219 * will be the stride in X dimension measuring in bytes.
2220 */
2221 public long getStride() {
2222 if (mByteBufferStride == -1) {
2223 getByteBuffer();
2224 }
2225 return mByteBufferStride;
2226 }
2227
2228 /**
Miao Wang8c150922015-10-26 17:44:10 -07002229 * Get the timestamp for the most recent buffer held by this Allocation.
2230 * The timestamp is guaranteed to be unique and monotonically increasing.
2231 * Default value: -1. The timestamp will be updated after each {@link
2232 * #ioReceive ioReceive()} call.
2233 *
2234 * It can be used to identify the images by comparing the unique timestamps
2235 * when used with {@link android.hardware.camera2} APIs.
2236 * Example steps:
2237 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
2238 * capture is completed.
2239 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
2240 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
2241 * alloc.getTimeStamp().
2242 * @return long Timestamp associated with the buffer held by the Allocation.
2243 */
2244 public long getTimeStamp() {
2245 return mTimeStamp;
2246 }
2247
2248 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002249 * Returns the handle to a raw buffer that is being managed by the screen
2250 * compositor. This operation is only valid for Allocations with {@link
2251 * #USAGE_IO_INPUT}.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002252 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002253 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002254 *
2255 */
2256 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08002257 if ((mUsage & USAGE_IO_INPUT) == 0) {
2258 throw new RSInvalidStateException("Allocation is not a surface texture.");
2259 }
Jason Sams1e68bac2015-03-17 16:36:55 -07002260
2261 if (mGetSurfaceSurface == null) {
2262 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
2263 }
2264
2265 return mGetSurfaceSurface;
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002266 }
2267
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002268 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002269 * Associate a {@link android.view.Surface} with this Allocation. This
2270 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07002271 *
2272 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08002273 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07002274 public void setSurface(Surface sur) {
2275 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08002276 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2277 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2278 }
2279
Jason Samse07694b2012-04-03 15:36:36 -07002280 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08002281 }
2282
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002283 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002284 * Creates an Allocation from a {@link android.graphics.Bitmap}.
Tim Murray00bb4542012-12-17 16:35:06 -08002285 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002286 * <p>With target API version 18 or greater, this Allocation will be created
2287 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
2288 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
2289 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002290 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002291 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002292 * @param b bitmap source for the allocation data
2293 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002294 * @return Allocation containing bitmap data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002295 *
2296 */
Jason Sams6d8eb262010-12-15 01:41:00 -08002297 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08002298 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2299 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Tim Murray78e64942013-04-09 17:28:56 -07002300 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Tim Murray00bb4542012-12-17 16:35:06 -08002301 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002302 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2303 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08002304 }
2305
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002306 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002307 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2308 * containing the horizontal list of cube faces. Each face must be a square,
2309 * have the same size as all other faces, and have a width that is a power
2310 * of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002311 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002312 * @param rs Context to which the allocation will belong.
Tim Murrayc11e25c2013-04-09 11:01:01 -07002313 * @param b Bitmap with cubemap faces layed out in the following
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002314 * format: right, left, top, bottom, front, back
2315 * @param mips specifies desired mipmap behaviour for the cubemap
2316 * @param usage bit field specifying how the cubemap is utilized
2317 *
2318 * @return allocation containing cubemap data
2319 *
2320 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002321 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08002322 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002323 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002324 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08002325
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002326 int height = b.getHeight();
2327 int width = b.getWidth();
2328
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002329 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002330 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2331 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002332 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002333 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002334 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002335 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002336 if (!isPow2) {
2337 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2338 }
2339
2340 Element e = elementFromBitmap(rs, b);
2341 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002342 tb.setX(height);
2343 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002344 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08002345 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002346 Type t = tb.create();
2347
Tim Murray460a0492013-11-19 12:45:54 -08002348 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002349 if(id == 0) {
2350 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2351 }
Miao Wang8c150922015-10-26 17:44:10 -07002352 return new Allocation(id, rs, t, usage, mips);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08002353 }
2354
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002355 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002356 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2357 * from a {@link android.graphics.Bitmap} containing the horizontal list of
2358 * cube faces. Each face must be a square, have the same size as all other
2359 * faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002360 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002361 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002362 * @param b bitmap with cubemap faces layed out in the following
2363 * format: right, left, top, bottom, front, back
2364 *
2365 * @return allocation containing cubemap data
2366 *
2367 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002368 static public Allocation createCubemapFromBitmap(RenderScript rs,
2369 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08002370 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08002371 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08002372 }
2373
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002374 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002375 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2376 * objects containing the cube faces. Each face must be a square, have the
2377 * same size as all other faces, and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002378 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002379 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002380 * @param xpos cubemap face in the positive x direction
2381 * @param xneg cubemap face in the negative x direction
2382 * @param ypos cubemap face in the positive y direction
2383 * @param yneg cubemap face in the negative y direction
2384 * @param zpos cubemap face in the positive z direction
2385 * @param zneg cubemap face in the negative z direction
2386 * @param mips specifies desired mipmap behaviour for the cubemap
2387 * @param usage bit field specifying how the cubemap is utilized
2388 *
2389 * @return allocation containing cubemap data
2390 *
2391 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002392 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2393 Bitmap xpos,
2394 Bitmap xneg,
2395 Bitmap ypos,
2396 Bitmap yneg,
2397 Bitmap zpos,
2398 Bitmap zneg,
2399 MipmapControl mips,
2400 int usage) {
2401 int height = xpos.getHeight();
2402 if (xpos.getWidth() != height ||
2403 xneg.getWidth() != height || xneg.getHeight() != height ||
2404 ypos.getWidth() != height || ypos.getHeight() != height ||
2405 yneg.getWidth() != height || yneg.getHeight() != height ||
2406 zpos.getWidth() != height || zpos.getHeight() != height ||
2407 zneg.getWidth() != height || zneg.getHeight() != height) {
2408 throw new RSIllegalArgumentException("Only square cube map faces supported");
2409 }
2410 boolean isPow2 = (height & (height - 1)) == 0;
2411 if (!isPow2) {
2412 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2413 }
2414
2415 Element e = elementFromBitmap(rs, xpos);
2416 Type.Builder tb = new Type.Builder(rs, e);
2417 tb.setX(height);
2418 tb.setY(height);
2419 tb.setFaces(true);
2420 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2421 Type t = tb.create();
2422 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2423
2424 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07002425 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002426 adapter.copyFrom(xpos);
2427 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2428 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002429 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002430 adapter.copyFrom(ypos);
2431 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2432 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07002433 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002434 adapter.copyFrom(zpos);
2435 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2436 adapter.copyFrom(zneg);
2437
2438 return cubemap;
2439 }
2440
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002441 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002442 * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2443 * from 6 {@link android.graphics.Bitmap} objects containing the cube
2444 * faces. Each face must be a square, have the same size as all other faces,
2445 * and have a width that is a power of 2.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002446 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002447 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002448 * @param xpos cubemap face in the positive x direction
2449 * @param xneg cubemap face in the negative x direction
2450 * @param ypos cubemap face in the positive y direction
2451 * @param yneg cubemap face in the negative y direction
2452 * @param zpos cubemap face in the positive z direction
2453 * @param zneg cubemap face in the negative z direction
2454 *
2455 * @return allocation containing cubemap data
2456 *
2457 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08002458 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2459 Bitmap xpos,
2460 Bitmap xneg,
2461 Bitmap ypos,
2462 Bitmap yneg,
2463 Bitmap zpos,
2464 Bitmap zneg) {
2465 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2466 zpos, zneg, MipmapControl.MIPMAP_NONE,
2467 USAGE_GRAPHICS_TEXTURE);
2468 }
2469
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002470 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002471 * Creates an Allocation from the Bitmap referenced
2472 * by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002473 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002474 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002475 * @param res application resources
2476 * @param id resource id to load the data from
2477 * @param mips specifies desired mipmap behaviour for the
2478 * allocation
2479 * @param usage bit field specifying how the allocation is
2480 * utilized
2481 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002482 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002483 *
2484 */
Jason Sams5476b452010-12-08 16:14:36 -08002485 static public Allocation createFromBitmapResource(RenderScript rs,
2486 Resources res,
2487 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08002488 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08002489 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07002490
Jason Sams771bebb2009-12-07 12:40:12 -08002491 rs.validate();
Jason Sams3ece2f32013-05-31 14:00:46 -07002492 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2493 throw new RSIllegalArgumentException("Unsupported usage specified.");
2494 }
Jason Sams5476b452010-12-08 16:14:36 -08002495 Bitmap b = BitmapFactory.decodeResource(res, id);
2496 Allocation alloc = createFromBitmap(rs, b, mips, usage);
2497 b.recycle();
2498 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07002499 }
2500
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002501 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002502 * Creates a non-mipmapped Allocation to use as a graphics texture from the
2503 * {@link android.graphics.Bitmap} referenced by resource ID.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002504 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002505 * <p>With target API version 18 or greater, this allocation will be created
2506 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
2507 * target API version 17 or lower, this allocation will be created with
2508 * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
Jason Sams455d6442013-02-05 19:20:18 -08002509 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002510 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002511 * @param res application resources
2512 * @param id resource id to load the data from
2513 *
Tim Murrayc11e25c2013-04-09 11:01:01 -07002514 * @return Allocation containing resource data
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002515 *
2516 */
Jason Sams5476b452010-12-08 16:14:36 -08002517 static public Allocation createFromBitmapResource(RenderScript rs,
2518 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08002519 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08002520 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2521 return createFromBitmapResource(rs, res, id,
2522 MipmapControl.MIPMAP_NONE,
Jason Sams3ece2f32013-05-31 14:00:46 -07002523 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
Jason Sams455d6442013-02-05 19:20:18 -08002524 }
Jason Sams6d8eb262010-12-15 01:41:00 -08002525 return createFromBitmapResource(rs, res, id,
2526 MipmapControl.MIPMAP_NONE,
2527 USAGE_GRAPHICS_TEXTURE);
2528 }
2529
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07002530 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002531 * Creates an Allocation containing string data encoded in UTF-8 format.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002532 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08002533 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08002534 * @param str string to create the allocation from
2535 * @param usage bit field specifying how the allocaiton is
2536 * utilized
2537 *
2538 */
Jason Sams5476b452010-12-08 16:14:36 -08002539 static public Allocation createFromString(RenderScript rs,
2540 String str,
2541 int usage) {
2542 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002543 byte[] allocArray = null;
2544 try {
2545 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08002546 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08002547 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002548 return alloc;
2549 }
2550 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08002551 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002552 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07002553 }
Jason Sams739c8262013-04-11 18:07:52 -07002554
2555 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002556 * Interface to handle notification when new buffers are available via
2557 * {@link #USAGE_IO_INPUT}. An application will receive one notification
2558 * when a buffer is available. Additional buffers will not trigger new
2559 * notifications until a buffer is processed.
Jason Sams739c8262013-04-11 18:07:52 -07002560 */
Jason Sams42ef2382013-08-29 13:30:59 -07002561 public interface OnBufferAvailableListener {
Jason Sams739c8262013-04-11 18:07:52 -07002562 public void onBufferAvailable(Allocation a);
2563 }
2564
2565 /**
Tim Murrayc11e25c2013-04-09 11:01:01 -07002566 * Set a notification handler for {@link #USAGE_IO_INPUT}.
Jason Sams739c8262013-04-11 18:07:52 -07002567 *
Jason Sams42ef2382013-08-29 13:30:59 -07002568 * @param callback instance of the OnBufferAvailableListener
2569 * class to be called when buffer arrive.
Jason Sams739c8262013-04-11 18:07:52 -07002570 */
Jason Sams42ef2382013-08-29 13:30:59 -07002571 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
Jason Sams739c8262013-04-11 18:07:52 -07002572 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002573 mAllocationMap.put(new Long(getID(mRS)), this);
Jason Sams739c8262013-04-11 18:07:52 -07002574 mBufferNotifier = callback;
2575 }
2576 }
2577
Tim Murrayb730d862014-08-18 16:14:24 -07002578 static void sendBufferNotification(long id) {
Jason Sams739c8262013-04-11 18:07:52 -07002579 synchronized(mAllocationMap) {
Tim Murray460a0492013-11-19 12:45:54 -08002580 Allocation a = mAllocationMap.get(new Long(id));
Jason Sams739c8262013-04-11 18:07:52 -07002581
2582 if ((a != null) && (a.mBufferNotifier != null)) {
2583 a.mBufferNotifier.onBufferAvailable(a);
2584 }
2585 }
2586 }
2587
Miao Wangf0f6e802015-02-03 17:16:43 -08002588 /**
2589 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
2590 *
2591 */
2592 @Override
2593 public void destroy() {
2594 if((mUsage & USAGE_IO_OUTPUT) != 0) {
2595 setSurface(null);
2596 }
2597 super.destroy();
2598 }
Jason Samsb8c5a842009-07-31 20:40:47 -07002599}