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