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