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