2 * Copyright (C) 2008-2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.renderscript;
19 import java.nio.ByteBuffer;
20 import java.util.HashMap;
22 import android.content.res.Resources;
23 import android.graphics.Bitmap;
24 import android.graphics.BitmapFactory;
25 import android.graphics.Canvas;
26 import android.os.Trace;
27 import android.util.Log;
28 import android.view.Surface;
31 * <p> This class provides the primary method through which data is passed to
32 * and from RenderScript kernels. An Allocation provides the backing store for
33 * a given {@link android.renderscript.Type}. </p>
35 * <p>An Allocation also contains a set of usage flags that denote how the
36 * Allocation could be used. For example, an Allocation may have usage flags
37 * specifying that it can be used from a script as well as input to a {@link
38 * android.renderscript.Sampler}. A developer must synchronize across these
39 * different usages using {@link android.renderscript.Allocation#syncAll} in
40 * order to ensure that different users of the Allocation have a consistent view
41 * of memory. For example, in the case where an Allocation is used as the output
42 * of one kernel and as Sampler input in a later kernel, a developer must call
43 * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
44 * second kernel to ensure correctness.
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>
50 * <div class="special reference">
51 * <h3>Developer Guides</h3>
52 * <p>For more information about creating an application that uses RenderScript, read the
53 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
57 public class Allocation extends BaseObj {
58 private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16;
63 Allocation mAdaptedAllocation;
65 MipmapControl mMipmapControl;
68 boolean mReadAllowed = true;
69 boolean mWriteAllowed = true;
70 boolean mAutoPadding = false;
76 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
82 static HashMap<Long, Allocation> mAllocationMap =
83 new HashMap<Long, Allocation>();
84 OnBufferAvailableListener mBufferNotifier;
86 private Surface mGetSurfaceSurface = null;
87 private ByteBuffer mByteBuffer = null;
88 private long mByteBufferStride = -1;
90 private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
91 final Class c = d.getClass();
93 throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
95 final Class cmp = c.getComponentType();
96 if (!cmp.isPrimitive()) {
97 throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
100 if (cmp == Long.TYPE) {
103 return mType.mElement.mType;
105 return Element.DataType.SIGNED_64;
108 if (cmp == Integer.TYPE) {
111 return mType.mElement.mType;
113 return Element.DataType.SIGNED_32;
116 if (cmp == Short.TYPE) {
118 validateIsInt16OrFloat16();
119 return mType.mElement.mType;
121 return Element.DataType.SIGNED_16;
124 if (cmp == Byte.TYPE) {
127 return mType.mElement.mType;
129 return Element.DataType.SIGNED_8;
132 if (cmp == Float.TYPE) {
136 return Element.DataType.FLOAT_32;
139 if (cmp == Double.TYPE) {
143 return Element.DataType.FLOAT_64;
150 * The usage of the Allocation. These signal to RenderScript where to place
151 * the Allocation in memory.
156 * The Allocation will be bound to and accessed by scripts.
158 public static final int USAGE_SCRIPT = 0x0001;
161 * The Allocation will be used as a texture source by one or more graphics
165 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
168 * The Allocation will be used as a graphics mesh.
170 * This was deprecated in API level 16.
173 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
177 * The Allocation will be used as the source of shader constants by one or
180 * This was deprecated in API level 16.
183 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
186 * The Allocation will be used as a target for offscreen rendering
188 * This was deprecated in API level 16.
191 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
194 * The Allocation will be used as a {@link android.view.Surface}
195 * consumer. This usage will cause the Allocation to be created
199 public static final int USAGE_IO_INPUT = 0x0020;
202 * The Allocation will be used as a {@link android.view.Surface}
203 * producer. The dimensions and format of the {@link
204 * android.view.Surface} will be forced to those of the
208 public static final int USAGE_IO_OUTPUT = 0x0040;
211 * The Allocation's backing store will be inherited from another object
212 * (usually a {@link android.graphics.Bitmap}); copying to or from the
213 * original source Bitmap will cause a synchronization rather than a full
214 * copy. {@link #syncAll} may also be used to synchronize the Allocation
215 * and the source Bitmap.
217 * <p>This is set by default for allocations created with {@link
218 * #createFromBitmap} in API version 18 and higher.</p>
221 public static final int USAGE_SHARED = 0x0080;
224 * Controls mipmap behavior when using the bitmap creation and update
227 public enum MipmapControl {
229 * No mipmaps will be generated and the type generated from the incoming
230 * bitmap will not contain additional LODs.
235 * A full mipmap chain will be created in script memory. The Type of
236 * the Allocation will contain a full mipmap chain. On upload, the full
237 * chain will be transferred.
242 * The Type of the Allocation will be the same as MIPMAP_NONE. It will
243 * not contain mipmaps. On upload, the allocation data will contain a
244 * full mipmap chain generated from the top level in script memory.
246 MIPMAP_ON_SYNC_TO_TEXTURE(2);
249 MipmapControl(int id) {
255 private long getIDSafe() {
256 if (mAdaptedAllocation != null) {
257 return mAdaptedAllocation.getID(mRS);
264 * Get the {@link android.renderscript.Element} of the {@link
265 * android.renderscript.Type} of the Allocation.
270 public Element getElement() {
271 return mType.getElement();
275 * Get the usage flags of the Allocation.
277 * @return usage this Allocation's set of the USAGE_* flags OR'd together
280 public int getUsage() {
286 * Get the Mipmap control flag of the Allocation.
288 * @return the Mipmap control flag of the Allocation
291 public MipmapControl getMipmap() {
292 return mMipmapControl;
296 * Enable/Disable AutoPadding for Vec3 elements.
297 * By default: Diabled.
299 * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
302 public void setAutoPadding(boolean useAutoPadding) {
303 mAutoPadding = useAutoPadding;
307 * Get the size of the Allocation in bytes.
309 * @return size of the Allocation in bytes.
312 public int getBytesSize() {
313 if (mType.mDimYuv != 0) {
314 return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
316 return mType.getCount() * mType.getElement().getBytesSize();
319 private void updateCacheInfo(Type t) {
320 mCurrentDimX = t.getX();
321 mCurrentDimY = t.getY();
322 mCurrentDimZ = t.getZ();
323 mCurrentCount = mCurrentDimX;
324 if (mCurrentDimY > 1) {
325 mCurrentCount *= mCurrentDimY;
327 if (mCurrentDimZ > 1) {
328 mCurrentCount *= mCurrentDimZ;
332 private void setBitmap(Bitmap b) {
336 Allocation(long id, RenderScript rs, Type t, int usage) {
338 if ((usage & ~(USAGE_SCRIPT |
339 USAGE_GRAPHICS_TEXTURE |
340 USAGE_GRAPHICS_VERTEX |
341 USAGE_GRAPHICS_CONSTANTS |
342 USAGE_GRAPHICS_RENDER_TARGET |
345 USAGE_SHARED)) != 0) {
346 throw new RSIllegalArgumentException("Unknown usage specified.");
349 if ((usage & USAGE_IO_INPUT) != 0) {
350 mWriteAllowed = false;
352 if ((usage & ~(USAGE_IO_INPUT |
353 USAGE_GRAPHICS_TEXTURE |
354 USAGE_SCRIPT)) != 0) {
355 throw new RSIllegalArgumentException("Invalid usage combination.");
363 // TODO: A3D doesn't have Type info during creation, so we can't
364 // calculate the size ahead of time. We can possibly add a method
365 // to update the size in the future if it seems reasonable.
366 mSize = mType.getCount() * mType.getElement().getBytesSize();
370 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
371 } catch (Exception e) {
372 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
373 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
377 Allocation(long id, RenderScript rs, Type t, int usage, MipmapControl mips) {
378 this(id, rs, t, usage);
379 mMipmapControl = mips;
382 protected void finalize() throws Throwable {
383 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
387 private void validateIsInt64() {
388 if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
389 (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
392 throw new RSIllegalArgumentException(
393 "64 bit integer source does not match allocation type " + mType.mElement.mType);
396 private void validateIsInt32() {
397 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
398 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
401 throw new RSIllegalArgumentException(
402 "32 bit integer source does not match allocation type " + mType.mElement.mType);
405 private void validateIsInt16OrFloat16() {
406 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
407 (mType.mElement.mType == Element.DataType.UNSIGNED_16) ||
408 (mType.mElement.mType == Element.DataType.FLOAT_16)) {
411 throw new RSIllegalArgumentException(
412 "16 bit integer source does not match allocation type " + mType.mElement.mType);
415 private void validateIsInt8() {
416 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
417 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
420 throw new RSIllegalArgumentException(
421 "8 bit integer source does not match allocation type " + mType.mElement.mType);
424 private void validateIsFloat32() {
425 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
428 throw new RSIllegalArgumentException(
429 "32 bit float source does not match allocation type " + mType.mElement.mType);
432 private void validateIsFloat64() {
433 if (mType.mElement.mType == Element.DataType.FLOAT_64) {
436 throw new RSIllegalArgumentException(
437 "64 bit float source does not match allocation type " + mType.mElement.mType);
440 private void validateIsObject() {
441 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
442 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
443 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
444 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
445 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
446 (mType.mElement.mType == Element.DataType.RS_MESH) ||
447 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
448 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
449 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
450 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
453 throw new RSIllegalArgumentException(
454 "Object source does not match allocation type " + mType.mElement.mType);
458 void updateFromNative() {
459 super.updateFromNative();
460 long typeID = mRS.nAllocationGetType(getID(mRS));
462 mType = new Type(typeID, mRS);
463 mType.updateFromNative();
464 updateCacheInfo(mType);
469 * Get the {@link android.renderscript.Type} of the Allocation.
474 public Type getType() {
479 * Propagate changes from one usage of the Allocation to the
480 * other usages of the Allocation.
483 public void syncAll(int srcLocation) {
485 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
486 switch (srcLocation) {
487 case USAGE_GRAPHICS_TEXTURE:
489 if ((mUsage & USAGE_SHARED) != 0) {
493 case USAGE_GRAPHICS_CONSTANTS:
494 case USAGE_GRAPHICS_VERTEX:
497 if ((mUsage & USAGE_SHARED) != 0) {
502 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
505 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
507 Trace.traceEnd(RenderScript.TRACE_TAG);
512 * Send a buffer to the output stream. The contents of the Allocation will
513 * be undefined after this operation. This operation is only valid if {@link
514 * #USAGE_IO_OUTPUT} is set on the Allocation.
518 public void ioSend() {
520 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
521 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
522 throw new RSIllegalArgumentException(
523 "Can only send buffer if IO_OUTPUT usage specified.");
526 mRS.nAllocationIoSend(getID(mRS));
528 Trace.traceEnd(RenderScript.TRACE_TAG);
533 * Receive the latest input into the Allocation. This operation
534 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
537 public void ioReceive() {
539 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
540 if ((mUsage & USAGE_IO_INPUT) == 0) {
541 throw new RSIllegalArgumentException(
542 "Can only receive if IO_INPUT usage specified.");
545 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS));
547 Trace.traceEnd(RenderScript.TRACE_TAG);
552 * Copy an array of RS objects to the Allocation.
554 * @param d Source array.
556 public void copyFrom(BaseObj[] d) {
558 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
561 if (d.length != mCurrentCount) {
562 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
563 mCurrentCount + ", array length = " + d.length);
566 if (RenderScript.sPointerSize == 8) {
567 long i[] = new long[d.length * 4];
568 for (int ct=0; ct < d.length; ct++) {
569 i[ct * 4] = d[ct].getID(mRS);
571 copy1DRangeFromUnchecked(0, mCurrentCount, i);
573 int i[] = new int[d.length];
574 for (int ct=0; ct < d.length; ct++) {
575 i[ct] = (int) d[ct].getID(mRS);
577 copy1DRangeFromUnchecked(0, mCurrentCount, i);
580 Trace.traceEnd(RenderScript.TRACE_TAG);
584 private void validateBitmapFormat(Bitmap b) {
585 Bitmap.Config bc = b.getConfig();
587 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
591 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
592 throw new RSIllegalArgumentException("Allocation kind is " +
593 mType.getElement().mKind + ", type " +
594 mType.getElement().mType +
595 " of " + mType.getElement().getBytesSize() +
596 " bytes, passed bitmap was " + bc);
600 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
601 (mType.getElement().getBytesSize() != 4)) {
602 throw new RSIllegalArgumentException("Allocation kind is " +
603 mType.getElement().mKind + ", type " +
604 mType.getElement().mType +
605 " of " + mType.getElement().getBytesSize() +
606 " bytes, passed bitmap was " + bc);
610 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
611 (mType.getElement().getBytesSize() != 2)) {
612 throw new RSIllegalArgumentException("Allocation kind is " +
613 mType.getElement().mKind + ", type " +
614 mType.getElement().mType +
615 " of " + mType.getElement().getBytesSize() +
616 " bytes, passed bitmap was " + bc);
620 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
621 (mType.getElement().getBytesSize() != 2)) {
622 throw new RSIllegalArgumentException("Allocation kind is " +
623 mType.getElement().mKind + ", type " +
624 mType.getElement().mType +
625 " of " + mType.getElement().getBytesSize() +
626 " bytes, passed bitmap was " + bc);
633 private void validateBitmapSize(Bitmap b) {
634 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
635 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
639 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
641 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
643 if (mCurrentDimZ > 0) {
644 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
645 } else if (mCurrentDimY > 0) {
646 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
648 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
651 Trace.traceEnd(RenderScript.TRACE_TAG);
656 * Copy into this Allocation from an array. This method does not guarantee
657 * that the Allocation is compatible with the input buffer; it copies memory
658 * without reinterpretation.
660 * @param array The source data array
662 public void copyFromUnchecked(Object array) {
664 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
665 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
666 java.lang.reflect.Array.getLength(array));
668 Trace.traceEnd(RenderScript.TRACE_TAG);
673 * Copy into this Allocation from an array. This method does not guarantee
674 * that the Allocation is compatible with the input buffer; it copies memory
675 * without reinterpretation.
677 * @param d the source data array
679 public void copyFromUnchecked(int[] d) {
680 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
684 * Copy into this Allocation from an array. This method does not guarantee
685 * that the Allocation is compatible with the input buffer; it copies memory
686 * without reinterpretation.
688 * @param d the source data array
690 public void copyFromUnchecked(short[] d) {
691 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
695 * Copy into this Allocation from an array. This method does not guarantee
696 * that the Allocation is compatible with the input buffer; it copies memory
697 * without reinterpretation.
699 * @param d the source data array
701 public void copyFromUnchecked(byte[] d) {
702 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
706 * Copy into this Allocation from an array. This method does not guarantee
707 * that the Allocation is compatible with the input buffer; it copies memory
708 * without reinterpretation.
710 * @param d the source data array
712 public void copyFromUnchecked(float[] d) {
713 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
718 * Copy into this Allocation from an array. This variant is type checked
719 * and will generate exceptions if the Allocation's {@link
720 * android.renderscript.Element} does not match the array's
723 * @param array The source data array
725 public void copyFrom(Object array) {
727 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
728 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
729 java.lang.reflect.Array.getLength(array));
731 Trace.traceEnd(RenderScript.TRACE_TAG);
736 * Copy into this Allocation from an array. This variant is type checked
737 * and will generate exceptions if the Allocation's {@link
738 * android.renderscript.Element} is not a 32 bit integer type.
740 * @param d the source data array
742 public void copyFrom(int[] d) {
744 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
748 * Copy into this Allocation from an array. This variant is type checked
749 * and will generate exceptions if the Allocation's {@link
750 * android.renderscript.Element} is not a 16 bit integer type.
752 * @param d the source data array
754 public void copyFrom(short[] d) {
755 validateIsInt16OrFloat16();
756 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
760 * Copy into this Allocation from an array. This variant is type checked
761 * and will generate exceptions if the Allocation's {@link
762 * android.renderscript.Element} is not an 8 bit integer type.
764 * @param d the source data array
766 public void copyFrom(byte[] d) {
768 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
772 * Copy into this Allocation from an array. This variant is type checked
773 * and will generate exceptions if the Allocation's {@link
774 * android.renderscript.Element} is not a 32 bit float type.
776 * @param d the source data array
778 public void copyFrom(float[] d) {
780 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
784 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
785 * height, width, and format of the bitmap must match the existing
788 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
789 * android.graphics.Bitmap} used to create the Allocation with {@link
790 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
791 * this will synchronize the Allocation with the latest data from the {@link
792 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
794 * @param b the source bitmap
796 public void copyFrom(Bitmap b) {
798 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
800 if (b.getConfig() == null) {
801 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
802 Canvas c = new Canvas(newBitmap);
803 c.drawBitmap(b, 0, 0, null);
807 validateBitmapSize(b);
808 validateBitmapFormat(b);
809 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
811 Trace.traceEnd(RenderScript.TRACE_TAG);
816 * Copy an Allocation from an Allocation. The types of both allocations
819 * @param a the source allocation
821 public void copyFrom(Allocation a) {
823 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
825 if (!mType.equals(a.getType())) {
826 throw new RSIllegalArgumentException("Types of allocations must match.");
828 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
830 Trace.traceEnd(RenderScript.TRACE_TAG);
835 * This is only intended to be used by auto-generated code reflected from
836 * the RenderScript script files and should not be used by developers.
841 public void setFromFieldPacker(int xoff, FieldPacker fp) {
843 int eSize = mType.mElement.getBytesSize();
844 final byte[] data = fp.getData();
845 int data_length = fp.getPos();
847 int count = data_length / eSize;
848 if ((eSize * count) != data_length) {
849 throw new RSIllegalArgumentException("Field packer length " + data_length +
850 " not divisible by element size " + eSize + ".");
852 copy1DRangeFromUnchecked(xoff, count, data);
857 * This is only intended to be used by auto-generated code reflected from
858 * the RenderScript script files and should not be used by developers.
861 * @param component_number
864 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
865 setFromFieldPacker(xoff, 0, 0, component_number, fp);
869 * This is only intended to be used by auto-generated code reflected from
870 * the RenderScript script files and should not be used by developers.
875 * @param component_number
878 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
880 if (component_number >= mType.mElement.mElements.length) {
881 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
884 throw new RSIllegalArgumentException("Offset x must be >= 0.");
887 throw new RSIllegalArgumentException("Offset y must be >= 0.");
890 throw new RSIllegalArgumentException("Offset z must be >= 0.");
893 final byte[] data = fp.getData();
894 int data_length = fp.getPos();
895 int eSize = mType.mElement.mElements[component_number].getBytesSize();
896 eSize *= mType.mElement.mArraySizes[component_number];
898 if (data_length != eSize) {
899 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
900 " does not match component size " + eSize + ".");
903 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
904 component_number, data, data_length);
907 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
910 throw new RSIllegalArgumentException("Offset must be >= 0.");
913 throw new RSIllegalArgumentException("Count must be >= 1.");
915 if((off + count) > mCurrentCount) {
916 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
917 ", got " + count + " at offset " + off + ".");
920 if(len < dataSize / 4 * 3) {
921 throw new RSIllegalArgumentException("Array too small for allocation type.");
925 throw new RSIllegalArgumentException("Array too small for allocation type.");
931 * Generate a mipmap chain. This is only valid if the Type of the Allocation
934 * <p>This function will generate a complete set of mipmaps from the top
935 * level LOD and place them into the script memory space.</p>
937 * <p>If the Allocation is also using other memory spaces, a call to {@link
938 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
940 public void generateMipmaps() {
941 mRS.nAllocationGenerateMipmaps(getID(mRS));
944 private void copy1DRangeFromUnchecked(int off, int count, Object array,
945 Element.DataType dt, int arrayLen) {
947 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
948 final int dataSize = mType.mElement.getBytesSize() * count;
949 // AutoPadding for Vec3 Element
950 boolean usePadding = false;
951 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
954 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
955 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
956 mType.mElement.mType.mSize, usePadding);
958 Trace.traceEnd(RenderScript.TRACE_TAG);
963 * Copy an array into part of this Allocation. This method does not
964 * guarantee that the Allocation is compatible with the input buffer.
966 * @param off The offset of the first element to be copied.
967 * @param count The number of elements to be copied.
968 * @param array The source data array
970 public void copy1DRangeFromUnchecked(int off, int count, Object array) {
971 copy1DRangeFromUnchecked(off, count, array,
972 validateObjectIsPrimitiveArray(array, false),
973 java.lang.reflect.Array.getLength(array));
977 * Copy an array into part of this Allocation. This method does not
978 * guarantee that the Allocation is compatible with the input buffer.
980 * @param off The offset of the first element to be copied.
981 * @param count The number of elements to be copied.
982 * @param d the source data array
984 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
985 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
989 * Copy an array into part of this Allocation. This method does not
990 * guarantee that the Allocation is compatible with the input buffer.
992 * @param off The offset of the first element to be copied.
993 * @param count The number of elements to be copied.
994 * @param d the source data array
996 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
997 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1001 * Copy an array into part of this Allocation. This method does not
1002 * guarantee that the Allocation is compatible with the input buffer.
1004 * @param off The offset of the first element to be copied.
1005 * @param count The number of elements to be copied.
1006 * @param d the source data array
1008 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
1009 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1013 * Copy an array into part of this Allocation. This method does not
1014 * guarantee that the Allocation is compatible with the input buffer.
1016 * @param off The offset of the first element to be copied.
1017 * @param count The number of elements to be copied.
1018 * @param d the source data array
1020 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
1021 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1026 * Copy an array into part of this Allocation. This variant is type checked
1027 * and will generate exceptions if the Allocation type does not
1028 * match the component type of the array passed in.
1030 * @param off The offset of the first element to be copied.
1031 * @param count The number of elements to be copied.
1032 * @param array The source data array.
1034 public void copy1DRangeFrom(int off, int count, Object array) {
1035 copy1DRangeFromUnchecked(off, count, array,
1036 validateObjectIsPrimitiveArray(array, true),
1037 java.lang.reflect.Array.getLength(array));
1041 * Copy an array into part of this Allocation. This variant is type checked
1042 * and will generate exceptions if the Allocation type is not a 32 bit
1045 * @param off The offset of the first element to be copied.
1046 * @param count The number of elements to be copied.
1047 * @param d the source data array
1049 public void copy1DRangeFrom(int off, int count, int[] d) {
1051 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1055 * Copy an array into part of this Allocation. This variant is type checked
1056 * and will generate exceptions if the Allocation type is not a 16 bit
1059 * @param off The offset of the first element to be copied.
1060 * @param count The number of elements to be copied.
1061 * @param d the source data array
1063 public void copy1DRangeFrom(int off, int count, short[] d) {
1064 validateIsInt16OrFloat16();
1065 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1069 * Copy an array into part of this Allocation. This variant is type checked
1070 * and will generate exceptions if the Allocation type is not an 8 bit
1073 * @param off The offset of the first element to be copied.
1074 * @param count The number of elements to be copied.
1075 * @param d the source data array
1077 public void copy1DRangeFrom(int off, int count, byte[] d) {
1079 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1083 * Copy an array into part of this Allocation. This variant is type checked
1084 * and will generate exceptions if the Allocation type is not a 32 bit float
1087 * @param off The offset of the first element to be copied.
1088 * @param count The number of elements to be copied.
1089 * @param d the source data array.
1091 public void copy1DRangeFrom(int off, int count, float[] d) {
1092 validateIsFloat32();
1093 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1097 * Copy part of an Allocation into this Allocation.
1099 * @param off The offset of the first element to be copied.
1100 * @param count The number of elements to be copied.
1101 * @param data the source data allocation.
1102 * @param dataOff off The offset of the first element in data to
1105 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
1106 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
1107 mRS.nAllocationData2D(getIDSafe(), off, 0,
1108 mSelectedLOD, mSelectedFace.mID,
1109 count, 1, data.getID(mRS), dataOff, 0,
1110 data.mSelectedLOD, data.mSelectedFace.mID);
1111 Trace.traceEnd(RenderScript.TRACE_TAG);
1114 private void validate2DRange(int xoff, int yoff, int w, int h) {
1115 if (mAdaptedAllocation != null) {
1119 if (xoff < 0 || yoff < 0) {
1120 throw new RSIllegalArgumentException("Offset cannot be negative.");
1122 if (h < 0 || w < 0) {
1123 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1125 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
1126 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1131 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
1132 Element.DataType dt, int arrayLen) {
1134 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
1136 validate2DRange(xoff, yoff, w, h);
1137 final int dataSize = mType.mElement.getBytesSize() * w * h;
1138 // AutoPadding for Vec3 Element
1139 boolean usePadding = false;
1140 int sizeBytes = arrayLen * dt.mSize;
1141 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1142 if (dataSize / 4 * 3 > sizeBytes) {
1143 throw new RSIllegalArgumentException("Array too small for allocation type.");
1146 sizeBytes = dataSize;
1148 if (dataSize > sizeBytes) {
1149 throw new RSIllegalArgumentException("Array too small for allocation type.");
1152 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1153 array, sizeBytes, dt,
1154 mType.mElement.mType.mSize, usePadding);
1156 Trace.traceEnd(RenderScript.TRACE_TAG);
1161 * Copy from an array into a rectangular region in this Allocation. The
1162 * array is assumed to be tightly packed.
1164 * @param xoff X offset of the region to update in this Allocation
1165 * @param yoff Y offset of the region to update in this Allocation
1166 * @param w Width of the region to update
1167 * @param h Height of the region to update
1168 * @param array Data to be placed into the Allocation
1170 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
1172 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1173 copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
1174 validateObjectIsPrimitiveArray(array, true),
1175 java.lang.reflect.Array.getLength(array));
1177 Trace.traceEnd(RenderScript.TRACE_TAG);
1182 * Copy from an array into a rectangular region in this Allocation. The
1183 * array is assumed to be tightly packed.
1185 * @param xoff X offset of the region to update in this Allocation
1186 * @param yoff Y offset of the region to update in this Allocation
1187 * @param w Width of the region to update
1188 * @param h Height of the region to update
1189 * @param data to be placed into the Allocation
1191 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
1193 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1194 Element.DataType.SIGNED_8, data.length);
1198 * Copy from an array into a rectangular region in this Allocation. The
1199 * array is assumed to be tightly packed.
1201 * @param xoff X offset of the region to update in this Allocation
1202 * @param yoff Y offset of the region to update in this Allocation
1203 * @param w Width of the region to update
1204 * @param h Height of the region to update
1205 * @param data to be placed into the Allocation
1207 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
1208 validateIsInt16OrFloat16();
1209 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1210 Element.DataType.SIGNED_16, data.length);
1214 * Copy from an array into a rectangular region in this Allocation. The
1215 * array is assumed to be tightly packed.
1217 * @param xoff X offset of the region to update in this Allocation
1218 * @param yoff Y offset of the region to update in this Allocation
1219 * @param w Width of the region to update
1220 * @param h Height of the region to update
1221 * @param data to be placed into the Allocation
1223 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
1225 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1226 Element.DataType.SIGNED_32, data.length);
1230 * Copy from an array into a rectangular region in this Allocation. The
1231 * array is assumed to be tightly packed.
1233 * @param xoff X offset of the region to update in this Allocation
1234 * @param yoff Y offset of the region to update in this Allocation
1235 * @param w Width of the region to update
1236 * @param h Height of the region to update
1237 * @param data to be placed into the Allocation
1239 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
1240 validateIsFloat32();
1241 copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
1242 Element.DataType.FLOAT_32, data.length);
1246 * Copy a rectangular region from an Allocation into a rectangular region in
1249 * @param xoff X offset of the region in this Allocation
1250 * @param yoff Y offset of the region in this Allocation
1251 * @param w Width of the region to update.
1252 * @param h Height of the region to update.
1253 * @param data source Allocation.
1254 * @param dataXoff X offset in source Allocation
1255 * @param dataYoff Y offset in source Allocation
1257 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
1258 Allocation data, int dataXoff, int dataYoff) {
1260 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1262 validate2DRange(xoff, yoff, w, h);
1263 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
1264 mSelectedLOD, mSelectedFace.mID,
1265 w, h, data.getID(mRS), dataXoff, dataYoff,
1266 data.mSelectedLOD, data.mSelectedFace.mID);
1268 Trace.traceEnd(RenderScript.TRACE_TAG);
1273 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
1274 * and width of the update will use the height and width of the {@link
1275 * android.graphics.Bitmap}.
1277 * @param xoff X offset of the region to update in this Allocation
1278 * @param yoff Y offset of the region to update in this Allocation
1279 * @param data the Bitmap to be copied
1281 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
1283 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
1285 if (data.getConfig() == null) {
1286 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
1287 Canvas c = new Canvas(newBitmap);
1288 c.drawBitmap(data, 0, 0, null);
1289 copy2DRangeFrom(xoff, yoff, newBitmap);
1292 validateBitmapFormat(data);
1293 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
1294 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
1296 Trace.traceEnd(RenderScript.TRACE_TAG);
1300 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
1301 if (mAdaptedAllocation != null) {
1305 if (xoff < 0 || yoff < 0 || zoff < 0) {
1306 throw new RSIllegalArgumentException("Offset cannot be negative.");
1308 if (h < 0 || w < 0 || d < 0) {
1309 throw new RSIllegalArgumentException("Height or width cannot be negative.");
1311 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
1312 throw new RSIllegalArgumentException("Updated region larger than allocation.");
1318 * Copy a rectangular region from the array into the allocation.
1319 * The array is assumed to be tightly packed.
1321 * The data type of the array is not required to be the same as
1322 * the element data type.
1324 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1325 Object array, Element.DataType dt, int arrayLen) {
1327 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked");
1329 validate3DRange(xoff, yoff, zoff, w, h, d);
1330 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1331 // AutoPadding for Vec3 Element
1332 boolean usePadding = false;
1333 int sizeBytes = arrayLen * dt.mSize;
1334 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1335 if (dataSize / 4 * 3 > sizeBytes) {
1336 throw new RSIllegalArgumentException("Array too small for allocation type.");
1339 sizeBytes = dataSize;
1341 if (dataSize > sizeBytes) {
1342 throw new RSIllegalArgumentException("Array too small for allocation type.");
1345 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1346 array, sizeBytes, dt,
1347 mType.mElement.mType.mSize, usePadding);
1349 Trace.traceEnd(RenderScript.TRACE_TAG);
1354 * Copy a rectangular region from the array into the allocation.
1355 * The array is assumed to be tightly packed.
1357 * @param xoff X offset of the region to update in this Allocation
1358 * @param yoff Y offset of the region to update in this Allocation
1359 * @param zoff Z offset of the region to update in this Allocation
1360 * @param w Width of the region to update
1361 * @param h Height of the region to update
1362 * @param d Depth of the region to update
1363 * @param array to be placed into the allocation
1365 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1367 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom");
1368 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
1369 validateObjectIsPrimitiveArray(array, true),
1370 java.lang.reflect.Array.getLength(array));
1372 Trace.traceEnd(RenderScript.TRACE_TAG);
1377 * Copy a rectangular region into the allocation from another
1380 * @param xoff X offset of the region to update in this Allocation
1381 * @param yoff Y offset of the region to update in this Allocation
1382 * @param zoff Z offset of the region to update in this Allocation
1383 * @param w Width of the region to update.
1384 * @param h Height of the region to update.
1385 * @param d Depth of the region to update.
1386 * @param data source allocation.
1387 * @param dataXoff X offset of the region in the source Allocation
1388 * @param dataYoff Y offset of the region in the source Allocation
1389 * @param dataZoff Z offset of the region in the source Allocation
1391 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
1392 Allocation data, int dataXoff, int dataYoff, int dataZoff) {
1394 validate3DRange(xoff, yoff, zoff, w, h, d);
1395 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1396 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
1402 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
1403 * bitmap must match the dimensions of the Allocation.
1405 * @param b The bitmap to be set from the Allocation.
1407 public void copyTo(Bitmap b) {
1409 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1411 validateBitmapFormat(b);
1412 validateBitmapSize(b);
1413 mRS.nAllocationCopyToBitmap(getID(mRS), b);
1415 Trace.traceEnd(RenderScript.TRACE_TAG);
1419 private void copyTo(Object array, Element.DataType dt, int arrayLen) {
1421 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
1423 boolean usePadding = false;
1424 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1428 if (dt.mSize * arrayLen < mSize / 4 * 3) {
1429 throw new RSIllegalArgumentException(
1430 "Size of output array cannot be smaller than size of allocation.");
1433 if (dt.mSize * arrayLen < mSize) {
1434 throw new RSIllegalArgumentException(
1435 "Size of output array cannot be smaller than size of allocation.");
1438 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
1440 Trace.traceEnd(RenderScript.TRACE_TAG);
1445 * Copy from the Allocation into an array. The array must be at
1446 * least as large as the Allocation. The
1447 * {@link android.renderscript.Element} must match the component
1448 * type of the array passed in.
1450 * @param array The array to be set from the Allocation.
1452 public void copyTo(Object array) {
1453 copyTo(array, validateObjectIsPrimitiveArray(array, true),
1454 java.lang.reflect.Array.getLength(array));
1458 * Copy from the Allocation into a byte array. The array must be at least
1459 * as large as the Allocation. The allocation must be of an 8 bit integer
1460 * {@link android.renderscript.Element} type.
1462 * @param d The array to be set from the Allocation.
1464 public void copyTo(byte[] d) {
1466 copyTo(d, Element.DataType.SIGNED_8, d.length);
1470 * Copy from the Allocation into a short array. The array must be at least
1471 * as large as the Allocation. The allocation must be of an 16 bit integer
1472 * {@link android.renderscript.Element} type.
1474 * @param d The array to be set from the Allocation.
1476 public void copyTo(short[] d) {
1477 validateIsInt16OrFloat16();
1478 copyTo(d, Element.DataType.SIGNED_16, d.length);
1482 * Copy from the Allocation into a int array. The array must be at least as
1483 * large as the Allocation. The allocation must be of an 32 bit integer
1484 * {@link android.renderscript.Element} type.
1486 * @param d The array to be set from the Allocation.
1488 public void copyTo(int[] d) {
1490 copyTo(d, Element.DataType.SIGNED_32, d.length);
1494 * Copy from the Allocation into a float array. The array must be at least
1495 * as large as the Allocation. The allocation must be of an 32 bit float
1496 * {@link android.renderscript.Element} type.
1498 * @param d The array to be set from the Allocation.
1500 public void copyTo(float[] d) {
1501 validateIsFloat32();
1502 copyTo(d, Element.DataType.FLOAT_32, d.length);
1508 * This is only intended to be used by auto-generated code reflected from
1509 * the RenderScript script files and should not be used by developers.
1514 * @param component_number
1517 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
1519 if (component_number >= mType.mElement.mElements.length) {
1520 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
1523 throw new RSIllegalArgumentException("Offset x must be >= 0.");
1526 throw new RSIllegalArgumentException("Offset y must be >= 0.");
1529 throw new RSIllegalArgumentException("Offset z must be >= 0.");
1532 final byte[] data = fp.getData();
1533 int data_length = data.length;
1534 int eSize = mType.mElement.mElements[component_number].getBytesSize();
1535 eSize *= mType.mElement.mArraySizes[component_number];
1537 if (data_length != eSize) {
1538 throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
1539 " does not match component size " + eSize + ".");
1542 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
1543 component_number, data, data_length);
1546 * Resize a 1D allocation. The contents of the allocation are preserved.
1547 * If new elements are allocated objects are created with null contents and
1548 * the new region is otherwise undefined.
1550 * <p>If the new region is smaller the references of any objects outside the
1551 * new region will be released.</p>
1553 * <p>A new type will be created with the new dimension.</p>
1555 * @param dimX The new size of the allocation.
1557 * @deprecated RenderScript objects should be immutable once created. The
1558 * replacement is to create a new allocation and copy the contents. This
1559 * function will throw an exception if API 21 or higher is used.
1561 public synchronized void resize(int dimX) {
1562 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) {
1563 throw new RSRuntimeException("Resize is not allowed in API 21+.");
1565 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
1566 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
1568 mRS.nAllocationResize1D(getID(mRS), dimX);
1569 mRS.finish(); // Necessary because resize is fifoed and update is async.
1571 long typeID = mRS.nAllocationGetType(getID(mRS));
1572 mType = new Type(typeID, mRS);
1573 mType.updateFromNative();
1574 updateCacheInfo(mType);
1577 private void copy1DRangeToUnchecked(int off, int count, Object array,
1578 Element.DataType dt, int arrayLen) {
1580 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked");
1581 final int dataSize = mType.mElement.getBytesSize() * count;
1582 // AutoPadding for Vec3 Element
1583 boolean usePadding = false;
1584 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1587 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
1588 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
1589 mType.mElement.mType.mSize, usePadding);
1591 Trace.traceEnd(RenderScript.TRACE_TAG);
1596 * Copy part of this Allocation into an array. This method does not
1597 * guarantee that the Allocation is compatible with the input buffer.
1599 * @param off The offset of the first element to be copied.
1600 * @param count The number of elements to be copied.
1601 * @param array The dest data array
1603 public void copy1DRangeToUnchecked(int off, int count, Object array) {
1604 copy1DRangeToUnchecked(off, count, array,
1605 validateObjectIsPrimitiveArray(array, false),
1606 java.lang.reflect.Array.getLength(array));
1610 * Copy part of this Allocation into an array. This method does not
1611 * guarantee that the Allocation is compatible with the input buffer.
1613 * @param off The offset of the first element to be copied.
1614 * @param count The number of elements to be copied.
1615 * @param d the source data array
1617 public void copy1DRangeToUnchecked(int off, int count, int[] d) {
1618 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
1622 * Copy part of this Allocation into an array. This method does not
1623 * guarantee that the Allocation is compatible with the input buffer.
1625 * @param off The offset of the first element to be copied.
1626 * @param count The number of elements to be copied.
1627 * @param d the source data array
1629 public void copy1DRangeToUnchecked(int off, int count, short[] d) {
1630 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
1634 * Copy part of this Allocation into an array. This method does not
1635 * guarantee that the Allocation is compatible with the input buffer.
1637 * @param off The offset of the first element to be copied.
1638 * @param count The number of elements to be copied.
1639 * @param d the source data array
1641 public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
1642 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
1646 * Copy part of this Allocation into an array. This method does not
1647 * guarantee that the Allocation is compatible with the input buffer.
1649 * @param off The offset of the first element to be copied.
1650 * @param count The number of elements to be copied.
1651 * @param d the source data array
1653 public void copy1DRangeToUnchecked(int off, int count, float[] d) {
1654 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
1659 * Copy part of this Allocation into an array. This method does not
1660 * and will generate exceptions if the Allocation type does not
1661 * match the component type of the array passed in.
1663 * @param off The offset of the first element to be copied.
1664 * @param count The number of elements to be copied.
1665 * @param array The source data array.
1667 public void copy1DRangeTo(int off, int count, Object array) {
1668 copy1DRangeToUnchecked(off, count, array,
1669 validateObjectIsPrimitiveArray(array, true),
1670 java.lang.reflect.Array.getLength(array));
1674 * Copy part of this Allocation into an array. This method does not
1675 * and will generate exceptions if the Allocation type is not a 32 bit
1678 * @param off The offset of the first element to be copied.
1679 * @param count The number of elements to be copied.
1680 * @param d the source data array
1682 public void copy1DRangeTo(int off, int count, int[] d) {
1684 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
1688 * Copy part of this Allocation into an array. This method does not
1689 * and will generate exceptions if the Allocation type is not a 16 bit
1692 * @param off The offset of the first element to be copied.
1693 * @param count The number of elements to be copied.
1694 * @param d the source data array
1696 public void copy1DRangeTo(int off, int count, short[] d) {
1697 validateIsInt16OrFloat16();
1698 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
1702 * Copy part of this Allocation into an array. This method does not
1703 * and will generate exceptions if the Allocation type is not an 8 bit
1706 * @param off The offset of the first element to be copied.
1707 * @param count The number of elements to be copied.
1708 * @param d the source data array
1710 public void copy1DRangeTo(int off, int count, byte[] d) {
1712 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
1716 * Copy part of this Allocation into an array. This method does not
1717 * and will generate exceptions if the Allocation type is not a 32 bit float
1720 * @param off The offset of the first element to be copied.
1721 * @param count The number of elements to be copied.
1722 * @param d the source data array.
1724 public void copy1DRangeTo(int off, int count, float[] d) {
1725 validateIsFloat32();
1726 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
1730 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
1731 Element.DataType dt, int arrayLen) {
1733 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked");
1735 validate2DRange(xoff, yoff, w, h);
1736 final int dataSize = mType.mElement.getBytesSize() * w * h;
1737 // AutoPadding for Vec3 Element
1738 boolean usePadding = false;
1739 int sizeBytes = arrayLen * dt.mSize;
1740 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1741 if (dataSize / 4 * 3 > sizeBytes) {
1742 throw new RSIllegalArgumentException("Array too small for allocation type.");
1745 sizeBytes = dataSize;
1747 if (dataSize > sizeBytes) {
1748 throw new RSIllegalArgumentException("Array too small for allocation type.");
1751 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
1752 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1754 Trace.traceEnd(RenderScript.TRACE_TAG);
1759 * Copy from a rectangular region in this Allocation into an array.
1761 * @param xoff X offset of the region to copy in this Allocation
1762 * @param yoff Y offset of the region to copy in this Allocation
1763 * @param w Width of the region to copy
1764 * @param h Height of the region to copy
1765 * @param array Dest Array to be copied into
1767 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
1768 copy2DRangeToUnchecked(xoff, yoff, w, h, array,
1769 validateObjectIsPrimitiveArray(array, true),
1770 java.lang.reflect.Array.getLength(array));
1774 * Copy from a rectangular region in this Allocation into an array.
1776 * @param xoff X offset of the region to copy in this Allocation
1777 * @param yoff Y offset of the region to copy in this Allocation
1778 * @param w Width of the region to copy
1779 * @param h Height of the region to copy
1780 * @param data Dest Array to be copied into
1782 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
1784 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1785 Element.DataType.SIGNED_8, data.length);
1789 * Copy from a rectangular region in this Allocation into an array.
1791 * @param xoff X offset of the region to copy in this Allocation
1792 * @param yoff Y offset of the region to copy in this Allocation
1793 * @param w Width of the region to copy
1794 * @param h Height of the region to copy
1795 * @param data Dest Array to be copied into
1797 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
1798 validateIsInt16OrFloat16();
1799 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1800 Element.DataType.SIGNED_16, data.length);
1804 * Copy from a rectangular region in this Allocation into an array.
1806 * @param xoff X offset of the region to copy in this Allocation
1807 * @param yoff Y offset of the region to copy in this Allocation
1808 * @param w Width of the region to copy
1809 * @param h Height of the region to copy
1810 * @param data Dest Array to be copied into
1812 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
1814 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1815 Element.DataType.SIGNED_32, data.length);
1819 * Copy from a rectangular region in this Allocation into an array.
1821 * @param xoff X offset of the region to copy in this Allocation
1822 * @param yoff Y offset of the region to copy in this Allocation
1823 * @param w Width of the region to copy
1824 * @param h Height of the region to copy
1825 * @param data Dest Array to be copied into
1827 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
1828 validateIsFloat32();
1829 copy2DRangeToUnchecked(xoff, yoff, w, h, data,
1830 Element.DataType.FLOAT_32, data.length);
1835 * Copy from a rectangular region in this Allocation into an array.
1836 * The array is assumed to be tightly packed.
1838 * The data type of the array is not required to be the same as
1839 * the element data type.
1841 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
1842 Object array, Element.DataType dt, int arrayLen) {
1844 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked");
1846 validate3DRange(xoff, yoff, zoff, w, h, d);
1847 final int dataSize = mType.mElement.getBytesSize() * w * h * d;
1848 // AutoPadding for Vec3 Element
1849 boolean usePadding = false;
1850 int sizeBytes = arrayLen * dt.mSize;
1851 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
1852 if (dataSize / 4 * 3 > sizeBytes) {
1853 throw new RSIllegalArgumentException("Array too small for allocation type.");
1856 sizeBytes = dataSize;
1858 if (dataSize > sizeBytes) {
1859 throw new RSIllegalArgumentException("Array too small for allocation type.");
1862 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
1863 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
1865 Trace.traceEnd(RenderScript.TRACE_TAG);
1870 * Copy from a rectangular region in this Allocation into an array.
1872 * @param xoff X offset of the region to copy in this Allocation
1873 * @param yoff Y offset of the region to copy in this Allocation
1874 * @param zoff Z offset of the region to copy in this Allocation
1875 * @param w Width of the region to copy
1876 * @param h Height of the region to copy
1877 * @param d Depth of the region to copy
1878 * @param array Dest Array to be copied into
1880 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
1881 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
1882 validateObjectIsPrimitiveArray(array, true),
1883 java.lang.reflect.Array.getLength(array));
1888 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
1890 mBitmapOptions.inScaled = false;
1894 * Creates a new Allocation with the given {@link
1895 * android.renderscript.Type}, mipmap flag, and usage flags.
1897 * @param type RenderScript type describing data layout
1898 * @param mips specifies desired mipmap behaviour for the
1900 * @param usage bit field specifying how the Allocation is
1903 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
1905 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
1907 if (type.getID(rs) == 0) {
1908 throw new RSInvalidStateException("Bad Type");
1910 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
1912 throw new RSRuntimeException("Allocation creation failed.");
1914 return new Allocation(id, rs, type, usage, mips);
1916 Trace.traceEnd(RenderScript.TRACE_TAG);
1921 * Creates an Allocation with the size specified by the type and no mipmaps
1922 * generated by default
1924 * @param rs Context to which the allocation will belong.
1925 * @param type renderscript type describing data layout
1926 * @param usage bit field specifying how the allocation is
1929 * @return allocation
1931 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1932 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1936 * Creates an Allocation for use by scripts with a given {@link
1937 * android.renderscript.Type} and no mipmaps
1939 * @param rs Context to which the Allocation will belong.
1940 * @param type RenderScript Type describing data layout
1942 * @return allocation
1944 static public Allocation createTyped(RenderScript rs, Type type) {
1945 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
1949 * Creates an Allocation with a specified number of given elements
1951 * @param rs Context to which the Allocation will belong.
1952 * @param e Element to use in the Allocation
1953 * @param count the number of Elements in the Allocation
1954 * @param usage bit field specifying how the Allocation is
1957 * @return allocation
1959 static public Allocation createSized(RenderScript rs, Element e,
1960 int count, int usage) {
1962 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
1964 Type.Builder b = new Type.Builder(rs, e);
1966 Type t = b.create();
1968 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
1970 throw new RSRuntimeException("Allocation creation failed.");
1972 return new Allocation(id, rs, t, usage, MipmapControl.MIPMAP_NONE);
1974 Trace.traceEnd(RenderScript.TRACE_TAG);
1979 * Creates an Allocation with a specified number of given elements
1981 * @param rs Context to which the Allocation will belong.
1982 * @param e Element to use in the Allocation
1983 * @param count the number of Elements in the Allocation
1985 * @return allocation
1987 static public Allocation createSized(RenderScript rs, Element e, int count) {
1988 return createSized(rs, e, count, USAGE_SCRIPT);
1991 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
1992 final Bitmap.Config bc = b.getConfig();
1993 if (bc == Bitmap.Config.ALPHA_8) {
1994 return Element.A_8(rs);
1996 if (bc == Bitmap.Config.ARGB_4444) {
1997 return Element.RGBA_4444(rs);
1999 if (bc == Bitmap.Config.ARGB_8888) {
2000 return Element.RGBA_8888(rs);
2002 if (bc == Bitmap.Config.RGB_565) {
2003 return Element.RGB_565(rs);
2005 throw new RSInvalidStateException("Bad bitmap type: " + bc);
2008 static Type typeFromBitmap(RenderScript rs, Bitmap b,
2009 MipmapControl mip) {
2010 Element e = elementFromBitmap(rs, b);
2011 Type.Builder tb = new Type.Builder(rs, e);
2012 tb.setX(b.getWidth());
2013 tb.setY(b.getHeight());
2014 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
2019 * Creates an Allocation from a {@link android.graphics.Bitmap}.
2021 * @param rs Context to which the allocation will belong.
2022 * @param b Bitmap source for the allocation data
2023 * @param mips specifies desired mipmap behaviour for the
2025 * @param usage bit field specifying how the allocation is
2028 * @return Allocation containing bitmap data
2031 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
2035 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
2038 // WAR undocumented color formats
2039 if (b.getConfig() == null) {
2040 if ((usage & USAGE_SHARED) != 0) {
2041 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
2043 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
2044 Canvas c = new Canvas(newBitmap);
2045 c.drawBitmap(b, 0, 0, null);
2046 return createFromBitmap(rs, newBitmap, mips, usage);
2049 Type t = typeFromBitmap(rs, b, mips);
2051 // enable optimized bitmap path only with no mipmap and script-only usage
2052 if (mips == MipmapControl.MIPMAP_NONE &&
2053 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
2054 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
2055 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
2057 throw new RSRuntimeException("Load failed.");
2060 // keep a reference to the Bitmap around to prevent GC
2061 Allocation alloc = new Allocation(id, rs, t, usage, mips);
2067 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
2069 throw new RSRuntimeException("Load failed.");
2071 return new Allocation(id, rs, t, usage, mips);
2073 Trace.traceEnd(RenderScript.TRACE_TAG);
2078 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
2079 * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
2080 * would contain the up-to-date data as READ ONLY.
2081 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2082 * the Allocation has certain alignment. The size of each row including padding,
2083 * called stride, can be queried using the {@link #getStride()} method.
2085 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
2087 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
2089 public ByteBuffer getByteBuffer() {
2090 // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
2091 if (mType.hasFaces()) {
2092 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
2094 if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
2095 mType.getYuv() == android.graphics.ImageFormat.YV12 ||
2096 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
2097 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
2099 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
2100 int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
2101 long[] stride = new long[1];
2102 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
2103 mByteBufferStride = stride[0];
2105 if ((mUsage & USAGE_IO_INPUT) != 0) {
2106 return mByteBuffer.asReadOnlyBuffer();
2112 * Creates a new Allocation Array with the given {@link
2113 * android.renderscript.Type}, and usage flags.
2114 * Note: If the input allocation is of usage: USAGE_IO_INPUT,
2115 * the created Allocation will be sharing the same BufferQueue.
2117 * @param rs RenderScript context
2118 * @param t RenderScript type describing data layout
2119 * @param usage bit field specifying how the Allocation is
2121 * @param numAlloc Number of Allocations in the array.
2122 * @return Allocation[]
2124 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) {
2126 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations");
2128 if (t.getID(rs) == 0) {
2129 throw new RSInvalidStateException("Bad Type");
2132 Allocation[] mAllocationArray = new Allocation[numAlloc];
2133 mAllocationArray[0] = createTyped(rs, t, usage);
2134 if ((usage & USAGE_IO_INPUT) != 0) {
2135 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
2136 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
2137 MAX_NUMBER_IO_INPUT_ALLOC);
2139 mAllocationArray[0].setupBufferQueue(numAlloc);;
2142 for (int i=1; i<numAlloc; i++) {
2143 mAllocationArray[i] = createFromAllcation(rs, mAllocationArray[0]);
2145 return mAllocationArray;
2147 Trace.traceEnd(RenderScript.TRACE_TAG);
2152 * Creates a new Allocation with the given {@link
2153 * android.renderscript.Allocation}. The same data layout of
2154 * the input Allocation will be applied.
2155 * If the input allocation is of usage: USAGE_IO_INPUT, the created
2156 * Allocation will be sharing the same BufferQueue.
2158 * @param rs Context to which the allocation will belong.
2159 * @param alloc RenderScript Allocation describing data layout.
2160 * @return Allocation sharing the same data structure.
2162 static Allocation createFromAllcation(RenderScript rs, Allocation alloc) {
2164 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation");
2166 if (alloc.getID(rs) == 0) {
2167 throw new RSInvalidStateException("Bad input Allocation");
2170 Type type = alloc.getType();
2171 int usage = alloc.getUsage();
2172 MipmapControl mips = alloc.getMipmap();
2173 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
2175 throw new RSRuntimeException("Allocation creation failed.");
2177 Allocation outAlloc = new Allocation(id, rs, type, usage, mips);
2178 if ((usage & USAGE_IO_INPUT) != 0) {
2179 outAlloc.shareBufferQueue(alloc);
2183 Trace.traceEnd(RenderScript.TRACE_TAG);
2188 * Initialize BufferQueue with specified max number of buffers.
2190 void setupBufferQueue(int numAlloc) {
2192 if ((mUsage & USAGE_IO_INPUT) == 0) {
2193 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2195 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc);
2199 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation.
2201 * @param alloc Allocation to associate with allocation
2203 void shareBufferQueue(Allocation alloc) {
2205 if ((mUsage & USAGE_IO_INPUT) == 0) {
2206 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT.");
2208 mGetSurfaceSurface = alloc.getSurface();
2209 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS));
2213 * Gets the stride of the Allocation.
2214 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
2215 * the Allocation has certain alignment. The size of each row including such
2216 * padding is called stride.
2218 * @return the stride. For 1D Allocation, the stride will be the number of
2219 * bytes of this Allocation. For 2D and 3D Allocations, the stride
2220 * will be the stride in X dimension measuring in bytes.
2222 public long getStride() {
2223 if (mByteBufferStride == -1) {
2226 return mByteBufferStride;
2230 * Get the timestamp for the most recent buffer held by this Allocation.
2231 * The timestamp is guaranteed to be unique and monotonically increasing.
2232 * Default value: -1. The timestamp will be updated after each {@link
2233 * #ioReceive ioReceive()} call.
2235 * It can be used to identify the images by comparing the unique timestamps
2236 * when used with {@link android.hardware.camera2} APIs.
2238 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the
2239 * capture is completed.
2240 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call.
2241 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with
2242 * alloc.getTimeStamp().
2243 * @return long Timestamp associated with the buffer held by the Allocation.
2245 public long getTimeStamp() {
2250 * Returns the handle to a raw buffer that is being managed by the screen
2251 * compositor. This operation is only valid for Allocations with {@link
2254 * @return Surface object associated with allocation
2257 public Surface getSurface() {
2258 if ((mUsage & USAGE_IO_INPUT) == 0) {
2259 throw new RSInvalidStateException("Allocation is not a surface texture.");
2262 if (mGetSurfaceSurface == null) {
2263 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS));
2266 return mGetSurfaceSurface;
2270 * Associate a {@link android.view.Surface} with this Allocation. This
2271 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
2273 * @param sur Surface to associate with allocation
2275 public void setSurface(Surface sur) {
2277 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
2278 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
2281 mRS.nAllocationSetSurface(getID(mRS), sur);
2285 * Creates an Allocation from a {@link android.graphics.Bitmap}.
2287 * <p>With target API version 18 or greater, this Allocation will be created
2288 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
2289 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
2290 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
2292 * @param rs Context to which the allocation will belong.
2293 * @param b bitmap source for the allocation data
2295 * @return Allocation containing bitmap data
2298 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
2299 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2300 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2301 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
2303 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2304 USAGE_GRAPHICS_TEXTURE);
2308 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
2309 * containing the horizontal list of cube faces. Each face must be a square,
2310 * have the same size as all other faces, and have a width that is a power
2313 * @param rs Context to which the allocation will belong.
2314 * @param b Bitmap with cubemap faces layed out in the following
2315 * format: right, left, top, bottom, front, back
2316 * @param mips specifies desired mipmap behaviour for the cubemap
2317 * @param usage bit field specifying how the cubemap is utilized
2319 * @return allocation containing cubemap data
2322 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
2327 int height = b.getHeight();
2328 int width = b.getWidth();
2330 if (width % 6 != 0) {
2331 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
2333 if (width / 6 != height) {
2334 throw new RSIllegalArgumentException("Only square cube map faces supported");
2336 boolean isPow2 = (height & (height - 1)) == 0;
2338 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2341 Element e = elementFromBitmap(rs, b);
2342 Type.Builder tb = new Type.Builder(rs, e);
2346 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2347 Type t = tb.create();
2349 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
2351 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
2353 return new Allocation(id, rs, t, usage, mips);
2357 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
2358 * from a {@link android.graphics.Bitmap} containing the horizontal list of
2359 * cube faces. Each face must be a square, have the same size as all other
2360 * faces, and have a width that is a power of 2.
2362 * @param rs Context to which the allocation will belong.
2363 * @param b bitmap with cubemap faces layed out in the following
2364 * format: right, left, top, bottom, front, back
2366 * @return allocation containing cubemap data
2369 static public Allocation createCubemapFromBitmap(RenderScript rs,
2371 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
2372 USAGE_GRAPHICS_TEXTURE);
2376 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
2377 * objects containing the cube faces. Each face must be a square, have the
2378 * same size as all other faces, and have a width that is a power of 2.
2380 * @param rs Context to which the allocation will belong.
2381 * @param xpos cubemap face in the positive x direction
2382 * @param xneg cubemap face in the negative x direction
2383 * @param ypos cubemap face in the positive y direction
2384 * @param yneg cubemap face in the negative y direction
2385 * @param zpos cubemap face in the positive z direction
2386 * @param zneg cubemap face in the negative z direction
2387 * @param mips specifies desired mipmap behaviour for the cubemap
2388 * @param usage bit field specifying how the cubemap is utilized
2390 * @return allocation containing cubemap data
2393 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2402 int height = xpos.getHeight();
2403 if (xpos.getWidth() != height ||
2404 xneg.getWidth() != height || xneg.getHeight() != height ||
2405 ypos.getWidth() != height || ypos.getHeight() != height ||
2406 yneg.getWidth() != height || yneg.getHeight() != height ||
2407 zpos.getWidth() != height || zpos.getHeight() != height ||
2408 zneg.getWidth() != height || zneg.getHeight() != height) {
2409 throw new RSIllegalArgumentException("Only square cube map faces supported");
2411 boolean isPow2 = (height & (height - 1)) == 0;
2413 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
2416 Element e = elementFromBitmap(rs, xpos);
2417 Type.Builder tb = new Type.Builder(rs, e);
2421 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
2422 Type t = tb.create();
2423 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
2425 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
2426 adapter.setFace(Type.CubemapFace.POSITIVE_X);
2427 adapter.copyFrom(xpos);
2428 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
2429 adapter.copyFrom(xneg);
2430 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
2431 adapter.copyFrom(ypos);
2432 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
2433 adapter.copyFrom(yneg);
2434 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
2435 adapter.copyFrom(zpos);
2436 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
2437 adapter.copyFrom(zneg);
2443 * Creates a non-mipmapped cubemap Allocation for use as a sampler input
2444 * from 6 {@link android.graphics.Bitmap} objects containing the cube
2445 * faces. Each face must be a square, have the same size as all other faces,
2446 * and have a width that is a power of 2.
2448 * @param rs Context to which the allocation will belong.
2449 * @param xpos cubemap face in the positive x direction
2450 * @param xneg cubemap face in the negative x direction
2451 * @param ypos cubemap face in the positive y direction
2452 * @param yneg cubemap face in the negative y direction
2453 * @param zpos cubemap face in the positive z direction
2454 * @param zneg cubemap face in the negative z direction
2456 * @return allocation containing cubemap data
2459 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
2466 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
2467 zpos, zneg, MipmapControl.MIPMAP_NONE,
2468 USAGE_GRAPHICS_TEXTURE);
2472 * Creates an Allocation from the Bitmap referenced
2475 * @param rs Context to which the allocation will belong.
2476 * @param res application resources
2477 * @param id resource id to load the data from
2478 * @param mips specifies desired mipmap behaviour for the
2480 * @param usage bit field specifying how the allocation is
2483 * @return Allocation containing resource data
2486 static public Allocation createFromBitmapResource(RenderScript rs,
2493 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
2494 throw new RSIllegalArgumentException("Unsupported usage specified.");
2496 Bitmap b = BitmapFactory.decodeResource(res, id);
2497 Allocation alloc = createFromBitmap(rs, b, mips, usage);
2503 * Creates a non-mipmapped Allocation to use as a graphics texture from the
2504 * {@link android.graphics.Bitmap} referenced by resource ID.
2506 * <p>With target API version 18 or greater, this allocation will be created
2507 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
2508 * target API version 17 or lower, this allocation will be created with
2509 * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
2511 * @param rs Context to which the allocation will belong.
2512 * @param res application resources
2513 * @param id resource id to load the data from
2515 * @return Allocation containing resource data
2518 static public Allocation createFromBitmapResource(RenderScript rs,
2521 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
2522 return createFromBitmapResource(rs, res, id,
2523 MipmapControl.MIPMAP_NONE,
2524 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
2526 return createFromBitmapResource(rs, res, id,
2527 MipmapControl.MIPMAP_NONE,
2528 USAGE_GRAPHICS_TEXTURE);
2532 * Creates an Allocation containing string data encoded in UTF-8 format.
2534 * @param rs Context to which the allocation will belong.
2535 * @param str string to create the allocation from
2536 * @param usage bit field specifying how the allocaiton is
2540 static public Allocation createFromString(RenderScript rs,
2544 byte[] allocArray = null;
2546 allocArray = str.getBytes("UTF-8");
2547 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
2548 alloc.copyFrom(allocArray);
2551 catch (Exception e) {
2552 throw new RSRuntimeException("Could not convert string to utf-8.");
2557 * Interface to handle notification when new buffers are available via
2558 * {@link #USAGE_IO_INPUT}. An application will receive one notification
2559 * when a buffer is available. Additional buffers will not trigger new
2560 * notifications until a buffer is processed.
2562 public interface OnBufferAvailableListener {
2563 public void onBufferAvailable(Allocation a);
2567 * Set a notification handler for {@link #USAGE_IO_INPUT}.
2569 * @param callback instance of the OnBufferAvailableListener
2570 * class to be called when buffer arrive.
2572 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
2573 synchronized(mAllocationMap) {
2574 mAllocationMap.put(new Long(getID(mRS)), this);
2575 mBufferNotifier = callback;
2579 static void sendBufferNotification(long id) {
2580 synchronized(mAllocationMap) {
2581 Allocation a = mAllocationMap.get(new Long(id));
2583 if ((a != null) && (a.mBufferNotifier != null)) {
2584 a.mBufferNotifier.onBufferAvailable(a);
2590 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
2594 public void destroy() {
2595 if((mUsage & USAGE_IO_OUTPUT) != 0) {