• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008-2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package 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                     throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2899                                                          MAX_NUMBER_IO_INPUT_ALLOC);
2900                 }
2901                 mAllocationArray[0].setupBufferQueue(numAlloc);;
2902             }
2903 
2904             for (int i=1; i<numAlloc; i++) {
2905                 mAllocationArray[i] = createFromAllocation(rs, mAllocationArray[0]);
2906             }
2907             return mAllocationArray;
2908         } finally {
2909             Trace.traceEnd(RenderScript.TRACE_TAG);
2910         }
2911     }
2912 
2913     /**
2914      * Creates a new Allocation with the given {@link
2915      * android.renderscript.Allocation}. The same data layout of
2916      * the input Allocation will be applied.
2917      * <p> If the input allocation is of usage: USAGE_IO_INPUT, the created
2918      * Allocation will be sharing the same BufferQueue.
2919      *
2920      * @param rs Context to which the allocation will belong.
2921      * @param alloc RenderScript Allocation describing data layout.
2922      * @return Allocation sharing the same data structure.
2923      */
createFromAllocation(RenderScript rs, Allocation alloc)2924     static Allocation createFromAllocation(RenderScript rs, Allocation alloc) {
2925         try {
2926             Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2927             rs.validate();
2928             if (alloc.getID(rs) == 0) {
2929                 throw new RSInvalidStateException("Bad input Allocation");
2930             }
2931 
2932             Type type = alloc.getType();
2933             int usage = alloc.getUsage();
2934             MipmapControl mips = alloc.getMipmap();
2935             long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2936             if (id == 0) {
2937                 throw new RSRuntimeException("Allocation creation failed.");
2938             }
2939             Allocation outAlloc = new Allocation(id, rs, type, false, usage, mips);
2940             if ((usage & USAGE_IO_INPUT) != 0) {
2941                 outAlloc.shareBufferQueue(alloc);
2942             }
2943             return outAlloc;
2944         } finally {
2945             Trace.traceEnd(RenderScript.TRACE_TAG);
2946         }
2947     }
2948 
2949     /**
2950      * Initialize BufferQueue with specified max number of buffers.
2951      */
setupBufferQueue(int numAlloc)2952     void setupBufferQueue(int numAlloc) {
2953         mRS.validate();
2954         if ((mUsage & USAGE_IO_INPUT) == 0) {
2955             throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2956         }
2957         mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2958     }
2959 
2960     /**
2961      * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2962      *
2963      * @param alloc Allocation to associate with allocation
2964      */
shareBufferQueue(Allocation alloc)2965     void shareBufferQueue(Allocation alloc) {
2966         mRS.validate();
2967         if ((mUsage & USAGE_IO_INPUT) == 0) {
2968             throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2969         }
2970         mGetSurfaceSurface = alloc.getSurface();
2971         mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2972     }
2973 
2974     /**
2975      * Gets the stride of the Allocation.
2976      * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2977      * the Allocation has certain alignment. The size of each row including such
2978      * padding is called stride.
2979      *
2980      * @return the stride. For 1D Allocation, the stride will be the number of
2981      *         bytes of this Allocation. For 2D and 3D Allocations, the stride
2982      *         will be the stride in X dimension measuring in bytes.
2983      */
getStride()2984     public long getStride() {
2985         if (mByteBufferStride == -1) {
2986             getByteBuffer();
2987         }
2988         return mByteBufferStride;
2989     }
2990 
2991     /**
2992      * Get the timestamp for the most recent buffer held by this Allocation.
2993      * The timestamp is guaranteed to be unique and monotonically increasing.
2994      * Default value: -1. The timestamp will be updated after each {@link
2995      * #ioReceive ioReceive()} call.
2996      *
2997      * It can be used to identify the images by comparing the unique timestamps
2998      * when used with {@link android.hardware.camera2} APIs.
2999      * Example steps:
3000      *   1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
3001      *      capture is completed.
3002      *   2. Get the timestamp after {@link #ioReceive ioReceive()} call.
3003      *   3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
3004      *      alloc.getTimeStamp().
3005      * @return long Timestamp associated with the buffer held by the Allocation.
3006      */
getTimeStamp()3007     public long getTimeStamp() {
3008         return mTimeStamp;
3009     }
3010 
3011     /**
3012      * Returns the handle to a raw buffer that is being managed by the screen
3013      * compositor. This operation is only valid for Allocations with {@link
3014      * #USAGE_IO_INPUT}.
3015      *
3016      * @return Surface object associated with allocation
3017      *
3018      */
getSurface()3019     public Surface getSurface() {
3020         if ((mUsage & USAGE_IO_INPUT) == 0) {
3021             throw new RSInvalidStateException("Allocation is not a surface texture.");
3022         }
3023 
3024         if (mGetSurfaceSurface == null) {
3025             mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
3026         }
3027 
3028         return mGetSurfaceSurface;
3029     }
3030 
3031     /**
3032      * Associate a {@link android.view.Surface} with this Allocation. This
3033      * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
3034      *
3035      * @param sur Surface to associate with allocation
3036      */
setSurface(Surface sur)3037     public void setSurface(Surface sur) {
3038         mRS.validate();
3039         if ((mUsage & USAGE_IO_OUTPUT) == 0) {
3040             throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
3041         }
3042 
3043         mRS.nAllocationSetSurface(getID(mRS), sur);
3044     }
3045 
3046     /**
3047      * Creates an Allocation from a {@link android.graphics.Bitmap}.
3048      *
3049      * <p>With target API version 18 or greater, this Allocation will be created
3050      * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
3051      * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
3052      * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
3053      *
3054      * @param rs Context to which the allocation will belong.
3055      * @param b bitmap source for the allocation data
3056      *
3057      * @return Allocation containing bitmap data
3058      *
3059      */
createFromBitmap(RenderScript rs, Bitmap b)3060     static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
3061         if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
3062             return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
3063                                     USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
3064         }
3065         return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
3066                                 USAGE_GRAPHICS_TEXTURE);
3067     }
3068 
3069     /**
3070      * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
3071      * containing the horizontal list of cube faces. Each face must be a square,
3072      * have the same size as all other faces, and have a width that is a power
3073      * of 2.
3074      *
3075      * @param rs Context to which the allocation will belong.
3076      * @param b Bitmap with cubemap faces layed out in the following
3077      *          format: right, left, top, bottom, front, back
3078      * @param mips specifies desired mipmap behaviour for the cubemap
3079      * @param usage bit field specifying how the cubemap is utilized
3080      *
3081      * @return allocation containing cubemap data
3082      *
3083      */
createCubemapFromBitmap(RenderScript rs, Bitmap b, MipmapControl mips, int usage)3084     static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
3085                                                      MipmapControl mips,
3086                                                      int usage) {
3087         rs.validate();
3088 
3089         int height = b.getHeight();
3090         int width = b.getWidth();
3091 
3092         if (width % 6 != 0) {
3093             throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
3094         }
3095         if (width / 6 != height) {
3096             throw new RSIllegalArgumentException("Only square cube map faces supported");
3097         }
3098         boolean isPow2 = (height & (height - 1)) == 0;
3099         if (!isPow2) {
3100             throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
3101         }
3102 
3103         Element e = elementFromBitmap(rs, b);
3104         Type.Builder tb = new Type.Builder(rs, e);
3105         tb.setX(height);
3106         tb.setY(height);
3107         tb.setFaces(true);
3108         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
3109         Type t = tb.create();
3110 
3111         long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
3112         if(id == 0) {
3113             throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
3114         }
3115         return new Allocation(id, rs, t, true, usage, mips);
3116     }
3117 
3118     /**
3119      * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
3120      * from a {@link android.graphics.Bitmap} containing the horizontal list of
3121      * cube faces. Each face must be a square, have the same size as all other
3122      * faces, and have a width that is a power of 2.
3123      *
3124      * @param rs Context to which the allocation will belong.
3125      * @param b bitmap with cubemap faces layed out in the following
3126      *          format: right, left, top, bottom, front, back
3127      *
3128      * @return allocation containing cubemap data
3129      *
3130      */
createCubemapFromBitmap(RenderScript rs, Bitmap b)3131     static public Allocation createCubemapFromBitmap(RenderScript rs,
3132                                                      Bitmap b) {
3133         return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
3134                                        USAGE_GRAPHICS_TEXTURE);
3135     }
3136 
3137     /**
3138      * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
3139      * objects containing the cube faces. Each face must be a square, have the
3140      * same size as all other faces, and have a width that is a power of 2.
3141      *
3142      * @param rs Context to which the allocation will belong.
3143      * @param xpos cubemap face in the positive x direction
3144      * @param xneg cubemap face in the negative x direction
3145      * @param ypos cubemap face in the positive y direction
3146      * @param yneg cubemap face in the negative y direction
3147      * @param zpos cubemap face in the positive z direction
3148      * @param zneg cubemap face in the negative z direction
3149      * @param mips specifies desired mipmap behaviour for the cubemap
3150      * @param usage bit field specifying how the cubemap is utilized
3151      *
3152      * @return allocation containing cubemap data
3153      *
3154      */
createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg, MipmapControl mips, int usage)3155     static public Allocation createCubemapFromCubeFaces(RenderScript rs,
3156                                                         Bitmap xpos,
3157                                                         Bitmap xneg,
3158                                                         Bitmap ypos,
3159                                                         Bitmap yneg,
3160                                                         Bitmap zpos,
3161                                                         Bitmap zneg,
3162                                                         MipmapControl mips,
3163                                                         int usage) {
3164         int height = xpos.getHeight();
3165         if (xpos.getWidth() != height ||
3166             xneg.getWidth() != height || xneg.getHeight() != height ||
3167             ypos.getWidth() != height || ypos.getHeight() != height ||
3168             yneg.getWidth() != height || yneg.getHeight() != height ||
3169             zpos.getWidth() != height || zpos.getHeight() != height ||
3170             zneg.getWidth() != height || zneg.getHeight() != height) {
3171             throw new RSIllegalArgumentException("Only square cube map faces supported");
3172         }
3173         boolean isPow2 = (height & (height - 1)) == 0;
3174         if (!isPow2) {
3175             throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
3176         }
3177 
3178         Element e = elementFromBitmap(rs, xpos);
3179         Type.Builder tb = new Type.Builder(rs, e);
3180         tb.setX(height);
3181         tb.setY(height);
3182         tb.setFaces(true);
3183         tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
3184         Type t = tb.create();
3185         Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
3186 
3187         AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
3188         adapter.setFace(Type.CubemapFace.POSITIVE_X);
3189         adapter.copyFrom(xpos);
3190         adapter.setFace(Type.CubemapFace.NEGATIVE_X);
3191         adapter.copyFrom(xneg);
3192         adapter.setFace(Type.CubemapFace.POSITIVE_Y);
3193         adapter.copyFrom(ypos);
3194         adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
3195         adapter.copyFrom(yneg);
3196         adapter.setFace(Type.CubemapFace.POSITIVE_Z);
3197         adapter.copyFrom(zpos);
3198         adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
3199         adapter.copyFrom(zneg);
3200 
3201         return cubemap;
3202     }
3203 
3204     /**
3205      * Creates a non-mipmapped cubemap Allocation for use as a sampler input
3206      * from 6 {@link android.graphics.Bitmap} objects containing the cube
3207      * faces. Each face must be a square, have the same size as all other faces,
3208      * and have a width that is a power of 2.
3209      *
3210      * @param rs Context to which the allocation will belong.
3211      * @param xpos cubemap face in the positive x direction
3212      * @param xneg cubemap face in the negative x direction
3213      * @param ypos cubemap face in the positive y direction
3214      * @param yneg cubemap face in the negative y direction
3215      * @param zpos cubemap face in the positive z direction
3216      * @param zneg cubemap face in the negative z direction
3217      *
3218      * @return allocation containing cubemap data
3219      *
3220      */
createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg)3221     static public Allocation createCubemapFromCubeFaces(RenderScript rs,
3222                                                         Bitmap xpos,
3223                                                         Bitmap xneg,
3224                                                         Bitmap ypos,
3225                                                         Bitmap yneg,
3226                                                         Bitmap zpos,
3227                                                         Bitmap zneg) {
3228         return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
3229                                           zpos, zneg, MipmapControl.MIPMAP_NONE,
3230                                           USAGE_GRAPHICS_TEXTURE);
3231     }
3232 
3233     /**
3234      * Creates an Allocation from the Bitmap referenced
3235      * by resource ID.
3236      *
3237      * @param rs Context to which the allocation will belong.
3238      * @param res application resources
3239      * @param id resource id to load the data from
3240      * @param mips specifies desired mipmap behaviour for the
3241      *             allocation
3242      * @param usage bit field specifying how the allocation is
3243      *              utilized
3244      *
3245      * @return Allocation containing resource data
3246      *
3247      */
createFromBitmapResource(RenderScript rs, Resources res, int id, MipmapControl mips, int usage)3248     static public Allocation createFromBitmapResource(RenderScript rs,
3249                                                       Resources res,
3250                                                       int id,
3251                                                       MipmapControl mips,
3252                                                       int usage) {
3253 
3254         rs.validate();
3255         if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
3256             throw new RSIllegalArgumentException("Unsupported usage specified.");
3257         }
3258         Bitmap b = BitmapFactory.decodeResource(res, id);
3259         Allocation alloc = createFromBitmap(rs, b, mips, usage);
3260         b.recycle();
3261         return alloc;
3262     }
3263 
3264     /**
3265      * Creates a non-mipmapped Allocation to use as a graphics texture from the
3266      * {@link android.graphics.Bitmap} referenced by resource ID.
3267      *
3268      * <p>With target API version 18 or greater, this allocation will be created
3269      * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
3270      * target API version 17 or lower, this allocation will be created with
3271      * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
3272      *
3273      * @param rs Context to which the allocation will belong.
3274      * @param res application resources
3275      * @param id resource id to load the data from
3276      *
3277      * @return Allocation containing resource data
3278      *
3279      */
createFromBitmapResource(RenderScript rs, Resources res, int id)3280     static public Allocation createFromBitmapResource(RenderScript rs,
3281                                                       Resources res,
3282                                                       int id) {
3283         if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
3284             return createFromBitmapResource(rs, res, id,
3285                                             MipmapControl.MIPMAP_NONE,
3286                                             USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
3287         }
3288         return createFromBitmapResource(rs, res, id,
3289                                         MipmapControl.MIPMAP_NONE,
3290                                         USAGE_GRAPHICS_TEXTURE);
3291     }
3292 
3293     /**
3294      * Creates an Allocation containing string data encoded in UTF-8 format.
3295      *
3296      * @param rs Context to which the allocation will belong.
3297      * @param str string to create the allocation from
3298      * @param usage bit field specifying how the allocaiton is
3299      *              utilized
3300      *
3301      */
createFromString(RenderScript rs, String str, int usage)3302     static public Allocation createFromString(RenderScript rs,
3303                                               String str,
3304                                               int usage) {
3305         rs.validate();
3306         byte[] allocArray = null;
3307         try {
3308             allocArray = str.getBytes("UTF-8");
3309             Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
3310             alloc.copyFrom(allocArray);
3311             return alloc;
3312         }
3313         catch (Exception e) {
3314             throw new RSRuntimeException("Could not convert string to utf-8.");
3315         }
3316     }
3317 
3318     /**
3319      * Interface to handle notification when new buffers are available via
3320      * {@link #USAGE_IO_INPUT}. An application will receive one notification
3321      * when a buffer is available. Additional buffers will not trigger new
3322      * notifications until a buffer is processed.
3323      */
3324     public interface OnBufferAvailableListener {
onBufferAvailable(Allocation a)3325         public void onBufferAvailable(Allocation a);
3326     }
3327 
3328     /**
3329      * Set a notification handler for {@link #USAGE_IO_INPUT}.
3330      *
3331      * @param callback instance of the OnBufferAvailableListener
3332      *                 class to be called when buffer arrive.
3333      */
setOnBufferAvailableListener(OnBufferAvailableListener callback)3334     public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
3335         synchronized(mAllocationMap) {
3336             mAllocationMap.put(new Long(getID(mRS)), this);
3337             mBufferNotifier = callback;
3338         }
3339     }
3340 
sendBufferNotification(long id)3341     static void sendBufferNotification(long id) {
3342         synchronized(mAllocationMap) {
3343             Allocation a = mAllocationMap.get(new Long(id));
3344 
3345             if ((a != null) && (a.mBufferNotifier != null)) {
3346                 a.mBufferNotifier.onBufferAvailable(a);
3347             }
3348         }
3349     }
3350 
3351     /**
3352      * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
3353      *
3354      */
3355     @Override
destroy()3356     public void destroy() {
3357         if((mUsage & USAGE_IO_OUTPUT) != 0) {
3358             setSurface(null);
3359         }
3360 
3361         if (mType != null && mOwningType) {
3362             mType.destroy();
3363         }
3364 
3365         super.destroy();
3366     }
3367 
3368 }
3369