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
17package android.support.v8.renderscript;
18
19import java.nio.ByteBuffer;
20import java.util.concurrent.locks.ReentrantReadWriteLock;
21
22import android.content.res.Resources;
23import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
25import android.graphics.Canvas;
26import android.util.Log;
27import 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 **/
58public 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