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