• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008-2012 The Android Open Source Project
3  *
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 
17 package androidx.renderscript;
18 
19 import java.nio.ByteBuffer;
20 import java.util.concurrent.locks.ReentrantReadWriteLock;
21 
22 import android.content.res.Resources;
23 import android.graphics.Bitmap;
24 import android.graphics.BitmapFactory;
25 import android.graphics.Canvas;
26 import android.util.Log;
27 import android.view.Surface;
28 
29 /**
30  * <p> This class provides the primary method through which data is passed to
31  * and from RenderScript kernels.  An Allocation provides the backing store for
32  * a given {@link androidx.renderscript.Type}.  </p>
33  *
34  * <p>An Allocation also contains a set of usage flags that denote how the
35  * Allocation could be used. For example, an Allocation may have usage flags
36  * specifying that it can be used from a script as well as input to a {@link
37  * androidx.renderscript.Sampler}. A developer must synchronize
38  * across these different usages using
39  * {@link androidx.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.
45  *
46  * <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>
49  *
50  * <div class="special reference">
51  * <h3>Developer Guides</h3>
52  * <p>For more information about creating an application that uses
53  * RenderScript, read the
54  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
55  * developer guide.</p>
56  * </div>
57  *
58  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
59  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
60  * guide</a> for the proposed alternatives.
61  **/
62 @Deprecated
63 public class Allocation extends BaseObj {
64     Type mType;
65     Bitmap mBitmap;
66     int mUsage;
67     int mSize;
68     Allocation mAdaptedAllocation;
69     ByteBuffer mByteBuffer = null;
70     long mByteBufferStride = 0;
71 
72     boolean mConstrainedLOD;
73     boolean mConstrainedFace;
74     boolean mConstrainedY;
75     boolean mConstrainedZ;
76     boolean mReadAllowed = true;
77     boolean mWriteAllowed = true;
78     boolean mAutoPadding = false;
79     int mSelectedY;
80     int mSelectedZ;
81     int mSelectedLOD;
82     Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
83 
84     int mCurrentDimX;
85     int mCurrentDimY;
86     int mCurrentDimZ;
87     int mCurrentCount;
88 
validateObjectIsPrimitiveArray(Object d, boolean checkType)89     private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
90         final Class c = d.getClass();
91         if (!c.isArray()) {
92             throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
93         }
94         final Class cmp = c.getComponentType();
95         if (!cmp.isPrimitive()) {
96             throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
97         }
98 
99         if (cmp == Long.TYPE) {
100             if (checkType) {
101                 validateIsInt64();
102                 return mType.mElement.mType;
103             }
104             return Element.DataType.SIGNED_64;
105         }
106 
107         if (cmp == Integer.TYPE) {
108             if (checkType) {
109                 validateIsInt32();
110                 return mType.mElement.mType;
111             }
112             return Element.DataType.SIGNED_32;
113         }
114 
115         if (cmp == Short.TYPE) {
116             if (checkType) {
117                 validateIsInt16();
118                 return mType.mElement.mType;
119             }
120             return Element.DataType.SIGNED_16;
121         }
122 
123         if (cmp == Byte.TYPE) {
124             if (checkType) {
125                 validateIsInt8();
126                 return mType.mElement.mType;
127             }
128             return Element.DataType.SIGNED_8;
129         }
130 
131         if (cmp == Float.TYPE) {
132             if (checkType) {
133                 validateIsFloat32();
134             }
135             return Element.DataType.FLOAT_32;
136         }
137 
138         if (cmp == Double.TYPE) {
139             if (checkType) {
140                 validateIsFloat64();
141             }
142             return Element.DataType.FLOAT_64;
143         }
144         return null;
145     }
146 
147     /*
148      * Hold reference to the shared allocation in compat context
149      * for Incremental Support Lib.
150      */
151     long mIncCompatAllocation;
152     boolean mIncAllocDestroyed;
153     /**
154      * The usage of the Allocation.  These signal to RenderScript where to place
155      * the Allocation in memory.
156      *
157      */
158 
159     /**
160      * The Allocation will be bound to and accessed by scripts.
161      */
162     public static final int USAGE_SCRIPT = 0x0001;
163 
164     /**
165      * The Allocation will be used as a texture source by one or more graphics
166      * programs.
167      *
168      */
169     public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
170 
171     /**
172      * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
173      * consumer.  This usage will cause the Allocation to be created as
174      * read-only.
175      *
176      */
177     public static final int USAGE_IO_INPUT = 0x0020;
178 
179     /**
180      * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
181      * producer.  The dimensions and format of the {@link
182      * android.graphics.SurfaceTexture} will be forced to those of the
183      * Allocation.
184      *
185      */
186     public static final int USAGE_IO_OUTPUT = 0x0040;
187 
188     /**
189      * The Allocation's backing store will be inherited from another object
190      * (usually a {@link android.graphics.Bitmap}); copying to or from the
191      * original source Bitmap will cause a synchronization rather than a full
192      * copy.  {@link #syncAll} may also be used to synchronize the Allocation
193      * and the source Bitmap.
194      *
195      * <p>This is set by default for allocations created with {@link
196      * #createFromBitmap} in API version 18 and higher.</p>
197      *
198      */
199     public static final int USAGE_SHARED = 0x0080;
200 
201     /**
202      * Controls mipmap behavior when using the bitmap creation and update
203      * functions.
204      */
205     public enum MipmapControl {
206         /**
207          * No mipmaps will be generated and the type generated from the incoming
208          * bitmap will not contain additional LODs.
209          */
210         MIPMAP_NONE(0),
211 
212         /**
213          * A full mipmap chain will be created in script memory.  The Type of
214          * the Allocation will contain a full mipmap chain.  On upload, the full
215          * chain will be transferred.
216          */
217         MIPMAP_FULL(1),
218 
219         /**
220          * The Type of the Allocation will be the same as MIPMAP_NONE.  It will
221          * not contain mipmaps.  On upload, the allocation data will contain a
222          * full mipmap chain generated from the top level in script memory.
223          */
224         MIPMAP_ON_SYNC_TO_TEXTURE(2);
225 
226         int mID;
MipmapControl(int id)227         MipmapControl(int id) {
228             mID = id;
229         }
230     }
231 
232     /**
233      * Getter & Setter for the placeholder allocation for Inc Support Lib.
234      *
235      */
getIncAllocID()236     public long getIncAllocID() {
237         return mIncCompatAllocation;
238     }
setIncAllocID(long id)239     public void setIncAllocID(long id) {
240         mIncCompatAllocation = id;
241     }
242 
getIDSafe()243     private long getIDSafe() {
244         if (mAdaptedAllocation != null) {
245             return mAdaptedAllocation.getID(mRS);
246         }
247         return getID(mRS);
248     }
249 
250 
251    /**
252      * Get the {@link androidx.renderscript.Element} of the {@link
253      * androidx.renderscript.Type} of the Allocation.
254      *
255      * @return Element
256      *
257      */
getElement()258     public Element getElement() {
259         return mType.getElement();
260     }
261 
262     /**
263      * Get the usage flags of the Allocation.
264      *
265      * @return usage this Allocation's set of the USAGE_* flags OR'd together
266      *
267      */
getUsage()268     public int getUsage() {
269         return mUsage;
270     }
271 
272     /**
273      * Specifies the mapping between the Allocation's cells and an array's elements
274      * when data is copied from the Allocation to the array, or vice-versa.
275      *
276      * Only applies to an Allocation whose Element is a vector of length 3 (such as
277      * {@link Element#U8_3} or {@link Element#RGB_888}). Enabling this feature may make
278      * copying data from the Allocation to an array or vice-versa less efficient.
279      *
280      * <p> Vec3 Element cells are stored in an Allocation as Vec4 Element cells with
281      * the same {@link androidx.renderscript.Element.DataType}, with the fourth vector
282      * component treated as padding. When this feature is enabled, only the data components,
283      * i.e. the first 3 vector components of each cell, will be mapped between the array
284      * and the Allocation. When disabled, explicit mapping of the padding components
285      * is required, as described in the following example.
286      *
287      * <p> For example, when copying an integer array to an Allocation of two {@link
288      * Element#I32_3} cells using {@link #copyFrom(int[])}:
289      * <p> When disabled:
290      *     The array must have at least 8 integers, with the first 4 integers copied
291      *     to the first cell of the Allocation, and the next 4 integers copied to
292      *     the second cell. The 4th and 8th integers are mapped as the padding components.
293      *
294      * <p> When enabled:
295      *     The array just needs to have at least 6 integers, with the first 3 integers
296      *     copied to the the first cell as data components, and the next 3 copied to
297      *     the second cell. There is no mapping for the padding components.
298      *
299      * <p> Similarly, when copying a byte array to an Allocation of two {@link
300      * Element#I32_3} cells, using {@link #copyFromUnchecked(int[])}:
301      * <p> When disabled:
302      *     The array must have at least 32 bytes, with the first 16 bytes copied
303      *     to the first cell of the Allocation, and the next 16 bytes copied to
304      *     the second cell. The 13th-16th and 29th-32nd bytes are mapped as padding
305      *     components.
306      *
307      * <p> When enabled:
308      *     The array just needs to have at least 24 bytes, with the first 12 bytes copied
309      *     to the first cell of the Allocation, and the next 12 bytes copied to
310      *     the second cell. There is no mapping for the padding components.
311      *
312      * <p> Similar to copying data to an Allocation from an array, when copying data from an
313      * Allocation to an array, the padding components for Vec3 Element cells will not be
314      * copied/mapped to the array if AutoPadding is enabled.
315      *
316      * <p> Default: Disabled.
317      *
318      * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
319      *
320      */
setAutoPadding(boolean useAutoPadding)321     public void setAutoPadding(boolean useAutoPadding) {
322         mAutoPadding = useAutoPadding;
323     }
324 
325     /**
326      * Get the size of the Allocation in bytes.
327      *
328      * @return size of the Allocation in bytes.
329      *
330      */
getBytesSize()331     public int getBytesSize() {
332         if (mType.mDimYuv != 0) {
333             return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
334         }
335         return mType.getCount() * mType.getElement().getBytesSize();
336     }
337 
updateCacheInfo(Type t)338     private void updateCacheInfo(Type t) {
339         mCurrentDimX = t.getX();
340         mCurrentDimY = t.getY();
341         mCurrentDimZ = t.getZ();
342         mCurrentCount = mCurrentDimX;
343         if (mCurrentDimY > 1) {
344             mCurrentCount *= mCurrentDimY;
345         }
346         if (mCurrentDimZ > 1) {
347             mCurrentCount *= mCurrentDimZ;
348         }
349     }
350 
setBitmap(Bitmap b)351     private void setBitmap(Bitmap b) {
352         mBitmap = b;
353     }
354 
Allocation(long id, RenderScript rs, Type t, int usage)355     Allocation(long id, RenderScript rs, Type t, int usage) {
356         super(id, rs);
357         if ((usage & ~(USAGE_SCRIPT |
358                        USAGE_GRAPHICS_TEXTURE |
359                        USAGE_IO_INPUT |
360                        USAGE_IO_OUTPUT |
361                        USAGE_SHARED)) != 0) {
362             throw new RSIllegalArgumentException("Unknown usage specified.");
363         }
364 
365         if ((usage & USAGE_IO_INPUT) != 0) {
366             mWriteAllowed = false;
367 
368             if ((usage & ~(USAGE_IO_INPUT |
369                            USAGE_GRAPHICS_TEXTURE |
370                            USAGE_SCRIPT)) != 0) {
371                 throw new RSIllegalArgumentException("Invalid usage combination.");
372             }
373         }
374 
375         mType = t;
376         mUsage = usage;
377         mIncCompatAllocation = 0;
378         mIncAllocDestroyed = false;
379 
380         if (t != null) {
381             // TODO: A3D doesn't have Type info during creation, so we can't
382             // calculate the size ahead of time. We can possibly add a method
383             // to update the size in the future if it seems reasonable.
384             mSize = mType.getCount() * mType.getElement().getBytesSize();
385             updateCacheInfo(t);
386         }
387         if (RenderScript.sUseGCHooks == true) {
388             try {
389                 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
390             } catch (Exception e) {
391                 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
392                 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
393             }
394         }
395     }
396 
finalize()397     protected void finalize() throws Throwable {
398         if (RenderScript.sUseGCHooks == true) {
399             RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
400         }
401         super.finalize();
402     }
403 
validateIsInt64()404     private void validateIsInt64() {
405         if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
406             (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
407             return;
408         }
409         throw new RSIllegalArgumentException(
410             "64 bit integer source does not match allocation type " + mType.mElement.mType);
411     }
412 
validateIsInt32()413     private void validateIsInt32() {
414         if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
415             (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
416             return;
417         }
418         throw new RSIllegalArgumentException(
419             "32 bit integer source does not match allocation type " + mType.mElement.mType);
420     }
421 
validateIsInt16()422     private void validateIsInt16() {
423         if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
424             (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
425             return;
426         }
427         throw new RSIllegalArgumentException(
428             "16 bit integer source does not match allocation type " + mType.mElement.mType);
429     }
430 
validateIsInt8()431     private void validateIsInt8() {
432         if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
433             (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
434             return;
435         }
436         throw new RSIllegalArgumentException(
437             "8 bit integer source does not match allocation type " + mType.mElement.mType);
438     }
439 
validateIsFloat32()440     private void validateIsFloat32() {
441         if (mType.mElement.mType == Element.DataType.FLOAT_32) {
442             return;
443         }
444         throw new RSIllegalArgumentException(
445             "32 bit float source does not match allocation type " + mType.mElement.mType);
446     }
447 
validateIsFloat64()448     private void validateIsFloat64() {
449         if (mType.mElement.mType == Element.DataType.FLOAT_64) {
450             return;
451         }
452         throw new RSIllegalArgumentException(
453             "64 bit float source does not match allocation type " + mType.mElement.mType);
454     }
455 
validateIsObject()456     private void validateIsObject() {
457         if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
458             (mType.mElement.mType == Element.DataType.RS_TYPE) ||
459             (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
460             (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
461             (mType.mElement.mType == Element.DataType.RS_SCRIPT)) {
462             return;
463         }
464         throw new RSIllegalArgumentException(
465             "Object source does not match allocation type " + mType.mElement.mType);
466     }
467 
468     /**
469      * Get the {@link androidx.renderscript.Type} of the Allocation.
470      *
471      * @return Type
472      *
473      */
getType()474     public Type getType() {
475         return mType;
476     }
477 
478     /**
479      * Propagate changes from one usage of the Allocation to the
480      * other usages of the Allocation.
481      *
482      */
syncAll(int srcLocation)483     public void syncAll(int srcLocation) {
484         switch (srcLocation) {
485         case USAGE_SCRIPT:
486         case USAGE_GRAPHICS_TEXTURE:
487             break;
488         default:
489             throw new RSIllegalArgumentException("Source must be exactly one usage type.");
490         }
491         mRS.validate();
492         mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
493     }
494 
495     /**
496      * Send a buffer to the output stream.  The contents of the Allocation will
497      * be undefined after this operation. This operation is only valid if {@link
498      * #USAGE_IO_OUTPUT} is set on the Allocation.
499      *
500      *
501      */
ioSend()502     public void ioSend() {
503         if ((mUsage & USAGE_IO_OUTPUT) == 0) {
504             throw new RSIllegalArgumentException(
505                 "Can only send buffer if IO_OUTPUT usage specified.");
506         }
507         mRS.validate();
508         mRS.nAllocationIoSend(getID(mRS));
509     }
510 
511     /**
512      * Delete once code is updated.
513      */
ioSendOutput()514     public void ioSendOutput() {
515         ioSend();
516     }
517     /**
518      * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
519      * <p> If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
520      * would contain the up-to-date data as READ ONLY.
521      * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
522      * the Allocation has certain alignment. The size of each row including padding,
523      * called stride, can be queried using the {@link #getStride()} method.
524      *
525      * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
526      *       The ByteBuffer will be Read-Only for devices before Lollopop (API 21).
527      *
528      * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
529      */
getByteBuffer()530     public ByteBuffer getByteBuffer() {
531         int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
532         // When running on devices before L, we need to construct the ByteBuffer
533         // and explicitly copy the data from the allocation to it.
534         if (mRS.getDispatchAPILevel() < 21) {
535             byte[] data = null;
536             if (mType.getZ() > 0) {
537                 // TODO: add support for 3D allocations.
538                 return null;
539             } else if (mType.getY() > 0) {
540                 // 2D Allocation
541                 data = new byte[xBytesSize * mType.getY()];
542                 copy2DRangeToUnchecked(0, 0, mType.getX(), mType.getY(), data,
543                                        Element.DataType.SIGNED_8, xBytesSize * mType.getY());
544             } else {
545                 // 1D Allocation
546                 data = new byte[xBytesSize];
547                 copy1DRangeToUnchecked(0, mType.getX(), data);
548             }
549             ByteBuffer bBuffer = ByteBuffer.wrap(data).asReadOnlyBuffer();
550             mByteBufferStride = xBytesSize;
551             return bBuffer;
552         }
553         // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
554         if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
555             mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), xBytesSize, mType.getY(), mType.getZ());
556         }
557         return mByteBuffer;
558     }
559 
560     /**
561      * Gets the stride of the Allocation.
562      * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
563      * the Allocation has certain alignment. The size of each row including such
564      * padding is called stride.
565      *
566      * @return the stride. For 1D Allocation, the stride will be the number of
567      *         bytes of this Allocation. For 2D and 3D Allocations, the stride
568      *         will be the stride in X dimension measuring in bytes.
569      */
getStride()570     public long getStride() {
571         if (mByteBufferStride ==0) {
572             if (mRS.getDispatchAPILevel() > 21) {
573                 mByteBufferStride = mRS.nAllocationGetStride(getID(mRS));
574             } else {
575                 mByteBufferStride = mType.getX() * mType.getElement().getBytesSize();
576             }
577         }
578         return mByteBufferStride;
579     }
580 
581     /**
582      * Receive the latest input into the Allocation. This operation
583      * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
584      *
585      */
ioReceive()586     public void ioReceive() {
587         if ((mUsage & USAGE_IO_INPUT) == 0) {
588             throw new RSIllegalArgumentException(
589                 "Can only receive if IO_INPUT usage specified.");
590         }
591         mRS.validate();
592         mRS.nAllocationIoReceive(getID(mRS));
593     }
594 
595     /**
596      * Copy an array of RS objects to the Allocation.
597      *
598      * @param d Source array.
599      */
copyFrom(BaseObj[] d)600     public void copyFrom(BaseObj[] d) {
601         mRS.validate();
602         validateIsObject();
603         if (d.length != mCurrentCount) {
604             throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
605                                                  mCurrentCount + ", array length = " + d.length);
606         }
607 
608         if (RenderScript.sPointerSize == 8) {
609             long i[] = new long[d.length * 4];
610             for (int ct=0; ct < d.length; ct++) {
611                 i[ct * 4] = d[ct].getID(mRS);
612             }
613             copy1DRangeFromUnchecked(0, mCurrentCount, i);
614         } else {
615             int i[] = new int[d.length];
616             for (int ct=0; ct < d.length; ct++) {
617                 i[ct] = (int)d[ct].getID(mRS);
618             }
619             copy1DRangeFromUnchecked(0, mCurrentCount, i);
620         }
621     }
622 
validateBitmapFormat(Bitmap b)623     private void validateBitmapFormat(Bitmap b) {
624         Bitmap.Config bc = b.getConfig();
625         if (bc == null) {
626             throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
627         }
628         switch (bc) {
629         case ALPHA_8:
630             if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
631                 throw new RSIllegalArgumentException("Allocation kind is " +
632                                                      mType.getElement().mKind + ", type " +
633                                                      mType.getElement().mType +
634                                                      " of " + mType.getElement().getBytesSize() +
635                                                      " bytes, passed bitmap was " + bc);
636             }
637             break;
638         case ARGB_8888:
639             if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
640                 (mType.getElement().getBytesSize() != 4)) {
641                 throw new RSIllegalArgumentException("Allocation kind is " +
642                                                      mType.getElement().mKind + ", type " +
643                                                      mType.getElement().mType +
644                                                      " of " + mType.getElement().getBytesSize() +
645                                                      " bytes, passed bitmap was " + bc);
646             }
647             break;
648         case RGB_565:
649             if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
650                 (mType.getElement().getBytesSize() != 2)) {
651                 throw new RSIllegalArgumentException("Allocation kind is " +
652                                                      mType.getElement().mKind + ", type " +
653                                                      mType.getElement().mType +
654                                                      " of " + mType.getElement().getBytesSize() +
655                                                      " bytes, passed bitmap was " + bc);
656             }
657             break;
658         case ARGB_4444:
659             if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
660                 (mType.getElement().getBytesSize() != 2)) {
661                 throw new RSIllegalArgumentException("Allocation kind is " +
662                                                      mType.getElement().mKind + ", type " +
663                                                      mType.getElement().mType +
664                                                      " of " + mType.getElement().getBytesSize() +
665                                                      " bytes, passed bitmap was " + bc);
666             }
667             break;
668 
669         }
670     }
671 
validateBitmapSize(Bitmap b)672     private void validateBitmapSize(Bitmap b) {
673         if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
674             throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
675         }
676     }
677 
copyFromUnchecked(Object array, Element.DataType dt, int arrayLen)678     private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
679         mRS.validate();
680         if (mCurrentDimZ > 0) {
681             copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
682         } else if (mCurrentDimY > 0) {
683             copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
684         } else {
685             copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
686         }
687     }
688 
689     /**
690      * Copy into this Allocation from an array. This method does not guarantee
691      * that the Allocation is compatible with the input buffer; it copies memory
692      * without reinterpretation.
693      *
694      * <p> If the Allocation does not have Vec3 Elements, then the size of the
695      * array in bytes must be at least the size of the Allocation {@link
696      * #getBytesSize getBytesSize()}.
697      *
698      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
699      * is disabled, then the size of the array in bytes must be at least the size
700      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
701      * the cells must be part of the array.
702      *
703      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
704      * is enabled, then the size of the array in bytes must be at least 3/4 the size
705      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
706      * the cells must not be part of the array.
707      *
708      * @param array The source array
709      */
copyFromUnchecked(Object array)710     public void copyFromUnchecked(Object array) {
711         copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
712                           java.lang.reflect.Array.getLength(array));
713     }
714 
715     /**
716      * Copy into this Allocation from an array. This method does not guarantee
717      * that the Allocation is compatible with the input buffer; it copies memory
718      * without reinterpretation.
719      *
720      * <p> If the Allocation does not have Vec3 Elements, then the size of the
721      * array in bytes must be at least the size of the Allocation {@link
722      * #getBytesSize getBytesSize()}.
723      *
724      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
725      * is disabled, then the size of the array in bytes must be at least the size
726      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
727      * the cells must be part of the array.
728      *
729      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
730      * is enabled, then the size of the array in bytes must be at least 3/4 the size
731      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
732      * the cells must not be part of the array.
733      *
734      * @param d the source array
735      */
copyFromUnchecked(int[] d)736     public void copyFromUnchecked(int[] d) {
737         copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
738     }
739 
740     /**
741      * Copy into this Allocation from an array. This method does not guarantee
742      * that the Allocation is compatible with the input buffer; it copies memory
743      * without reinterpretation.
744      *
745      * <p> If the Allocation does not have Vec3 Elements, then the size of the
746      * array in bytes must be at least the size of the Allocation {@link
747      * #getBytesSize getBytesSize()}.
748      *
749      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
750      * is disabled, then the size of the array in bytes must be at least the size
751      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
752      * the cells must be part of the array.
753      *
754      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
755      * is enabled, then the size of the array in bytes must be at least 3/4 the size
756      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
757      * the cells must not be part of the array.
758      *
759      * @param d the source array
760      */
copyFromUnchecked(short[] d)761     public void copyFromUnchecked(short[] d) {
762         copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
763     }
764 
765     /**
766      * Copy into this Allocation from an array. This method does not guarantee
767      * that the Allocation is compatible with the input buffer; it copies memory
768      * without reinterpretation.
769      *
770      * <p> If the Allocation does not have Vec3 Elements, then the size of the
771      * array in bytes must be at least the size of the Allocation {@link
772      * #getBytesSize getBytesSize()}.
773      *
774      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
775      * is disabled, then the size of the array in bytes must be at least the size
776      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
777      * the cells must be part of the array.
778      *
779      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
780      * is enabled, then the size of the array in bytes must be at least 3/4 the size
781      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
782      * the cells must not be part of the array.
783      *
784      * @param d the source array
785      */
copyFromUnchecked(byte[] d)786     public void copyFromUnchecked(byte[] d) {
787         copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
788     }
789 
790     /**
791      * Copy into this Allocation from an array. This method does not guarantee
792      * that the Allocation is compatible with the input buffer; it copies memory
793      * without reinterpretation.
794      *
795      * <p> If the Allocation does not have Vec3 Elements, then the size of the
796      * array in bytes must be at least the size of the Allocation {@link
797      * #getBytesSize getBytesSize()}.
798      *
799      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
800      * is disabled, then the size of the array in bytes must be at least the size
801      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
802      * the cells must be part of the array.
803      *
804      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
805      * is enabled, then the size of the array in bytes must be at least 3/4 the size
806      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
807      * the cells must not be part of the array.
808      *
809      * @param d the source array
810      */
copyFromUnchecked(float[] d)811     public void copyFromUnchecked(float[] d) {
812         copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
813     }
814 
815 
816     /**
817      * Copy into this Allocation from an array.  This variant is type checked
818      * and will generate exceptions if the Allocation's {@link
819      * androidx.renderscript.Element} does not match the array's
820      * primitive type.
821      *
822      * <p> If the Allocation does not have Vec3 Elements, then the size of the
823      * array in bytes must be at least the size of the Allocation {@link
824      * #getBytesSize getBytesSize()}.
825      *
826      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
827      * is disabled, then the size of the array in bytes must be at least the size
828      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
829      * the cells must be part of the array.
830      *
831      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
832      * is enabled, then the size of the array in bytes must be at least 3/4 the size
833      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
834      * the cells must not be part of the array.
835      *
836      * @param array The source array
837      */
copyFrom(Object array)838     public void copyFrom(Object array) {
839         copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
840                           java.lang.reflect.Array.getLength(array));
841     }
842 
843     /**
844      * Copy into this Allocation from an array.  This variant is type checked
845      * and will generate exceptions if the Allocation's {@link
846      * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
847      * integers {@link androidx.renderscript.Element.DataType}.
848      *
849      * <p> If the Allocation does not have Vec3 Elements, then the size of the
850      * array in bytes must be at least the size of the Allocation {@link
851      * #getBytesSize getBytesSize()}.
852      *
853      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
854      * is disabled, then the size of the array in bytes must be at least the size
855      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
856      * the cells must be part of the array.
857      *
858      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
859      * is enabled, then the size of the array in bytes must be at least 3/4 the size
860      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
861      * the cells must not be part of the array.
862      *
863      * @param d the source array
864      */
copyFrom(int[] d)865     public void copyFrom(int[] d) {
866         validateIsInt32();
867         copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
868     }
869 
870     /**
871      * Copy into this Allocation from an array.  This variant is type checked
872      * and will generate exceptions if the Allocation's {@link
873      * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
874      * integers {@link androidx.renderscript.Element.DataType}.
875      *
876      * <p> If the Allocation does not have Vec3 Elements, then the size of the
877      * array in bytes must be at least the size of the Allocation {@link
878      * #getBytesSize getBytesSize()}.
879      *
880      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
881      * is disabled, then the size of the array in bytes must be at least the size
882      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
883      * the cells must be part of the array.
884      *
885      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
886      * is enabled, then the size of the array in bytes must be at least 3/4 the size
887      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
888      * the cells must not be part of the array.
889      *
890      * @param d the source array
891      */
copyFrom(short[] d)892     public void copyFrom(short[] d) {
893         validateIsInt16();
894         copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
895     }
896 
897     /**
898      * Copy into this Allocation from an array.  This variant is type checked
899      * and will generate exceptions if the Allocation's {@link
900      * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
901      * integers {@link androidx.renderscript.Element.DataType}.
902      *
903      * <p> If the Allocation does not have Vec3 Elements, then the size of the
904      * array in bytes must be at least the size of the Allocation {@link
905      * #getBytesSize getBytesSize()}.
906      *
907      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
908      * is disabled, then the size of the array in bytes must be at least the size
909      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
910      * the cells must be part of the array.
911      *
912      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
913      * is enabled, then the size of the array in bytes must be at least 3/4 the size
914      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
915      * the cells must not be part of the array.
916      *
917      * @param d the source array
918      */
copyFrom(byte[] d)919     public void copyFrom(byte[] d) {
920         validateIsInt8();
921         copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
922     }
923 
924     /**
925      * Copy into this Allocation from an array.  This variant is type checked
926      * and will generate exceptions if the Allocation's {@link
927      * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
928      * 32 bit floats {@link androidx.renderscript.Element.DataType}.
929      *
930      * <p> If the Allocation does not have Vec3 Elements, then the size of the
931      * array in bytes must be at least the size of the Allocation {@link
932      * #getBytesSize getBytesSize()}.
933      *
934      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
935      * is disabled, then the size of the array in bytes must be at least the size
936      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
937      * the cells must be part of the array.
938      *
939      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
940      * is enabled, then the size of the array in bytes must be at least 3/4 the size
941      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
942      * the cells must not be part of the array.
943      *
944      * @param d the source array
945      */
copyFrom(float[] d)946     public void copyFrom(float[] d) {
947         validateIsFloat32();
948         copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
949     }
950 
951     /**
952      * Copy into an Allocation from a {@link android.graphics.Bitmap}.  The
953      * height, width, and format of the bitmap must match the existing
954      * allocation.
955      *
956      * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
957      * android.graphics.Bitmap} used to create the Allocation with {@link
958      * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
959      * this will synchronize the Allocation with the latest data from the {@link
960      * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
961      *
962      * @param b the source bitmap
963      */
copyFrom(Bitmap b)964     public void copyFrom(Bitmap b) {
965         mRS.validate();
966         if (b.getConfig() == null) {
967             Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
968             Canvas c = new Canvas(newBitmap);
969             c.drawBitmap(b, 0, 0, null);
970             copyFrom(newBitmap);
971             return;
972         }
973         validateBitmapSize(b);
974         validateBitmapFormat(b);
975         mRS.nAllocationCopyFromBitmap(getID(mRS), b);
976     }
977 
978     /**
979      * Copy an Allocation from an Allocation.  The types of both allocations
980      * must be identical.
981      *
982      * @param a the source allocation
983      */
copyFrom(Allocation a)984     public void copyFrom(Allocation a) {
985         mRS.validate();
986         if (!mType.equals(a.getType())) {
987             throw new RSIllegalArgumentException("Types of allocations must match.");
988         }
989         copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
990     }
991 
992 
993     /**
994      * This is only intended to be used by auto-generated code reflected from
995      * the RenderScript script files and should not be used by developers.
996      *
997      * @param xoff
998      * @param fp
999      */
setFromFieldPacker(int xoff, FieldPacker fp)1000     public void setFromFieldPacker(int xoff, FieldPacker fp) {
1001         mRS.validate();
1002         int eSize = mType.mElement.getBytesSize();
1003         final byte[] data = fp.getData();
1004         int data_length = fp.getPos();
1005 
1006         int count = data_length / eSize;
1007         if ((eSize * count) != data_length) {
1008             throw new RSIllegalArgumentException("Field packer length " + data_length +
1009                                                " not divisible by element size " + eSize + ".");
1010         }
1011         copy1DRangeFromUnchecked(xoff, count, data);
1012     }
1013 
1014     /**
1015      * This is only intended to be used by auto-generated code reflected from
1016      * the RenderScript script files.
1017      *
1018      * @param xoff
1019      * @param component_number
1020      * @param fp
1021      */
setFromFieldPacker(int xoff, int component_number, FieldPacker fp)1022     public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
1023         mRS.validate();
1024         if (component_number >= mType.mElement.mElements.length) {
1025             throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1026         }
1027         if(xoff < 0) {
1028             throw new RSIllegalArgumentException("Offset must be >= 0.");
1029         }
1030 
1031         final byte[] data = fp.getData();
1032         int data_length = fp.getPos();
1033         int eSize = mType.mElement.mElements[component_number].getBytesSize();
1034         eSize *= mType.mElement.mArraySizes[component_number];
1035 
1036         if (data_length != eSize) {
1037             throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1038                                                " does not match component size " + eSize + ".");
1039         }
1040 
1041         mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
1042                                      component_number, data, data_length);
1043     }
1044 
1045     /**
1046      * @hide
1047      * This is only intended to be used by auto-generated code reflected from
1048      * the RenderScript script files.
1049      *
1050      * @param xoff
1051      * @param yoff
1052      * @param zoff
1053      * @param component_number
1054      * @param fp
1055      */
1056     /*
1057     public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
1058         mRS.validate();
1059         if (component_number >= mType.mElement.mElements.length) {
1060             throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1061         }
1062         if(xoff < 0) {
1063             throw new RSIllegalArgumentException("Offset x must be >= 0.");
1064         }
1065         if(yoff < 0) {
1066             throw new RSIllegalArgumentException("Offset y must be >= 0.");
1067         }
1068         if(zoff < 0) {
1069             throw new RSIllegalArgumentException("Offset z must be >= 0.");
1070         }
1071 
1072         final byte[] data = fp.getData();
1073         int data_length = fp.getPos();
1074         int eSize = mType.mElement.mElements[component_number].getBytesSize();
1075         eSize *= mType.mElement.mArraySizes[component_number];
1076 
1077         if (data_length != eSize) {
1078             throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1079                                                " does not match component size " + eSize + ".");
1080         }
1081 
1082         mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1083                                    component_number, data, data_length);
1084     }
1085     */
1086 
data1DChecks(int off, int count, int len, int dataSize, boolean usePadding)1087     private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
1088         mRS.validate();
1089         if(off < 0) {
1090             throw new RSIllegalArgumentException("Offset must be >= 0.");
1091         }
1092         if(count < 1) {
1093             throw new RSIllegalArgumentException("Count must be >= 1.");
1094         }
1095         if((off + count) > mCurrentCount) {
1096             throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
1097                                                ", got " + count + " at offset " + off + ".");
1098         }
1099         if(usePadding) {
1100             if(len < dataSize / 4 * 3) {
1101                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1102             }
1103         } else {
1104             if(len < dataSize) {
1105                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1106             }
1107         }
1108     }
1109 
1110     /**
1111      * Generate a mipmap chain. This is only valid if the Type of the Allocation
1112      * includes mipmaps.
1113      *
1114      * <p>This function will generate a complete set of mipmaps from the top
1115      * level LOD and place them into the script memory space.</p>
1116      *
1117      * <p>If the Allocation is also using other memory spaces, a call to {@link
1118      * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
1119      */
generateMipmaps()1120     public void generateMipmaps() {
1121         mRS.nAllocationGenerateMipmaps(getID(mRS));
1122     }
1123 
copy1DRangeFromUnchecked(int off, int count, Object array, Element.DataType dt, int arrayLen)1124     private void copy1DRangeFromUnchecked(int off, int count, Object array,
1125                                           Element.DataType dt, int arrayLen) {
1126         final int dataSize = mType.mElement.getBytesSize() * count;
1127         // AutoPadding for Vec3 Element
1128         boolean usePadding = false;
1129         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1130             usePadding = true;
1131         }
1132         data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1133         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1134                               mType.mElement.mType.mSize, usePadding);
1135     }
1136 
1137     /**
1138      * Copy an array into a 1D region of this Allocation.  This method does not
1139      * guarantee that the Allocation is compatible with the input buffer.
1140      *
1141      * <p> The size of the region is: count * {@link #getElement}.{@link
1142      * Element#getBytesSize}.
1143      *
1144      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1145      * array in bytes must be at least the size of the region.
1146      *
1147      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1148      * is disabled, then the size of the array in bytes must be at least the size
1149      * of the region. The padding bytes for the cells must be part of the array.
1150      *
1151      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1152      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1153      * of the region. The padding bytes for the cells must not be part of the array.
1154      *
1155      * @param off The offset of the first element to be copied.
1156      * @param count The number of elements to be copied.
1157      * @param array The source array
1158      */
copy1DRangeFromUnchecked(int off, int count, Object array)1159     public void copy1DRangeFromUnchecked(int off, int count, Object array) {
1160         copy1DRangeFromUnchecked(off, count, array,
1161                                  validateObjectIsPrimitiveArray(array, false),
1162                                  java.lang.reflect.Array.getLength(array));
1163     }
1164 
1165     /**
1166      * Copy an array into a 1D region of this Allocation.  This method does not
1167      * guarantee that the Allocation is compatible with the input buffer.
1168      *
1169      * <p> The size of the region is: count * {@link #getElement}.{@link
1170      * Element#getBytesSize}.
1171      *
1172      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1173      * array in bytes must be at least the size of the region.
1174      *
1175      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1176      * is disabled, then the size of the array in bytes must be at least the size
1177      * of the region. The padding bytes for the cells must be part of the array.
1178      *
1179      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1180      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1181      * of the region. The padding bytes for the cells must not be part of the array.
1182      *
1183      * @param off The offset of the first element to be copied.
1184      * @param count The number of elements to be copied.
1185      * @param d the source array
1186      */
copy1DRangeFromUnchecked(int off, int count, int[] d)1187     public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
1188         copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1189     }
1190 
1191     /**
1192      * Copy an array into a 1D region of this Allocation.  This method does not
1193      * guarantee that the Allocation is compatible with the input buffer.
1194      *
1195      * <p> The size of the region is: count * {@link #getElement}.{@link
1196      * Element#getBytesSize}.
1197      *
1198      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1199      * array in bytes must be at least the size of the region.
1200      *
1201      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1202      * is disabled, then the size of the array in bytes must be at least the size
1203      * of the region. The padding bytes for the cells must be part of the array.
1204      *
1205      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1206      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1207      * of the region. The padding bytes for the cells must not be part of the array.
1208      *
1209      * @param off The offset of the first element to be copied.
1210      * @param count The number of elements to be copied.
1211      * @param d the source array
1212      */
copy1DRangeFromUnchecked(int off, int count, short[] d)1213     public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
1214         copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1215     }
1216 
1217     /**
1218      * Copy an array into a 1D region of this Allocation.  This method does not
1219      * guarantee that the Allocation is compatible with the input buffer.
1220      *
1221      * <p> The size of the region is: count * {@link #getElement}.{@link
1222      * Element#getBytesSize}.
1223      *
1224      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1225      * array in bytes must be at least the size of the region.
1226      *
1227      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1228      * is disabled, then the size of the array in bytes must be at least the size
1229      * of the region. The padding bytes for the cells must be part of the array.
1230      *
1231      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1232      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1233      * of the region. The padding bytes for the cells must not be part of the array.
1234      *
1235      * @param off The offset of the first element to be copied.
1236      * @param count The number of elements to be copied.
1237      * @param d the source array
1238      */
copy1DRangeFromUnchecked(int off, int count, byte[] d)1239     public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
1240         copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1241     }
1242 
1243     /**
1244      * Copy an array into a 1D region of this Allocation.  This method does not
1245      * guarantee that the Allocation is compatible with the input buffer.
1246      *
1247      * <p> The size of the region is: count * {@link #getElement}.{@link
1248      * Element#getBytesSize}.
1249      *
1250      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1251      * array in bytes must be at least the size of the region.
1252      *
1253      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1254      * is disabled, then the size of the array in bytes must be at least the size
1255      * of the region. The padding bytes for the cells must be part of the array.
1256      *
1257      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1258      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1259      * of the region. The padding bytes for the cells must not be part of the array.
1260      *
1261      * @param off The offset of the first element to be copied.
1262      * @param count The number of elements to be copied.
1263      * @param d the source array
1264      */
copy1DRangeFromUnchecked(int off, int count, float[] d)1265     public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
1266         copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1267     }
1268 
1269 
1270     /**
1271      * Copy an array into a 1D region of this Allocation.  This variant is type checked
1272      * and will generate exceptions if the Allocation's {@link
1273      * androidx.renderscript.Element} does not match the component type
1274      * of the array passed in.
1275      *
1276      * <p> The size of the region is: count * {@link #getElement}.{@link
1277      * Element#getBytesSize}.
1278      *
1279      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1280      * array in bytes must be at least the size of the region.
1281      *
1282      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1283      * is disabled, then the size of the array in bytes must be at least the size
1284      * of the region. The padding bytes for the cells must be part of the array.
1285      *
1286      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1287      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1288      * of the region. The padding bytes for the cells must not be part of the array.
1289      *
1290      * @param off The offset of the first element to be copied.
1291      * @param count The number of elements to be copied.
1292      * @param array The source array.
1293      */
copy1DRangeFrom(int off, int count, Object array)1294     public void copy1DRangeFrom(int off, int count, Object array) {
1295         copy1DRangeFromUnchecked(off, count, array,
1296                                  validateObjectIsPrimitiveArray(array, true),
1297                                  java.lang.reflect.Array.getLength(array));
1298     }
1299 
1300     /**
1301      * Copy an array into a 1D region of this Allocation.  This variant is type checked
1302      * and will generate exceptions if the Allocation's {@link
1303      * androidx.renderscript.Element} is not an 32 bit integer nor a vector of 32 bit
1304      * integers {@link androidx.renderscript.Element.DataType}.
1305      *
1306      * <p> The size of the region is: count * {@link #getElement}.{@link
1307      * Element#getBytesSize}.
1308      *
1309      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1310      * array in bytes must be at least the size of the region.
1311      *
1312      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1313      * is disabled, then the size of the array in bytes must be at least the size
1314      * of the region. The padding bytes for the cells must be part of the array.
1315      *
1316      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1317      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1318      * of the region. The padding bytes for the cells must not be part of the array.
1319      *
1320      * @param off The offset of the first element to be copied.
1321      * @param count The number of elements to be copied.
1322      * @param d the source array
1323      */
copy1DRangeFrom(int off, int count, int[] d)1324     public void copy1DRangeFrom(int off, int count, int[] d) {
1325         validateIsInt32();
1326         copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1327     }
1328 
1329     /**
1330      * Copy an array into a 1D region of this Allocation.  This variant is type checked
1331      * and will generate exceptions if the Allocation's {@link
1332      * androidx.renderscript.Element} is not an 16 bit integer nor a vector of 16 bit
1333      * integers {@link androidx.renderscript.Element.DataType}.
1334      *
1335      * <p> The size of the region is: count * {@link #getElement}.{@link
1336      * Element#getBytesSize}.
1337      *
1338      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1339      * array in bytes must be at least the size of the region.
1340      *
1341      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1342      * is disabled, then the size of the array in bytes must be at least the size
1343      * of the region. The padding bytes for the cells must be part of the array.
1344      *
1345      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1346      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1347      * of the region. The padding bytes for the cells must not be part of the array.
1348      *
1349      * @param off The offset of the first element to be copied.
1350      * @param count The number of elements to be copied.
1351      * @param d the source array
1352      */
copy1DRangeFrom(int off, int count, short[] d)1353     public void copy1DRangeFrom(int off, int count, short[] d) {
1354         validateIsInt16();
1355         copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1356     }
1357 
1358     /**
1359      * Copy an array into a 1D region of this Allocation.  This variant is type checked
1360      * and will generate exceptions if the Allocation's {@link
1361      * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
1362      * integers {@link androidx.renderscript.Element.DataType}.
1363      *
1364      * <p> The size of the region is: count * {@link #getElement}.{@link
1365      * Element#getBytesSize}.
1366      *
1367      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1368      * array in bytes must be at least the size of the region.
1369      *
1370      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1371      * is disabled, then the size of the array in bytes must be at least the size
1372      * of the region. The padding bytes for the cells must be part of the array.
1373      *
1374      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1375      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1376      * of the region. The padding bytes for the cells must not be part of the array.
1377      *
1378      * @param off The offset of the first element to be copied.
1379      * @param count The number of elements to be copied.
1380      * @param d the source array
1381      */
copy1DRangeFrom(int off, int count, byte[] d)1382     public void copy1DRangeFrom(int off, int count, byte[] d) {
1383         validateIsInt8();
1384         copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1385     }
1386 
1387     /**
1388      * Copy an array into a 1D region of this Allocation.  This variant is type checked
1389      * and will generate exceptions if the Allocation's {@link
1390      * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
1391      * 32 bit floats {@link androidx.renderscript.Element.DataType}.
1392      *
1393      * <p> The size of the region is: count * {@link #getElement}.{@link
1394      * Element#getBytesSize}.
1395      *
1396      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1397      * array in bytes must be at least the size of the region.
1398      *
1399      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1400      * is disabled, then the size of the array in bytes must be at least the size
1401      * of the region. The padding bytes for the cells must be part of the array.
1402      *
1403      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1404      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1405      * of the region. The padding bytes for the cells must not be part of the array.
1406      *
1407      * @param off The offset of the first element to be copied.
1408      * @param count The number of elements to be copied.
1409      * @param d the source array.
1410      */
copy1DRangeFrom(int off, int count, float[] d)1411     public void copy1DRangeFrom(int off, int count, float[] d) {
1412         validateIsFloat32();
1413         copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1414     }
1415 
1416      /**
1417      * Copy part of an Allocation into this Allocation.
1418      *
1419      * @param off The offset of the first element to be copied.
1420      * @param count The number of elements to be copied.
1421      * @param data the source data allocation.
1422      * @param dataOff off The offset of the first element in data to
1423      *          be copied.
1424      */
copy1DRangeFrom(int off, int count, Allocation data, int dataOff)1425     public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
1426         mRS.nAllocationData2D(getIDSafe(), off, 0,
1427                               mSelectedLOD, mSelectedFace.mID,
1428                               count, 1, data.getID(mRS), dataOff, 0,
1429                               data.mSelectedLOD, data.mSelectedFace.mID);
1430     }
1431 
validate2DRange(int xoff, int yoff, int w, int h)1432     private void validate2DRange(int xoff, int yoff, int w, int h) {
1433         if (mAdaptedAllocation != null) {
1434 
1435         } else {
1436 
1437             if (xoff < 0 || yoff < 0) {
1438                 throw new RSIllegalArgumentException("Offset cannot be negative.");
1439             }
1440             if (h < 0 || w < 0) {
1441                 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1442             }
1443             if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1444                 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1445             }
1446         }
1447     }
1448 
copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array, Element.DataType dt, int arrayLen)1449     void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1450                                   Element.DataType dt, int arrayLen) {
1451         mRS.validate();
1452         validate2DRange(xoff, yoff, w, h);
1453         final int dataSize = mType.mElement.getBytesSize() * w * h;
1454         // AutoPadding for Vec3 Element
1455         boolean usePadding = false;
1456         int sizeBytes = arrayLen * dt.mSize;
1457         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1458             if (dataSize / 4 * 3 > sizeBytes) {
1459                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1460             }
1461             usePadding = true;
1462             sizeBytes = dataSize;
1463         } else {
1464             if (dataSize > sizeBytes) {
1465                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1466             }
1467         }
1468         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1469                               array, sizeBytes, dt,
1470                               mType.mElement.mType.mSize, usePadding);
1471     }
1472 
1473     /**
1474      * Copy from an array into a rectangular region in this Allocation.  The
1475      * array is assumed to be tightly packed. This variant is type checked
1476      * and will generate exceptions if the Allocation's {@link
1477      * androidx.renderscript.Element} does not match the input data type.
1478      *
1479      * <p> The size of the region is: w * h * {@link #getElement}.{@link
1480      * Element#getBytesSize}.
1481      *
1482      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1483      * array in bytes must be at least the size of the region.
1484      *
1485      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1486      * is disabled, then the size of the array in bytes must be at least the size
1487      * of the region. The padding bytes for the cells must be part of the array.
1488      *
1489      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1490      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1491      * of the region. The padding bytes for the cells must not be part of the array.
1492      *
1493      * @param xoff X offset of the region to update in this Allocation
1494      * @param yoff Y offset of the region to update in this Allocation
1495      * @param w Width of the region to update
1496      * @param h Height of the region to update
1497      * @param array Data to be placed into the Allocation
1498      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array)1499     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
1500         copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1501                                  validateObjectIsPrimitiveArray(array, true),
1502                                  java.lang.reflect.Array.getLength(array));
1503     }
1504 
1505     /**
1506      * Copy from an array into a rectangular region in this Allocation.  The
1507      * array is assumed to be tightly packed. This variant is type checked
1508      * and will generate exceptions if the Allocation's {@link
1509      * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
1510      * integers {@link androidx.renderscript.Element.DataType}.
1511      *
1512      * <p> The size of the region is: w * h * {@link #getElement}.{@link
1513      * Element#getBytesSize}.
1514      *
1515      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1516      * array in bytes must be at least the size of the region.
1517      *
1518      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1519      * is disabled, then the size of the array in bytes must be at least the size
1520      * of the region. The padding bytes for the cells must be part of the array.
1521      *
1522      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1523      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1524      * of the region. The padding bytes for the cells must not be part of the array.
1525      *
1526      * @param xoff X offset of the region to update in this Allocation
1527      * @param yoff Y offset of the region to update in this Allocation
1528      * @param w Width of the region to update
1529      * @param h Height of the region to update
1530      * @param data to be placed into the Allocation
1531      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data)1532     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
1533         validateIsInt8();
1534         copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1535                                  Element.DataType.SIGNED_8, data.length);
1536     }
1537 
1538     /**
1539      * Copy from an array into a rectangular region in this Allocation.  The
1540      * array is assumed to be tightly packed. This variant is type checked
1541      * and will generate exceptions if the Allocation's {@link
1542      * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
1543      * integers {@link androidx.renderscript.Element.DataType}.
1544      *
1545      * <p> The size of the region is: w * h * {@link #getElement}.{@link
1546      * Element#getBytesSize}.
1547      *
1548      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1549      * array in bytes must be at least the size of the region.
1550      *
1551      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1552      * is disabled, then the size of the array in bytes must be at least the size
1553      * of the region. The padding bytes for the cells must be part of the array.
1554      *
1555      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1556      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1557      * of the region. The padding bytes for the cells must not be part of the array.
1558      *
1559      * @param xoff X offset of the region to update in this Allocation
1560      * @param yoff Y offset of the region to update in this Allocation
1561      * @param w Width of the region to update
1562      * @param h Height of the region to update
1563      * @param data to be placed into the Allocation
1564      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data)1565     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
1566         validateIsInt16();
1567         copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1568                                  Element.DataType.SIGNED_16, data.length);
1569     }
1570 
1571     /**
1572      * Copy from an array into a rectangular region in this Allocation.  The
1573      * array is assumed to be tightly packed. This variant is type checked
1574      * and will generate exceptions if the Allocation's {@link
1575      * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
1576      * integers {@link androidx.renderscript.Element.DataType}.
1577      *
1578      * <p> The size of the region is: w * h * {@link #getElement}.{@link
1579      * Element#getBytesSize}.
1580      *
1581      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1582      * array in bytes must be at least the size of the region.
1583      *
1584      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1585      * is disabled, then the size of the array in bytes must be at least the size
1586      * of the region. The padding bytes for the cells must be part of the array.
1587      *
1588      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1589      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1590      * of the region. The padding bytes for the cells must not be part of the array.
1591      *
1592      * @param xoff X offset of the region to update in this Allocation
1593      * @param yoff Y offset of the region to update in this Allocation
1594      * @param w Width of the region to update
1595      * @param h Height of the region to update
1596      * @param data to be placed into the Allocation
1597      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data)1598     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
1599         validateIsInt32();
1600         copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1601                                  Element.DataType.SIGNED_32, data.length);
1602     }
1603 
1604     /**
1605      * Copy from an array into a rectangular region in this Allocation.  The
1606      * array is assumed to be tightly packed. This variant is type checked
1607      * and will generate exceptions if the Allocation's {@link
1608      * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
1609      * 32 bit floats {@link androidx.renderscript.Element.DataType}.
1610      *
1611      * <p> The size of the region is: w * h * {@link #getElement}.{@link
1612      * Element#getBytesSize}.
1613      *
1614      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1615      * array in bytes must be at least the size of the region.
1616      *
1617      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1618      * is disabled, then the size of the array in bytes must be at least the size
1619      * of the region. The padding bytes for the cells must be part of the array.
1620      *
1621      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1622      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1623      * of the region. The padding bytes for the cells must not be part of the array.
1624      *
1625      * @param xoff X offset of the region to update in this Allocation
1626      * @param yoff Y offset of the region to update in this Allocation
1627      * @param w Width of the region to update
1628      * @param h Height of the region to update
1629      * @param data to be placed into the Allocation
1630      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data)1631     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
1632         validateIsFloat32();
1633         copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1634                                  Element.DataType.FLOAT_32, data.length);
1635     }
1636 
1637     /**
1638      * Copy a rectangular region from an Allocation into a rectangular region in
1639      * this Allocation.
1640      *
1641      * @param xoff X offset of the region in this Allocation
1642      * @param yoff Y offset of the region in this Allocation
1643      * @param w Width of the region to update.
1644      * @param h Height of the region to update.
1645      * @param data source Allocation.
1646      * @param dataXoff X offset in source Allocation
1647      * @param dataYoff Y offset in source Allocation
1648      */
copy2DRangeFrom(int xoff, int yoff, int w, int h, Allocation data, int dataXoff, int dataYoff)1649     public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1650                                 Allocation data, int dataXoff, int dataYoff) {
1651         mRS.validate();
1652         validate2DRange(xoff, yoff, w, h);
1653         mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1654                               mSelectedLOD, mSelectedFace.mID,
1655                               w, h, data.getID(mRS), dataXoff, dataYoff,
1656                               data.mSelectedLOD, data.mSelectedFace.mID);
1657     }
1658 
1659     /**
1660      * Copy a {@link android.graphics.Bitmap} into an Allocation.  The height
1661      * and width of the update will use the height and width of the {@link
1662      * android.graphics.Bitmap}.
1663      *
1664      * @param xoff X offset of the region to update in this Allocation
1665      * @param yoff Y offset of the region to update in this Allocation
1666      * @param data the Bitmap to be copied
1667      */
copy2DRangeFrom(int xoff, int yoff, Bitmap data)1668     public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
1669         mRS.validate();
1670         if (data.getConfig() == null) {
1671             Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1672             Canvas c = new Canvas(newBitmap);
1673             c.drawBitmap(data, 0, 0, null);
1674             copy2DRangeFrom(xoff, yoff, newBitmap);
1675             return;
1676         }
1677         validateBitmapFormat(data);
1678         validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1679         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1680     }
1681 
validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d)1682     private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1683         if (mAdaptedAllocation != null) {
1684 
1685         } else {
1686 
1687             if (xoff < 0 || yoff < 0 || zoff < 0) {
1688                 throw new RSIllegalArgumentException("Offset cannot be negative.");
1689             }
1690             if (h < 0 || w < 0 || d < 0) {
1691                 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1692             }
1693             if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1694                 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1695             }
1696         }
1697     }
1698 
1699     /**
1700      * Copy a rectangular region from the array into the allocation.
1701      * The array is assumed to be tightly packed.
1702      *
1703      * The data type of the array is not required to be the same as
1704      * the element data type.
1705      */
copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, Object array, Element.DataType dt, int arrayLen)1706     private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1707                                           Object array, Element.DataType dt, int arrayLen) {
1708         mRS.validate();
1709         validate3DRange(xoff, yoff, zoff, w, h, d);
1710         final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1711         // AutoPadding for Vec3 Element
1712         boolean usePadding = false;
1713         int sizeBytes = arrayLen * dt.mSize;
1714         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1715             if (dataSize / 4 * 3 > sizeBytes) {
1716                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1717             }
1718             usePadding = true;
1719             sizeBytes = dataSize;
1720         } else {
1721             if (dataSize > sizeBytes) {
1722                 throw new RSIllegalArgumentException("Array too small for allocation type.");
1723             }
1724         }
1725         mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1726                               array, sizeBytes, dt,
1727                               mType.mElement.mType.mSize, usePadding);
1728     }
1729 
1730     /**
1731      * Copy from an array into a 3D region in this Allocation.  The
1732      * array is assumed to be tightly packed. This variant is type checked
1733      * and will generate exceptions if the Allocation's {@link
1734      * androidx.renderscript.Element} does not match the input data type.
1735      *
1736      * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
1737      * Element#getBytesSize}.
1738      *
1739      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1740      * array in bytes must be at least the size of the region.
1741      *
1742      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1743      * is disabled, then the size of the array in bytes must be at least the size
1744      * of the region. The padding bytes for the cells must be part of the array.
1745      *
1746      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1747      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1748      * of the region. The padding bytes for the cells must not be part of the array.
1749      *
1750      * @param xoff X offset of the region to update in this Allocation
1751      * @param yoff Y offset of the region to update in this Allocation
1752      * @param zoff Z offset of the region to update in this Allocation
1753      * @param w Width of the region to update
1754      * @param h Height of the region to update
1755      * @param d Depth of the region to update
1756      * @param array to be placed into the allocation
1757      */
copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array)1758     public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1759         copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1760                                  validateObjectIsPrimitiveArray(array, true),
1761                                  java.lang.reflect.Array.getLength(array));
1762     }
1763 
1764     /**
1765      * Copy a rectangular region into the allocation from another
1766      * allocation.
1767      *
1768      * @param xoff X offset of the region to update in this Allocation
1769      * @param yoff Y offset of the region to update in this Allocation
1770      * @param zoff Z offset of the region to update in this Allocation
1771      * @param w Width of the region to update.
1772      * @param h Height of the region to update.
1773      * @param d Depth of the region to update.
1774      * @param data source allocation.
1775      * @param dataXoff X offset of the region in the source Allocation
1776      * @param dataYoff Y offset of the region in the source Allocation
1777      * @param dataZoff Z offset of the region in the source Allocation
1778      */
copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Allocation data, int dataXoff, int dataYoff, int dataZoff)1779     public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1780                                 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1781         mRS.validate();
1782         validate3DRange(xoff, yoff, zoff, w, h, d);
1783         mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1784                               w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1785                               data.mSelectedLOD);
1786     }
1787 
1788 
1789     /**
1790      * Copy from the Allocation into a {@link android.graphics.Bitmap}.  The
1791      * bitmap must match the dimensions of the Allocation.
1792      *
1793      * @param b The bitmap to be set from the Allocation.
1794      */
copyTo(Bitmap b)1795     public void copyTo(Bitmap b) {
1796         mRS.validate();
1797         validateBitmapFormat(b);
1798         validateBitmapSize(b);
1799         mRS.nAllocationCopyToBitmap(getID(mRS), b);
1800     }
1801 
copyTo(Object array, Element.DataType dt, int arrayLen)1802     private void copyTo(Object array, Element.DataType dt, int arrayLen) {
1803         mRS.validate();
1804         boolean usePadding = false;
1805         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1806             usePadding = true;
1807         }
1808         if (usePadding) {
1809             if (dt.mSize * arrayLen < mSize / 4 * 3) {
1810                 throw new RSIllegalArgumentException(
1811                     "Size of output array cannot be smaller than size of allocation.");
1812             }
1813         } else {
1814             if (dt.mSize * arrayLen < mSize) {
1815                 throw new RSIllegalArgumentException(
1816                     "Size of output array cannot be smaller than size of allocation.");
1817             }
1818         }
1819         mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1820     }
1821 
1822     /**
1823      * Copy from the Allocation into an array. The method is type checked
1824      * and will generate exceptions if the Allocation's {@link
1825      * androidx.renderscript.Element} does not match the input data type.
1826      *
1827      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1828      * array in bytes must be at least the size of the Allocation {@link
1829      * #getBytesSize getBytesSize()}.
1830      *
1831      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1832      * is disabled, then the size of the array in bytes must be at least the size
1833      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1834      * the cells will be part of the array.
1835      *
1836      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1837      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1838      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1839      * the cells must not be part of the array.
1840      *
1841      * @param array The array to be set from the Allocation.
1842      */
copyTo(Object array)1843     public void copyTo(Object array) {
1844         copyTo(array, validateObjectIsPrimitiveArray(array, true),
1845                java.lang.reflect.Array.getLength(array));
1846     }
1847 
1848     /**
1849      * Copy from the Allocation into a byte array. This variant is type checked
1850      * and will generate exceptions if the Allocation's {@link
1851      * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
1852      * integers {@link androidx.renderscript.Element.DataType}.
1853      *
1854      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1855      * array in bytes must be at least the size of the Allocation {@link
1856      * #getBytesSize getBytesSize()}.
1857      *
1858      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1859      * is disabled, then the size of the array in bytes must be at least the size
1860      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1861      * the cells will be part of the array.
1862      *
1863      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1864      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1865      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1866      * the cells must not be part of the array.
1867      *
1868      * @param d The array to be set from the Allocation.
1869      */
copyTo(byte[] d)1870     public void copyTo(byte[] d) {
1871         validateIsInt8();
1872         copyTo(d, Element.DataType.SIGNED_8, d.length);
1873     }
1874 
1875     /**
1876      * Copy from the Allocation into a short array. This variant is type checked
1877      * and will generate exceptions if the Allocation's {@link
1878      * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
1879      * integers {@link androidx.renderscript.Element.DataType}.
1880      *
1881      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1882      * array in bytes must be at least the size of the Allocation {@link
1883      * #getBytesSize getBytesSize()}.
1884      *
1885      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1886      * is disabled, then the size of the array in bytes must be at least the size
1887      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1888      * the cells will be part of the array.
1889      *
1890      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1891      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1892      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1893      * the cells must not be part of the array.
1894      *
1895      * @param d The array to be set from the Allocation.
1896      */
copyTo(short[] d)1897     public void copyTo(short[] d) {
1898         validateIsInt16();
1899         copyTo(d, Element.DataType.SIGNED_16, d.length);
1900     }
1901 
1902     /**
1903      * Copy from the Allocation into a int array. This variant is type checked
1904      * and will generate exceptions if the Allocation's {@link
1905      * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
1906      * integers {@link androidx.renderscript.Element.DataType}.
1907      *
1908      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1909      * array in bytes must be at least the size of the Allocation {@link
1910      * #getBytesSize getBytesSize()}.
1911      *
1912      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1913      * is disabled, then the size of the array in bytes must be at least the size
1914      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1915      * the cells will be part of the array.
1916      *
1917      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1918      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1919      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1920      * the cells must not be part of the array.
1921      *
1922      * @param d The array to be set from the Allocation.
1923      */
copyTo(int[] d)1924     public void copyTo(int[] d) {
1925         validateIsInt32();
1926         copyTo(d, Element.DataType.SIGNED_32, d.length);
1927     }
1928 
1929     /**
1930      * Copy from the Allocation into a float array. This variant is type checked
1931      * and will generate exceptions if the Allocation's {@link
1932      * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
1933      * 32 bit floats {@link androidx.renderscript.Element.DataType}.
1934      *
1935      * <p> If the Allocation does not have Vec3 Elements, then the size of the
1936      * array in bytes must be at least the size of the Allocation {@link
1937      * #getBytesSize getBytesSize()}.
1938      *
1939      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1940      * is disabled, then the size of the array in bytes must be at least the size
1941      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1942      * the cells will be part of the array.
1943      *
1944      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
1945      * is enabled, then the size of the array in bytes must be at least 3/4 the size
1946      * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
1947      * the cells must not be part of the array.
1948      *
1949      * @param d The array to be set from the Allocation.
1950      */
copyTo(float[] d)1951     public void copyTo(float[] d) {
1952         validateIsFloat32();
1953         copyTo(d, Element.DataType.FLOAT_32, d.length);
1954     }
1955 
1956     /**
1957      * @hide
1958      * This is only intended to be used by auto-generated code reflected from
1959      * the RenderScript script files and should not be used by developers.
1960      *
1961      * @param xoff
1962      * @param yoff
1963      * @param zoff
1964      * @param component_number
1965      * @param fp
1966      */
1967     /*
1968     public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
1969         mRS.validate();
1970         if (component_number >= mType.mElement.mElements.length) {
1971             throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1972         }
1973         if(xoff < 0) {
1974             throw new RSIllegalArgumentException("Offset x must be >= 0.");
1975         }
1976         if(yoff < 0) {
1977             throw new RSIllegalArgumentException("Offset y must be >= 0.");
1978         }
1979         if(zoff < 0) {
1980             throw new RSIllegalArgumentException("Offset z must be >= 0.");
1981         }
1982 
1983         final byte[] data = fp.getData();
1984         int data_length = data.length;
1985         int eSize = mType.mElement.mElements[component_number].getBytesSize();
1986         eSize *= mType.mElement.mArraySizes[component_number];
1987 
1988         if (data_length != eSize) {
1989             throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1990                                                " does not match component size " + eSize + ".");
1991         }
1992 
1993         mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1994                                    component_number, data, data_length);
1995     }
1996     */
1997 
copy1DRangeToUnchecked(int off, int count, Object array, Element.DataType dt, int arrayLen)1998     private void copy1DRangeToUnchecked(int off, int count, Object array,
1999                                         Element.DataType dt, int arrayLen) {
2000         final int dataSize = mType.mElement.getBytesSize() * count;
2001         // AutoPadding for Vec3 Element
2002         boolean usePadding = false;
2003         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
2004             usePadding = true;
2005         }
2006         data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
2007         mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
2008                               mType.mElement.mType.mSize, usePadding);
2009     }
2010 
2011     /**
2012      * Copy a 1D region of this Allocation into an array.  This method does not
2013      * guarantee that the Allocation is compatible with the input buffer.
2014      *
2015      * <p> The size of the region is: count * {@link #getElement}.{@link
2016      * Element#getBytesSize}.
2017      *
2018      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2019      * array in bytes must be at least the size of the region.
2020      *
2021      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2022      * is disabled, then the size of the array in bytes must be at least the size
2023      * of the region. The padding bytes for the cells must be part of the array.
2024      *
2025      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2026      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2027      * of the region. The padding bytes for the cells must not be part of the array.
2028      *
2029      * @param off The offset of the first element to be copied.
2030      * @param count The number of elements to be copied.
2031      * @param array The dest array
2032      */
copy1DRangeToUnchecked(int off, int count, Object array)2033     public void copy1DRangeToUnchecked(int off, int count, Object array) {
2034         copy1DRangeToUnchecked(off, count, array,
2035                                validateObjectIsPrimitiveArray(array, false),
2036                                java.lang.reflect.Array.getLength(array));
2037     }
2038 
2039     /**
2040      * Copy a 1D region of this Allocation into an array.  This method does not
2041      * guarantee that the Allocation is compatible with the input buffer.
2042      *
2043      * <p> The size of the region is: count * {@link #getElement}.{@link
2044      * Element#getBytesSize}.
2045      *
2046      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2047      * array in bytes must be at least the size of the region.
2048      *
2049      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2050      * is disabled, then the size of the array in bytes must be at least the size
2051      * of the region. The padding bytes for the cells must be part of the array.
2052      *
2053      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2054      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2055      * of the region. The padding bytes for the cells must not be part of the array.
2056      *
2057      * @param off The offset of the first element to be copied.
2058      * @param count The number of elements to be copied.
2059      * @param d the source array
2060      */
copy1DRangeToUnchecked(int off, int count, int[] d)2061     public void copy1DRangeToUnchecked(int off, int count, int[] d) {
2062         copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
2063     }
2064 
2065     /**
2066      * Copy a 1D region of this Allocation into an array.  This method does not
2067      * guarantee that the Allocation is compatible with the input buffer.
2068      *
2069      * <p> The size of the region is: count * {@link #getElement}.{@link
2070      * Element#getBytesSize}.
2071      *
2072      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2073      * array in bytes must be at least the size of the region.
2074      *
2075      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2076      * is disabled, then the size of the array in bytes must be at least the size
2077      * of the region. The padding bytes for the cells must be part of the array.
2078      *
2079      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2080      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2081      * of the region. The padding bytes for the cells must not be part of the array.
2082      *
2083      * @param off The offset of the first element to be copied.
2084      * @param count The number of elements to be copied.
2085      * @param d the source array
2086      */
copy1DRangeToUnchecked(int off, int count, short[] d)2087     public void copy1DRangeToUnchecked(int off, int count, short[] d) {
2088         copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
2089     }
2090 
2091     /**
2092      * Copy a 1D region of this Allocation into an array.  This method does not
2093      * guarantee that the Allocation is compatible with the input buffer.
2094      *
2095      * <p> The size of the region is: count * {@link #getElement}.{@link
2096      * Element#getBytesSize}.
2097      *
2098      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2099      * array in bytes must be at least the size of the region.
2100      *
2101      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2102      * is disabled, then the size of the array in bytes must be at least the size
2103      * of the region. The padding bytes for the cells must be part of the array.
2104      *
2105      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2106      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2107      * of the region. The padding bytes for the cells must not be part of the array.
2108      *
2109      * @param off The offset of the first element to be copied.
2110      * @param count The number of elements to be copied.
2111      * @param d the source array
2112      */
copy1DRangeToUnchecked(int off, int count, byte[] d)2113     public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
2114         copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
2115     }
2116 
2117     /**
2118      * Copy a 1D region of this Allocation into an array.  This method does not
2119      * guarantee that the Allocation is compatible with the input buffer.
2120      *
2121      * <p> The size of the region is: count * {@link #getElement}.{@link
2122      * Element#getBytesSize}.
2123      *
2124      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2125      * array in bytes must be at least the size of the region.
2126      *
2127      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2128      * is disabled, then the size of the array in bytes must be at least the size
2129      * of the region. The padding bytes for the cells must be part of the array.
2130      *
2131      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2132      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2133      * of the region. The padding bytes for the cells must not be part of the array.
2134      *
2135      * @param off The offset of the first element to be copied.
2136      * @param count The number of elements to be copied.
2137      * @param d the source array
2138      */
copy1DRangeToUnchecked(int off, int count, float[] d)2139     public void copy1DRangeToUnchecked(int off, int count, float[] d) {
2140         copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
2141     }
2142 
2143 
2144     /**
2145      * Copy a 1D region of this Allocation into an array.  This method is type checked
2146      * and will generate exceptions if the Allocation's {@link
2147      * androidx.renderscript.Element} does not match the component type
2148      * of the array passed in.
2149      *
2150      * <p> The size of the region is: count * {@link #getElement}.{@link
2151      * Element#getBytesSize}.
2152      *
2153      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2154      * array in bytes must be at least the size of the region.
2155      *
2156      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2157      * is disabled, then the size of the array in bytes must be at least the size
2158      * of the region. The padding bytes for the cells must be part of the array.
2159      *
2160      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2161      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2162      * of the region. The padding bytes for the cells must not be part of the array.
2163      *
2164      * @param off The offset of the first element to be copied.
2165      * @param count The number of elements to be copied.
2166      * @param array The source array.
2167      */
copy1DRangeTo(int off, int count, Object array)2168     public void copy1DRangeTo(int off, int count, Object array) {
2169         copy1DRangeToUnchecked(off, count, array,
2170                                validateObjectIsPrimitiveArray(array, true),
2171                                java.lang.reflect.Array.getLength(array));
2172     }
2173 
2174     /**
2175      * Copy a 1D region of this Allocation into an array. This variant is type checked
2176      * and will generate exceptions if the Allocation's {@link
2177      * androidx.renderscript.Element} is neither a 32 bit integer nor a vector of 32 bit
2178      * integers {@link androidx.renderscript.Element.DataType}.
2179      *
2180      * <p> The size of the region is: count * {@link #getElement}.{@link
2181      * Element#getBytesSize}.
2182      *
2183      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2184      * array in bytes must be at least the size of the region.
2185      *
2186      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2187      * is disabled, then the size of the array in bytes must be at least the size
2188      * of the region. The padding bytes for the cells must be part of the array.
2189      *
2190      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2191      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2192      * of the region. The padding bytes for the cells must not be part of the array.
2193      *
2194      * @param off The offset of the first element to be copied.
2195      * @param count The number of elements to be copied.
2196      * @param d the source array
2197      */
copy1DRangeTo(int off, int count, int[] d)2198     public void copy1DRangeTo(int off, int count, int[] d) {
2199         validateIsInt32();
2200         copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
2201     }
2202 
2203     /**
2204      * Copy a 1D region of this Allocation into an array. This variant is type checked
2205      * and will generate exceptions if the Allocation's {@link
2206      * androidx.renderscript.Element} is neither a 16 bit integer nor a vector of 16 bit
2207      * integers {@link androidx.renderscript.Element.DataType}.
2208      *
2209      * <p> The size of the region is: count * {@link #getElement}.{@link
2210      * Element#getBytesSize}.
2211      *
2212      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2213      * array in bytes must be at least the size of the region.
2214      *
2215      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2216      * is disabled, then the size of the array in bytes must be at least the size
2217      * of the region. The padding bytes for the cells must be part of the array.
2218      *
2219      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2220      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2221      * of the region. The padding bytes for the cells must not be part of the array.
2222      *
2223      * @param off The offset of the first element to be copied.
2224      * @param count The number of elements to be copied.
2225      * @param d the source array
2226      */
copy1DRangeTo(int off, int count, short[] d)2227     public void copy1DRangeTo(int off, int count, short[] d) {
2228         validateIsInt16();
2229         copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
2230     }
2231 
2232     /**
2233      * Copy a 1D region of this Allocation into an array. This variant is type checked
2234      * and will generate exceptions if the Allocation's {@link
2235      * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
2236      * integers {@link androidx.renderscript.Element.DataType}.
2237      *
2238      * <p> The size of the region is: count * {@link #getElement}.{@link
2239      * Element#getBytesSize}.
2240      *
2241      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2242      * array in bytes must be at least the size of the region.
2243      *
2244      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2245      * is disabled, then the size of the array in bytes must be at least the size
2246      * of the region. The padding bytes for the cells must be part of the array.
2247      *
2248      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2249      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2250      * of the region. The padding bytes for the cells must not be part of the array.
2251      *
2252      * @param off The offset of the first element to be copied.
2253      * @param count The number of elements to be copied.
2254      * @param d the source array
2255      */
copy1DRangeTo(int off, int count, byte[] d)2256     public void copy1DRangeTo(int off, int count, byte[] d) {
2257         validateIsInt8();
2258         copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
2259     }
2260 
2261     /**
2262      * Copy a 1D region of this Allocation into an array. This variant is type checked
2263      * and will generate exceptions if the Allocation's {@link
2264      * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
2265      * 32 bit floats {@link androidx.renderscript.Element.DataType}.
2266      *
2267      * <p> The size of the region is: count * {@link #getElement}.{@link
2268      * Element#getBytesSize}.
2269      *
2270      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2271      * array in bytes must be at least the size of the region.
2272      *
2273      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2274      * is disabled, then the size of the array in bytes must be at least the size
2275      * of the region. The padding bytes for the cells must be part of the array.
2276      *
2277      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2278      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2279      * of the region. The padding bytes for the cells must not be part of the array.
2280      *
2281      * @param off The offset of the first element to be copied.
2282      * @param count The number of elements to be copied.
2283      * @param d the source array.
2284      */
copy1DRangeTo(int off, int count, float[] d)2285     public void copy1DRangeTo(int off, int count, float[] d) {
2286         validateIsFloat32();
2287         copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
2288     }
2289 
2290 
copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array, Element.DataType dt, int arrayLen)2291     void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
2292                                 Element.DataType dt, int arrayLen) {
2293         mRS.validate();
2294         validate2DRange(xoff, yoff, w, h);
2295         final int dataSize = mType.mElement.getBytesSize() * w * h;
2296         // AutoPadding for Vec3 Element
2297         boolean usePadding = false;
2298         int sizeBytes = arrayLen * dt.mSize;
2299         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
2300             if (dataSize / 4 * 3 > sizeBytes) {
2301                 throw new RSIllegalArgumentException("Array too small for allocation type.");
2302             }
2303             usePadding = true;
2304             sizeBytes = dataSize;
2305         } else {
2306             if (dataSize > sizeBytes) {
2307                 throw new RSIllegalArgumentException("Array too small for allocation type.");
2308             }
2309         }
2310         mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
2311                               array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
2312     }
2313 
2314     /**
2315      * Copy from a rectangular region in this Allocation into an array. This
2316      * method is type checked and will generate exceptions if the Allocation's
2317      * {@link androidx.renderscript.Element} does not match the component type
2318      * of the array passed in.
2319      *
2320      * <p> The size of the region is: w * h * {@link #getElement}.{@link
2321      * Element#getBytesSize}.
2322      *
2323      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2324      * array in bytes must be at least the size of the region.
2325      *
2326      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2327      * is disabled, then the size of the array in bytes must be at least the size
2328      * of the region. The padding bytes for the cells must be part of the array.
2329      *
2330      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2331      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2332      * of the region. The padding bytes for the cells must not be part of the array.
2333      *
2334      * @param xoff X offset of the region to copy in this Allocation
2335      * @param yoff Y offset of the region to copy in this Allocation
2336      * @param w Width of the region to copy
2337      * @param h Height of the region to copy
2338      * @param array Dest Array to be copied into
2339      */
copy2DRangeTo(int xoff, int yoff, int w, int h, Object array)2340     public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
2341         copy2DRangeToUnchecked(xoff, yoff, w, h, array,
2342                                validateObjectIsPrimitiveArray(array, true),
2343                                java.lang.reflect.Array.getLength(array));
2344     }
2345 
2346     /**
2347      * Copy from a rectangular region in this Allocation into an array. This
2348      * variant is type checked and will generate exceptions if the Allocation's
2349      * {@link androidx.renderscript.Element} is neither an 8 bit integer nor a vector
2350      * of 8 bit integers {@link androidx.renderscript.Element.DataType}.
2351      *
2352      * <p> The size of the region is: w * h * {@link #getElement}.{@link
2353      * Element#getBytesSize}.
2354      *
2355      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2356      * array in bytes must be at least the size of the region.
2357      *
2358      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2359      * is disabled, then the size of the array in bytes must be at least the size
2360      * of the region. The padding bytes for the cells must be part of the array.
2361      *
2362      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2363      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2364      * of the region. The padding bytes for the cells must not be part of the array.
2365      *
2366      * @param xoff X offset of the region to copy in this Allocation
2367      * @param yoff Y offset of the region to copy in this Allocation
2368      * @param w Width of the region to copy
2369      * @param h Height of the region to copy
2370      * @param data Dest Array to be copied into
2371      */
copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data)2372     public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
2373         validateIsInt8();
2374         copy2DRangeToUnchecked(xoff, yoff, w, h, data,
2375                                Element.DataType.SIGNED_8, data.length);
2376     }
2377 
2378     /**
2379      * Copy from a rectangular region in this Allocation into an array. This
2380      * variant is type checked and will generate exceptions if the Allocation's
2381      * {@link androidx.renderscript.Element} is neither a 16 bit integer nor a vector
2382      * of 16 bit integers {@link androidx.renderscript.Element.DataType}.
2383      *
2384      * <p> The size of the region is: w * h * {@link #getElement}.{@link
2385      * Element#getBytesSize}.
2386      *
2387      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2388      * array in bytes must be at least the size of the region.
2389      *
2390      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2391      * is disabled, then the size of the array in bytes must be at least the size
2392      * of the region. The padding bytes for the cells must be part of the array.
2393      *
2394      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2395      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2396      * of the region. The padding bytes for the cells must not be part of the array.
2397      *
2398      * @param xoff X offset of the region to copy in this Allocation
2399      * @param yoff Y offset of the region to copy in this Allocation
2400      * @param w Width of the region to copy
2401      * @param h Height of the region to copy
2402      * @param data Dest Array to be copied into
2403      */
copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data)2404     public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
2405         validateIsInt16();
2406         copy2DRangeToUnchecked(xoff, yoff, w, h, data,
2407                                Element.DataType.SIGNED_16, data.length);
2408     }
2409 
2410     /**
2411      * Copy from a rectangular region in this Allocation into an array. This
2412      * variant is type checked and will generate exceptions if the Allocation's
2413      * {@link androidx.renderscript.Element} is neither a 32 bit integer nor a vector
2414      * of 32 bit integers {@link androidx.renderscript.Element.DataType}.
2415      *
2416      * <p> The size of the region is: w * h * {@link #getElement}.{@link
2417      * Element#getBytesSize}.
2418      *
2419      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2420      * array in bytes must be at least the size of the region.
2421      *
2422      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2423      * is disabled, then the size of the array in bytes must be at least the size
2424      * of the region. The padding bytes for the cells must be part of the array.
2425      *
2426      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2427      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2428      * of the region. The padding bytes for the cells must not be part of the array.
2429      *
2430      * @param xoff X offset of the region to copy in this Allocation
2431      * @param yoff Y offset of the region to copy in this Allocation
2432      * @param w Width of the region to copy
2433      * @param h Height of the region to copy
2434      * @param data Dest Array to be copied into
2435      */
copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data)2436     public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
2437         validateIsInt32();
2438         copy2DRangeToUnchecked(xoff, yoff, w, h, data,
2439                                Element.DataType.SIGNED_32, data.length);
2440     }
2441 
2442     /**
2443      * Copy from a rectangular region in this Allocation into an array. This
2444      * variant is type checked and will generate exceptions if the Allocation's
2445      * {@link androidx.renderscript.Element} is neither a 32 bit float nor a vector
2446      * of 32 bit floats {@link androidx.renderscript.Element.DataType}.
2447      *
2448      * <p> The size of the region is: w * h * {@link #getElement}.{@link
2449      * Element#getBytesSize}.
2450      *
2451      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2452      * array in bytes must be at least the size of the region.
2453      *
2454      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2455      * is disabled, then the size of the array in bytes must be at least the size
2456      * of the region. The padding bytes for the cells must be part of the array.
2457      *
2458      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2459      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2460      * of the region. The padding bytes for the cells must not be part of the array.
2461      *
2462      * @param xoff X offset of the region to copy in this Allocation
2463      * @param yoff Y offset of the region to copy in this Allocation
2464      * @param w Width of the region to copy
2465      * @param h Height of the region to copy
2466      * @param data Dest Array to be copied into
2467      */
copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data)2468     public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
2469         validateIsFloat32();
2470         copy2DRangeToUnchecked(xoff, yoff, w, h, data,
2471                                Element.DataType.FLOAT_32, data.length);
2472     }
2473 
2474 
2475     /**
2476      * Copy from a 3D region in this Allocation into an array. This method does
2477      * not guarantee that the Allocation is compatible with the input buffer.
2478      * The array is assumed to be tightly packed.
2479      *
2480      * The data type of the array is not required to be the same as
2481      * the element data type.
2482      */
2483     /*
2484     private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
2485                                         Object array, Element.DataType dt, int arrayLen) {
2486         mRS.validate();
2487         validate3DRange(xoff, yoff, zoff, w, h, d);
2488         final int dataSize = mType.mElement.getBytesSize() * w * h * d;
2489         // AutoPadding for Vec3 Element
2490         boolean usePadding = false;
2491         int sizeBytes = arrayLen * dt.mSize;
2492         if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
2493             if (dataSize / 4 * 3 > sizeBytes) {
2494                 throw new RSIllegalArgumentException("Array too small for allocation type.");
2495             }
2496             usePadding = true;
2497             sizeBytes = dataSize;
2498         } else {
2499             if (dataSize > sizeBytes) {
2500                 throw new RSIllegalArgumentException("Array too small for allocation type.");
2501             }
2502         }
2503         mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
2504                               array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
2505     }
2506     */
2507 
2508     /**
2509      * @hide
2510      * Copy from a 3D region in this Allocation into an array. This
2511      * method is type checked and will generate exceptions if the Allocation's
2512      * {@link androidx.renderscript.Element} does not match the component type
2513      * of the array passed in.
2514      *
2515      * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
2516      * Element#getBytesSize}.
2517      *
2518      * <p> If the Allocation does not have Vec3 Elements, then the size of the
2519      * array in bytes must be at least the size of the region.
2520      *
2521      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2522      * is disabled, then the size of the array in bytes must be at least the size
2523      * of the region. The padding bytes for the cells must be part of the array.
2524      *
2525      * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
2526      * is enabled, then the size of the array in bytes must be at least 3/4 the size
2527      * of the region. The padding bytes for the cells must not be part of the array.
2528      *
2529      * @param xoff X offset of the region to copy in this Allocation
2530      * @param yoff Y offset of the region to copy in this Allocation
2531      * @param zoff Z offset of the region to copy in this Allocation
2532      * @param w Width of the region to copy
2533      * @param h Height of the region to copy
2534      * @param d Depth of the region to copy
2535      * @param array Dest Array to be copied into
2536      */
2537     /*
2538     public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
2539         copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
2540                                  validateObjectIsPrimitiveArray(array, true),
2541                                  java.lang.reflect.Array.getLength(array));
2542     }
2543     */
2544 
2545     // creation
2546 
2547     static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
2548     static {
2549         mBitmapOptions.inScaled = false;
2550     }
2551 
2552     /**
2553      * Creates a new Allocation with the given {@link
2554      * androidx.renderscript.Type}, mipmap flag, and usage flags.
2555      *
2556      * @param type RenderScript type describing data layout
2557      * @param mips specifies desired mipmap behaviour for the
2558      *             allocation
2559      * @param usage bit field specifying how the Allocation is
2560      *              utilized
2561      */
createTyped(RenderScript rs, Type type, MipmapControl mips, int usage)2562     static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
2563         rs.validate();
2564         if (type.getID(rs) == 0) {
2565             throw new RSInvalidStateException("Bad Type");
2566         }
2567 
2568         if(!rs.usingIO() && (usage & (USAGE_IO_INPUT | USAGE_IO_INPUT)) != 0) {
2569             throw new RSRuntimeException("USAGE_IO not supported, Allocation creation failed.");
2570         }
2571 
2572         long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2573         if (id == 0) {
2574             throw new RSRuntimeException("Allocation creation failed.");
2575         }
2576         return new Allocation(id, rs, type, usage);
2577     }
2578 
2579     /**
2580      * Creates an Allocation with the size specified by the type and no mipmaps
2581      * generated by default
2582      *
2583      * @param rs Context to which the allocation will belong.
2584      * @param type renderscript type describing data layout
2585      * @param usage bit field specifying how the allocation is
2586      *              utilized
2587      *
2588      * @return allocation
2589      */
createTyped(RenderScript rs, Type type, int usage)2590     static public Allocation createTyped(RenderScript rs, Type type, int usage) {
2591         return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
2592     }
2593 
2594     /**
2595      * Creates an Allocation for use by scripts with a given {@link
2596      * androidx.renderscript.Type} and no mipmaps
2597      *
2598      * @param rs Context to which the Allocation will belong.
2599      * @param type RenderScript Type describing data layout
2600      *
2601      * @return allocation
2602      */
createTyped(RenderScript rs, Type type)2603     static public Allocation createTyped(RenderScript rs, Type type) {
2604         return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
2605     }
2606 
2607     /**
2608      * Creates an Allocation with a specified number of given elements
2609      *
2610      * @param rs Context to which the Allocation will belong.
2611      * @param e Element to use in the Allocation
2612      * @param count the number of Elements in the Allocation
2613      * @param usage bit field specifying how the Allocation is
2614      *              utilized
2615      *
2616      * @return allocation
2617      */
createSized(RenderScript rs, Element e, int count, int usage)2618     static public Allocation createSized(RenderScript rs, Element e,
2619                                          int count, int usage) {
2620         rs.validate();
2621         Type.Builder b = new Type.Builder(rs, e);
2622         b.setX(count);
2623         Type t = b.create();
2624 
2625         long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
2626         if (id == 0) {
2627             throw new RSRuntimeException("Allocation creation failed.");
2628         }
2629         return new Allocation(id, rs, t, usage);
2630     }
2631 
2632     /**
2633      * Creates an Allocation with a specified number of given elements
2634      *
2635      * @param rs Context to which the Allocation will belong.
2636      * @param e Element to use in the Allocation
2637      * @param count the number of Elements in the Allocation
2638      *
2639      * @return allocation
2640      */
createSized(RenderScript rs, Element e, int count)2641     static public Allocation createSized(RenderScript rs, Element e, int count) {
2642         return createSized(rs, e, count, USAGE_SCRIPT);
2643     }
2644 
elementFromBitmap(RenderScript rs, Bitmap b)2645     static Element elementFromBitmap(RenderScript rs, Bitmap b) {
2646         final Bitmap.Config bc = b.getConfig();
2647         if (bc == Bitmap.Config.ALPHA_8) {
2648             return Element.A_8(rs);
2649         }
2650         if (bc == Bitmap.Config.ARGB_4444) {
2651             return Element.RGBA_4444(rs);
2652         }
2653         if (bc == Bitmap.Config.ARGB_8888) {
2654             return Element.RGBA_8888(rs);
2655         }
2656         if (bc == Bitmap.Config.RGB_565) {
2657             return Element.RGB_565(rs);
2658         }
2659         throw new RSInvalidStateException("Bad bitmap type: " + bc);
2660     }
2661 
typeFromBitmap(RenderScript rs, Bitmap b, MipmapControl mip)2662     static Type typeFromBitmap(RenderScript rs, Bitmap b,
2663                                        MipmapControl mip) {
2664         Element e = elementFromBitmap(rs, b);
2665         Type.Builder tb = new Type.Builder(rs, e);
2666         tb.setX(b.getWidth());
2667         tb.setY(b.getHeight());
2668         tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
2669         return tb.create();
2670     }
2671 
2672     /**
2673      * Creates an Allocation from a {@link android.graphics.Bitmap}.
2674      *
2675      * @param rs Context to which the allocation will belong.
2676      * @param b Bitmap source for the allocation data
2677      * @param mips specifies desired mipmap behaviour for the
2678      *             allocation
2679      * @param usage bit field specifying how the allocation is
2680      *              utilized
2681      *
2682      * @return Allocation containing bitmap data
2683      *
2684      */
createFromBitmap(RenderScript rs, Bitmap b, MipmapControl mips, int usage)2685     static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
2686                                               MipmapControl mips,
2687                                               int usage) {
2688         rs.validate();
2689 
2690         // WAR undocumented color formats
2691         if (b.getConfig() == null) {
2692             if ((usage & USAGE_SHARED) != 0) {
2693                 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2694             }
2695             Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2696             Canvas c = new Canvas(newBitmap);
2697             c.drawBitmap(b, 0, 0, null);
2698             return createFromBitmap(rs, newBitmap, mips, usage);
2699         }
2700 
2701         Type t = typeFromBitmap(rs, b, mips);
2702 
2703         // enable optimized bitmap path only with no mipmap and script-only usage
2704         if (mips == MipmapControl.MIPMAP_NONE &&
2705             t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2706             usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2707             long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2708             if (id == 0) {
2709                 throw new RSRuntimeException("Load failed.");
2710             }
2711 
2712             // keep a reference to the Bitmap around to prevent GC
2713             Allocation alloc = new Allocation(id, rs, t, usage);
2714             alloc.setBitmap(b);
2715             return alloc;
2716         }
2717 
2718 
2719         long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
2720         if (id == 0) {
2721             throw new RSRuntimeException("Load failed.");
2722         }
2723         return new Allocation(id, rs, t, usage);
2724     }
2725 
2726     /**
2727      * Associate a {@link android.view.Surface} with this Allocation. This
2728      * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
2729      *
2730      * @param sur Surface to associate with allocation
2731      */
setSurface(Surface sur)2732     public void setSurface(Surface sur) {
2733         mRS.validate();
2734         if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2735             throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2736         }
2737 
2738         mRS.nAllocationSetSurface(getID(mRS), sur);
2739     }
2740 
2741     /**
2742      * Creates an Allocation from a {@link android.graphics.Bitmap}.
2743      *
2744      * <p>This Allocation will be created with {@link #USAGE_SHARED}, and
2745      * {@link #USAGE_SCRIPT}.</p>
2746      *
2747      * @param rs Context to which the allocation will belong.
2748      * @param b bitmap source for the allocation data
2749      *
2750      * @return Allocation containing bitmap data
2751      *
2752      */
createFromBitmap(RenderScript rs, Bitmap b)2753     static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
2754         return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2755                                 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
2756     }
2757 
2758     /**
2759      * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2760      * containing the horizontal list of cube faces. Each face must be a square,
2761      * have the same size as all other faces, and have a width that is a power
2762      * of 2.
2763      *
2764      * @param rs Context to which the allocation will belong.
2765      * @param b Bitmap with cubemap faces layed out in the following
2766      *          format: right, left, top, bottom, front, back
2767      * @param mips specifies desired mipmap behaviour for the cubemap
2768      * @param usage bit field specifying how the cubemap is utilized
2769      *
2770      * @return allocation containing cubemap data
2771      *
2772      */
createCubemapFromBitmap(RenderScript rs, Bitmap b, MipmapControl mips, int usage)2773     static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
2774                                                      MipmapControl mips,
2775                                                      int usage) {
2776         rs.validate();
2777 
2778         int height = b.getHeight();
2779         int width = b.getWidth();
2780 
2781         if (width % 6 != 0) {
2782             throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2783         }
2784         if (width / 6 != height) {
2785             throw new RSIllegalArgumentException("Only square cube map faces supported");
2786         }
2787         boolean isPow2 = (height & (height - 1)) == 0;
2788         if (!isPow2) {
2789             throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2790         }
2791 
2792         Element e = elementFromBitmap(rs, b);
2793         Type.Builder tb = new Type.Builder(rs, e);
2794         tb.setX(height);
2795         tb.setY(height);
2796         tb.setFaces(true);
2797         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2798         Type t = tb.create();
2799 
2800         long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
2801         if(id == 0) {
2802             throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2803         }
2804         return new Allocation(id, rs, t, usage);
2805     }
2806 
2807     /**
2808      * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2809      * from a {@link android.graphics.Bitmap} containing the horizontal list of
2810      * cube faces. Each face must be a square, have the same size as all other
2811      * faces, and have a width that is a power of 2.
2812      *
2813      * @param rs Context to which the allocation will belong.
2814      * @param b bitmap with cubemap faces layed out in the following
2815      *          format: right, left, top, bottom, front, back
2816      *
2817      * @return allocation containing cubemap data
2818      *
2819      */
createCubemapFromBitmap(RenderScript rs, Bitmap b)2820     static public Allocation createCubemapFromBitmap(RenderScript rs,
2821                                                      Bitmap b) {
2822         return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2823                                        USAGE_GRAPHICS_TEXTURE);
2824     }
2825 
2826     /**
2827      * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2828      * objects containing the cube faces. Each face must be a square, have the
2829      * same size as all other faces, and have a width that is a power of 2.
2830      *
2831      * @param rs Context to which the allocation will belong.
2832      * @param xpos cubemap face in the positive x direction
2833      * @param xneg cubemap face in the negative x direction
2834      * @param ypos cubemap face in the positive y direction
2835      * @param yneg cubemap face in the negative y direction
2836      * @param zpos cubemap face in the positive z direction
2837      * @param zneg cubemap face in the negative z direction
2838      * @param mips specifies desired mipmap behaviour for the cubemap
2839      * @param usage bit field specifying how the cubemap is utilized
2840      *
2841      * @return allocation containing cubemap data
2842      *
2843      */
createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg, MipmapControl mips, int usage)2844     static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2845                                                         Bitmap xpos,
2846                                                         Bitmap xneg,
2847                                                         Bitmap ypos,
2848                                                         Bitmap yneg,
2849                                                         Bitmap zpos,
2850                                                         Bitmap zneg,
2851                                                         MipmapControl mips,
2852                                                         int usage) {
2853         /*
2854         int height = xpos.getHeight();
2855         if (xpos.getWidth() != height ||
2856             xneg.getWidth() != height || xneg.getHeight() != height ||
2857             ypos.getWidth() != height || ypos.getHeight() != height ||
2858             yneg.getWidth() != height || yneg.getHeight() != height ||
2859             zpos.getWidth() != height || zpos.getHeight() != height ||
2860             zneg.getWidth() != height || zneg.getHeight() != height) {
2861             throw new RSIllegalArgumentException("Only square cube map faces supported");
2862         }
2863         boolean isPow2 = (height & (height - 1)) == 0;
2864         if (!isPow2) {
2865             throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2866         }
2867 
2868         Element e = elementFromBitmap(rs, xpos);
2869         Type.Builder tb = new Type.Builder(rs, e);
2870         tb.setX(height);
2871         tb.setY(height);
2872         tb.setFaces(true);
2873         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2874         Type t = tb.create();
2875         Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2876 
2877         AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
2878         adapter.setFace(Type.CubemapFace.POSITIVE_X);
2879         adapter.copyFrom(xpos);
2880         adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2881         adapter.copyFrom(xneg);
2882         adapter.setFace(Type.CubemapFace.POSITIVE_Y);
2883         adapter.copyFrom(ypos);
2884         adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2885         adapter.copyFrom(yneg);
2886         adapter.setFace(Type.CubemapFace.POSITIVE_Z);
2887         adapter.copyFrom(zpos);
2888         adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2889         adapter.copyFrom(zneg);
2890 
2891         return cubemap;
2892         */
2893         return null;
2894     }
2895 
2896     /**
2897      * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2898      * from 6 {@link android.graphics.Bitmap} objects containing the cube
2899      * faces. Each face must be a square, have the same size as all other faces,
2900      * and have a width that is a power of 2.
2901      *
2902      * @param rs Context to which the allocation will belong.
2903      * @param xpos cubemap face in the positive x direction
2904      * @param xneg cubemap face in the negative x direction
2905      * @param ypos cubemap face in the positive y direction
2906      * @param yneg cubemap face in the negative y direction
2907      * @param zpos cubemap face in the positive z direction
2908      * @param zneg cubemap face in the negative z direction
2909      *
2910      * @return allocation containing cubemap data
2911      *
2912      */
createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg)2913     static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2914                                                         Bitmap xpos,
2915                                                         Bitmap xneg,
2916                                                         Bitmap ypos,
2917                                                         Bitmap yneg,
2918                                                         Bitmap zpos,
2919                                                         Bitmap zneg) {
2920         return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2921                                           zpos, zneg, MipmapControl.MIPMAP_NONE,
2922                                           USAGE_GRAPHICS_TEXTURE);
2923     }
2924 
2925     /**
2926      * Creates an Allocation from the Bitmap referenced
2927      * by resource ID.
2928      *
2929      * @param rs Context to which the allocation will belong.
2930      * @param res application resources
2931      * @param id resource id to load the data from
2932      * @param mips specifies desired mipmap behaviour for the
2933      *             allocation
2934      * @param usage bit field specifying how the allocation is
2935      *              utilized
2936      *
2937      * @return Allocation containing resource data
2938      *
2939      */
createFromBitmapResource(RenderScript rs, Resources res, int id, MipmapControl mips, int usage)2940     static public Allocation createFromBitmapResource(RenderScript rs,
2941                                                       Resources res,
2942                                                       int id,
2943                                                       MipmapControl mips,
2944                                                       int usage) {
2945 
2946         rs.validate();
2947         if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2948             throw new RSIllegalArgumentException("Unsupported usage specified.");
2949         }
2950         Bitmap b = BitmapFactory.decodeResource(res, id);
2951         Allocation alloc = createFromBitmap(rs, b, mips, usage);
2952         b.recycle();
2953         return alloc;
2954     }
2955 
2956     /**
2957      * Creates a non-mipmapped Allocation to use as a graphics texture from the
2958      * {@link android.graphics.Bitmap} referenced by resource ID.
2959      *
2960      * <p>This allocation will be created with {@link #USAGE_SCRIPT} and
2961      * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
2962      *
2963      * @param rs Context to which the allocation will belong.
2964      * @param res application resources
2965      * @param id resource id to load the data from
2966      *
2967      * @return Allocation containing resource data
2968      *
2969      */
createFromBitmapResource(RenderScript rs, Resources res, int id)2970     static public Allocation createFromBitmapResource(RenderScript rs,
2971                                                       Resources res,
2972                                                       int id) {
2973         return createFromBitmapResource(rs, res, id,
2974                                         MipmapControl.MIPMAP_NONE,
2975                                         USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
2976     }
2977 
2978     /**
2979      * Creates an Allocation containing string data encoded in UTF-8 format.
2980      *
2981      * @param rs Context to which the allocation will belong.
2982      * @param str string to create the allocation from
2983      * @param usage bit field specifying how the allocaiton is
2984      *              utilized
2985      *
2986      */
createFromString(RenderScript rs, String str, int usage)2987     static public Allocation createFromString(RenderScript rs,
2988                                               String str,
2989                                               int usage) {
2990         rs.validate();
2991         byte[] allocArray = null;
2992         try {
2993             allocArray = str.getBytes("UTF-8");
2994             Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
2995             alloc.copyFrom(allocArray);
2996             return alloc;
2997         }
2998         catch (Exception e) {
2999             throw new RSRuntimeException("Could not convert string to utf-8.");
3000         }
3001     }
3002 
3003     /**
3004      * Frees any native resources associated with this object.  The
3005      * primary use is to force immediate cleanup of resources when it is
3006      * believed the GC will not respond quickly enough.
3007      * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
3008      */
3009     @Override
destroy()3010     public void destroy() {
3011         if (mIncCompatAllocation != 0) {
3012             boolean shouldDestroy = false;
3013             synchronized(this) {
3014                 if (!mIncAllocDestroyed) {
3015                     shouldDestroy = true;
3016                     mIncAllocDestroyed = true;
3017                 }
3018             }
3019 
3020             if (shouldDestroy) {
3021                 // must include nObjDestroy in the critical section
3022                 ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
3023                 rlock.lock();
3024                 if(mRS.isAlive()) {
3025                     mRS.nIncObjDestroy(mIncCompatAllocation);
3026                 }
3027                 rlock.unlock();
3028                 mIncCompatAllocation = 0;
3029             }
3030         }
3031         if ((mUsage & (USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
3032             setSurface(null);
3033         }
3034         super.destroy();
3035     }
3036 
3037 }
3038