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