Automatic sources dropoff on 2020-06-10 18:32:38.095721
The change is generated with prebuilt drop tool.
Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/androidx/renderscript/Allocation.java b/androidx/renderscript/Allocation.java
new file mode 100644
index 0000000..b6588c0
--- /dev/null
+++ b/androidx/renderscript/Allocation.java
@@ -0,0 +1,3032 @@
+/*
+ * Copyright (C) 2008-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.util.Log;
+import android.view.Surface;
+
+/**
+ * <p> This class provides the primary method through which data is passed to
+ * and from RenderScript kernels. An Allocation provides the backing store for
+ * a given {@link androidx.renderscript.Type}. </p>
+ *
+ * <p>An Allocation also contains a set of usage flags that denote how the
+ * Allocation could be used. For example, an Allocation may have usage flags
+ * specifying that it can be used from a script as well as input to a {@link
+ * androidx.renderscript.Sampler}. A developer must synchronize
+ * across these different usages using
+ * {@link androidx.renderscript.Allocation#syncAll} in
+ * order to ensure that different users of the Allocation have a consistent view
+ * of memory. For example, in the case where an Allocation is used as the output
+ * of one kernel and as Sampler input in a later kernel, a developer must call
+ * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
+ * second kernel to ensure correctness.
+ *
+ * <p>An Allocation can be populated with the {@link #copyFrom} routines. For
+ * more complex Element types, the {@link #copyFromUnchecked} methods can be
+ * used to copy from byte arrays or similar constructs.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses
+ * RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Allocation extends BaseObj {
+ Type mType;
+ Bitmap mBitmap;
+ int mUsage;
+ int mSize;
+ Allocation mAdaptedAllocation;
+ ByteBuffer mByteBuffer = null;
+ long mByteBufferStride = 0;
+
+ boolean mConstrainedLOD;
+ boolean mConstrainedFace;
+ boolean mConstrainedY;
+ boolean mConstrainedZ;
+ boolean mReadAllowed = true;
+ boolean mWriteAllowed = true;
+ boolean mAutoPadding = false;
+ int mSelectedY;
+ int mSelectedZ;
+ int mSelectedLOD;
+ Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
+
+ int mCurrentDimX;
+ int mCurrentDimY;
+ int mCurrentDimZ;
+ int mCurrentCount;
+
+ private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
+ final Class c = d.getClass();
+ if (!c.isArray()) {
+ throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
+ }
+ final Class cmp = c.getComponentType();
+ if (!cmp.isPrimitive()) {
+ throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
+ }
+
+ if (cmp == Long.TYPE) {
+ if (checkType) {
+ validateIsInt64();
+ return mType.mElement.mType;
+ }
+ return Element.DataType.SIGNED_64;
+ }
+
+ if (cmp == Integer.TYPE) {
+ if (checkType) {
+ validateIsInt32();
+ return mType.mElement.mType;
+ }
+ return Element.DataType.SIGNED_32;
+ }
+
+ if (cmp == Short.TYPE) {
+ if (checkType) {
+ validateIsInt16();
+ return mType.mElement.mType;
+ }
+ return Element.DataType.SIGNED_16;
+ }
+
+ if (cmp == Byte.TYPE) {
+ if (checkType) {
+ validateIsInt8();
+ return mType.mElement.mType;
+ }
+ return Element.DataType.SIGNED_8;
+ }
+
+ if (cmp == Float.TYPE) {
+ if (checkType) {
+ validateIsFloat32();
+ }
+ return Element.DataType.FLOAT_32;
+ }
+
+ if (cmp == Double.TYPE) {
+ if (checkType) {
+ validateIsFloat64();
+ }
+ return Element.DataType.FLOAT_64;
+ }
+ return null;
+ }
+
+ /*
+ * Hold reference to the shared allocation in compat context
+ * for Incremental Support Lib.
+ */
+ long mIncCompatAllocation;
+ boolean mIncAllocDestroyed;
+ /**
+ * The usage of the Allocation. These signal to RenderScript where to place
+ * the Allocation in memory.
+ *
+ */
+
+ /**
+ * The Allocation will be bound to and accessed by scripts.
+ */
+ public static final int USAGE_SCRIPT = 0x0001;
+
+ /**
+ * The Allocation will be used as a texture source by one or more graphics
+ * programs.
+ *
+ */
+ public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
+
+ /**
+ * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+ * consumer. This usage will cause the Allocation to be created as
+ * read-only.
+ *
+ */
+ public static final int USAGE_IO_INPUT = 0x0020;
+
+ /**
+ * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+ * producer. The dimensions and format of the {@link
+ * android.graphics.SurfaceTexture} will be forced to those of the
+ * Allocation.
+ *
+ */
+ public static final int USAGE_IO_OUTPUT = 0x0040;
+
+ /**
+ * The Allocation's backing store will be inherited from another object
+ * (usually a {@link android.graphics.Bitmap}); copying to or from the
+ * original source Bitmap will cause a synchronization rather than a full
+ * copy. {@link #syncAll} may also be used to synchronize the Allocation
+ * and the source Bitmap.
+ *
+ * <p>This is set by default for allocations created with {@link
+ * #createFromBitmap} in API version 18 and higher.</p>
+ *
+ */
+ public static final int USAGE_SHARED = 0x0080;
+
+ /**
+ * Controls mipmap behavior when using the bitmap creation and update
+ * functions.
+ */
+ public enum MipmapControl {
+ /**
+ * No mipmaps will be generated and the type generated from the incoming
+ * bitmap will not contain additional LODs.
+ */
+ MIPMAP_NONE(0),
+
+ /**
+ * A full mipmap chain will be created in script memory. The Type of
+ * the Allocation will contain a full mipmap chain. On upload, the full
+ * chain will be transferred.
+ */
+ MIPMAP_FULL(1),
+
+ /**
+ * The Type of the Allocation will be the same as MIPMAP_NONE. It will
+ * not contain mipmaps. On upload, the allocation data will contain a
+ * full mipmap chain generated from the top level in script memory.
+ */
+ MIPMAP_ON_SYNC_TO_TEXTURE(2);
+
+ int mID;
+ MipmapControl(int id) {
+ mID = id;
+ }
+ }
+
+ /**
+ * Getter & Setter for the dummy allocation for Inc Support Lib.
+ *
+ */
+ public long getIncAllocID() {
+ return mIncCompatAllocation;
+ }
+ public void setIncAllocID(long id) {
+ mIncCompatAllocation = id;
+ }
+
+ private long getIDSafe() {
+ if (mAdaptedAllocation != null) {
+ return mAdaptedAllocation.getID(mRS);
+ }
+ return getID(mRS);
+ }
+
+
+ /**
+ * Get the {@link androidx.renderscript.Element} of the {@link
+ * androidx.renderscript.Type} of the Allocation.
+ *
+ * @return Element
+ *
+ */
+ public Element getElement() {
+ return mType.getElement();
+ }
+
+ /**
+ * Get the usage flags of the Allocation.
+ *
+ * @return usage this Allocation's set of the USAGE_* flags OR'd together
+ *
+ */
+ public int getUsage() {
+ return mUsage;
+ }
+
+ /**
+ * Specifies the mapping between the Allocation's cells and an array's elements
+ * when data is copied from the Allocation to the array, or vice-versa.
+ *
+ * Only applies to an Allocation whose Element is a vector of length 3 (such as
+ * {@link Element#U8_3} or {@link Element#RGB_888}). Enabling this feature may make
+ * copying data from the Allocation to an array or vice-versa less efficient.
+ *
+ * <p> Vec3 Element cells are stored in an Allocation as Vec4 Element cells with
+ * the same {@link androidx.renderscript.Element.DataType}, with the fourth vector
+ * component treated as padding. When this feature is enabled, only the data components,
+ * i.e. the first 3 vector components of each cell, will be mapped between the array
+ * and the Allocation. When disabled, explicit mapping of the padding components
+ * is required, as described in the following example.
+ *
+ * <p> For example, when copying an integer array to an Allocation of two {@link
+ * Element#I32_3} cells using {@link #copyFrom(int[])}:
+ * <p> When disabled:
+ * The array must have at least 8 integers, with the first 4 integers copied
+ * to the first cell of the Allocation, and the next 4 integers copied to
+ * the second cell. The 4th and 8th integers are mapped as the padding components.
+ *
+ * <p> When enabled:
+ * The array just needs to have at least 6 integers, with the first 3 integers
+ * copied to the the first cell as data components, and the next 3 copied to
+ * the second cell. There is no mapping for the padding components.
+ *
+ * <p> Similarly, when copying a byte array to an Allocation of two {@link
+ * Element#I32_3} cells, using {@link #copyFromUnchecked(int[])}:
+ * <p> When disabled:
+ * The array must have at least 32 bytes, with the first 16 bytes copied
+ * to the first cell of the Allocation, and the next 16 bytes copied to
+ * the second cell. The 13th-16th and 29th-32nd bytes are mapped as padding
+ * components.
+ *
+ * <p> When enabled:
+ * The array just needs to have at least 24 bytes, with the first 12 bytes copied
+ * to the first cell of the Allocation, and the next 12 bytes copied to
+ * the second cell. There is no mapping for the padding components.
+ *
+ * <p> Similar to copying data to an Allocation from an array, when copying data from an
+ * Allocation to an array, the padding components for Vec3 Element cells will not be
+ * copied/mapped to the array if AutoPadding is enabled.
+ *
+ * <p> Default: Disabled.
+ *
+ * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
+ *
+ */
+ public void setAutoPadding(boolean useAutoPadding) {
+ mAutoPadding = useAutoPadding;
+ }
+
+ /**
+ * Get the size of the Allocation in bytes.
+ *
+ * @return size of the Allocation in bytes.
+ *
+ */
+ public int getBytesSize() {
+ if (mType.mDimYuv != 0) {
+ return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
+ }
+ return mType.getCount() * mType.getElement().getBytesSize();
+ }
+
+ private void updateCacheInfo(Type t) {
+ mCurrentDimX = t.getX();
+ mCurrentDimY = t.getY();
+ mCurrentDimZ = t.getZ();
+ mCurrentCount = mCurrentDimX;
+ if (mCurrentDimY > 1) {
+ mCurrentCount *= mCurrentDimY;
+ }
+ if (mCurrentDimZ > 1) {
+ mCurrentCount *= mCurrentDimZ;
+ }
+ }
+
+ private void setBitmap(Bitmap b) {
+ mBitmap = b;
+ }
+
+ Allocation(long id, RenderScript rs, Type t, int usage) {
+ super(id, rs);
+ if ((usage & ~(USAGE_SCRIPT |
+ USAGE_GRAPHICS_TEXTURE |
+ USAGE_IO_INPUT |
+ USAGE_IO_OUTPUT |
+ USAGE_SHARED)) != 0) {
+ throw new RSIllegalArgumentException("Unknown usage specified.");
+ }
+
+ if ((usage & USAGE_IO_INPUT) != 0) {
+ mWriteAllowed = false;
+
+ if ((usage & ~(USAGE_IO_INPUT |
+ USAGE_GRAPHICS_TEXTURE |
+ USAGE_SCRIPT)) != 0) {
+ throw new RSIllegalArgumentException("Invalid usage combination.");
+ }
+ }
+
+ mType = t;
+ mUsage = usage;
+ mIncCompatAllocation = 0;
+ mIncAllocDestroyed = false;
+
+ if (t != null) {
+ // TODO: A3D doesn't have Type info during creation, so we can't
+ // calculate the size ahead of time. We can possibly add a method
+ // to update the size in the future if it seems reasonable.
+ mSize = mType.getCount() * mType.getElement().getBytesSize();
+ updateCacheInfo(t);
+ }
+ if (RenderScript.sUseGCHooks == true) {
+ try {
+ RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
+ } catch (Exception e) {
+ Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
+ throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
+ }
+ }
+ }
+
+ protected void finalize() throws Throwable {
+ if (RenderScript.sUseGCHooks == true) {
+ RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
+ }
+ super.finalize();
+ }
+
+ private void validateIsInt64() {
+ if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
+ (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "64 bit integer source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsInt32() {
+ if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
+ (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "32 bit integer source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsInt16() {
+ if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
+ (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "16 bit integer source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsInt8() {
+ if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
+ (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "8 bit integer source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsFloat32() {
+ if (mType.mElement.mType == Element.DataType.FLOAT_32) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "32 bit float source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsFloat64() {
+ if (mType.mElement.mType == Element.DataType.FLOAT_64) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "64 bit float source does not match allocation type " + mType.mElement.mType);
+ }
+
+ private void validateIsObject() {
+ if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
+ (mType.mElement.mType == Element.DataType.RS_TYPE) ||
+ (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
+ (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
+ (mType.mElement.mType == Element.DataType.RS_SCRIPT)) {
+ return;
+ }
+ throw new RSIllegalArgumentException(
+ "Object source does not match allocation type " + mType.mElement.mType);
+ }
+
+ /**
+ * Get the {@link androidx.renderscript.Type} of the Allocation.
+ *
+ * @return Type
+ *
+ */
+ public Type getType() {
+ return mType;
+ }
+
+ /**
+ * Propagate changes from one usage of the Allocation to the
+ * other usages of the Allocation.
+ *
+ */
+ public void syncAll(int srcLocation) {
+ switch (srcLocation) {
+ case USAGE_SCRIPT:
+ case USAGE_GRAPHICS_TEXTURE:
+ break;
+ default:
+ throw new RSIllegalArgumentException("Source must be exactly one usage type.");
+ }
+ mRS.validate();
+ mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
+ }
+
+ /**
+ * Send a buffer to the output stream. The contents of the Allocation will
+ * be undefined after this operation. This operation is only valid if {@link
+ * #USAGE_IO_OUTPUT} is set on the Allocation.
+ *
+ *
+ */
+ public void ioSend() {
+ if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+ throw new RSIllegalArgumentException(
+ "Can only send buffer if IO_OUTPUT usage specified.");
+ }
+ mRS.validate();
+ mRS.nAllocationIoSend(getID(mRS));
+ }
+
+ /**
+ * Delete once code is updated.
+ */
+ public void ioSendOutput() {
+ ioSend();
+ }
+ /**
+ * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
+ * <p> If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
+ * would contain the up-to-date data as READ ONLY.
+ * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+ * the Allocation has certain alignment. The size of each row including padding,
+ * called stride, can be queried using the {@link #getStride()} method.
+ *
+ * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
+ * The ByteBuffer will be Read-Only for devices before Lollopop (API 21).
+ *
+ * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
+ */
+ public ByteBuffer getByteBuffer() {
+ int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
+ // When running on devices before L, we need to construct the ByteBuffer
+ // and explicitly copy the data from the allocation to it.
+ if (mRS.getDispatchAPILevel() < 21) {
+ byte[] data = null;
+ if (mType.getZ() > 0) {
+ // TODO: add support for 3D allocations.
+ return null;
+ } else if (mType.getY() > 0) {
+ // 2D Allocation
+ data = new byte[xBytesSize * mType.getY()];
+ copy2DRangeToUnchecked(0, 0, mType.getX(), mType.getY(), data,
+ Element.DataType.SIGNED_8, xBytesSize * mType.getY());
+ } else {
+ // 1D Allocation
+ data = new byte[xBytesSize];
+ copy1DRangeToUnchecked(0, mType.getX(), data);
+ }
+ ByteBuffer bBuffer = ByteBuffer.wrap(data).asReadOnlyBuffer();
+ mByteBufferStride = xBytesSize;
+ return bBuffer;
+ }
+ // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
+ if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
+ mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), xBytesSize, mType.getY(), mType.getZ());
+ }
+ return mByteBuffer;
+ }
+
+ /**
+ * Gets the stride of the Allocation.
+ * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+ * the Allocation has certain alignment. The size of each row including such
+ * padding is called stride.
+ *
+ * @return the stride. For 1D Allocation, the stride will be the number of
+ * bytes of this Allocation. For 2D and 3D Allocations, the stride
+ * will be the stride in X dimension measuring in bytes.
+ */
+ public long getStride() {
+ if (mByteBufferStride ==0) {
+ if (mRS.getDispatchAPILevel() > 21) {
+ mByteBufferStride = mRS.nAllocationGetStride(getID(mRS));
+ } else {
+ mByteBufferStride = mType.getX() * mType.getElement().getBytesSize();
+ }
+ }
+ return mByteBufferStride;
+ }
+
+ /**
+ * Receive the latest input into the Allocation. This operation
+ * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
+ *
+ */
+ public void ioReceive() {
+ if ((mUsage & USAGE_IO_INPUT) == 0) {
+ throw new RSIllegalArgumentException(
+ "Can only receive if IO_INPUT usage specified.");
+ }
+ mRS.validate();
+ mRS.nAllocationIoReceive(getID(mRS));
+ }
+
+ /**
+ * Copy an array of RS objects to the Allocation.
+ *
+ * @param d Source array.
+ */
+ public void copyFrom(BaseObj[] d) {
+ mRS.validate();
+ validateIsObject();
+ if (d.length != mCurrentCount) {
+ throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
+ mCurrentCount + ", array length = " + d.length);
+ }
+
+ if (RenderScript.sPointerSize == 8) {
+ long i[] = new long[d.length * 4];
+ for (int ct=0; ct < d.length; ct++) {
+ i[ct * 4] = d[ct].getID(mRS);
+ }
+ copy1DRangeFromUnchecked(0, mCurrentCount, i);
+ } else {
+ int i[] = new int[d.length];
+ for (int ct=0; ct < d.length; ct++) {
+ i[ct] = (int)d[ct].getID(mRS);
+ }
+ copy1DRangeFromUnchecked(0, mCurrentCount, i);
+ }
+ }
+
+ private void validateBitmapFormat(Bitmap b) {
+ Bitmap.Config bc = b.getConfig();
+ if (bc == null) {
+ throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
+ }
+ switch (bc) {
+ case ALPHA_8:
+ if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getBytesSize() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case ARGB_8888:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+ (mType.getElement().getBytesSize() != 4)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getBytesSize() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case RGB_565:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
+ (mType.getElement().getBytesSize() != 2)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getBytesSize() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case ARGB_4444:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+ (mType.getElement().getBytesSize() != 2)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getBytesSize() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+
+ }
+ }
+
+ private void validateBitmapSize(Bitmap b) {
+ if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
+ throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
+ }
+ }
+
+ private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ if (mCurrentDimZ > 0) {
+ copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
+ } else if (mCurrentDimY > 0) {
+ copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
+ } else {
+ copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
+ }
+ }
+
+ /**
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param array The source array
+ */
+ public void copyFromUnchecked(Object array) {
+ copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFromUnchecked(int[] d) {
+ copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFromUnchecked(short[] d) {
+ copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFromUnchecked(byte[] d) {
+ copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFromUnchecked(float[] d) {
+ copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
+ }
+
+
+ /**
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the array's
+ * primitive type.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param array The source array
+ */
+ public void copyFrom(Object array) {
+ copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFrom(int[] d) {
+ validateIsInt32();
+ copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFrom(short[] d) {
+ validateIsInt16();
+ copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFrom(byte[] d) {
+ validateIsInt8();
+ copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+ * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d the source array
+ */
+ public void copyFrom(float[] d) {
+ validateIsFloat32();
+ copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
+ }
+
+ /**
+ * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
+ * height, width, and format of the bitmap must match the existing
+ * allocation.
+ *
+ * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
+ * android.graphics.Bitmap} used to create the Allocation with {@link
+ * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
+ * this will synchronize the Allocation with the latest data from the {@link
+ * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
+ *
+ * @param b the source bitmap
+ */
+ public void copyFrom(Bitmap b) {
+ mRS.validate();
+ if (b.getConfig() == null) {
+ Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(newBitmap);
+ c.drawBitmap(b, 0, 0, null);
+ copyFrom(newBitmap);
+ return;
+ }
+ validateBitmapSize(b);
+ validateBitmapFormat(b);
+ mRS.nAllocationCopyFromBitmap(getID(mRS), b);
+ }
+
+ /**
+ * Copy an Allocation from an Allocation. The types of both allocations
+ * must be identical.
+ *
+ * @param a the source allocation
+ */
+ public void copyFrom(Allocation a) {
+ mRS.validate();
+ if (!mType.equals(a.getType())) {
+ throw new RSIllegalArgumentException("Types of allocations must match.");
+ }
+ copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
+ }
+
+
+ /**
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files and should not be used by developers.
+ *
+ * @param xoff
+ * @param fp
+ */
+ public void setFromFieldPacker(int xoff, FieldPacker fp) {
+ mRS.validate();
+ int eSize = mType.mElement.getBytesSize();
+ final byte[] data = fp.getData();
+ int data_length = fp.getPos();
+
+ int count = data_length / eSize;
+ if ((eSize * count) != data_length) {
+ throw new RSIllegalArgumentException("Field packer length " + data_length +
+ " not divisible by element size " + eSize + ".");
+ }
+ copy1DRangeFromUnchecked(xoff, count, data);
+ }
+
+ /**
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files.
+ *
+ * @param xoff
+ * @param component_number
+ * @param fp
+ */
+ public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+ mRS.validate();
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new RSIllegalArgumentException("Offset must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int data_length = fp.getPos();
+ int eSize = mType.mElement.mElements[component_number].getBytesSize();
+ eSize *= mType.mElement.mArraySizes[component_number];
+
+ if (data_length != eSize) {
+ throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
+ component_number, data, data_length);
+ }
+
+ /**
+ * @hide
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files.
+ *
+ * @param xoff
+ * @param yoff
+ * @param zoff
+ * @param component_number
+ * @param fp
+ */
+ /*
+ public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
+ mRS.validate();
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new RSIllegalArgumentException("Offset x must be >= 0.");
+ }
+ if(yoff < 0) {
+ throw new RSIllegalArgumentException("Offset y must be >= 0.");
+ }
+ if(zoff < 0) {
+ throw new RSIllegalArgumentException("Offset z must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int data_length = fp.getPos();
+ int eSize = mType.mElement.mElements[component_number].getBytesSize();
+ eSize *= mType.mElement.mArraySizes[component_number];
+
+ if (data_length != eSize) {
+ throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+ component_number, data, data_length);
+ }
+ */
+
+ private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
+ mRS.validate();
+ if(off < 0) {
+ throw new RSIllegalArgumentException("Offset must be >= 0.");
+ }
+ if(count < 1) {
+ throw new RSIllegalArgumentException("Count must be >= 1.");
+ }
+ if((off + count) > mCurrentCount) {
+ throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
+ ", got " + count + " at offset " + off + ".");
+ }
+ if(usePadding) {
+ if(len < dataSize / 4 * 3) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ } else {
+ if(len < dataSize) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ }
+ }
+
+ /**
+ * Generate a mipmap chain. This is only valid if the Type of the Allocation
+ * includes mipmaps.
+ *
+ * <p>This function will generate a complete set of mipmaps from the top
+ * level LOD and place them into the script memory space.</p>
+ *
+ * <p>If the Allocation is also using other memory spaces, a call to {@link
+ * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
+ */
+ public void generateMipmaps() {
+ mRS.nAllocationGenerateMipmaps(getID(mRS));
+ }
+
+ private void copy1DRangeFromUnchecked(int off, int count, Object array,
+ Element.DataType dt, int arrayLen) {
+ final int dataSize = mType.mElement.getBytesSize() * count;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ usePadding = true;
+ }
+ data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
+ mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
+ mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param array The source array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, Object array) {
+ copy1DRangeFromUnchecked(off, count, array,
+ validateObjectIsPrimitiveArray(array, false),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+ copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+ copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+ copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+ copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
+ }
+
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the component type
+ * of the array passed in.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param array The source array.
+ */
+ public void copy1DRangeFrom(int off, int count, Object array) {
+ copy1DRangeFromUnchecked(off, count, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not an 32 bit integer nor a vector of 32 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFrom(int off, int count, int[] d) {
+ validateIsInt32();
+ copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not an 16 bit integer nor a vector of 16 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFrom(int off, int count, short[] d) {
+ validateIsInt16();
+ copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeFrom(int off, int count, byte[] d) {
+ validateIsInt8();
+ copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy an array into a 1D region of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+ * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array.
+ */
+ public void copy1DRangeFrom(int off, int count, float[] d) {
+ validateIsFloat32();
+ copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
+ }
+
+ /**
+ * Copy part of an Allocation into this Allocation.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param data the source data allocation.
+ * @param dataOff off The offset of the first element in data to
+ * be copied.
+ */
+ public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
+ mRS.nAllocationData2D(getIDSafe(), off, 0,
+ mSelectedLOD, mSelectedFace.mID,
+ count, 1, data.getID(mRS), dataOff, 0,
+ data.mSelectedLOD, data.mSelectedFace.mID);
+ }
+
+ private void validate2DRange(int xoff, int yoff, int w, int h) {
+ if (mAdaptedAllocation != null) {
+
+ } else {
+
+ if (xoff < 0 || yoff < 0) {
+ throw new RSIllegalArgumentException("Offset cannot be negative.");
+ }
+ if (h < 0 || w < 0) {
+ throw new RSIllegalArgumentException("Height or width cannot be negative.");
+ }
+ if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
+ throw new RSIllegalArgumentException("Updated region larger than allocation.");
+ }
+ }
+ }
+
+ void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
+ Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ validate2DRange(xoff, yoff, w, h);
+ final int dataSize = mType.mElement.getBytesSize() * w * h;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ int sizeBytes = arrayLen * dt.mSize;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ if (dataSize / 4 * 3 > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ usePadding = true;
+ sizeBytes = dataSize;
+ } else {
+ if (dataSize > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ }
+ mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
+ array, sizeBytes, dt,
+ mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the input data type.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param array Data to be placed into the Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
+ copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
+ validateIsInt8();
+ copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_8, data.length);
+ }
+
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
+ validateIsInt16();
+ copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_16, data.length);
+ }
+
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
+ validateIsInt32();
+ copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_32, data.length);
+ }
+
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+ * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
+ validateIsFloat32();
+ copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.FLOAT_32, data.length);
+ }
+
+ /**
+ * Copy a rectangular region from an Allocation into a rectangular region in
+ * this Allocation.
+ *
+ * @param xoff X offset of the region in this Allocation
+ * @param yoff Y offset of the region in this Allocation
+ * @param w Width of the region to update.
+ * @param h Height of the region to update.
+ * @param data source Allocation.
+ * @param dataXoff X offset in source Allocation
+ * @param dataYoff Y offset in source Allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
+ Allocation data, int dataXoff, int dataYoff) {
+ mRS.validate();
+ validate2DRange(xoff, yoff, w, h);
+ mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
+ mSelectedLOD, mSelectedFace.mID,
+ w, h, data.getID(mRS), dataXoff, dataYoff,
+ data.mSelectedLOD, data.mSelectedFace.mID);
+ }
+
+ /**
+ * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
+ * and width of the update will use the height and width of the {@link
+ * android.graphics.Bitmap}.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param data the Bitmap to be copied
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
+ mRS.validate();
+ if (data.getConfig() == null) {
+ Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(newBitmap);
+ c.drawBitmap(data, 0, 0, null);
+ copy2DRangeFrom(xoff, yoff, newBitmap);
+ return;
+ }
+ validateBitmapFormat(data);
+ validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
+ mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
+ }
+
+ private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
+ if (mAdaptedAllocation != null) {
+
+ } else {
+
+ if (xoff < 0 || yoff < 0 || zoff < 0) {
+ throw new RSIllegalArgumentException("Offset cannot be negative.");
+ }
+ if (h < 0 || w < 0 || d < 0) {
+ throw new RSIllegalArgumentException("Height or width cannot be negative.");
+ }
+ if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
+ throw new RSIllegalArgumentException("Updated region larger than allocation.");
+ }
+ }
+ }
+
+ /**
+ * Copy a rectangular region from the array into the allocation.
+ * The array is assumed to be tightly packed.
+ *
+ * The data type of the array is not required to be the same as
+ * the element data type.
+ */
+ private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
+ Object array, Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ validate3DRange(xoff, yoff, zoff, w, h, d);
+ final int dataSize = mType.mElement.getBytesSize() * w * h * d;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ int sizeBytes = arrayLen * dt.mSize;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ if (dataSize / 4 * 3 > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ usePadding = true;
+ sizeBytes = dataSize;
+ } else {
+ if (dataSize > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ }
+ mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
+ array, sizeBytes, dt,
+ mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy from an array into a 3D region in this Allocation. The
+ * array is assumed to be tightly packed. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the input data type.
+ *
+ * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param zoff Z offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param d Depth of the region to update
+ * @param array to be placed into the allocation
+ */
+ public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
+ copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy a rectangular region into the allocation from another
+ * allocation.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param zoff Z offset of the region to update in this Allocation
+ * @param w Width of the region to update.
+ * @param h Height of the region to update.
+ * @param d Depth of the region to update.
+ * @param data source allocation.
+ * @param dataXoff X offset of the region in the source Allocation
+ * @param dataYoff Y offset of the region in the source Allocation
+ * @param dataZoff Z offset of the region in the source Allocation
+ */
+ public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
+ Allocation data, int dataXoff, int dataYoff, int dataZoff) {
+ mRS.validate();
+ validate3DRange(xoff, yoff, zoff, w, h, d);
+ mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+ w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
+ data.mSelectedLOD);
+ }
+
+
+ /**
+ * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
+ * bitmap must match the dimensions of the Allocation.
+ *
+ * @param b The bitmap to be set from the Allocation.
+ */
+ public void copyTo(Bitmap b) {
+ mRS.validate();
+ validateBitmapFormat(b);
+ validateBitmapSize(b);
+ mRS.nAllocationCopyToBitmap(getID(mRS), b);
+ }
+
+ private void copyTo(Object array, Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ boolean usePadding = false;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ usePadding = true;
+ }
+ if (usePadding) {
+ if (dt.mSize * arrayLen < mSize / 4 * 3) {
+ throw new RSIllegalArgumentException(
+ "Size of output array cannot be smaller than size of allocation.");
+ }
+ } else {
+ if (dt.mSize * arrayLen < mSize) {
+ throw new RSIllegalArgumentException(
+ "Size of output array cannot be smaller than size of allocation.");
+ }
+ }
+ mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy from the Allocation into an array. The method is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the input data type.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells will be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param array The array to be set from the Allocation.
+ */
+ public void copyTo(Object array) {
+ copyTo(array, validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy from the Allocation into a byte array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells will be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d The array to be set from the Allocation.
+ */
+ public void copyTo(byte[] d) {
+ validateIsInt8();
+ copyTo(d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy from the Allocation into a short array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells will be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d The array to be set from the Allocation.
+ */
+ public void copyTo(short[] d) {
+ validateIsInt16();
+ copyTo(d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy from the Allocation into a int array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells will be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d The array to be set from the Allocation.
+ */
+ public void copyTo(int[] d) {
+ validateIsInt32();
+ copyTo(d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy from the Allocation into a float array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+ * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the Allocation {@link
+ * #getBytesSize getBytesSize()}.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells will be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+ * the cells must not be part of the array.
+ *
+ * @param d The array to be set from the Allocation.
+ */
+ public void copyTo(float[] d) {
+ validateIsFloat32();
+ copyTo(d, Element.DataType.FLOAT_32, d.length);
+ }
+
+ /**
+ * @hide
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files and should not be used by developers.
+ *
+ * @param xoff
+ * @param yoff
+ * @param zoff
+ * @param component_number
+ * @param fp
+ */
+ /*
+ public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
+ mRS.validate();
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new RSIllegalArgumentException("Offset x must be >= 0.");
+ }
+ if(yoff < 0) {
+ throw new RSIllegalArgumentException("Offset y must be >= 0.");
+ }
+ if(zoff < 0) {
+ throw new RSIllegalArgumentException("Offset z must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int data_length = data.length;
+ int eSize = mType.mElement.mElements[component_number].getBytesSize();
+ eSize *= mType.mElement.mArraySizes[component_number];
+
+ if (data_length != eSize) {
+ throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+ component_number, data, data_length);
+ }
+ */
+
+ private void copy1DRangeToUnchecked(int off, int count, Object array,
+ Element.DataType dt, int arrayLen) {
+ final int dataSize = mType.mElement.getBytesSize() * count;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ usePadding = true;
+ }
+ data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
+ mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
+ mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param array The dest array
+ */
+ public void copy1DRangeToUnchecked(int off, int count, Object array) {
+ copy1DRangeToUnchecked(off, count, array,
+ validateObjectIsPrimitiveArray(array, false),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeToUnchecked(int off, int count, int[] d) {
+ copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeToUnchecked(int off, int count, short[] d) {
+ copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
+ copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeToUnchecked(int off, int count, float[] d) {
+ copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
+ }
+
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This method is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} does not match the component type
+ * of the array passed in.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param array The source array.
+ */
+ public void copy1DRangeTo(int off, int count, Object array) {
+ copy1DRangeToUnchecked(off, count, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit integer nor a vector of 32 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeTo(int off, int count, int[] d) {
+ validateIsInt32();
+ copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 16 bit integer nor a vector of 16 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeTo(int off, int count, short[] d) {
+ validateIsInt16();
+ copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
+ * integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array
+ */
+ public void copy1DRangeTo(int off, int count, byte[] d) {
+ validateIsInt8();
+ copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
+ }
+
+ /**
+ * Copy a 1D region of this Allocation into an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+ * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: count * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source array.
+ */
+ public void copy1DRangeTo(int off, int count, float[] d) {
+ validateIsFloat32();
+ copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
+ }
+
+
+ void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
+ Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ validate2DRange(xoff, yoff, w, h);
+ final int dataSize = mType.mElement.getBytesSize() * w * h;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ int sizeBytes = arrayLen * dt.mSize;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ if (dataSize / 4 * 3 > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ usePadding = true;
+ sizeBytes = dataSize;
+ } else {
+ if (dataSize > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ }
+ mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
+ array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
+ }
+
+ /**
+ * Copy from a rectangular region in this Allocation into an array. This
+ * method is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} does not match the component type
+ * of the array passed in.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param array Dest Array to be copied into
+ */
+ public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
+ copy2DRangeToUnchecked(xoff, yoff, w, h, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+
+ /**
+ * Copy from a rectangular region in this Allocation into an array. This
+ * variant is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} is neither an 8 bit integer nor a vector
+ * of 8 bit integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param data Dest Array to be copied into
+ */
+ public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
+ validateIsInt8();
+ copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_8, data.length);
+ }
+
+ /**
+ * Copy from a rectangular region in this Allocation into an array. This
+ * variant is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} is neither a 16 bit integer nor a vector
+ * of 16 bit integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param data Dest Array to be copied into
+ */
+ public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
+ validateIsInt16();
+ copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_16, data.length);
+ }
+
+ /**
+ * Copy from a rectangular region in this Allocation into an array. This
+ * variant is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} is neither a 32 bit integer nor a vector
+ * of 32 bit integers {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param data Dest Array to be copied into
+ */
+ public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
+ validateIsInt32();
+ copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.SIGNED_32, data.length);
+ }
+
+ /**
+ * Copy from a rectangular region in this Allocation into an array. This
+ * variant is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} is neither a 32 bit float nor a vector
+ * of 32 bit floats {@link androidx.renderscript.Element.DataType}.
+ *
+ * <p> The size of the region is: w * h * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param data Dest Array to be copied into
+ */
+ public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
+ validateIsFloat32();
+ copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+ Element.DataType.FLOAT_32, data.length);
+ }
+
+
+ /**
+ * Copy from a 3D region in this Allocation into an array. This method does
+ * not guarantee that the Allocation is compatible with the input buffer.
+ * The array is assumed to be tightly packed.
+ *
+ * The data type of the array is not required to be the same as
+ * the element data type.
+ */
+ /*
+ private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
+ Object array, Element.DataType dt, int arrayLen) {
+ mRS.validate();
+ validate3DRange(xoff, yoff, zoff, w, h, d);
+ final int dataSize = mType.mElement.getBytesSize() * w * h * d;
+ // AutoPadding for Vec3 Element
+ boolean usePadding = false;
+ int sizeBytes = arrayLen * dt.mSize;
+ if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+ if (dataSize / 4 * 3 > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ usePadding = true;
+ sizeBytes = dataSize;
+ } else {
+ if (dataSize > sizeBytes) {
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
+ }
+ }
+ mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
+ array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
+ }
+ */
+
+ /**
+ * @hide
+ * Copy from a 3D region in this Allocation into an array. This
+ * method is type checked and will generate exceptions if the Allocation's
+ * {@link androidx.renderscript.Element} does not match the component type
+ * of the array passed in.
+ *
+ * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
+ * Element#getBytesSize}.
+ *
+ * <p> If the Allocation does not have Vec3 Elements, then the size of the
+ * array in bytes must be at least the size of the region.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is disabled, then the size of the array in bytes must be at least the size
+ * of the region. The padding bytes for the cells must be part of the array.
+ *
+ * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+ * is enabled, then the size of the array in bytes must be at least 3/4 the size
+ * of the region. The padding bytes for the cells must not be part of the array.
+ *
+ * @param xoff X offset of the region to copy in this Allocation
+ * @param yoff Y offset of the region to copy in this Allocation
+ * @param zoff Z offset of the region to copy in this Allocation
+ * @param w Width of the region to copy
+ * @param h Height of the region to copy
+ * @param d Depth of the region to copy
+ * @param array Dest Array to be copied into
+ */
+ /*
+ public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
+ copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
+ validateObjectIsPrimitiveArray(array, true),
+ java.lang.reflect.Array.getLength(array));
+ }
+ */
+
+ // creation
+
+ static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+ static {
+ mBitmapOptions.inScaled = false;
+ }
+
+ /**
+ * Creates a new Allocation with the given {@link
+ * androidx.renderscript.Type}, mipmap flag, and usage flags.
+ *
+ * @param type RenderScript type describing data layout
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the Allocation is
+ * utilized
+ */
+ static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
+ rs.validate();
+ if (type.getID(rs) == 0) {
+ throw new RSInvalidStateException("Bad Type");
+ }
+
+ if(!rs.usingIO() && (usage & (USAGE_IO_INPUT | USAGE_IO_INPUT)) != 0) {
+ throw new RSRuntimeException("USAGE_IO not supported, Allocation creation failed.");
+ }
+
+ long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, type, usage);
+ }
+
+ /**
+ * Creates an Allocation with the size specified by the type and no mipmaps
+ * generated by default
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param type renderscript type describing data layout
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return allocation
+ */
+ static public Allocation createTyped(RenderScript rs, Type type, int usage) {
+ return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
+ }
+
+ /**
+ * Creates an Allocation for use by scripts with a given {@link
+ * androidx.renderscript.Type} and no mipmaps
+ *
+ * @param rs Context to which the Allocation will belong.
+ * @param type RenderScript Type describing data layout
+ *
+ * @return allocation
+ */
+ static public Allocation createTyped(RenderScript rs, Type type) {
+ return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
+ }
+
+ /**
+ * Creates an Allocation with a specified number of given elements
+ *
+ * @param rs Context to which the Allocation will belong.
+ * @param e Element to use in the Allocation
+ * @param count the number of Elements in the Allocation
+ * @param usage bit field specifying how the Allocation is
+ * utilized
+ *
+ * @return allocation
+ */
+ static public Allocation createSized(RenderScript rs, Element e,
+ int count, int usage) {
+ rs.validate();
+ Type.Builder b = new Type.Builder(rs, e);
+ b.setX(count);
+ Type t = b.create();
+
+ long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Creates an Allocation with a specified number of given elements
+ *
+ * @param rs Context to which the Allocation will belong.
+ * @param e Element to use in the Allocation
+ * @param count the number of Elements in the Allocation
+ *
+ * @return allocation
+ */
+ static public Allocation createSized(RenderScript rs, Element e, int count) {
+ return createSized(rs, e, count, USAGE_SCRIPT);
+ }
+
+ static Element elementFromBitmap(RenderScript rs, Bitmap b) {
+ final Bitmap.Config bc = b.getConfig();
+ if (bc == Bitmap.Config.ALPHA_8) {
+ return Element.A_8(rs);
+ }
+ if (bc == Bitmap.Config.ARGB_4444) {
+ return Element.RGBA_4444(rs);
+ }
+ if (bc == Bitmap.Config.ARGB_8888) {
+ return Element.RGBA_8888(rs);
+ }
+ if (bc == Bitmap.Config.RGB_565) {
+ return Element.RGB_565(rs);
+ }
+ throw new RSInvalidStateException("Bad bitmap type: " + bc);
+ }
+
+ static Type typeFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mip) {
+ Element e = elementFromBitmap(rs, b);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(b.getWidth());
+ tb.setY(b.getHeight());
+ tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
+ return tb.create();
+ }
+
+ /**
+ * Creates an Allocation from a {@link android.graphics.Bitmap}.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param b Bitmap source for the allocation data
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return Allocation containing bitmap data
+ *
+ */
+ static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mips,
+ int usage) {
+ rs.validate();
+
+ // WAR undocumented color formats
+ if (b.getConfig() == null) {
+ if ((usage & USAGE_SHARED) != 0) {
+ throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
+ }
+ Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(newBitmap);
+ c.drawBitmap(b, 0, 0, null);
+ return createFromBitmap(rs, newBitmap, mips, usage);
+ }
+
+ Type t = typeFromBitmap(rs, b, mips);
+
+ // enable optimized bitmap path only with no mipmap and script-only usage
+ if (mips == MipmapControl.MIPMAP_NONE &&
+ t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
+ usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
+ long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
+ if (id == 0) {
+ throw new RSRuntimeException("Load failed.");
+ }
+
+ // keep a reference to the Bitmap around to prevent GC
+ Allocation alloc = new Allocation(id, rs, t, usage);
+ alloc.setBitmap(b);
+ return alloc;
+ }
+
+
+ long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+ if (id == 0) {
+ throw new RSRuntimeException("Load failed.");
+ }
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Associate a {@link android.view.Surface} with this Allocation. This
+ * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
+ *
+ * @param sur Surface to associate with allocation
+ */
+ public void setSurface(Surface sur) {
+ mRS.validate();
+ if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+ throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
+ }
+
+ mRS.nAllocationSetSurface(getID(mRS), sur);
+ }
+
+ /**
+ * Creates an Allocation from a {@link android.graphics.Bitmap}.
+ *
+ * <p>This Allocation will be created with {@link #USAGE_SHARED}, and
+ * {@link #USAGE_SCRIPT}.</p>
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param b bitmap source for the allocation data
+ *
+ * @return Allocation containing bitmap data
+ *
+ */
+ static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
+ return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+ USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
+ * containing the horizontal list of cube faces. Each face must be a square,
+ * have the same size as all other faces, and have a width that is a power
+ * of 2.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param b Bitmap with cubemap faces layed out in the following
+ * format: right, left, top, bottom, front, back
+ * @param mips specifies desired mipmap behaviour for the cubemap
+ * @param usage bit field specifying how the cubemap is utilized
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mips,
+ int usage) {
+ rs.validate();
+
+ int height = b.getHeight();
+ int width = b.getWidth();
+
+ if (width % 6 != 0) {
+ throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
+ }
+ if (width / 6 != height) {
+ throw new RSIllegalArgumentException("Only square cube map faces supported");
+ }
+ boolean isPow2 = (height & (height - 1)) == 0;
+ if (!isPow2) {
+ throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+ }
+
+ Element e = elementFromBitmap(rs, b);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(height);
+ tb.setY(height);
+ tb.setFaces(true);
+ tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+ Type t = tb.create();
+
+ long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+ if(id == 0) {
+ throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
+ }
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
+ * from a {@link android.graphics.Bitmap} containing the horizontal list of
+ * cube faces. Each face must be a square, have the same size as all other
+ * faces, and have a width that is a power of 2.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param b bitmap with cubemap faces layed out in the following
+ * format: right, left, top, bottom, front, back
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromBitmap(RenderScript rs,
+ Bitmap b) {
+ return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
+ * objects containing the cube faces. Each face must be a square, have the
+ * same size as all other faces, and have a width that is a power of 2.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param xpos cubemap face in the positive x direction
+ * @param xneg cubemap face in the negative x direction
+ * @param ypos cubemap face in the positive y direction
+ * @param yneg cubemap face in the negative y direction
+ * @param zpos cubemap face in the positive z direction
+ * @param zneg cubemap face in the negative z direction
+ * @param mips specifies desired mipmap behaviour for the cubemap
+ * @param usage bit field specifying how the cubemap is utilized
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+ Bitmap xpos,
+ Bitmap xneg,
+ Bitmap ypos,
+ Bitmap yneg,
+ Bitmap zpos,
+ Bitmap zneg,
+ MipmapControl mips,
+ int usage) {
+ /*
+ int height = xpos.getHeight();
+ if (xpos.getWidth() != height ||
+ xneg.getWidth() != height || xneg.getHeight() != height ||
+ ypos.getWidth() != height || ypos.getHeight() != height ||
+ yneg.getWidth() != height || yneg.getHeight() != height ||
+ zpos.getWidth() != height || zpos.getHeight() != height ||
+ zneg.getWidth() != height || zneg.getHeight() != height) {
+ throw new RSIllegalArgumentException("Only square cube map faces supported");
+ }
+ boolean isPow2 = (height & (height - 1)) == 0;
+ if (!isPow2) {
+ throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+ }
+
+ Element e = elementFromBitmap(rs, xpos);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(height);
+ tb.setY(height);
+ tb.setFaces(true);
+ tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+ Type t = tb.create();
+ Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
+
+ AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
+ adapter.setFace(Type.CubemapFace.POSITIVE_X);
+ adapter.copyFrom(xpos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_X);
+ adapter.copyFrom(xneg);
+ adapter.setFace(Type.CubemapFace.POSITIVE_Y);
+ adapter.copyFrom(ypos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
+ adapter.copyFrom(yneg);
+ adapter.setFace(Type.CubemapFace.POSITIVE_Z);
+ adapter.copyFrom(zpos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
+ adapter.copyFrom(zneg);
+
+ return cubemap;
+ */
+ return null;
+ }
+
+ /**
+ * Creates a non-mipmapped cubemap Allocation for use as a sampler input
+ * from 6 {@link android.graphics.Bitmap} objects containing the cube
+ * faces. Each face must be a square, have the same size as all other faces,
+ * and have a width that is a power of 2.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param xpos cubemap face in the positive x direction
+ * @param xneg cubemap face in the negative x direction
+ * @param ypos cubemap face in the positive y direction
+ * @param yneg cubemap face in the negative y direction
+ * @param zpos cubemap face in the positive z direction
+ * @param zneg cubemap face in the negative z direction
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+ Bitmap xpos,
+ Bitmap xneg,
+ Bitmap ypos,
+ Bitmap yneg,
+ Bitmap zpos,
+ Bitmap zneg) {
+ return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
+ zpos, zneg, MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates an Allocation from the Bitmap referenced
+ * by resource ID.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param res application resources
+ * @param id resource id to load the data from
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return Allocation containing resource data
+ *
+ */
+ static public Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id,
+ MipmapControl mips,
+ int usage) {
+
+ rs.validate();
+ if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
+ throw new RSIllegalArgumentException("Unsupported usage specified.");
+ }
+ Bitmap b = BitmapFactory.decodeResource(res, id);
+ Allocation alloc = createFromBitmap(rs, b, mips, usage);
+ b.recycle();
+ return alloc;
+ }
+
+ /**
+ * Creates a non-mipmapped Allocation to use as a graphics texture from the
+ * {@link android.graphics.Bitmap} referenced by resource ID.
+ *
+ * <p>This allocation will be created with {@link #USAGE_SCRIPT} and
+ * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param res application resources
+ * @param id resource id to load the data from
+ *
+ * @return Allocation containing resource data
+ *
+ */
+ static public Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id) {
+ return createFromBitmapResource(rs, res, id,
+ MipmapControl.MIPMAP_NONE,
+ USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates an Allocation containing string data encoded in UTF-8 format.
+ *
+ * @param rs Context to which the allocation will belong.
+ * @param str string to create the allocation from
+ * @param usage bit field specifying how the allocaiton is
+ * utilized
+ *
+ */
+ static public Allocation createFromString(RenderScript rs,
+ String str,
+ int usage) {
+ rs.validate();
+ byte[] allocArray = null;
+ try {
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
+ alloc.copyFrom(allocArray);
+ return alloc;
+ }
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
+ }
+ }
+
+ /**
+ * Frees any native resources associated with this object. The
+ * primary use is to force immediate cleanup of resources when it is
+ * believed the GC will not respond quickly enough.
+ * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
+ */
+ @Override
+ public void destroy() {
+ if (mIncCompatAllocation != 0) {
+ boolean shouldDestroy = false;
+ synchronized(this) {
+ if (!mIncAllocDestroyed) {
+ shouldDestroy = true;
+ mIncAllocDestroyed = true;
+ }
+ }
+
+ if (shouldDestroy) {
+ // must include nObjDestroy in the critical section
+ ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+ rlock.lock();
+ if(mRS.isAlive()) {
+ mRS.nIncObjDestroy(mIncCompatAllocation);
+ }
+ rlock.unlock();
+ mIncCompatAllocation = 0;
+ }
+ }
+ if ((mUsage & (USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
+ setSurface(null);
+ }
+ super.destroy();
+ }
+
+}
diff --git a/androidx/renderscript/BaseObj.java b/androidx/renderscript/BaseObj.java
new file mode 100644
index 0000000..eda0066
--- /dev/null
+++ b/androidx/renderscript/BaseObj.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * BaseObj is the base class for all RenderScript objects owned by a RS context.
+ * It is responsible for lifetime management and resource tracking. This class
+ * should not be used by a user application.
+ *
+ **/
+public class BaseObj {
+ BaseObj(long id, RenderScript rs) {
+ rs.validate();
+ mRS = rs;
+ mID = id;
+ mDestroyed = false;
+ }
+
+ void setID(long id) {
+ if (mID != 0) {
+ throw new RSRuntimeException("Internal Error, reset of object ID.");
+ }
+ mID = id;
+ }
+
+ /**
+ * Lookup the native object ID for this object. Primarily used by the
+ * generated reflected code.
+ *
+ * @param rs Context to verify against internal context for
+ * match.
+ *
+ * @return long
+ */
+ long getID(RenderScript rs) {
+ mRS.validate();
+ if (mDestroyed) {
+ throw new RSInvalidStateException("using a destroyed object.");
+ }
+ if (mID == 0) {
+ throw new RSRuntimeException("Internal error: Object id 0.");
+ }
+ if ((rs != null) && (rs != mRS)) {
+ throw new RSInvalidStateException("using object with mismatched context.");
+ }
+ return mID;
+ }
+
+ android.renderscript.BaseObj getNObj() {
+ return null;
+ }
+
+ void checkValid() {
+ if ((mID == 0) && (getNObj() == null)) {
+ throw new RSIllegalArgumentException("Invalid object.");
+ }
+ }
+
+ private long mID;
+ private boolean mDestroyed;
+ RenderScript mRS;
+
+ private void helpDestroy() {
+ boolean shouldDestroy = false;
+ synchronized(this) {
+ if (!mDestroyed) {
+ shouldDestroy = true;
+ mDestroyed = true;
+ }
+ }
+
+ if (shouldDestroy) {
+ // must include nObjDestroy in the critical section
+ ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+ rlock.lock();
+ if(mRS.isAlive()) {
+ mRS.nObjDestroy(mID);
+ }
+ rlock.unlock();
+ mRS = null;
+ mID = 0;
+ }
+ }
+
+
+ protected void finalize() throws Throwable {
+ helpDestroy();
+ super.finalize();
+ }
+
+ /**
+ * Frees any native resources associated with this object. The
+ * primary use is to force immediate cleanup of resources when it is
+ * believed the GC will not respond quickly enough.
+ */
+ public void destroy() {
+ if(mDestroyed) {
+ throw new RSInvalidStateException("Object already destroyed.");
+ }
+ helpDestroy();
+ }
+
+ /**
+ * Calculates the hash code value for a BaseObj.
+ *
+ * @return int
+ */
+ @Override
+ public int hashCode() {
+ return (int)((mID & 0xfffffff) ^ (mID >> 32));
+ }
+
+ /**
+ * Compare the current BaseObj with another BaseObj for equality.
+ *
+ * @param obj The object to check equality with.
+ *
+ * @return boolean
+ */
+ @Override
+ public boolean equals(Object obj) {
+ // Early-out check to see if both BaseObjs are actually the same
+ if (this == obj)
+ return true;
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ BaseObj b = (BaseObj) obj;
+ return mID == b.mID;
+ }
+}
+
diff --git a/androidx/renderscript/Byte2.java b/androidx/renderscript/Byte2.java
new file mode 100644
index 0000000..cf738f4
--- /dev/null
+++ b/androidx/renderscript/Byte2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte2 type back to the Android system.
+ *
+ **/
+public class Byte2 {
+ public Byte2() {
+ }
+
+ public Byte2(byte initX, byte initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public byte x;
+ public byte y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Byte3.java b/androidx/renderscript/Byte3.java
new file mode 100644
index 0000000..559e34a
--- /dev/null
+++ b/androidx/renderscript/Byte3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte3 type back to the Android system.
+ *
+ **/
+public class Byte3 {
+ public Byte3() {
+ }
+
+ public Byte3(byte initX, byte initY, byte initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public byte x;
+ public byte y;
+ public byte z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Byte4.java b/androidx/renderscript/Byte4.java
new file mode 100644
index 0000000..0a71e63
--- /dev/null
+++ b/androidx/renderscript/Byte4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte4 type back to the Android system.
+ *
+ **/
+public class Byte4 {
+ public Byte4() {
+ }
+
+ public Byte4(byte initX, byte initY, byte initZ, byte initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public byte x;
+ public byte y;
+ public byte z;
+ public byte w;
+}
+
+
+
diff --git a/androidx/renderscript/Double2.java b/androidx/renderscript/Double2.java
new file mode 100644
index 0000000..9abcd01
--- /dev/null
+++ b/androidx/renderscript/Double2.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double2 type back
+ * to the Android system.
+ *
+ **/
+public class Double2 {
+ public Double2() {
+ }
+
+ public Double2(double initX, double initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public double x;
+ public double y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Double3.java b/androidx/renderscript/Double3.java
new file mode 100644
index 0000000..0d07a50
--- /dev/null
+++ b/androidx/renderscript/Double3.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double3 type back
+ * to the Android system.
+ *
+ **/
+public class Double3 {
+ public Double3() {
+ }
+
+ public Double3(double initX, double initY, double initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public double x;
+ public double y;
+ public double z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Double4.java b/androidx/renderscript/Double4.java
new file mode 100644
index 0000000..3350abf
--- /dev/null
+++ b/androidx/renderscript/Double4.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double4 type back
+ * to the Android system.
+ *
+ **/
+public class Double4 {
+ public Double4() {
+ }
+
+ public Double4(double initX, double initY, double initZ, double initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public double x;
+ public double y;
+ public double z;
+ public double w;
+}
+
+
+
diff --git a/androidx/renderscript/Element.java b/androidx/renderscript/Element.java
new file mode 100644
index 0000000..44dbc61
--- /dev/null
+++ b/androidx/renderscript/Element.java
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.reflect.Field;
+
+import android.util.Log;
+
+/**
+ * <p>An Element represents one item within an {@link
+ * androidx.renderscript.Allocation}. An Element is roughly
+ * equivalent to a C type in a RenderScript kernel. Elements may be basic or
+ * complex. Some basic elements are</p> <ul> <li>A single float value
+ * (equivalent to a float in a kernel)</li> <li>A four-element float vector
+ * (equivalent to a float4 in a kernel)</li> <li>An unsigned 32-bit integer
+ * (equivalent to an unsigned int in a kernel)</li> <li>A single signed 8-bit
+ * integer (equivalent to a char in a kernel)</li> </ul> <p>A complex element is
+ * roughly equivalent to a C struct and contains a number of basic or complex
+ * Elements. From Java code, a complex element contains a list of sub-elements
+ * and names that represents a particular data structure. Structs used in RS
+ * scripts are available to Java code by using the
+ * {@code ScriptField_structname} class that is reflected from a particular
+ * script.</p>
+ *
+ * <p>Basic Elements are comprised of a {@link
+ * androidx.renderscript.Element.DataType} and a {@link
+ * androidx.renderscript.Element.DataKind}. The DataType encodes C
+ * type information of an Element, while the DataKind encodes how that Element
+ * should be interpreted by a {@link androidx.renderscript.Sampler}.
+ * Note that {@link androidx.renderscript.Allocation} objects with
+ * DataKind {@link androidx.renderscript.Element.DataKind#USER} cannot
+ * be used as input for a {@link androidx.renderscript.Sampler}. In
+ * general, {@link androidx.renderscript.Allocation} objects that are
+ * intended for use with a {@link androidx.renderscript.Sampler}
+ * should use bitmap-derived Elements such as
+ * {@link androidx.renderscript.Element#RGBA_8888} or {@link
+ * androidx.renderscript#Element.A_8}.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript,
+ * read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Element extends BaseObj {
+ int mSize;
+ Element[] mElements;
+ String[] mElementNames;
+ int[] mArraySizes;
+ int[] mOffsetInBytes;
+ int[] mVisibleElementMap;
+
+ DataType mType;
+ DataKind mKind;
+ boolean mNormalized;
+ int mVectorSize;
+
+ private void updateVisibleSubElements() {
+ if (mElements == null) {
+ return;
+ }
+
+ int noPaddingFieldCount = 0;
+ int fieldCount = mElementNames.length;
+ // Find out how many elements are not padding
+ for (int ct = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].charAt(0) != '#') {
+ noPaddingFieldCount ++;
+ }
+ }
+ mVisibleElementMap = new int[noPaddingFieldCount];
+
+ // Make a map that points us at non-padding elements
+ for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].charAt(0) != '#') {
+ mVisibleElementMap[ctNoPadding ++] = ct;
+ }
+ }
+ }
+
+ /**
+ * @return element size in bytes
+ */
+ public int getBytesSize() {
+ return mSize;
+ }
+
+ /**
+ * Returns the number of vector components. 2 for float2, 4 for
+ * float4, etc.
+ * @return element vector size
+ */
+ public int getVectorSize() {
+ return mVectorSize;
+ }
+
+
+ /**
+ * DataType represents the basic type information for a basic element. The
+ * naming convention follows. For numeric types it is FLOAT,
+ * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
+ * size of the data. BOOLEAN is a true / false (1,0)
+ * represented in an 8 bit container. The UNSIGNED variants
+ * with multiple bit definitions are for packed graphical data
+ * formats and represent vectors with per vector member sizes
+ * which are treated as a single unit for packing and alignment
+ * purposes.
+ *
+ * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+ * as 32 bits for alignment purposes.
+ *
+ * RS_* objects. 32 bit opaque handles.
+ */
+ public enum DataType {
+ NONE (0, 0),
+ //FLOAT_16 (1, 2),
+ FLOAT_32 (2, 4),
+ FLOAT_64 (3, 8),
+ SIGNED_8 (4, 1),
+ SIGNED_16 (5, 2),
+ SIGNED_32 (6, 4),
+ SIGNED_64 (7, 8),
+ UNSIGNED_8 (8, 1),
+ UNSIGNED_16 (9, 2),
+ UNSIGNED_32 (10, 4),
+ UNSIGNED_64 (11, 8),
+
+ BOOLEAN(12, 1),
+
+ UNSIGNED_5_6_5 (13, 2),
+ UNSIGNED_5_5_5_1 (14, 2),
+ UNSIGNED_4_4_4_4 (15, 2),
+
+ MATRIX_4X4 (16, 64),
+ MATRIX_3X3 (17, 36),
+ MATRIX_2X2 (18, 16),
+
+ RS_ELEMENT (1000),
+ RS_TYPE (1001),
+ RS_ALLOCATION (1002),
+ RS_SAMPLER (1003),
+ RS_SCRIPT (1004);
+
+ int mID;
+ int mSize;
+ DataType(int id, int size) {
+ mID = id;
+ mSize = size;
+ }
+
+ DataType(int id) {
+ mID = id;
+ mSize = 4;
+ if (RenderScript.sPointerSize == 8) {
+ mSize = 32;
+ }
+ }
+ }
+
+ /**
+ * The special interpretation of the data if required. This is primarly
+ * useful for graphical data. USER indicates no special interpretation is
+ * expected. PIXEL is used in conjunction with the standard data types for
+ * representing texture formats.
+ */
+ public enum DataKind {
+ USER (0),
+
+ PIXEL_L (7),
+ PIXEL_A (8),
+ PIXEL_LA (9),
+ PIXEL_RGB (10),
+ PIXEL_RGBA (11),
+ PIXEL_DEPTH (12),
+ PIXEL_YUV(13);
+
+ int mID;
+ DataKind(int id) {
+ mID = id;
+ }
+ }
+
+ /**
+ * Return if a element is too complex for use as a data source for a Mesh or
+ * a Program.
+ *
+ * @return boolean
+ */
+ public boolean isComplex() {
+ if (mElements == null) {
+ return false;
+ }
+ for (int ct=0; ct < mElements.length; ct++) {
+ if (mElements[ct].mElements != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Elements could be simple, such as an int or a float, or a
+ * structure with multiple sub elements, such as a collection of
+ * floats, float2, float4. This function returns zero for simple
+ * elements or the number of sub-elements otherwise.
+ * @return number of sub-elements in this element
+ */
+ public int getSubElementCount() {
+ if (mVisibleElementMap == null) {
+ return 0;
+ }
+ return mVisibleElementMap.length;
+ }
+
+ /**
+ * For complex elements, this function will return the
+ * sub-element at index
+ * @param index index of the sub-element to return
+ * @return sub-element in this element at given index
+ */
+ public Element getSubElement(int index) {
+ if (mVisibleElementMap == null) {
+ throw new RSIllegalArgumentException("Element contains no sub-elements");
+ }
+ if (index < 0 || index >= mVisibleElementMap.length) {
+ throw new RSIllegalArgumentException("Illegal sub-element index");
+ }
+ return mElements[mVisibleElementMap[index]];
+ }
+
+ /**
+ * For complex elements, this function will return the
+ * sub-element name at index
+ * @param index index of the sub-element
+ * @return sub-element in this element at given index
+ */
+ public String getSubElementName(int index) {
+ if (mVisibleElementMap == null) {
+ throw new RSIllegalArgumentException("Element contains no sub-elements");
+ }
+ if (index < 0 || index >= mVisibleElementMap.length) {
+ throw new RSIllegalArgumentException("Illegal sub-element index");
+ }
+ return mElementNames[mVisibleElementMap[index]];
+ }
+
+ /**
+ * For complex elements, some sub-elements could be statically
+ * sized arrays. This function will return the array size for
+ * sub-element at index
+ * @param index index of the sub-element
+ * @return array size of sub-element in this element at given index
+ */
+ public int getSubElementArraySize(int index) {
+ if (mVisibleElementMap == null) {
+ throw new RSIllegalArgumentException("Element contains no sub-elements");
+ }
+ if (index < 0 || index >= mVisibleElementMap.length) {
+ throw new RSIllegalArgumentException("Illegal sub-element index");
+ }
+ return mArraySizes[mVisibleElementMap[index]];
+ }
+
+ /**
+ * This function specifies the location of a sub-element within
+ * the element
+ * @param index index of the sub-element
+ * @return offset in bytes of sub-element in this element at given index
+ */
+ public int getSubElementOffsetBytes(int index) {
+ if (mVisibleElementMap == null) {
+ throw new RSIllegalArgumentException("Element contains no sub-elements");
+ }
+ if (index < 0 || index >= mVisibleElementMap.length) {
+ throw new RSIllegalArgumentException("Illegal sub-element index");
+ }
+ return mOffsetInBytes[mVisibleElementMap[index]];
+ }
+
+ /**
+ * @return element data type
+ */
+ public DataType getDataType() {
+ return mType;
+ }
+
+ /**
+ * @return element data kind
+ */
+ public DataKind getDataKind() {
+ return mKind;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single Boolean.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ public static Element BOOLEAN(RenderScript rs) {
+ if(rs.mElement_BOOLEAN == null) {
+ rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
+ }
+ return rs.mElement_BOOLEAN;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single UNSIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ public static Element U8(RenderScript rs) {
+ if(rs.mElement_U8 == null) {
+ rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
+ }
+ return rs.mElement_U8;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single SIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ public static Element I8(RenderScript rs) {
+ if(rs.mElement_I8 == null) {
+ rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
+ }
+ return rs.mElement_I8;
+ }
+
+ public static Element U16(RenderScript rs) {
+ if(rs.mElement_U16 == null) {
+ rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
+ }
+ return rs.mElement_U16;
+ }
+
+ public static Element I16(RenderScript rs) {
+ if(rs.mElement_I16 == null) {
+ rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
+ }
+ return rs.mElement_I16;
+ }
+
+ public static Element U32(RenderScript rs) {
+ if(rs.mElement_U32 == null) {
+ rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
+ }
+ return rs.mElement_U32;
+ }
+
+ public static Element I32(RenderScript rs) {
+ if(rs.mElement_I32 == null) {
+ rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
+ }
+ return rs.mElement_I32;
+ }
+
+ public static Element U64(RenderScript rs) {
+ if(rs.mElement_U64 == null) {
+ rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
+ }
+ return rs.mElement_U64;
+ }
+
+ public static Element I64(RenderScript rs) {
+ if(rs.mElement_I64 == null) {
+ rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
+ }
+ return rs.mElement_I64;
+ }
+
+ public static Element F32(RenderScript rs) {
+ if(rs.mElement_F32 == null) {
+ rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
+ }
+ return rs.mElement_F32;
+ }
+
+ public static Element F64(RenderScript rs) {
+ if(rs.mElement_F64 == null) {
+ rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
+ }
+ return rs.mElement_F64;
+ }
+
+ public static Element ELEMENT(RenderScript rs) {
+ if(rs.mElement_ELEMENT == null) {
+ rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
+ }
+ return rs.mElement_ELEMENT;
+ }
+
+ public static Element TYPE(RenderScript rs) {
+ if(rs.mElement_TYPE == null) {
+ rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
+ }
+ return rs.mElement_TYPE;
+ }
+
+ public static Element ALLOCATION(RenderScript rs) {
+ if(rs.mElement_ALLOCATION == null) {
+ rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
+ }
+ return rs.mElement_ALLOCATION;
+ }
+
+ public static Element SAMPLER(RenderScript rs) {
+ if(rs.mElement_SAMPLER == null) {
+ rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
+ }
+ return rs.mElement_SAMPLER;
+ }
+
+ public static Element SCRIPT(RenderScript rs) {
+ if(rs.mElement_SCRIPT == null) {
+ rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
+ }
+ return rs.mElement_SCRIPT;
+ }
+
+
+ public static Element A_8(RenderScript rs) {
+ if(rs.mElement_A_8 == null) {
+ rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
+ }
+ return rs.mElement_A_8;
+ }
+
+ public static Element RGB_565(RenderScript rs) {
+ if(rs.mElement_RGB_565 == null) {
+ rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
+ }
+ return rs.mElement_RGB_565;
+ }
+
+ public static Element RGB_888(RenderScript rs) {
+ if(rs.mElement_RGB_888 == null) {
+ rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
+ }
+ return rs.mElement_RGB_888;
+ }
+
+ public static Element RGBA_5551(RenderScript rs) {
+ if(rs.mElement_RGBA_5551 == null) {
+ rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
+ }
+ return rs.mElement_RGBA_5551;
+ }
+
+ public static Element RGBA_4444(RenderScript rs) {
+ if(rs.mElement_RGBA_4444 == null) {
+ rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
+ }
+ return rs.mElement_RGBA_4444;
+ }
+
+ public static Element RGBA_8888(RenderScript rs) {
+ if(rs.mElement_RGBA_8888 == null) {
+ rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
+ }
+ return rs.mElement_RGBA_8888;
+ }
+
+ public static Element F32_2(RenderScript rs) {
+ if(rs.mElement_FLOAT_2 == null) {
+ rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
+ }
+ return rs.mElement_FLOAT_2;
+ }
+
+ public static Element F32_3(RenderScript rs) {
+ if(rs.mElement_FLOAT_3 == null) {
+ rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
+ }
+ return rs.mElement_FLOAT_3;
+ }
+
+ public static Element F32_4(RenderScript rs) {
+ if(rs.mElement_FLOAT_4 == null) {
+ rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
+ }
+ return rs.mElement_FLOAT_4;
+ }
+
+ public static Element F64_2(RenderScript rs) {
+ if(rs.mElement_DOUBLE_2 == null) {
+ rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
+ }
+ return rs.mElement_DOUBLE_2;
+ }
+
+ public static Element F64_3(RenderScript rs) {
+ if(rs.mElement_DOUBLE_3 == null) {
+ rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
+ }
+ return rs.mElement_DOUBLE_3;
+ }
+
+ public static Element F64_4(RenderScript rs) {
+ if(rs.mElement_DOUBLE_4 == null) {
+ rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
+ }
+ return rs.mElement_DOUBLE_4;
+ }
+
+ public static Element U8_2(RenderScript rs) {
+ if(rs.mElement_UCHAR_2 == null) {
+ rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
+ }
+ return rs.mElement_UCHAR_2;
+ }
+
+ public static Element U8_3(RenderScript rs) {
+ if(rs.mElement_UCHAR_3 == null) {
+ rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
+ }
+ return rs.mElement_UCHAR_3;
+ }
+
+ public static Element U8_4(RenderScript rs) {
+ if(rs.mElement_UCHAR_4 == null) {
+ rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
+ }
+ return rs.mElement_UCHAR_4;
+ }
+
+ public static Element I8_2(RenderScript rs) {
+ if(rs.mElement_CHAR_2 == null) {
+ rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
+ }
+ return rs.mElement_CHAR_2;
+ }
+
+ public static Element I8_3(RenderScript rs) {
+ if(rs.mElement_CHAR_3 == null) {
+ rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
+ }
+ return rs.mElement_CHAR_3;
+ }
+
+ public static Element I8_4(RenderScript rs) {
+ if(rs.mElement_CHAR_4 == null) {
+ rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
+ }
+ return rs.mElement_CHAR_4;
+ }
+
+ public static Element U16_2(RenderScript rs) {
+ if(rs.mElement_USHORT_2 == null) {
+ rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
+ }
+ return rs.mElement_USHORT_2;
+ }
+
+ public static Element U16_3(RenderScript rs) {
+ if(rs.mElement_USHORT_3 == null) {
+ rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
+ }
+ return rs.mElement_USHORT_3;
+ }
+
+ public static Element U16_4(RenderScript rs) {
+ if(rs.mElement_USHORT_4 == null) {
+ rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
+ }
+ return rs.mElement_USHORT_4;
+ }
+
+ public static Element I16_2(RenderScript rs) {
+ if(rs.mElement_SHORT_2 == null) {
+ rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
+ }
+ return rs.mElement_SHORT_2;
+ }
+
+ public static Element I16_3(RenderScript rs) {
+ if(rs.mElement_SHORT_3 == null) {
+ rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
+ }
+ return rs.mElement_SHORT_3;
+ }
+
+ public static Element I16_4(RenderScript rs) {
+ if(rs.mElement_SHORT_4 == null) {
+ rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
+ }
+ return rs.mElement_SHORT_4;
+ }
+
+ public static Element U32_2(RenderScript rs) {
+ if(rs.mElement_UINT_2 == null) {
+ rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
+ }
+ return rs.mElement_UINT_2;
+ }
+
+ public static Element U32_3(RenderScript rs) {
+ if(rs.mElement_UINT_3 == null) {
+ rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
+ }
+ return rs.mElement_UINT_3;
+ }
+
+ public static Element U32_4(RenderScript rs) {
+ if(rs.mElement_UINT_4 == null) {
+ rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
+ }
+ return rs.mElement_UINT_4;
+ }
+
+ public static Element I32_2(RenderScript rs) {
+ if(rs.mElement_INT_2 == null) {
+ rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
+ }
+ return rs.mElement_INT_2;
+ }
+
+ public static Element I32_3(RenderScript rs) {
+ if(rs.mElement_INT_3 == null) {
+ rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
+ }
+ return rs.mElement_INT_3;
+ }
+
+ public static Element I32_4(RenderScript rs) {
+ if(rs.mElement_INT_4 == null) {
+ rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
+ }
+ return rs.mElement_INT_4;
+ }
+
+ public static Element U64_2(RenderScript rs) {
+ if(rs.mElement_ULONG_2 == null) {
+ rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
+ }
+ return rs.mElement_ULONG_2;
+ }
+
+ public static Element U64_3(RenderScript rs) {
+ if(rs.mElement_ULONG_3 == null) {
+ rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
+ }
+ return rs.mElement_ULONG_3;
+ }
+
+ public static Element U64_4(RenderScript rs) {
+ if(rs.mElement_ULONG_4 == null) {
+ rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
+ }
+ return rs.mElement_ULONG_4;
+ }
+
+ public static Element I64_2(RenderScript rs) {
+ if(rs.mElement_LONG_2 == null) {
+ rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
+ }
+ return rs.mElement_LONG_2;
+ }
+
+ public static Element I64_3(RenderScript rs) {
+ if(rs.mElement_LONG_3 == null) {
+ rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
+ }
+ return rs.mElement_LONG_3;
+ }
+
+ public static Element I64_4(RenderScript rs) {
+ if(rs.mElement_LONG_4 == null) {
+ rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
+ }
+ return rs.mElement_LONG_4;
+ }
+
+ public static Element MATRIX_4X4(RenderScript rs) {
+ if(rs.mElement_MATRIX_4X4 == null) {
+ rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
+ }
+ return rs.mElement_MATRIX_4X4;
+ }
+
+ public static Element MATRIX_3X3(RenderScript rs) {
+ if(rs.mElement_MATRIX_3X3 == null) {
+ rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
+ }
+ return rs.mElement_MATRIX_3X3;
+ }
+
+ public static Element MATRIX_2X2(RenderScript rs) {
+ if(rs.mElement_MATRIX_2X2 == null) {
+ rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
+ }
+ return rs.mElement_MATRIX_2X2;
+ }
+
+ Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
+ super(id, rs);
+ mSize = 0;
+ mVectorSize = 1;
+ mElements = e;
+ mElementNames = n;
+ mArraySizes = as;
+ mType = DataType.NONE;
+ mKind = DataKind.USER;
+ mOffsetInBytes = new int[mElements.length];
+ for (int ct = 0; ct < mElements.length; ct++ ) {
+ mOffsetInBytes[ct] = mSize;
+ mSize += mElements[ct].mSize * mArraySizes[ct];
+ }
+ updateVisibleSubElements();
+ }
+
+ Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
+ super(id, rs);
+ if ((dt != DataType.UNSIGNED_5_6_5) &&
+ (dt != DataType.UNSIGNED_4_4_4_4) &&
+ (dt != DataType.UNSIGNED_5_5_5_1)) {
+ if (size == 3) {
+ mSize = dt.mSize * 4;
+ } else {
+ mSize = dt.mSize * size;
+ }
+ } else {
+ mSize = dt.mSize;
+ }
+ mType = dt;
+ mKind = dk;
+ mNormalized = norm;
+ mVectorSize = size;
+ }
+
+ Element(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /*
+ * Get an identical dummy Element for Compat Context
+ *
+ */
+ public long getDummyElement(RenderScript mRS) {
+ return mRS.nIncElementCreate(mType.mID, mKind.mID, mNormalized, mVectorSize);
+ }
+ /**
+ * Create a custom Element of the specified DataType. The DataKind will be
+ * set to USER and the vector size to 1 indicating non-vector.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @return Element
+ */
+ static Element createUser(RenderScript rs, DataType dt) {
+ DataKind dk = DataKind.USER;
+ boolean norm = false;
+ int vecSize = 1;
+ long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
+ return new Element(id, rs, dt, dk, norm, vecSize);
+ }
+
+ /**
+ * Create a custom vector element of the specified DataType and vector size.
+ * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
+ * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
+ * UNSIGNED_32, UNSIGNED_64, BOOLEAN) are supported.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new Element.
+ * @param size Vector size for the new Element. Range 2-4 inclusive
+ * supported.
+ *
+ * @return Element
+ */
+ public static Element createVector(RenderScript rs, DataType dt, int size) {
+ if (size < 2 || size > 4) {
+ throw new RSIllegalArgumentException("Vector size out of range 2-4.");
+ }
+
+ switch (dt) {
+ // Support only primitive integer/float/boolean types as vectors.
+ case FLOAT_32:
+ case FLOAT_64:
+ case SIGNED_8:
+ case SIGNED_16:
+ case SIGNED_32:
+ case SIGNED_64:
+ case UNSIGNED_8:
+ case UNSIGNED_16:
+ case UNSIGNED_32:
+ case UNSIGNED_64:
+ case BOOLEAN: {
+ DataKind dk = DataKind.USER;
+ boolean norm = false;
+ long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+ return new Element(id, rs, dt, dk, norm, size);
+ }
+
+ default: {
+ throw new RSIllegalArgumentException("Cannot create vector of " +
+ "non-primitive type.");
+ }
+ }
+ }
+
+ /**
+ * Create a new pixel Element type. A matching DataType and DataKind must
+ * be provided. The DataType and DataKind must contain the same number of
+ * components. Vector size will be set to 1.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @param dk The DataKind to specify the mapping of each component in the
+ * DataType.
+ *
+ * @return Element
+ */
+ public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
+ if (!(dk == DataKind.PIXEL_L ||
+ dk == DataKind.PIXEL_A ||
+ dk == DataKind.PIXEL_LA ||
+ dk == DataKind.PIXEL_RGB ||
+ dk == DataKind.PIXEL_RGBA ||
+ dk == DataKind.PIXEL_DEPTH ||
+ dk == DataKind.PIXEL_YUV)) {
+ throw new RSIllegalArgumentException("Unsupported DataKind");
+ }
+ if (!(dt == DataType.UNSIGNED_8 ||
+ dt == DataType.UNSIGNED_16 ||
+ dt == DataType.UNSIGNED_5_6_5 ||
+ dt == DataType.UNSIGNED_4_4_4_4 ||
+ dt == DataType.UNSIGNED_5_5_5_1)) {
+ throw new RSIllegalArgumentException("Unsupported DataType");
+ }
+ if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
+ throw new RSIllegalArgumentException("Bad kind and type combo");
+ }
+ if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
+ throw new RSIllegalArgumentException("Bad kind and type combo");
+ }
+ if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
+ throw new RSIllegalArgumentException("Bad kind and type combo");
+ }
+ if (dt == DataType.UNSIGNED_16 &&
+ dk != DataKind.PIXEL_DEPTH) {
+ throw new RSIllegalArgumentException("Bad kind and type combo");
+ }
+
+ int size = 1;
+ switch (dk) {
+ case PIXEL_LA:
+ size = 2;
+ break;
+ case PIXEL_RGB:
+ size = 3;
+ break;
+ case PIXEL_RGBA:
+ size = 4;
+ break;
+ }
+
+ boolean norm = true;
+ long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+ return new Element(id, rs, dt, dk, norm, size);
+ }
+
+ /**
+ * Check if the current Element is compatible with another Element.
+ * Primitive Elements are compatible if they share the same underlying
+ * size and type (i.e. U8 is compatible with A_8). User-defined Elements
+ * must be equal in order to be compatible. This requires strict name
+ * equivalence for all sub-Elements (in addition to structural equivalence).
+ *
+ * @param e The Element to check compatibility with.
+ *
+ * @return boolean true if the Elements are compatible, otherwise false.
+ */
+ public boolean isCompatible(Element e) {
+ // Try strict BaseObj equality to start with.
+ if (this.equals(e)) {
+ return true;
+ }
+
+ // Ignore mKind because it is allowed to be different (user vs. pixel).
+ // We also ignore mNormalized because it can be different. The mType
+ // field must not be NONE since we require name equivalence for
+ // all user-created Elements.
+ return ((mSize == e.mSize) &&
+ (mType != DataType.NONE) &&
+ (mType == e.mType) &&
+ (mVectorSize == e.mVectorSize));
+ }
+
+ /**
+ * Builder class for producing complex elements with matching field and name
+ * pairs. The builder starts empty. The order in which elements are added
+ * is retained for the layout in memory.
+ *
+ */
+ public static class Builder {
+
+ RenderScript mRS;
+ Element[] mElements;
+ String[] mElementNames;
+ int[] mArraySizes;
+ int mCount;
+ int mSkipPadding;
+
+ /**
+ * Create a builder object.
+ *
+ * @param rs
+ */
+ public Builder(RenderScript rs) {
+ mRS = rs;
+ mCount = 0;
+ mElements = new Element[8];
+ mElementNames = new String[8];
+ mArraySizes = new int[8];
+ }
+
+ /**
+ * Add an array of elements to this element.
+ *
+ * @param element
+ * @param name
+ * @param arraySize
+ */
+ public Builder add(Element element, String name, int arraySize) {
+ if (arraySize < 1) {
+ throw new RSIllegalArgumentException("Array size cannot be less than 1.");
+ }
+
+ // Skip padding fields after a vector 3 type.
+ if (mSkipPadding != 0) {
+ if (name.startsWith("#padding_")) {
+ mSkipPadding = 0;
+ return this;
+ }
+ }
+
+ if (element.mVectorSize == 3) {
+ mSkipPadding = 1;
+ } else {
+ mSkipPadding = 0;
+ }
+
+ if(mCount == mElements.length) {
+ Element[] e = new Element[mCount + 8];
+ String[] s = new String[mCount + 8];
+ int[] as = new int[mCount + 8];
+ System.arraycopy(mElements, 0, e, 0, mCount);
+ System.arraycopy(mElementNames, 0, s, 0, mCount);
+ System.arraycopy(mArraySizes, 0, as, 0, mCount);
+ mElements = e;
+ mElementNames = s;
+ mArraySizes = as;
+ }
+ mElements[mCount] = element;
+ mElementNames[mCount] = name;
+ mArraySizes[mCount] = arraySize;
+ mCount++;
+
+ return this;
+ }
+
+ /**
+ * Add a single element to this Element.
+ *
+ * @param element
+ * @param name
+ */
+ public Builder add(Element element, String name) {
+ return add(element, name, 1);
+ }
+
+ /**
+ * Create the element from this builder.
+ *
+ *
+ * @return Element
+ */
+ public Element create() {
+ mRS.validate();
+ Element[] ein = new Element[mCount];
+ String[] sin = new String[mCount];
+ int[] asin = new int[mCount];
+ java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
+ java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
+ java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
+
+ long[] ids = new long[ein.length];
+ for (int ct = 0; ct < ein.length; ct++ ) {
+ ids[ct] = ein[ct].getID(mRS);
+ }
+
+ long id = mRS.nElementCreate2(ids, sin, asin);
+ return new Element(id, mRS, ein, sin, asin);
+ }
+ }
+}
+
diff --git a/androidx/renderscript/FieldPacker.java b/androidx/renderscript/FieldPacker.java
new file mode 100644
index 0000000..34e9ae6
--- /dev/null
+++ b/androidx/renderscript/FieldPacker.java
@@ -0,0 +1,946 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import androidx.renderscript.RenderScript;
+import java.util.BitSet;
+
+/**
+ * Utility class for packing arguments and structures from Android system objects to
+ * RenderScript objects.
+ *
+ * This class is only intended to be used to support the
+ * reflected code generated by the RS tool chain. It should not
+ * be called directly.
+ *
+ **/
+public class FieldPacker {
+ public FieldPacker(int len) {
+ mPos = 0;
+ mLen = len;
+ mData = new byte[len];
+ mAlignment = new BitSet();
+ }
+
+ public FieldPacker(byte[] data) {
+ // Advance mPos to the end of the buffer, since we are copying in the
+ // full data input.
+ mPos = data.length;
+ mLen = data.length;
+ mData = data;
+ mAlignment = new BitSet();
+ // TODO: We should either have an actual FieldPacker copy constructor
+ // or drop support for computing alignment like this. As it stands,
+ // subAlign() can never work correctly for copied FieldPacker objects.
+ }
+
+ static FieldPacker createFromArray(Object[] args) {
+ FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
+ for (Object arg : args) {
+ fp.addSafely(arg);
+ }
+ fp.resize(fp.mPos);
+ return fp;
+ }
+
+ public void align(int v) {
+ if ((v <= 0) || ((v & (v - 1)) != 0)) {
+ throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
+ }
+
+ while ((mPos & (v - 1)) != 0) {
+ mAlignment.flip(mPos);
+ mData[mPos++] = 0;
+ }
+ }
+
+ public void subalign(int v) {
+ if ((v & (v - 1)) != 0) {
+ throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
+ }
+
+ while ((mPos & (v - 1)) != 0) {
+ mPos--;
+ }
+
+ if (mPos > 0) {
+ while (mAlignment.get(mPos - 1) == true) {
+ mPos--;
+ mAlignment.flip(mPos);
+ }
+ }
+
+ }
+
+ public void reset() {
+ mPos = 0;
+ }
+ public void reset(int i) {
+ if ((i < 0) || (i > mLen)) {
+ throw new RSIllegalArgumentException("out of range argument: " + i);
+ }
+ mPos = i;
+ }
+
+ public void skip(int i) {
+ int res = mPos + i;
+ if ((res < 0) || (res > mLen)) {
+ throw new RSIllegalArgumentException("out of range argument: " + i);
+ }
+ mPos = res;
+ }
+
+ public void addI8(byte v) {
+ mData[mPos++] = v;
+ }
+
+ public byte subI8() {
+ subalign(1);
+ return mData[--mPos];
+ }
+
+ public void addI16(short v) {
+ align(2);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)(v >> 8);
+ }
+
+ public short subI16() {
+ subalign(2);
+ short v = 0;
+ v = (short)((mData[--mPos] & 0xff) << 8);
+ v = (short)(v | (short)(mData[--mPos] & 0xff));
+ return v;
+ }
+
+
+ public void addI32(int v) {
+ align(4);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)((v >> 8) & 0xff);
+ mData[mPos++] = (byte)((v >> 16) & 0xff);
+ mData[mPos++] = (byte)((v >> 24) & 0xff);
+ }
+
+ public int subI32() {
+ subalign(4);
+ int v = 0;
+ v = ((mData[--mPos] & 0xff) << 24);
+ v = v | ((mData[--mPos] & 0xff) << 16);
+ v = v | ((mData[--mPos] & 0xff) << 8);
+ v = v | ((mData[--mPos] & 0xff));
+ return v;
+ }
+
+
+ public void addI64(long v) {
+ align(8);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)((v >> 8) & 0xff);
+ mData[mPos++] = (byte)((v >> 16) & 0xff);
+ mData[mPos++] = (byte)((v >> 24) & 0xff);
+ mData[mPos++] = (byte)((v >> 32) & 0xff);
+ mData[mPos++] = (byte)((v >> 40) & 0xff);
+ mData[mPos++] = (byte)((v >> 48) & 0xff);
+ mData[mPos++] = (byte)((v >> 56) & 0xff);
+ }
+
+ public long subI64() {
+ subalign(8);
+ long v = 0;
+ byte x = 0;
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 56l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 48l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 40l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 32l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 24l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 16l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff) << 8l);
+ x = ((mData[--mPos]));
+ v = (long)(v | (((long)x) & 0xff));
+ return v;
+ }
+
+ public void addU8(short v) {
+ if ((v < 0) || (v > 0xff)) {
+ android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
+ throw new IllegalArgumentException("Saving value out of range for type");
+ }
+ mData[mPos++] = (byte)v;
+ }
+
+ public void addU16(int v) {
+ if ((v < 0) || (v > 0xffff)) {
+ android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
+ throw new IllegalArgumentException("Saving value out of range for type");
+ }
+ align(2);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)(v >> 8);
+ }
+
+ public void addU32(long v) {
+ if ((v < 0) || (v > 0xffffffffL)) {
+ android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
+ throw new IllegalArgumentException("Saving value out of range for type");
+ }
+ align(4);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)((v >> 8) & 0xff);
+ mData[mPos++] = (byte)((v >> 16) & 0xff);
+ mData[mPos++] = (byte)((v >> 24) & 0xff);
+ }
+
+ public void addU64(long v) {
+ if (v < 0) {
+ android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
+ throw new IllegalArgumentException("Saving value out of range for type");
+ }
+ align(8);
+ mData[mPos++] = (byte)(v & 0xff);
+ mData[mPos++] = (byte)((v >> 8) & 0xff);
+ mData[mPos++] = (byte)((v >> 16) & 0xff);
+ mData[mPos++] = (byte)((v >> 24) & 0xff);
+ mData[mPos++] = (byte)((v >> 32) & 0xff);
+ mData[mPos++] = (byte)((v >> 40) & 0xff);
+ mData[mPos++] = (byte)((v >> 48) & 0xff);
+ mData[mPos++] = (byte)((v >> 56) & 0xff);
+ }
+
+ public void addF32(float v) {
+ addI32(Float.floatToRawIntBits(v));
+ }
+
+ public float subF32() {
+ return Float.intBitsToFloat(subI32());
+ }
+
+ public void addF64(double v) {
+ addI64(Double.doubleToRawLongBits(v));
+ }
+
+ public double subF64() {
+ return Double.longBitsToDouble(subI64());
+ }
+
+ public void addObj(BaseObj obj) {
+ if (obj != null) {
+ if (RenderScript.sPointerSize == 8) {
+ addI64(obj.getID(null));
+ addI64(0);
+ addI64(0);
+ addI64(0);
+ } else {
+ addI32((int)obj.getID(null));
+ }
+ } else {
+ if (RenderScript.sPointerSize == 8) {
+ addI64(0);
+ addI64(0);
+ addI64(0);
+ addI64(0);
+ } else {
+ addI32(0);
+ }
+ }
+ }
+
+ public void addF32(Float2 v) {
+ addF32(v.x);
+ addF32(v.y);
+ }
+ public void addF32(Float3 v) {
+ addF32(v.x);
+ addF32(v.y);
+ addF32(v.z);
+ }
+ public void addF32(Float4 v) {
+ addF32(v.x);
+ addF32(v.y);
+ addF32(v.z);
+ addF32(v.w);
+ }
+
+ public void addF64(Double2 v) {
+ addF64(v.x);
+ addF64(v.y);
+ }
+ public void addF64(Double3 v) {
+ addF64(v.x);
+ addF64(v.y);
+ addF64(v.z);
+ }
+ public void addF64(Double4 v) {
+ addF64(v.x);
+ addF64(v.y);
+ addF64(v.z);
+ addF64(v.w);
+ }
+
+ public void addI8(Byte2 v) {
+ addI8(v.x);
+ addI8(v.y);
+ }
+ public void addI8(Byte3 v) {
+ addI8(v.x);
+ addI8(v.y);
+ addI8(v.z);
+ }
+ public void addI8(Byte4 v) {
+ addI8(v.x);
+ addI8(v.y);
+ addI8(v.z);
+ addI8(v.w);
+ }
+
+ public void addU8(Short2 v) {
+ addU8(v.x);
+ addU8(v.y);
+ }
+ public void addU8(Short3 v) {
+ addU8(v.x);
+ addU8(v.y);
+ addU8(v.z);
+ }
+ public void addU8(Short4 v) {
+ addU8(v.x);
+ addU8(v.y);
+ addU8(v.z);
+ addU8(v.w);
+ }
+
+ public void addI16(Short2 v) {
+ addI16(v.x);
+ addI16(v.y);
+ }
+ public void addI16(Short3 v) {
+ addI16(v.x);
+ addI16(v.y);
+ addI16(v.z);
+ }
+ public void addI16(Short4 v) {
+ addI16(v.x);
+ addI16(v.y);
+ addI16(v.z);
+ addI16(v.w);
+ }
+
+ public void addU16(Int2 v) {
+ addU16(v.x);
+ addU16(v.y);
+ }
+ public void addU16(Int3 v) {
+ addU16(v.x);
+ addU16(v.y);
+ addU16(v.z);
+ }
+ public void addU16(Int4 v) {
+ addU16(v.x);
+ addU16(v.y);
+ addU16(v.z);
+ addU16(v.w);
+ }
+
+ public void addI32(Int2 v) {
+ addI32(v.x);
+ addI32(v.y);
+ }
+ public void addI32(Int3 v) {
+ addI32(v.x);
+ addI32(v.y);
+ addI32(v.z);
+ }
+ public void addI32(Int4 v) {
+ addI32(v.x);
+ addI32(v.y);
+ addI32(v.z);
+ addI32(v.w);
+ }
+
+ public void addU32(Long2 v) {
+ addU32(v.x);
+ addU32(v.y);
+ }
+ public void addU32(Long3 v) {
+ addU32(v.x);
+ addU32(v.y);
+ addU32(v.z);
+ }
+ public void addU32(Long4 v) {
+ addU32(v.x);
+ addU32(v.y);
+ addU32(v.z);
+ addU32(v.w);
+ }
+
+ public void addI64(Long2 v) {
+ addI64(v.x);
+ addI64(v.y);
+ }
+ public void addI64(Long3 v) {
+ addI64(v.x);
+ addI64(v.y);
+ addI64(v.z);
+ }
+ public void addI64(Long4 v) {
+ addI64(v.x);
+ addI64(v.y);
+ addI64(v.z);
+ addI64(v.w);
+ }
+
+ public void addU64(Long2 v) {
+ addU64(v.x);
+ addU64(v.y);
+ }
+ public void addU64(Long3 v) {
+ addU64(v.x);
+ addU64(v.y);
+ addU64(v.z);
+ }
+ public void addU64(Long4 v) {
+ addU64(v.x);
+ addU64(v.y);
+ addU64(v.z);
+ addU64(v.w);
+ }
+
+
+ public Float2 subFloat2() {
+ Float2 v = new Float2();
+ v.y = subF32();
+ v.x = subF32();
+ return v;
+ }
+ public Float3 subFloat3() {
+ Float3 v = new Float3();
+ v.z = subF32();
+ v.y = subF32();
+ v.x = subF32();
+ return v;
+ }
+ public Float4 subFloat4() {
+ Float4 v = new Float4();
+ v.w = subF32();
+ v.z = subF32();
+ v.y = subF32();
+ v.x = subF32();
+ return v;
+ }
+
+ public Double2 subDouble2() {
+ Double2 v = new Double2();
+ v.y = subF64();
+ v.x = subF64();
+ return v;
+ }
+ public Double3 subDouble3() {
+ Double3 v = new Double3();
+ v.z = subF64();
+ v.y = subF64();
+ v.x = subF64();
+ return v;
+ }
+ public Double4 subDouble4() {
+ Double4 v = new Double4();
+ v.w = subF64();
+ v.z = subF64();
+ v.y = subF64();
+ v.x = subF64();
+ return v;
+ }
+
+ public Byte2 subByte2() {
+ Byte2 v = new Byte2();
+ v.y = subI8();
+ v.x = subI8();
+ return v;
+ }
+ public Byte3 subByte3() {
+ Byte3 v = new Byte3();
+ v.z = subI8();
+ v.y = subI8();
+ v.x = subI8();
+ return v;
+ }
+ public Byte4 subByte4() {
+ Byte4 v = new Byte4();
+ v.w = subI8();
+ v.z = subI8();
+ v.y = subI8();
+ v.x = subI8();
+ return v;
+ }
+
+ public Short2 subShort2() {
+ Short2 v = new Short2();
+ v.y = subI16();
+ v.x = subI16();
+ return v;
+ }
+ public Short3 subShort3() {
+ Short3 v = new Short3();
+ v.z = subI16();
+ v.y = subI16();
+ v.x = subI16();
+ return v;
+ }
+ public Short4 subShort4() {
+ Short4 v = new Short4();
+ v.w = subI16();
+ v.z = subI16();
+ v.y = subI16();
+ v.x = subI16();
+ return v;
+ }
+
+ public Int2 subInt2() {
+ Int2 v = new Int2();
+ v.y = subI32();
+ v.x = subI32();
+ return v;
+ }
+ public Int3 subInt3() {
+ Int3 v = new Int3();
+ v.z = subI32();
+ v.y = subI32();
+ v.x = subI32();
+ return v;
+ }
+ public Int4 subInt4() {
+ Int4 v = new Int4();
+ v.w = subI32();
+ v.z = subI32();
+ v.y = subI32();
+ v.x = subI32();
+ return v;
+ }
+
+ public Long2 subLong2() {
+ Long2 v = new Long2();
+ v.y = subI64();
+ v.x = subI64();
+ return v;
+ }
+ public Long3 subLong3() {
+ Long3 v = new Long3();
+ v.z = subI64();
+ v.y = subI64();
+ v.x = subI64();
+ return v;
+ }
+ public Long4 subLong4() {
+ Long4 v = new Long4();
+ v.w = subI64();
+ v.z = subI64();
+ v.y = subI64();
+ v.x = subI64();
+ return v;
+ }
+
+
+
+ public void addMatrix(Matrix4f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public Matrix4f subMatrix4f() {
+ Matrix4f v = new Matrix4f();
+ for (int i = v.mMat.length - 1; i >= 0; i--) {
+ v.mMat[i] = subF32();
+ }
+ return v;
+ }
+
+ public void addMatrix(Matrix3f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public Matrix3f subMatrix3f() {
+ Matrix3f v = new Matrix3f();
+ for (int i = v.mMat.length - 1; i >= 0; i--) {
+ v.mMat[i] = subF32();
+ }
+ return v;
+ }
+
+ public void addMatrix(Matrix2f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public Matrix2f subMatrix2f() {
+ Matrix2f v = new Matrix2f();
+ for (int i = v.mMat.length - 1; i >= 0; i--) {
+ v.mMat[i] = subF32();
+ }
+ return v;
+ }
+
+ public void addBoolean(boolean v) {
+ addI8((byte)(v ? 1 : 0));
+ }
+
+ public boolean subBoolean() {
+ byte v = subI8();
+ if (v == 1) {
+ return true;
+ }
+ return false;
+ }
+
+ public final byte[] getData() {
+ return mData;
+ }
+
+ /**
+ * Get the actual length used for the FieldPacker.
+ *
+ * @hide
+ */
+ public int getPos() {
+ return mPos;
+ }
+
+ private static void addToPack(FieldPacker fp, Object obj) {
+ if (obj instanceof Boolean) {
+ fp.addBoolean(((Boolean)obj).booleanValue());
+ return;
+ }
+
+ if (obj instanceof Byte) {
+ fp.addI8(((Byte)obj).byteValue());
+ return;
+ }
+
+ if (obj instanceof Short) {
+ fp.addI16(((Short)obj).shortValue());
+ return;
+ }
+
+ if (obj instanceof Integer) {
+ fp.addI32(((Integer)obj).intValue());
+ return;
+ }
+
+ if (obj instanceof Long) {
+ fp.addI64(((Long)obj).longValue());
+ return;
+ }
+
+ if (obj instanceof Float) {
+ fp.addF32(((Float)obj).floatValue());
+ return;
+ }
+
+ if (obj instanceof Double) {
+ fp.addF64(((Double)obj).doubleValue());
+ return;
+ }
+
+ if (obj instanceof Byte2) {
+ fp.addI8((Byte2)obj);
+ return;
+ }
+
+ if (obj instanceof Byte3) {
+ fp.addI8((Byte3)obj);
+ return;
+ }
+
+ if (obj instanceof Byte4) {
+ fp.addI8((Byte4)obj);
+ return;
+ }
+
+ if (obj instanceof Short2) {
+ fp.addI16((Short2)obj);
+ return;
+ }
+
+ if (obj instanceof Short3) {
+ fp.addI16((Short3)obj);
+ return;
+ }
+
+ if (obj instanceof Short4) {
+ fp.addI16((Short4)obj);
+ return;
+ }
+
+ if (obj instanceof Int2) {
+ fp.addI32((Int2)obj);
+ return;
+ }
+
+ if (obj instanceof Int3) {
+ fp.addI32((Int3)obj);
+ return;
+ }
+
+ if (obj instanceof Int4) {
+ fp.addI32((Int4)obj);
+ return;
+ }
+
+ if (obj instanceof Long2) {
+ fp.addI64((Long2)obj);
+ return;
+ }
+
+ if (obj instanceof Long3) {
+ fp.addI64((Long3)obj);
+ return;
+ }
+
+ if (obj instanceof Long4) {
+ fp.addI64((Long4)obj);
+ return;
+ }
+
+ if (obj instanceof Float2) {
+ fp.addF32((Float2)obj);
+ return;
+ }
+
+ if (obj instanceof Float3) {
+ fp.addF32((Float3)obj);
+ return;
+ }
+
+ if (obj instanceof Float4) {
+ fp.addF32((Float4)obj);
+ return;
+ }
+
+ if (obj instanceof Double2) {
+ fp.addF64((Double2)obj);
+ return;
+ }
+
+ if (obj instanceof Double3) {
+ fp.addF64((Double3)obj);
+ return;
+ }
+
+ if (obj instanceof Double4) {
+ fp.addF64((Double4)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix2f) {
+ fp.addMatrix((Matrix2f)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix3f) {
+ fp.addMatrix((Matrix3f)obj);
+ return;
+ }
+
+ if (obj instanceof Matrix4f) {
+ fp.addMatrix((Matrix4f)obj);
+ return;
+ }
+
+ if (obj instanceof BaseObj) {
+ fp.addObj((BaseObj)obj);
+ return;
+ }
+ }
+
+ private static int getPackedSize(Object obj) {
+ if (obj instanceof Boolean) {
+ return 1;
+ }
+
+ if (obj instanceof Byte) {
+ return 1;
+ }
+
+ if (obj instanceof Short) {
+ return 2;
+ }
+
+ if (obj instanceof Integer) {
+ return 4;
+ }
+
+ if (obj instanceof Long) {
+ return 8;
+ }
+
+ if (obj instanceof Float) {
+ return 4;
+ }
+
+ if (obj instanceof Double) {
+ return 8;
+ }
+
+ if (obj instanceof Byte2) {
+ return 2;
+ }
+
+ if (obj instanceof Byte3) {
+ return 3;
+ }
+
+ if (obj instanceof Byte4) {
+ return 4;
+ }
+
+ if (obj instanceof Short2) {
+ return 4;
+ }
+
+ if (obj instanceof Short3) {
+ return 6;
+ }
+
+ if (obj instanceof Short4) {
+ return 8;
+ }
+
+ if (obj instanceof Int2) {
+ return 8;
+ }
+
+ if (obj instanceof Int3) {
+ return 12;
+ }
+
+ if (obj instanceof Int4) {
+ return 16;
+ }
+
+ if (obj instanceof Long2) {
+ return 16;
+ }
+
+ if (obj instanceof Long3) {
+ return 24;
+ }
+
+ if (obj instanceof Long4) {
+ return 32;
+ }
+
+ if (obj instanceof Float2) {
+ return 8;
+ }
+
+ if (obj instanceof Float3) {
+ return 12;
+ }
+
+ if (obj instanceof Float4) {
+ return 16;
+ }
+
+ if (obj instanceof Double2) {
+ return 16;
+ }
+
+ if (obj instanceof Double3) {
+ return 24;
+ }
+
+ if (obj instanceof Double4) {
+ return 32;
+ }
+
+ if (obj instanceof Matrix2f) {
+ return 16;
+ }
+
+ if (obj instanceof Matrix3f) {
+ return 36;
+ }
+
+ if (obj instanceof Matrix4f) {
+ return 64;
+ }
+
+ if (obj instanceof BaseObj) {
+ if (RenderScript.sPointerSize == 8) {
+ return 32;
+ } else {
+ return 4;
+ }
+ }
+
+ return 0;
+ }
+
+ static FieldPacker createFieldPack(Object[] args) {
+ int len = 0;
+ for (Object arg : args) {
+ len += getPackedSize(arg);
+ }
+ FieldPacker fp = new FieldPacker(len);
+ for (Object arg : args) {
+ addToPack(fp, arg);
+ }
+ return fp;
+ }
+
+
+ private boolean resize(int newSize) {
+ if (newSize == mLen) {
+ return false;
+ }
+
+ byte[] newData = new byte[newSize];
+ System.arraycopy(mData, 0, newData, 0, mPos);
+ mData = newData;
+ mLen = newSize;
+ return true;
+ }
+
+ private void addSafely(Object obj) {
+ boolean retry;
+ final int oldPos = mPos;
+ do {
+ retry = false;
+ try {
+ addToPack(this, obj);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ mPos = oldPos;
+ resize(mLen * 2);
+ retry = true;
+ }
+ } while (retry);
+ }
+
+ private byte mData[];
+ private int mPos;
+ private int mLen;
+ private BitSet mAlignment;
+}
diff --git a/androidx/renderscript/Float2.java b/androidx/renderscript/Float2.java
new file mode 100644
index 0000000..01a166b
--- /dev/null
+++ b/androidx/renderscript/Float2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float2 {
+ public Float2() {
+ }
+
+ public Float2(float initX, float initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public float x;
+ public float y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Float3.java b/androidx/renderscript/Float3.java
new file mode 100644
index 0000000..bb7932a
--- /dev/null
+++ b/androidx/renderscript/Float3.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float3 {
+ public Float3() {
+ }
+ public Float3(float initX, float initY, float initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public float x;
+ public float y;
+ public float z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Float4.java b/androidx/renderscript/Float4.java
new file mode 100644
index 0000000..8336d9e
--- /dev/null
+++ b/androidx/renderscript/Float4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float4 {
+ public Float4() {
+ }
+
+ public Float4(float initX, float initY, float initZ, float initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public float x;
+ public float y;
+ public float z;
+ public float w;
+}
+
+
+
diff --git a/androidx/renderscript/Int2.java b/androidx/renderscript/Int2.java
new file mode 100644
index 0000000..fe86fe3
--- /dev/null
+++ b/androidx/renderscript/Int2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int2 type back to the Android system.
+ *
+ **/
+public class Int2 {
+ public Int2() {
+ }
+
+ public Int2(int initX, int initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public int x;
+ public int y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Int3.java b/androidx/renderscript/Int3.java
new file mode 100644
index 0000000..bd6fbc7
--- /dev/null
+++ b/androidx/renderscript/Int3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int3 type back to the Android system.
+ *
+ **/
+public class Int3 {
+ public Int3() {
+ }
+
+ public Int3(int initX, int initY, int initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public int x;
+ public int y;
+ public int z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Int4.java b/androidx/renderscript/Int4.java
new file mode 100644
index 0000000..91e0b9f
--- /dev/null
+++ b/androidx/renderscript/Int4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int4 type back to the Android system.
+ *
+ **/
+public class Int4 {
+ public Int4() {
+ }
+
+ public Int4(int initX, int initY, int initZ, int initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public int x;
+ public int y;
+ public int z;
+ public int w;
+}
+
+
+
diff --git a/androidx/renderscript/Long2.java b/androidx/renderscript/Long2.java
new file mode 100644
index 0000000..0871706
--- /dev/null
+++ b/androidx/renderscript/Long2.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long2 type back to the Android system.
+ **/
+public class Long2 {
+ public Long2() {
+ }
+
+ public Long2(long initX, long initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public long x;
+ public long y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Long3.java b/androidx/renderscript/Long3.java
new file mode 100644
index 0000000..250b50f
--- /dev/null
+++ b/androidx/renderscript/Long3.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long3 type back to the Android system.
+ **/
+public class Long3 {
+ public Long3() {
+ }
+
+ public Long3(long initX, long initY, long initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public long x;
+ public long y;
+ public long z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Long4.java b/androidx/renderscript/Long4.java
new file mode 100644
index 0000000..438d34e
--- /dev/null
+++ b/androidx/renderscript/Long4.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long4 type back to the Android system.
+ **/
+public class Long4 {
+ public Long4() {
+ }
+
+ public Long4(long initX, long initY, long initZ, long initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public long x;
+ public long y;
+ public long z;
+ public long w;
+}
+
+
+
diff --git a/androidx/renderscript/Matrix2f.java b/androidx/renderscript/Matrix2f.java
new file mode 100644
index 0000000..b5c5a08
--- /dev/null
+++ b/androidx/renderscript/Matrix2f.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2009-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
+ *
+ **/
+public class Matrix2f {
+
+ /**
+ * Creates a new identity 2x2 matrix
+ */
+ public Matrix2f() {
+ mMat = new float[4];
+ loadIdentity();
+ }
+
+ /**
+ * Creates a new matrix and sets its values from the given
+ * parameter
+ *
+ * @param dataArray values to set the matrix to, must be 4
+ * floats long
+ */
+ public Matrix2f(float[] dataArray) {
+ mMat = new float[4];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Return a reference to the internal array representing matrix
+ * values. Modifying this array will also change the matrix
+ *
+ * @return internal array representing the matrix
+ */
+ public float[] getArray() {
+ return mMat;
+ }
+
+ /**
+ * Returns the value for a given row and column
+ *
+ * @param x column of the value to return
+ * @param y row of the value to return
+ *
+ * @return value in the yth row and xth column
+ */
+ public float get(int x, int y) {
+ return mMat[x*2 + y];
+ }
+
+ /**
+ * Sets the value for a given row and column
+ *
+ * @param x column of the value to set
+ * @param y row of the value to set
+ */
+ public void set(int x, int y, float v) {
+ mMat[x*2 + y] = v;
+ }
+
+ /**
+ * Sets the matrix values to identity
+ */
+ public void loadIdentity() {
+ mMat[0] = 1;
+ mMat[1] = 0;
+
+ mMat[2] = 0;
+ mMat[3] = 1;
+ }
+
+ /**
+ * Sets the values of the matrix to those of the parameter
+ *
+ * @param src matrix to load the values from
+ */
+ public void load(Matrix2f src) {
+ System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Sets current values to be a rotation matrix of given angle
+ *
+ * @param rot rotation angle
+ */
+ public void loadRotate(float rot) {
+ float c, s;
+ rot *= (float)(java.lang.Math.PI / 180.0f);
+ c = (float)java.lang.Math.cos(rot);
+ s = (float)java.lang.Math.sin(rot);
+ mMat[0] = c;
+ mMat[1] = -s;
+ mMat[2] = s;
+ mMat[3] = c;
+ }
+
+ /**
+ * Sets current values to be a scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ */
+ public void loadScale(float x, float y) {
+ loadIdentity();
+ mMat[0] = x;
+ mMat[3] = y;
+ }
+
+ /**
+ * Sets current values to be the result of multiplying two given
+ * matrices
+ *
+ * @param lhs left hand side matrix
+ * @param rhs right hand side matrix
+ */
+ public void loadMultiply(Matrix2f lhs, Matrix2f rhs) {
+ for (int i=0 ; i<2 ; i++) {
+ float ri0 = 0;
+ float ri1 = 0;
+ for (int j=0 ; j<2 ; j++) {
+ float rhs_ij = rhs.get(i,j);
+ ri0 += lhs.get(j,0) * rhs_ij;
+ ri1 += lhs.get(j,1) * rhs_ij;
+ }
+ set(i,0, ri0);
+ set(i,1, ri1);
+ }
+ }
+
+ /**
+ * Post-multiplies the current matrix by a given parameter
+ *
+ * @param rhs right hand side to multiply by
+ */
+ public void multiply(Matrix2f rhs) {
+ Matrix2f tmp = new Matrix2f();
+ tmp.loadMultiply(this, rhs);
+ load(tmp);
+ }
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * rotation matrix of given angle
+ *
+ * @param rot angle of rotation
+ */
+ public void rotate(float rot) {
+ Matrix2f tmp = new Matrix2f();
+ tmp.loadRotate(rot);
+ multiply(tmp);
+ }
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ */
+ public void scale(float x, float y) {
+ Matrix2f tmp = new Matrix2f();
+ tmp.loadScale(x, y);
+ multiply(tmp);
+ }
+ /**
+ * Sets the current matrix to its transpose
+ */
+ public void transpose() {
+ float temp = mMat[1];
+ mMat[1] = mMat[2];
+ mMat[2] = temp;
+ }
+
+ final float[] mMat;
+}
+
+
+
diff --git a/androidx/renderscript/Matrix3f.java b/androidx/renderscript/Matrix3f.java
new file mode 100644
index 0000000..699c42b
--- /dev/null
+++ b/androidx/renderscript/Matrix3f.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
+ *
+ **/
+public class Matrix3f {
+
+ /**
+ * Creates a new identity 3x3 matrix
+ */
+ public Matrix3f() {
+ mMat = new float[9];
+ loadIdentity();
+ }
+
+ /**
+ * Creates a new matrix and sets its values from the given
+ * parameter
+ *
+ * @param dataArray values to set the matrix to, must be 9
+ * floats long
+ */
+ public Matrix3f(float[] dataArray) {
+ mMat = new float[9];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Return a reference to the internal array representing matrix
+ * values. Modifying this array will also change the matrix
+ *
+ * @return internal array representing the matrix
+ */
+ public float[] getArray() {
+ return mMat;
+ }
+
+ /**
+ * Returns the value for a given row and column
+ *
+ * @param x column of the value to return
+ * @param y row of the value to return
+ *
+ * @return value in the yth row and xth column
+ */
+ public float get(int x, int y) {
+ return mMat[x*3 + y];
+ }
+
+ /**
+ * Sets the value for a given row and column
+ *
+ * @param x column of the value to set
+ * @param y row of the value to set
+ */
+ public void set(int x, int y, float v) {
+ mMat[x*3 + y] = v;
+ }
+
+ /**
+ * Sets the matrix values to identity
+ */
+ public void loadIdentity() {
+ mMat[0] = 1;
+ mMat[1] = 0;
+ mMat[2] = 0;
+
+ mMat[3] = 0;
+ mMat[4] = 1;
+ mMat[5] = 0;
+
+ mMat[6] = 0;
+ mMat[7] = 0;
+ mMat[8] = 1;
+ }
+
+ /**
+ * Sets the values of the matrix to those of the parameter
+ *
+ * @param src matrix to load the values from
+ */
+ public void load(Matrix3f src) {
+ System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Sets current values to be a rotation matrix of certain angle
+ * about a given axis
+ *
+ * @param rot angle of rotation
+ * @param x rotation axis x
+ * @param y rotation axis y
+ * @param z rotation axis z
+ */
+ public void loadRotate(float rot, float x, float y, float z) {
+ float c, s;
+ rot *= (float)(java.lang.Math.PI / 180.0f);
+ c = (float)java.lang.Math.cos(rot);
+ s = (float)java.lang.Math.sin(rot);
+
+ float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+ if (!(len != 1)) {
+ float recipLen = 1.f / len;
+ x *= recipLen;
+ y *= recipLen;
+ z *= recipLen;
+ }
+ float nc = 1.0f - c;
+ float xy = x * y;
+ float yz = y * z;
+ float zx = z * x;
+ float xs = x * s;
+ float ys = y * s;
+ float zs = z * s;
+ mMat[0] = x*x*nc + c;
+ mMat[3] = xy*nc - zs;
+ mMat[6] = zx*nc + ys;
+ mMat[1] = xy*nc + zs;
+ mMat[4] = y*y*nc + c;
+ mMat[7] = yz*nc - xs;
+ mMat[2] = zx*nc - ys;
+ mMat[5] = yz*nc + xs;
+ mMat[8] = z*z*nc + c;
+ }
+
+ /**
+ * Makes the upper 2x2 a rotation matrix of the given angle
+ *
+ * @param rot rotation angle
+ */
+ public void loadRotate(float rot) {
+ loadIdentity();
+ float c, s;
+ rot *= (float)(java.lang.Math.PI / 180.0f);
+ c = (float)java.lang.Math.cos(rot);
+ s = (float)java.lang.Math.sin(rot);
+ mMat[0] = c;
+ mMat[1] = -s;
+ mMat[3] = s;
+ mMat[4] = c;
+ }
+
+ /**
+ * Makes the upper 2x2 a scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ */
+ public void loadScale(float x, float y) {
+ loadIdentity();
+ mMat[0] = x;
+ mMat[4] = y;
+ }
+
+ /**
+ * Sets current values to be a scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ * @param z scale component z
+ */
+ public void loadScale(float x, float y, float z) {
+ loadIdentity();
+ mMat[0] = x;
+ mMat[4] = y;
+ mMat[8] = z;
+ }
+
+ /**
+ * Sets current values to be a translation matrix of given
+ * dimensions
+ *
+ * @param x translation component x
+ * @param y translation component y
+ */
+ public void loadTranslate(float x, float y) {
+ loadIdentity();
+ mMat[6] = x;
+ mMat[7] = y;
+ }
+
+ /**
+ * Sets current values to be the result of multiplying two given
+ * matrices
+ *
+ * @param lhs left hand side matrix
+ * @param rhs right hand side matrix
+ */
+ public void loadMultiply(Matrix3f lhs, Matrix3f rhs) {
+ for (int i=0 ; i<3 ; i++) {
+ float ri0 = 0;
+ float ri1 = 0;
+ float ri2 = 0;
+ for (int j=0 ; j<3 ; j++) {
+ float rhs_ij = rhs.get(i,j);
+ ri0 += lhs.get(j,0) * rhs_ij;
+ ri1 += lhs.get(j,1) * rhs_ij;
+ ri2 += lhs.get(j,2) * rhs_ij;
+ }
+ set(i,0, ri0);
+ set(i,1, ri1);
+ set(i,2, ri2);
+ }
+ }
+
+ /**
+ * Post-multiplies the current matrix by a given parameter
+ *
+ * @param rhs right hand side to multiply by
+ */
+ public void multiply(Matrix3f rhs) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadMultiply(this, rhs);
+ load(tmp);
+ }
+
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * rotation matrix of certain angle about a given axis
+ *
+ * @param rot angle of rotation
+ * @param x rotation axis x
+ * @param y rotation axis y
+ * @param z rotation axis z
+ */
+ public void rotate(float rot, float x, float y, float z) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadRotate(rot, x, y, z);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the upper 2x2 of the current matrix by
+ * post-multiplying it with a rotation matrix of given angle
+ *
+ * @param rot angle of rotation
+ */
+ public void rotate(float rot) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadRotate(rot);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the upper 2x2 of the current matrix by
+ * post-multiplying it with a scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ */
+ public void scale(float x, float y) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadScale(x, y);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ * @param z scale component z
+ */
+ public void scale(float x, float y, float z) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadScale(x, y, z);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * translation matrix of given dimensions
+ *
+ * @param x translation component x
+ * @param y translation component y
+ */
+ public void translate(float x, float y) {
+ Matrix3f tmp = new Matrix3f();
+ tmp.loadTranslate(x, y);
+ multiply(tmp);
+ }
+
+ /**
+ * Sets the current matrix to its transpose
+ */
+ public void transpose() {
+ for(int i = 0; i < 2; ++i) {
+ for(int j = i + 1; j < 3; ++j) {
+ float temp = mMat[i*3 + j];
+ mMat[i*3 + j] = mMat[j*3 + i];
+ mMat[j*3 + i] = temp;
+ }
+ }
+ }
+
+ final float[] mMat;
+}
+
+
diff --git a/androidx/renderscript/Matrix4f.java b/androidx/renderscript/Matrix4f.java
new file mode 100644
index 0000000..6a38af8
--- /dev/null
+++ b/androidx/renderscript/Matrix4f.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2009-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
+ *
+ **/
+public class Matrix4f {
+
+ /**
+ * Creates a new identity 4x4 matrix
+ */
+ public Matrix4f() {
+ mMat = new float[16];
+ loadIdentity();
+ }
+
+ /**
+ * Creates a new matrix and sets its values from the given
+ * parameter
+ *
+ * @param dataArray values to set the matrix to, must be 16
+ * floats long
+ */
+ public Matrix4f(float[] dataArray) {
+ mMat = new float[16];
+ System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Return a reference to the internal array representing matrix
+ * values. Modifying this array will also change the matrix
+ *
+ * @return internal array representing the matrix
+ */
+ public float[] getArray() {
+ return mMat;
+ }
+
+ /**
+ * Returns the value for a given row and column
+ *
+ * @param x column of the value to return
+ * @param y row of the value to return
+ *
+ * @return value in the yth row and xth column
+ */
+ public float get(int x, int y) {
+ return mMat[x*4 + y];
+ }
+
+ /**
+ * Sets the value for a given row and column
+ *
+ * @param x column of the value to set
+ * @param y row of the value to set
+ */
+ public void set(int x, int y, float v) {
+ mMat[x*4 + y] = v;
+ }
+
+ /**
+ * Sets the matrix values to identity
+ */
+ public void loadIdentity() {
+ mMat[0] = 1;
+ mMat[1] = 0;
+ mMat[2] = 0;
+ mMat[3] = 0;
+
+ mMat[4] = 0;
+ mMat[5] = 1;
+ mMat[6] = 0;
+ mMat[7] = 0;
+
+ mMat[8] = 0;
+ mMat[9] = 0;
+ mMat[10] = 1;
+ mMat[11] = 0;
+
+ mMat[12] = 0;
+ mMat[13] = 0;
+ mMat[14] = 0;
+ mMat[15] = 1;
+ }
+
+ /**
+ * Sets the values of the matrix to those of the parameter
+ *
+ * @param src matrix to load the values from
+ */
+ public void load(Matrix4f src) {
+ System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+ }
+
+ /**
+ * Sets the values of the matrix to those of the parameter
+ *
+ * @param src matrix to load the values from
+ * @hide
+ */
+ public void load(Matrix3f src) {
+ mMat[0] = src.mMat[0];
+ mMat[1] = src.mMat[1];
+ mMat[2] = src.mMat[2];
+ mMat[3] = 0;
+
+ mMat[4] = src.mMat[3];
+ mMat[5] = src.mMat[4];
+ mMat[6] = src.mMat[5];
+ mMat[7] = 0;
+
+ mMat[8] = src.mMat[6];
+ mMat[9] = src.mMat[7];
+ mMat[10] = src.mMat[8];
+ mMat[11] = 0;
+
+ mMat[12] = 0;
+ mMat[13] = 0;
+ mMat[14] = 0;
+ mMat[15] = 1;
+ }
+
+ /**
+ * Sets current values to be a rotation matrix of certain angle
+ * about a given axis
+ *
+ * @param rot angle of rotation
+ * @param x rotation axis x
+ * @param y rotation axis y
+ * @param z rotation axis z
+ */
+ public void loadRotate(float rot, float x, float y, float z) {
+ float c, s;
+ mMat[3] = 0;
+ mMat[7] = 0;
+ mMat[11]= 0;
+ mMat[12]= 0;
+ mMat[13]= 0;
+ mMat[14]= 0;
+ mMat[15]= 1;
+ rot *= (float)(java.lang.Math.PI / 180.0f);
+ c = (float)java.lang.Math.cos(rot);
+ s = (float)java.lang.Math.sin(rot);
+
+ float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+ if (!(len != 1)) {
+ float recipLen = 1.f / len;
+ x *= recipLen;
+ y *= recipLen;
+ z *= recipLen;
+ }
+ float nc = 1.0f - c;
+ float xy = x * y;
+ float yz = y * z;
+ float zx = z * x;
+ float xs = x * s;
+ float ys = y * s;
+ float zs = z * s;
+ mMat[ 0] = x*x*nc + c;
+ mMat[ 4] = xy*nc - zs;
+ mMat[ 8] = zx*nc + ys;
+ mMat[ 1] = xy*nc + zs;
+ mMat[ 5] = y*y*nc + c;
+ mMat[ 9] = yz*nc - xs;
+ mMat[ 2] = zx*nc - ys;
+ mMat[ 6] = yz*nc + xs;
+ mMat[10] = z*z*nc + c;
+ }
+
+ /**
+ * Sets current values to be a scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ * @param z scale component z
+ */
+ public void loadScale(float x, float y, float z) {
+ loadIdentity();
+ mMat[0] = x;
+ mMat[5] = y;
+ mMat[10] = z;
+ }
+
+ /**
+ * Sets current values to be a translation matrix of given
+ * dimensions
+ *
+ * @param x translation component x
+ * @param y translation component y
+ * @param z translation component z
+ */
+ public void loadTranslate(float x, float y, float z) {
+ loadIdentity();
+ mMat[12] = x;
+ mMat[13] = y;
+ mMat[14] = z;
+ }
+
+ /**
+ * Sets current values to be the result of multiplying two given
+ * matrices
+ *
+ * @param lhs left hand side matrix
+ * @param rhs right hand side matrix
+ */
+ public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
+ for (int i=0 ; i<4 ; i++) {
+ float ri0 = 0;
+ float ri1 = 0;
+ float ri2 = 0;
+ float ri3 = 0;
+ for (int j=0 ; j<4 ; j++) {
+ float rhs_ij = rhs.get(i,j);
+ ri0 += lhs.get(j,0) * rhs_ij;
+ ri1 += lhs.get(j,1) * rhs_ij;
+ ri2 += lhs.get(j,2) * rhs_ij;
+ ri3 += lhs.get(j,3) * rhs_ij;
+ }
+ set(i,0, ri0);
+ set(i,1, ri1);
+ set(i,2, ri2);
+ set(i,3, ri3);
+ }
+ }
+
+ /**
+ * Set current values to be an orthographic projection matrix
+ *
+ * @param l location of the left vertical clipping plane
+ * @param r location of the right vertical clipping plane
+ * @param b location of the bottom horizontal clipping plane
+ * @param t location of the top horizontal clipping plane
+ * @param n location of the near clipping plane
+ * @param f location of the far clipping plane
+ */
+ public void loadOrtho(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ mMat[0] = 2 / (r - l);
+ mMat[5] = 2 / (t - b);
+ mMat[10]= -2 / (f - n);
+ mMat[12]= -(r + l) / (r - l);
+ mMat[13]= -(t + b) / (t - b);
+ mMat[14]= -(f + n) / (f - n);
+ }
+
+ /**
+ * Set current values to be an orthographic projection matrix
+ * with the right and bottom clipping planes set to the given
+ * values. Left and top clipping planes are set to 0. Near and
+ * far are set to -1, 1 respectively
+ *
+ * @param w location of the right vertical clipping plane
+ * @param h location of the bottom horizontal clipping plane
+ *
+ */
+ public void loadOrthoWindow(int w, int h) {
+ loadOrtho(0,w, h,0, -1,1);
+ }
+
+ /**
+ * Sets current values to be a perspective projection matrix
+ *
+ * @param l location of the left vertical clipping plane
+ * @param r location of the right vertical clipping plane
+ * @param b location of the bottom horizontal clipping plane
+ * @param t location of the top horizontal clipping plane
+ * @param n location of the near clipping plane, must be positive
+ * @param f location of the far clipping plane, must be positive
+ *
+ */
+ public void loadFrustum(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ mMat[0] = 2 * n / (r - l);
+ mMat[5] = 2 * n / (t - b);
+ mMat[8] = (r + l) / (r - l);
+ mMat[9] = (t + b) / (t - b);
+ mMat[10]= -(f + n) / (f - n);
+ mMat[11]= -1;
+ mMat[14]= -2*f*n / (f - n);
+ mMat[15]= 0;
+ }
+
+ /**
+ * Sets current values to be a perspective projection matrix
+ *
+ * @param fovy vertical field of view angle in degrees
+ * @param aspect aspect ratio of the screen
+ * @param near near cliping plane, must be positive
+ * @param far far clipping plane, must be positive
+ */
+ public void loadPerspective(float fovy, float aspect, float near, float far) {
+ float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
+ float bottom = -top;
+ float left = bottom * aspect;
+ float right = top * aspect;
+ loadFrustum(left, right, bottom, top, near, far);
+ }
+
+ /**
+ * Helper function to set the current values to a perspective
+ * projection matrix with aspect ratio defined by the parameters
+ * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
+ *
+ * @param w screen width
+ * @param h screen height
+ */
+ public void loadProjectionNormalized(int w, int h) {
+ // range -1,1 in the narrow axis at z = 0.
+ Matrix4f m1 = new Matrix4f();
+ Matrix4f m2 = new Matrix4f();
+
+ if(w > h) {
+ float aspect = ((float)w) / h;
+ m1.loadFrustum(-aspect,aspect, -1,1, 1,100);
+ } else {
+ float aspect = ((float)h) / w;
+ m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+ }
+
+ m2.loadRotate(180, 0, 1, 0);
+ m1.loadMultiply(m1, m2);
+
+ m2.loadScale(-2, 2, 1);
+ m1.loadMultiply(m1, m2);
+
+ m2.loadTranslate(0, 0, 2);
+ m1.loadMultiply(m1, m2);
+
+ load(m1);
+ }
+
+ /**
+ * Post-multiplies the current matrix by a given parameter
+ *
+ * @param rhs right hand side to multiply by
+ */
+ public void multiply(Matrix4f rhs) {
+ Matrix4f tmp = new Matrix4f();
+ tmp.loadMultiply(this, rhs);
+ load(tmp);
+ }
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * rotation matrix of certain angle about a given axis
+ *
+ * @param rot angle of rotation
+ * @param x rotation axis x
+ * @param y rotation axis y
+ * @param z rotation axis z
+ */
+ public void rotate(float rot, float x, float y, float z) {
+ Matrix4f tmp = new Matrix4f();
+ tmp.loadRotate(rot, x, y, z);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * scale matrix of given dimensions
+ *
+ * @param x scale component x
+ * @param y scale component y
+ * @param z scale component z
+ */
+ public void scale(float x, float y, float z) {
+ Matrix4f tmp = new Matrix4f();
+ tmp.loadScale(x, y, z);
+ multiply(tmp);
+ }
+
+ /**
+ * Modifies the current matrix by post-multiplying it with a
+ * translation matrix of given dimensions
+ *
+ * @param x translation component x
+ * @param y translation component y
+ * @param z translation component z
+ */
+ public void translate(float x, float y, float z) {
+ Matrix4f tmp = new Matrix4f();
+ tmp.loadTranslate(x, y, z);
+ multiply(tmp);
+ }
+ private float computeCofactor(int i, int j) {
+ int c0 = (i+1) % 4;
+ int c1 = (i+2) % 4;
+ int c2 = (i+3) % 4;
+ int r0 = (j+1) % 4;
+ int r1 = (j+2) % 4;
+ int r2 = (j+3) % 4;
+
+ float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
+ mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
+ - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
+ mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
+ + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
+ mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
+
+ float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
+ return cofactor;
+ }
+
+ /**
+ * Sets the current matrix to its inverse
+ */
+ public boolean inverse() {
+
+ Matrix4f result = new Matrix4f();
+
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ result.mMat[4*i + j] = computeCofactor(i, j);
+ }
+ }
+
+ // Dot product of 0th column of source and 0th row of result
+ float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
+ mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
+
+ if (Math.abs(det) < 1e-6) {
+ return false;
+ }
+
+ det = 1.0f / det;
+ for (int i = 0; i < 16; ++i) {
+ mMat[i] = result.mMat[i] * det;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the current matrix to its inverse transpose
+ */
+ public boolean inverseTranspose() {
+
+ Matrix4f result = new Matrix4f();
+
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ result.mMat[4*j + i] = computeCofactor(i, j);
+ }
+ }
+
+ float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
+ mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
+
+ if (Math.abs(det) < 1e-6) {
+ return false;
+ }
+
+ det = 1.0f / det;
+ for (int i = 0; i < 16; ++i) {
+ mMat[i] = result.mMat[i] * det;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the current matrix to its transpose
+ */
+ public void transpose() {
+ for(int i = 0; i < 3; ++i) {
+ for(int j = i + 1; j < 4; ++j) {
+ float temp = mMat[i*4 + j];
+ mMat[i*4 + j] = mMat[j*4 + i];
+ mMat[j*4 + i] = temp;
+ }
+ }
+ }
+
+ final float[] mMat;
+}
diff --git a/androidx/renderscript/RSDriverException.java b/androidx/renderscript/RSDriverException.java
new file mode 100644
index 0000000..11b5be2
--- /dev/null
+++ b/androidx/renderscript/RSDriverException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSDriverException extends RSRuntimeException {
+ public RSDriverException(String string) {
+ super(string);
+ }
+}
+
+
+
diff --git a/androidx/renderscript/RSIllegalArgumentException.java b/androidx/renderscript/RSIllegalArgumentException.java
new file mode 100644
index 0000000..6e7c0e9
--- /dev/null
+++ b/androidx/renderscript/RSIllegalArgumentException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSIllegalArgumentException extends RSRuntimeException {
+ public RSIllegalArgumentException(String string) {
+ super(string);
+ }
+}
+
+
diff --git a/androidx/renderscript/RSInvalidStateException.java b/androidx/renderscript/RSInvalidStateException.java
new file mode 100644
index 0000000..82cc7c9
--- /dev/null
+++ b/androidx/renderscript/RSInvalidStateException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSInvalidStateException extends RSRuntimeException {
+ public RSInvalidStateException(String string) {
+ super(string);
+ }
+}
+
+
+
diff --git a/androidx/renderscript/RSRuntimeException.java b/androidx/renderscript/RSRuntimeException.java
new file mode 100644
index 0000000..886cd14
--- /dev/null
+++ b/androidx/renderscript/RSRuntimeException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSRuntimeException
+ extends java.lang.RuntimeException {
+ public RSRuntimeException(String string) {
+ super(string);
+ }
+}
+
diff --git a/androidx/renderscript/RenderScript.java b/androidx/renderscript/RenderScript.java
new file mode 100644
index 0000000..cf80342
--- /dev/null
+++ b/androidx/renderscript/RenderScript.java
@@ -0,0 +1,1748 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.ArrayList;
+import java.nio.ByteBuffer;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Process;
+import android.util.Log;
+import android.view.Surface;
+
+/**
+ * This class provides access to a RenderScript context, which controls RenderScript
+ * initialization, resource management, and teardown. An instance of the RenderScript
+ * class must be created before any other RS objects can be created.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
+ * </div>
+ **/
+public class RenderScript {
+ static final String LOG_TAG = "RenderScript_jni";
+ static final boolean DEBUG = false;
+ @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+ static final boolean LOG_ENABLED = false;
+ static final int SUPPORT_LIB_API = 23;
+ static final int SUPPORT_LIB_VERSION = 2301;
+
+ static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
+ private boolean mIsProcessContext = false;
+ private boolean mEnableMultiInput = false;
+ private int mDispatchAPILevel = 0;
+
+ private int mContextFlags = 0;
+ private int mContextSdkVersion = 0;
+
+ private Context mApplicationContext;
+ private String mNativeLibDir;
+
+ static private String mBlackList = "";
+ /**
+ * Sets the blackList of Models to only use support lib runtime.
+ * Should be used before context create.
+ *
+ * @param blackList User provided black list string.
+ *
+ * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..."
+ * e.g. : To Blacklist Nexus 7(2013) and Nexus 5.
+ * mBlackList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)";
+ */
+ static public void setBlackList(String blackList) {
+ if (blackList != null) {
+ mBlackList = blackList;
+ }
+ }
+ /**
+ * Force using support lib runtime.
+ * Should be used before context create.
+ *
+ */
+ static public void forceCompat() {
+ sNative = 0;
+ }
+ /*
+ * We use a class initializer to allow the native code to cache some
+ * field offsets.
+ */
+ @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+ static boolean sInitialized;
+ static boolean sUseGCHooks;
+ static Object sRuntime;
+ static Method registerNativeAllocation;
+ static Method registerNativeFree;
+
+ static Object lock = new Object();
+
+ // Non-threadsafe functions.
+ native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
+ native boolean nLoadIOSO();
+ native long nDeviceCreate();
+ native void nDeviceDestroy(long dev);
+ native void nDeviceSetConfig(long dev, int param, int value);
+ native int nContextGetUserMessage(long con, int[] data);
+ native String nContextGetErrorMessage(long con);
+ native int nContextPeekMessage(long con, int[] subID);
+ native void nContextInitToClient(long con);
+ native void nContextDeinitToClient(long con);
+
+ static private int sNative = -1;
+ static private int sSdkVersion = -1;
+ static private boolean useIOlib = false;
+ static private boolean useNative;
+
+ /*
+ * Context creation flag that specifies a normal context.
+ * RenderScript Support lib only support normal context.
+ */
+ public static final int CREATE_FLAG_NONE = 0x0000;
+
+ int getDispatchAPILevel() {
+ return mDispatchAPILevel;
+ }
+
+ boolean isUseNative() {
+ return useNative;
+ }
+ /*
+ * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing.
+ */
+ static native int rsnSystemGetPointerSize();
+ static int sPointerSize;
+ static public int getPointerSize() {
+ // We provide an accessor rather than making the data item public for two reasons.
+ // 1) Prevents anyone outside this class from writing the data item.
+ // 2) Prevents anyone outside this class from reading the data item unless a class
+ // instance has been created (ensuring the data item has been initialized).
+ // DISCLAIMER: Reflection can circumvent these preventive measures.
+ synchronized(lock) {
+ if (!sInitialized)
+ throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated");
+ }
+ return sPointerSize;
+ }
+
+ /**
+ * Determines whether or not we should be thunking into the native
+ * RenderScript layer or actually using the compatibility library.
+ */
+ static private boolean setupNative(int sdkVersion, Context ctx) {
+ // if targetSdkVersion is higher than the device api version, always use compat mode.
+ // Workaround for KK
+ if (android.os.Build.VERSION.SDK_INT < sdkVersion &&
+ android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+ sNative = 0;
+ }
+
+ if (sNative == -1) {
+
+ // get the value of the debug.rs.forcecompat property
+ int forcecompat = 0;
+ try {
+ Class<?> sysprop = Class.forName("android.os.SystemProperties");
+ Class[] signature = {String.class, Integer.TYPE};
+ Method getint = sysprop.getDeclaredMethod("getInt", signature);
+ Object[] args = {"debug.rs.forcecompat", new Integer(0)};
+ forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
+ } catch (Exception e) {
+
+ }
+
+ if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
+ && forcecompat == 0) {
+ sNative = 1;
+ } else {
+ sNative = 0;
+ }
+
+
+ if (sNative == 1) {
+ // Workarounds that may disable thunking go here
+ ApplicationInfo info;
+ try {
+ info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
+ PackageManager.GET_META_DATA);
+ } catch (PackageManager.NameNotFoundException e) {
+ // assume no workarounds needed
+ return true;
+ }
+ long minorVersion = 0;
+
+ // load minorID from reflection
+ try {
+ Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
+ Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
+ minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
+ } catch (Exception e) {
+ // minor version remains 0 on devices with no possible WARs
+ }
+
+ if (info.metaData != null) {
+ // asynchronous teardown: minor version 1+
+ if (info.metaData.getBoolean("androidx.renderscript.EnableAsyncTeardown") == true) {
+ if (minorVersion == 0) {
+ sNative = 0;
+ }
+ }
+
+ // blur issues on some drivers with 4.4
+ if (info.metaData.getBoolean("androidx.renderscript.EnableBlurWorkaround") == true) {
+ if (android.os.Build.VERSION.SDK_INT <= 19) {
+ //android.util.Log.e("rs", "war on");
+ sNative = 0;
+ }
+ }
+ }
+ // end of workarounds
+ }
+ }
+
+ if (sNative == 1) {
+ // check against the blacklist
+ if (mBlackList.length() > 0) {
+ String deviceInfo = '(' +
+ android.os.Build.MANUFACTURER +
+ ':' +
+ android.os.Build.PRODUCT +
+ ':' +
+ android.os.Build.MODEL +
+ ')';
+ if (mBlackList.contains(deviceInfo)) {
+ sNative = 0;
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Name of the file that holds the object cache.
+ */
+ private static final String CACHE_PATH = "com.android.renderscript.cache";
+ static String mCachePath;
+
+ /**
+ * Sets the directory to use as a persistent storage for the
+ * renderscript object file cache.
+ *
+ * @hide
+ * @param cacheDir A directory the current process can write to
+ */
+ public static void setupDiskCache(File cacheDir) {
+ File f = new File(cacheDir, CACHE_PATH);
+ mCachePath = f.getAbsolutePath();
+ f.mkdirs();
+ }
+
+ /**
+ * ContextType specifies the specific type of context to be created.
+ *
+ */
+ public enum ContextType {
+ /**
+ * NORMAL context, this is the default and what shipping apps should
+ * use.
+ */
+ NORMAL (0),
+
+ /**
+ * DEBUG context, perform extra runtime checks to validate the
+ * kernels and APIs are being used as intended. Get and SetElementAt
+ * will be bounds checked in this mode.
+ */
+ DEBUG (1),
+
+ /**
+ * PROFILE context, Intended to be used once the first time an
+ * application is run on a new device. This mode allows the runtime to
+ * do additional testing and performance tuning.
+ */
+ PROFILE (2);
+
+ int mID;
+ ContextType(int id) {
+ mID = id;
+ }
+ }
+
+ ContextType mContextType;
+ // Methods below are wrapped to protect the non-threadsafe
+ // lockless fifo.
+
+ native long rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
+ synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
+ return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
+ }
+ native void rsnContextDestroy(long con);
+ synchronized void nContextDestroy() {
+ validate();
+
+ // take teardown lock
+ // teardown lock can only be taken when no objects are being destroyed
+ ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+ wlock.lock();
+
+ long curCon = mContext;
+ // context is considered dead as of this point
+ mContext = 0;
+
+ wlock.unlock();
+ rsnContextDestroy(curCon);
+ }
+ native void rsnContextSetPriority(long con, int p);
+ synchronized void nContextSetPriority(int p) {
+ validate();
+ rsnContextSetPriority(mContext, p);
+ }
+ native void rsnContextDump(long con, int bits);
+ synchronized void nContextDump(int bits) {
+ validate();
+ rsnContextDump(mContext, bits);
+ }
+ native void rsnContextFinish(long con);
+ synchronized void nContextFinish() {
+ validate();
+ rsnContextFinish(mContext);
+ }
+
+ native void rsnContextSendMessage(long con, int id, int[] data);
+ synchronized void nContextSendMessage(int id, int[] data) {
+ validate();
+ rsnContextSendMessage(mContext, id, data);
+ }
+
+ // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
+ native void rsnObjDestroy(long con, long id);
+ void nObjDestroy(long id) {
+ // There is a race condition here. The calling code may be run
+ // by the gc while teardown is occuring. This protects againts
+ // deleting dead objects.
+ if (mContext != 0) {
+ rsnObjDestroy(mContext, id);
+ }
+ }
+
+ native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
+ synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
+ validate();
+ return rsnElementCreate(mContext, type, kind, norm, vecSize);
+ }
+ native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
+ synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
+ validate();
+ return rsnElementCreate2(mContext, elements, names, arraySizes);
+ }
+ native void rsnElementGetNativeData(long con, long id, int[] elementData);
+ synchronized void nElementGetNativeData(long id, int[] elementData) {
+ validate();
+ rsnElementGetNativeData(mContext, id, elementData);
+ }
+ native void rsnElementGetSubElements(long con, long id,
+ long[] IDs, String[] names, int[] arraySizes);
+ synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
+ validate();
+ rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
+ }
+
+ native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
+ synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
+ validate();
+ return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
+ }
+
+ native void rsnTypeGetNativeData(long con, long id, long[] typeData);
+ synchronized void nTypeGetNativeData(long id, long[] typeData) {
+ validate();
+ rsnTypeGetNativeData(mContext, id, typeData);
+ }
+
+ native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
+ synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
+ validate();
+ return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
+ }
+ native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+ synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
+ validate();
+ return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
+ }
+
+ native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
+ synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
+ validate();
+ return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
+ }
+
+
+ native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+ synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
+ validate();
+ return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
+ }
+ native long rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
+ synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
+ validate();
+ return rsnAllocationCreateBitmapRef(mContext, type, bmp);
+ }
+ native long rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
+ synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
+ validate();
+ return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
+ }
+
+ native void rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
+ synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
+ validate();
+ rsnAllocationCopyToBitmap(mContext, alloc, bmp);
+ }
+
+
+ native void rsnAllocationSyncAll(long con, long alloc, int src);
+ synchronized void nAllocationSyncAll(long alloc, int src) {
+ validate();
+ rsnAllocationSyncAll(mContext, alloc, src);
+ }
+
+ native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
+ synchronized void nAllocationSetSurface(long alloc, Surface sur) {
+ validate();
+ rsnAllocationSetSurface(mContext, alloc, sur);
+ }
+
+ native void rsnAllocationIoSend(long con, long alloc);
+ synchronized void nAllocationIoSend(long alloc) {
+ validate();
+ rsnAllocationIoSend(mContext, alloc);
+ }
+ native void rsnAllocationIoReceive(long con, long alloc);
+ synchronized void nAllocationIoReceive(long alloc) {
+ validate();
+ rsnAllocationIoReceive(mContext, alloc);
+ }
+ native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ);
+ synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) {
+ validate();
+ return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ);
+ }
+ native long rsnAllocationGetStride(long con, long alloc);
+ synchronized long nAllocationGetStride(long alloc) {
+ validate();
+ return rsnAllocationGetStride(mContext, alloc);
+ }
+
+ native void rsnAllocationGenerateMipmaps(long con, long alloc);
+ synchronized void nAllocationGenerateMipmaps(long alloc) {
+ validate();
+ rsnAllocationGenerateMipmaps(mContext, alloc);
+ }
+ native void rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
+ synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
+ validate();
+ rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
+ }
+
+
+ native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
+ int mSize, boolean usePadding);
+ synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
+ int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
+ }
+
+ native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
+ synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+ validate();
+ rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
+ }
+ /*
+ native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
+ synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+ validate();
+ rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
+ }
+ */
+
+ native void rsnAllocationData2D(long con,
+ long dstAlloc, int dstXoff, int dstYoff,
+ int dstMip, int dstFace,
+ int width, int height,
+ long srcAlloc, int srcXoff, int srcYoff,
+ int srcMip, int srcFace);
+ synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
+ int dstMip, int dstFace,
+ int width, int height,
+ long srcAlloc, int srcXoff, int srcYoff,
+ int srcMip, int srcFace) {
+ validate();
+ rsnAllocationData2D(mContext,
+ dstAlloc, dstXoff, dstYoff,
+ dstMip, dstFace,
+ width, height,
+ srcAlloc, srcXoff, srcYoff,
+ srcMip, srcFace);
+ }
+
+ native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
+ int w, int h, Object d, int sizeBytes, int dt,
+ int mSize, boolean usePadding);
+ synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
+ int w, int h, Object d, int sizeBytes, Element.DataType dt,
+ int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
+ }
+
+ native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
+ synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
+ validate();
+ rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
+ }
+
+ native void rsnAllocationData3D(long con,
+ long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+ int dstMip,
+ int width, int height, int depth,
+ long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+ int srcMip);
+ synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+ int dstMip,
+ int width, int height, int depth,
+ long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+ int srcMip) {
+ validate();
+ rsnAllocationData3D(mContext,
+ dstAlloc, dstXoff, dstYoff, dstZoff,
+ dstMip, width, height, depth,
+ srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
+ }
+
+
+ native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
+ int w, int h, int depth, Object d, int sizeBytes, int dt,
+ int mSize, boolean usePadding);
+ synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
+ int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
+ int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
+ dt.mID, mSize, usePadding);
+ }
+
+ native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
+ synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
+ }
+
+ native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
+ int sizeBytes, int dt, int mSize, boolean usePadding);
+ synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
+ int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
+ }
+
+ /*
+ native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
+ int mip, int compIdx, byte[] d, int sizeBytes);
+ synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
+ int mip, int compIdx, byte[] d, int sizeBytes) {
+ validate();
+ rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
+ }
+ */
+
+ native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
+ int w, int h, Object d, int sizeBytes, int dt,
+ int mSize, boolean usePadding);
+ synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
+ int w, int h, Object d, int sizeBytes, Element.DataType dt,
+ int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
+ }
+
+ /*
+ native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
+ int w, int h, int depth, Object d, int sizeBytes, int dt,
+ int mSize, boolean usePadding);
+ synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
+ int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
+ int mSize, boolean usePadding) {
+ validate();
+ rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
+ }
+ */
+
+ native long rsnAllocationGetType(long con, long id);
+ synchronized long nAllocationGetType(long id) {
+ validate();
+ return rsnAllocationGetType(mContext, id);
+ }
+
+ native void rsnAllocationResize1D(long con, long id, int dimX);
+ synchronized void nAllocationResize1D(long id, int dimX) {
+ validate();
+ rsnAllocationResize1D(mContext, id, dimX);
+ }
+ native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
+ synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
+ validate();
+ rsnAllocationResize2D(mContext, id, dimX, dimY);
+ }
+
+ native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
+ synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
+ }
+ native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
+ synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
+ }
+ native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
+ synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptInvoke(curCon, id, slot, mUseInc);
+ }
+ native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
+ native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
+ native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
+ int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
+ native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
+ int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
+ synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
+ validate();
+ if (params == null) {
+ rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
+ } else {
+ rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
+ }
+ }
+
+ synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
+ int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
+ validate();
+ if (params == null) {
+ rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
+ } else {
+ rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
+ }
+ }
+
+ native void rsnScriptForEach(long con, long id, int slot, long[] ains,
+ long aout, byte[] params, int[] limits);
+
+ synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
+ byte[] params, int[] limits) {
+ if (!mEnableMultiInput) {
+ Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23");
+ throw new RSRuntimeException("Multi-input kernels are not supported before API 23)");
+ }
+ validate();
+ rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
+ }
+
+ native void rsnScriptReduce(long con, long id, int slot, long[] ains,
+ long aout, int[] limits);
+ synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
+ int[] limits) {
+ validate();
+ rsnScriptReduce(mContext, id, slot, ains, aout, limits);
+ }
+
+ native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
+ synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
+ }
+ native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
+ synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
+ }
+ native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
+ synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
+ }
+ native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
+ synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
+ }
+ native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
+ synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
+ }
+ native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
+ synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
+ }
+ native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
+ long e, int[] dims, boolean mUseInc);
+ synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
+ long e, int[] dims, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
+ }
+ native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
+ synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
+ }
+
+ native long rsnScriptCCreate(long con, String resName, String cacheDir,
+ byte[] script, int length);
+ synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
+ validate();
+ return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
+ }
+
+ native long rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
+ synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
+ validate();
+ if (mUseInc) {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+ Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21");
+ throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)");
+ }
+
+ if (!mIncLoaded) {
+ try {
+ System.loadLibrary("RSSupport");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
+ throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
+ }
+ if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
+ throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
+ }
+ mIncLoaded = true;
+ }
+ if (mIncCon == 0) {
+ //Create a dummy compat context (synchronous).
+ long device = nIncDeviceCreate();
+ mIncCon = nIncContextCreate(device, 0, 0, 0);
+ }
+ return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
+ } else {
+ return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
+ }
+ }
+
+ native long rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
+ synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
+ }
+
+ native long rsnScriptInvokeIDCreate(long con, long sid, int slot);
+ synchronized long nScriptInvokeIDCreate(long sid, int slot) {
+ validate();
+ return rsnScriptInvokeIDCreate(mContext, sid, slot);
+ }
+
+ native long rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
+ synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
+ validate();
+ long curCon = mContext;
+ if (mUseInc) {
+ curCon = mIncCon;
+ }
+ return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
+ }
+
+ native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
+ synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
+ validate();
+ return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
+ }
+
+ native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
+ synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
+ validate();
+ rsnScriptGroupSetInput(mContext, group, kernel, alloc);
+ }
+
+ native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
+ synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
+ validate();
+ rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
+ }
+
+ native void rsnScriptGroupExecute(long con, long group);
+ synchronized void nScriptGroupExecute(long group) {
+ validate();
+ rsnScriptGroupExecute(mContext, group);
+ }
+
+ native long rsnSamplerCreate(long con, int magFilter, int minFilter,
+ int wrapS, int wrapT, int wrapR, float aniso);
+ synchronized long nSamplerCreate(int magFilter, int minFilter,
+ int wrapS, int wrapT, int wrapR, float aniso) {
+ validate();
+ return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ }
+
+// entry points for ScriptGroup2
+ native long rsnClosureCreate(long con, long kernelID, long returnValue,
+ long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+ long[] depFieldIDs);
+ synchronized long nClosureCreate(long kernelID, long returnValue,
+ long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+ long[] depFieldIDs) {
+ validate();
+ long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
+ sizes, depClosures, depFieldIDs);
+ if (c == 0) {
+ throw new RSRuntimeException("Failed creating closure.");
+ }
+ return c;
+ }
+
+ native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
+ long[] fieldIDs, long[] values, int[] sizes);
+ synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
+ long[] fieldIDs, long[] values, int[] sizes) {
+ validate();
+ long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
+ values, sizes);
+ if (c == 0) {
+ throw new RSRuntimeException("Failed creating closure.");
+ }
+ return c;
+ }
+
+ native void rsnClosureSetArg(long con, long closureID, int index,
+ long value, int size);
+ synchronized void nClosureSetArg(long closureID, int index, long value,
+ int size) {
+ validate();
+ rsnClosureSetArg(mContext, closureID, index, value, size);
+ }
+
+ native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
+ long value, int size);
+ // Does this have to be synchronized?
+ synchronized void nClosureSetGlobal(long closureID, long fieldID,
+ long value, int size) {
+ validate(); // TODO: is this necessary?
+ rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
+ }
+
+ native long rsnScriptGroup2Create(long con, String name, String cachePath,
+ long[] closures);
+ synchronized long nScriptGroup2Create(String name, String cachePath,
+ long[] closures) {
+ validate();
+ return rsnScriptGroup2Create(mContext, name, cachePath, closures);
+ }
+
+ native void rsnScriptGroup2Execute(long con, long groupID);
+ synchronized void nScriptGroup2Execute(long groupID) {
+ validate();
+ rsnScriptGroup2Execute(mContext, groupID);
+ }
+
+ native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ float alpha, long A, long B, float beta, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc);
+ synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ float alpha, long A, long B, float beta, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc) {
+ validate();
+ rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
+ }
+
+ native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ double alpha, long A, long B, double beta, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc);
+ synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ double alpha, long A, long B, double beta, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc) {
+ validate();
+ rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
+ }
+
+ native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc);
+ synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc) {
+ validate();
+ rsnScriptIntrinsicBLAS_Complex(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
+ }
+
+ native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc);
+ synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
+ int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+ double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
+ int KL, int KU, boolean mUseInc) {
+ validate();
+ rsnScriptIntrinsicBLAS_Z(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
+ }
+
+ native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K,
+ long A, int a_offset, long B, int b_offset, long C, int c_offset,
+ int c_mult_int, boolean mUseInc);
+ synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
+ long A, int a_offset, long B, int b_offset, long C, int c_offset,
+ int c_mult_int, boolean mUseInc) {
+ validate();
+ rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc);
+ }
+
+// Additional Entry points For inc libRSSupport
+
+ native boolean nIncLoadSO(int deviceApi, String libPath);
+ native long nIncDeviceCreate();
+ native void nIncDeviceDestroy(long dev);
+ // Methods below are wrapped to protect the non-threadsafe
+ // lockless fifo.
+ native long rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
+ synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
+ return rsnIncContextCreate(dev, ver, sdkVer, contextType);
+ }
+ native void rsnIncContextDestroy(long con);
+ synchronized void nIncContextDestroy() {
+ validate();
+
+ // take teardown lock
+ // teardown lock can only be taken when no objects are being destroyed
+ ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+ wlock.lock();
+
+ long curCon = mIncCon;
+ // context is considered dead as of this point
+ mIncCon = 0;
+
+ wlock.unlock();
+ rsnIncContextDestroy(curCon);
+ }
+
+ native void rsnIncContextFinish(long con);
+ synchronized void nIncContextFinish() {
+ validate();
+ rsnIncContextFinish(mIncCon);
+ }
+
+ native void rsnIncObjDestroy(long con, long id);
+ void nIncObjDestroy(long id) {
+ // There is a race condition here. The calling code may be run
+ // by the gc while teardown is occuring. This protects againts
+ // deleting dead objects.
+ if (mIncCon != 0) {
+ rsnIncObjDestroy(mIncCon, id);
+ }
+ }
+ native long rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
+ synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
+ validate();
+ return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
+ }
+ native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
+ synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
+ validate();
+ return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
+ }
+ native long rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize);
+ synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) {
+ validate();
+ return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize);
+ }
+
+ long mContext;
+ private boolean mDestroyed = false;
+ //Dummy device & context for Inc Support Lib
+ long mIncCon;
+ //indicator of whether inc support lib has been loaded or not.
+ boolean mIncLoaded;
+ ReentrantReadWriteLock mRWLock;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ MessageThread mMessageThread;
+
+ Element mElement_U8;
+ Element mElement_I8;
+ Element mElement_U16;
+ Element mElement_I16;
+ Element mElement_U32;
+ Element mElement_I32;
+ Element mElement_U64;
+ Element mElement_I64;
+ Element mElement_F32;
+ Element mElement_F64;
+ Element mElement_BOOLEAN;
+
+ Element mElement_ELEMENT;
+ Element mElement_TYPE;
+ Element mElement_ALLOCATION;
+ Element mElement_SAMPLER;
+ Element mElement_SCRIPT;
+
+ Element mElement_A_8;
+ Element mElement_RGB_565;
+ Element mElement_RGB_888;
+ Element mElement_RGBA_5551;
+ Element mElement_RGBA_4444;
+ Element mElement_RGBA_8888;
+
+ Element mElement_FLOAT_2;
+ Element mElement_FLOAT_3;
+ Element mElement_FLOAT_4;
+
+ Element mElement_DOUBLE_2;
+ Element mElement_DOUBLE_3;
+ Element mElement_DOUBLE_4;
+
+ Element mElement_UCHAR_2;
+ Element mElement_UCHAR_3;
+ Element mElement_UCHAR_4;
+
+ Element mElement_CHAR_2;
+ Element mElement_CHAR_3;
+ Element mElement_CHAR_4;
+
+ Element mElement_USHORT_2;
+ Element mElement_USHORT_3;
+ Element mElement_USHORT_4;
+
+ Element mElement_SHORT_2;
+ Element mElement_SHORT_3;
+ Element mElement_SHORT_4;
+
+ Element mElement_UINT_2;
+ Element mElement_UINT_3;
+ Element mElement_UINT_4;
+
+ Element mElement_INT_2;
+ Element mElement_INT_3;
+ Element mElement_INT_4;
+
+ Element mElement_ULONG_2;
+ Element mElement_ULONG_3;
+ Element mElement_ULONG_4;
+
+ Element mElement_LONG_2;
+ Element mElement_LONG_3;
+ Element mElement_LONG_4;
+
+ Element mElement_MATRIX_4X4;
+ Element mElement_MATRIX_3X3;
+ Element mElement_MATRIX_2X2;
+
+ Sampler mSampler_CLAMP_NEAREST;
+ Sampler mSampler_CLAMP_LINEAR;
+ Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
+ Sampler mSampler_WRAP_NEAREST;
+ Sampler mSampler_WRAP_LINEAR;
+ Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
+ Sampler mSampler_MIRRORED_REPEAT_NEAREST;
+ Sampler mSampler_MIRRORED_REPEAT_LINEAR;
+ Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
+
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+
+ /**
+ * The base class from which an application should derive in order
+ * to receive RS messages from scripts. When a script calls {@code
+ * rsSendToClient}, the data fields will be filled, and the run
+ * method will be called on a separate thread. This will occur
+ * some time after {@code rsSendToClient} completes in the script,
+ * as {@code rsSendToClient} is asynchronous. Message handlers are
+ * not guaranteed to have completed when {@link
+ * androidx.renderscript.RenderScript#finish} returns.
+ *
+ */
+ public static class RSMessageHandler implements Runnable {
+ protected int[] mData;
+ protected int mID;
+ protected int mLength;
+ public void run() {
+ }
+ }
+ /**
+ * If an application is expecting messages, it should set this
+ * field to an instance of {@link RSMessageHandler}. This
+ * instance will receive all the user messages sent from {@code
+ * sendToClient} by scripts from this context.
+ *
+ */
+ RSMessageHandler mMessageCallback = null;
+
+ public void setMessageHandler(RSMessageHandler msg) {
+ mMessageCallback = msg;
+ }
+ public RSMessageHandler getMessageHandler() {
+ return mMessageCallback;
+ }
+
+ /**
+ * Place a message into the message queue to be sent back to the message
+ * handler once all previous commands have been executed.
+ *
+ * @param id
+ * @param data
+ */
+ public void sendMessage(int id, int[] data) {
+ nContextSendMessage(id, data);
+ }
+
+ /**
+ * The runtime error handler base class. An application should derive from this class
+ * if it wishes to install an error handler. When errors occur at runtime,
+ * the fields in this class will be filled, and the run method will be called.
+ *
+ */
+ public static class RSErrorHandler implements Runnable {
+ protected String mErrorMessage;
+ protected int mErrorNum;
+ public void run() {
+ }
+ }
+
+ /**
+ * Application Error handler. All runtime errors will be dispatched to the
+ * instance of RSAsyncError set here. If this field is null a
+ * {@link RSRuntimeException} will instead be thrown with details about the error.
+ * This will cause program termaination.
+ *
+ */
+ RSErrorHandler mErrorCallback = null;
+
+ public void setErrorHandler(RSErrorHandler msg) {
+ mErrorCallback = msg;
+ }
+ public RSErrorHandler getErrorHandler() {
+ return mErrorCallback;
+ }
+
+ /**
+ * RenderScript worker thread priority enumeration. The default value is
+ * NORMAL. Applications wishing to do background processing should set
+ * their priority to LOW to avoid starving forground processes.
+ */
+ public enum Priority {
+ LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
+ NORMAL (Process.THREAD_PRIORITY_DISPLAY);
+
+ int mID;
+ Priority(int id) {
+ mID = id;
+ }
+ }
+
+ void validateObject(BaseObj o) {
+ if (o != null) {
+ if (o.mRS != this) {
+ throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
+ }
+ }
+ }
+
+ void validate() {
+ if (mContext == 0) {
+ throw new RSInvalidStateException("Calling RS with no Context active.");
+ }
+ }
+
+ /**
+ * check if IO support lib is available.
+ */
+ boolean usingIO() {
+ return useIOlib;
+ }
+ /**
+ * Change the priority of the worker threads for this context.
+ *
+ * @param p New priority to be set.
+ */
+ public void setPriority(Priority p) {
+ validate();
+ nContextSetPriority(p.mID);
+ }
+
+ static class MessageThread extends Thread {
+ RenderScript mRS;
+ boolean mRun = true;
+ int[] mAuxData = new int[2];
+
+ static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
+ static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
+ static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
+ static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
+
+ static final int RS_MESSAGE_TO_CLIENT_USER = 4;
+ static final int RS_ERROR_FATAL_DEBUG = 0x800;
+ static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
+
+ MessageThread(RenderScript rs) {
+ super("RSMessageThread");
+ mRS = rs;
+
+ }
+
+ public void run() {
+ // This function is a temporary solution. The final solution will
+ // used typed allocations where the message id is the type indicator.
+ int[] rbuf = new int[16];
+ mRS.nContextInitToClient(mRS.mContext);
+ while(mRun) {
+ rbuf[0] = 0;
+ int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
+ int size = mAuxData[1];
+ int subID = mAuxData[0];
+
+ if (msg == RS_MESSAGE_TO_CLIENT_USER) {
+ if ((size>>2) >= rbuf.length) {
+ rbuf = new int[(size + 3) >> 2];
+ }
+ if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
+ RS_MESSAGE_TO_CLIENT_USER) {
+ throw new RSDriverException("Error processing message from RenderScript.");
+ }
+
+ if(mRS.mMessageCallback != null) {
+ mRS.mMessageCallback.mData = rbuf;
+ mRS.mMessageCallback.mID = subID;
+ mRS.mMessageCallback.mLength = size;
+ mRS.mMessageCallback.run();
+ } else {
+ throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
+ }
+ continue;
+ }
+
+ if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
+ String e = mRS.nContextGetErrorMessage(mRS.mContext);
+
+ // Copied from java/android/renderscript/RenderScript.java
+ // Throw RSRuntimeException under the following conditions:
+ //
+ // 1) It is an unknown fatal error.
+ // 2) It is a debug fatal error, and we are not in a
+ // debug context.
+ // 3) It is a debug fatal error, and we do not have an
+ // error callback.
+ if (subID >= RS_ERROR_FATAL_UNKNOWN ||
+ (subID >= RS_ERROR_FATAL_DEBUG &&
+ (mRS.mContextType != ContextType.DEBUG ||
+ mRS.mErrorCallback == null))) {
+ android.util.Log.e(LOG_TAG, "fatal RS error, " + e);
+ throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
+ }
+
+ if(mRS.mErrorCallback != null) {
+ mRS.mErrorCallback.mErrorMessage = e;
+ mRS.mErrorCallback.mErrorNum = subID;
+ mRS.mErrorCallback.run();
+ } else {
+ android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
+ // Do not throw here. In these cases, we do not have
+ // a fatal error.
+ }
+ continue;
+ }
+
+ // 2: teardown.
+ // But we want to avoid starving other threads during
+ // teardown by yielding until the next line in the destructor
+ // can execute to set mRun = false
+ try {
+ sleep(1, 0);
+ } catch(InterruptedException e) {
+ }
+ }
+ //Log.d(LOG_TAG, "MessageThread exiting.");
+ }
+ }
+
+ RenderScript(Context ctx) {
+ mContextType = ContextType.NORMAL;
+ if (ctx != null) {
+ mApplicationContext = ctx.getApplicationContext();
+ // Only set mNativeLibDir for API 9+.
+ mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
+ }
+ mIncCon = 0;
+ mIncLoaded = false;
+ mRWLock = new ReentrantReadWriteLock();
+ }
+
+ /**
+ * Gets the application context associated with the RenderScript context.
+ *
+ * @return The application context.
+ */
+ public final Context getApplicationContext() {
+ return mApplicationContext;
+ }
+
+ /**
+ * Create a RenderScript context.
+ *
+ * @param ctx The context.
+ * @return RenderScript
+ */
+ private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
+ RenderScript rs = new RenderScript(ctx);
+
+ if (sSdkVersion == -1) {
+ sSdkVersion = sdkVersion;
+ } else if (sSdkVersion != sdkVersion) {
+ throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
+ }
+ useNative = setupNative(sSdkVersion, ctx);
+ synchronized(lock) {
+ if (sInitialized == false) {
+ try {
+ Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
+ Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
+ sRuntime = get_runtime.invoke(null);
+ Class<?> argClass = android.os.Build.VERSION.SDK_INT >= 29 ? Long.TYPE : Integer.TYPE;
+ // The int version is (so far) always defined, but deprecated for APIs >= 29.
+ registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", argClass);
+ registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", argClass);
+ sUseGCHooks = true;
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "No GC methods");
+ sUseGCHooks = false;
+ }
+ try {
+ // For API 9 - 22, always use the absolute path of librsjni.so
+ // http://b/25226912
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+ rs.mNativeLibDir != null) {
+ System.load(rs.mNativeLibDir + "/librsjni.so");
+ } else {
+ System.loadLibrary("rsjni");
+ }
+ sInitialized = true;
+ sPointerSize = rsnSystemGetPointerSize();
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(LOG_TAG, "Error loading RS jni library: " + e);
+ throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
+ }
+ }
+ }
+
+ if (useNative) {
+ android.util.Log.v(LOG_TAG, "RS native mode");
+ } else {
+ android.util.Log.v(LOG_TAG, "RS compat mode");
+ }
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ useIOlib = true;
+ }
+
+ // The target API level used to init dispatchTable.
+ int dispatchAPI = sdkVersion;
+ if (sdkVersion < android.os.Build.VERSION.SDK_INT) {
+ // If the device API is higher than target API level, init dispatch table based on device API.
+ dispatchAPI = android.os.Build.VERSION.SDK_INT;
+ }
+
+ String rssupportPath = null;
+ // For API 9 - 22, always use the absolute path of libRSSupport.so
+ // http://b/25226912
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+ rs.mNativeLibDir != null) {
+ rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
+ }
+ if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
+ if (useNative) {
+ android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
+ useNative = false;
+ }
+ try {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+ rs.mNativeLibDir != null) {
+ System.load(rssupportPath);
+ } else {
+ System.loadLibrary("RSSupport");
+ }
+ } catch (UnsatisfiedLinkError e) {
+ Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
+ throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
+ }
+ if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
+ Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
+ throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
+ }
+ }
+
+ if (useIOlib) {
+ try {
+ System.loadLibrary("RSSupportIO");
+ } catch (UnsatisfiedLinkError e) {
+ useIOlib = false;
+ }
+ if (!useIOlib || !rs.nLoadIOSO()) {
+ android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
+ useIOlib = false;
+ }
+ }
+
+ // For old APIs with dlopen bug, need to load blas lib in Java first.
+ // Only try load to blasV8 when the desired API level includes IntrinsicBLAS.
+ if (dispatchAPI >= 23) {
+ // Enable multi-input kernels only when diapatchAPI is M+.
+ rs.mEnableMultiInput = true;
+ try {
+ System.loadLibrary("blasV8");
+ } catch (UnsatisfiedLinkError e) {
+ Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e);
+ }
+ }
+
+ long device = rs.nDeviceCreate();
+ rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
+ rs.mContextType = ct;
+ rs.mContextFlags = flags;
+ rs.mContextSdkVersion = sdkVersion;
+ rs.mDispatchAPILevel = dispatchAPI;
+ if (rs.mContext == 0) {
+ throw new RSDriverException("Failed to create RS context.");
+ }
+ rs.mMessageThread = new MessageThread(rs);
+ rs.mMessageThread.start();
+ return rs;
+ }
+
+ /**
+ * Create a RenderScript context.
+ *
+ * See documentation for @create for details
+ *
+ * @param ctx The context.
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx) {
+ return create(ctx, ContextType.NORMAL);
+ }
+
+ /**
+ * calls create(ctx, ct, CREATE_FLAG_NONE)
+ *
+ * See documentation for @create for details
+ *
+ * @param ctx The context.
+ * @param ct The type of context to be created.
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx, ContextType ct) {
+ return create(ctx, ct, CREATE_FLAG_NONE);
+ }
+
+ /**
+ * Gets or creates a RenderScript context of the specified type.
+ *
+ * The returned context will be cached for future reuse within
+ * the process. When an application is finished using
+ * RenderScript it should call releaseAllContexts()
+ *
+ * A process context is a context designed for easy creation and
+ * lifecycle management. Multiple calls to this function will
+ * return the same object provided they are called with the same
+ * options. This allows it to be used any time a RenderScript
+ * context is needed.
+ *
+ *
+ * @param ctx The context.
+ * @param ct The type of context to be created.
+ * @param flags The OR of the CREATE_FLAG_* options desired
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx, ContextType ct, int flags) {
+ int v = ctx.getApplicationInfo().targetSdkVersion;
+ return create(ctx, v, ct, flags);
+ }
+
+ /**
+ * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
+ *
+ * Used by the RenderScriptThunker to maintain backward compatibility.
+ *
+ * @hide
+ * @param ctx The context.
+ * @param sdkVersion The target SDK Version.
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx, int sdkVersion) {
+ return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
+ }
+
+
+ /**
+ * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE)
+ * Create a RenderScript context.
+ *
+ * @hide
+ * @param ctx The context.
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
+ return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE);
+ }
+
+ /**
+ * Gets or creates a RenderScript context of the specified type.
+ *
+ * @param ctx The context.
+ * @param ct The type of context to be created.
+ * @param sdkVersion The target SDK Version.
+ * @param flags The OR of the CREATE_FLAG_* options desired
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
+ synchronized (mProcessContextList) {
+ for (RenderScript prs : mProcessContextList) {
+ if ((prs.mContextType == ct) &&
+ (prs.mContextFlags == flags) &&
+ (prs.mContextSdkVersion == sdkVersion)) {
+
+ return prs;
+ }
+ }
+
+ RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
+ prs.mIsProcessContext = true;
+ mProcessContextList.add(prs);
+ return prs;
+ }
+ }
+
+ /**
+ *
+ * Releases all the process contexts. This is the same as
+ * calling .destroy() on each unique context retreived with
+ * create(...). If no contexts have been created this
+ * function does nothing.
+ *
+ * Typically you call this when your application is losing focus
+ * and will not be using a context for some time.
+ *
+ * This has no effect on a context created with
+ * createMultiContext()
+ */
+ public static void releaseAllContexts() {
+ ArrayList<RenderScript> oldList;
+ synchronized (mProcessContextList) {
+ oldList = mProcessContextList;
+ mProcessContextList = new ArrayList<RenderScript>();
+ }
+
+ for (RenderScript prs : oldList) {
+ prs.mIsProcessContext = false;
+ prs.destroy();
+ }
+ oldList.clear();
+ }
+
+
+
+ /**
+ * Create a RenderScript context.
+ *
+ * This is an advanced function intended for applications which
+ * need to create more than one RenderScript context to be used
+ * at the same time.
+ *
+ * If you need a single context please use create()
+ *
+ * @param ctx The context.
+ * @return RenderScript
+ */
+ public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
+ return internalCreate(ctx, API_number, ct, flags);
+ }
+
+ /**
+ * Print the currently available debugging information about the state of
+ * the RS context to the log.
+ *
+ */
+ public void contextDump() {
+ validate();
+ nContextDump(0);
+ }
+
+ /**
+ * Wait for any pending asynchronous opeations (such as copies to a RS
+ * allocation or RS script executions) to complete.
+ *
+ */
+ public void finish() {
+ nContextFinish();
+ }
+
+ private void helpDestroy() {
+ boolean shouldDestroy = false;
+ synchronized(this) {
+ if (!mDestroyed) {
+ shouldDestroy = true;
+ mDestroyed = true;
+ }
+ }
+
+ if (shouldDestroy) {
+ nContextFinish();
+ if (mIncCon != 0) {
+ nIncContextFinish();
+ nIncContextDestroy();
+ mIncCon = 0;
+ }
+ nContextDeinitToClient(mContext);
+ mMessageThread.mRun = false;
+ // Interrupt mMessageThread so it gets to see immediately that mRun is false
+ // and exit rightaway.
+ mMessageThread.interrupt();
+
+ // Wait for mMessageThread to join. Try in a loop, in case this thread gets interrupted
+ // during the wait. If interrupted, set the "interrupted" status of the current thread.
+ boolean hasJoined = false, interrupted = false;
+ while (!hasJoined) {
+ try {
+ mMessageThread.join();
+ hasJoined = true;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ if (interrupted) {
+ Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
+ Thread.currentThread().interrupt();
+ }
+
+ nContextDestroy();
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ helpDestroy();
+ super.finalize();
+ }
+
+ /**
+ * Destroys this RenderScript context. Once this function is called,
+ * using this context or any objects belonging to this context is
+ * illegal.
+ *
+ * This function is a NOP if the context was created
+ * with create(). Please use releaseAllContexts() to clean up
+ * contexts created with the create function.
+ */
+ public void destroy() {
+ if (mIsProcessContext) {
+ // users cannot destroy a process context
+ return;
+ }
+ validate();
+ helpDestroy();
+ }
+
+ boolean isAlive() {
+ return mContext != 0;
+ }
+
+ long safeID(BaseObj o) {
+ if(o != null) {
+ return o.getID(this);
+ }
+ return 0;
+ }
+}
diff --git a/androidx/renderscript/Sampler.java b/androidx/renderscript/Sampler.java
new file mode 100644
index 0000000..57b94d5
--- /dev/null
+++ b/androidx/renderscript/Sampler.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+/**
+ * Sampler object that defines how Allocations can be read as textures within a
+ * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
+ * function to return values from normalized coordinates.
+ *
+ * Any Allocation used with a Sampler must have been created with {@link
+ * androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a
+ * Sampler on an {@link androidx.renderscript.Allocation} that was not
+ * created with
+ * {@link androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is
+ * undefined.
+ **/
+public class Sampler extends BaseObj {
+ public enum Value {
+ NEAREST (0),
+ LINEAR (1),
+ LINEAR_MIP_LINEAR (2),
+ LINEAR_MIP_NEAREST (5),
+ WRAP (3),
+ CLAMP (4),
+ MIRRORED_REPEAT (6);
+
+ int mID;
+ Value(int id) {
+ mID = id;
+ }
+ }
+
+ Value mMin;
+ Value mMag;
+ Value mWrapS;
+ Value mWrapT;
+ Value mWrapR;
+ float mAniso;
+
+ Sampler(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * @return minification setting for the sampler
+ */
+ public Value getMinification() {
+ return mMin;
+ }
+
+ /**
+ * @return magnification setting for the sampler
+ */
+ public Value getMagnification() {
+ return mMag;
+ }
+
+ /**
+ * @return S wrapping mode for the sampler
+ */
+ public Value getWrapS() {
+ return mWrapS;
+ }
+
+ /**
+ * @return T wrapping mode for the sampler
+ */
+ public Value getWrapT() {
+ return mWrapT;
+ }
+
+ /**
+ * @return anisotropy setting for the sampler
+ */
+ public float getAnisotropy() {
+ return mAniso;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * clamp.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler CLAMP_NEAREST(RenderScript rs) {
+ if(rs.mSampler_CLAMP_NEAREST == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.NEAREST);
+ b.setMagnification(Value.NEAREST);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ rs.mSampler_CLAMP_NEAREST = b.create();
+ }
+ return rs.mSampler_CLAMP_NEAREST;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to linear and wrap modes set to
+ * clamp.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler CLAMP_LINEAR(RenderScript rs) {
+ if(rs.mSampler_CLAMP_LINEAR == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.LINEAR);
+ b.setMagnification(Value.LINEAR);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ rs.mSampler_CLAMP_LINEAR = b.create();
+ }
+ return rs.mSampler_CLAMP_LINEAR;
+ }
+
+ /**
+ * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
+ * wrap modes set to clamp.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
+ if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.LINEAR_MIP_LINEAR);
+ b.setMagnification(Value.LINEAR);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
+ }
+ return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * wrap.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler WRAP_NEAREST(RenderScript rs) {
+ if(rs.mSampler_WRAP_NEAREST == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.NEAREST);
+ b.setMagnification(Value.NEAREST);
+ b.setWrapS(Value.WRAP);
+ b.setWrapT(Value.WRAP);
+ rs.mSampler_WRAP_NEAREST = b.create();
+ }
+ return rs.mSampler_WRAP_NEAREST;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to linear and wrap modes set to
+ * wrap.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler WRAP_LINEAR(RenderScript rs) {
+ if(rs.mSampler_WRAP_LINEAR == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.LINEAR);
+ b.setMagnification(Value.LINEAR);
+ b.setWrapS(Value.WRAP);
+ b.setWrapT(Value.WRAP);
+ rs.mSampler_WRAP_LINEAR = b.create();
+ }
+ return rs.mSampler_WRAP_LINEAR;
+ }
+
+ /**
+ * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
+ * wrap modes set to wrap.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
+ if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.LINEAR_MIP_LINEAR);
+ b.setMagnification(Value.LINEAR);
+ b.setWrapS(Value.WRAP);
+ b.setWrapT(Value.WRAP);
+ rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
+ }
+ return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * mirrored repeat.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler MIRRORED_REPEAT_NEAREST(RenderScript rs) {
+ if(rs.mSampler_MIRRORED_REPEAT_NEAREST == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.NEAREST);
+ b.setMagnification(Value.NEAREST);
+ b.setWrapS(Value.MIRRORED_REPEAT);
+ b.setWrapT(Value.MIRRORED_REPEAT);
+ rs.mSampler_MIRRORED_REPEAT_NEAREST = b.create();
+ }
+ return rs.mSampler_MIRRORED_REPEAT_NEAREST;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to linear and wrap modes set to
+ * mirrored repeat.
+ *
+ * @param rs Context to which the sampler will belong.
+ *
+ * @return Sampler
+ */
+ public static Sampler MIRRORED_REPEAT_LINEAR(RenderScript rs) {
+ if(rs.mSampler_MIRRORED_REPEAT_LINEAR == null) {
+ Builder b = new Builder(rs);
+ b.setMinification(Value.LINEAR);
+ b.setMagnification(Value.LINEAR);
+ b.setWrapS(Value.MIRRORED_REPEAT);
+ b.setWrapT(Value.MIRRORED_REPEAT);
+ rs.mSampler_MIRRORED_REPEAT_LINEAR = b.create();
+ }
+ return rs.mSampler_MIRRORED_REPEAT_LINEAR;
+ }
+
+ /**
+ * Builder for creating non-standard samplers. This is only necessary if
+ * a Sampler with different min and mag modes is desired.
+ */
+ public static class Builder {
+ RenderScript mRS;
+ Value mMin;
+ Value mMag;
+ Value mWrapS;
+ Value mWrapT;
+ Value mWrapR;
+ float mAniso;
+
+ public Builder(RenderScript rs) {
+ mRS = rs;
+ mMin = Value.NEAREST;
+ mMag = Value.NEAREST;
+ mWrapS = Value.WRAP;
+ mWrapT = Value.WRAP;
+ mWrapR = Value.WRAP;
+ mAniso = 1.0f;
+ }
+
+ public void setMinification(Value v) {
+ if (v == Value.NEAREST ||
+ v == Value.LINEAR ||
+ v == Value.LINEAR_MIP_LINEAR ||
+ v == Value.LINEAR_MIP_NEAREST) {
+ mMin = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
+ public void setMagnification(Value v) {
+ if (v == Value.NEAREST || v == Value.LINEAR) {
+ mMag = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
+ public void setWrapS(Value v) {
+ if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
+ mWrapS = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
+ public void setWrapT(Value v) {
+ if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
+ mWrapT = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
+ public void setAnisotropy(float v) {
+ if(v >= 0.0f) {
+ mAniso = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
+ public Sampler create() {
+ mRS.validate();
+ long id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
+ mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
+ Sampler sampler = new Sampler(id, mRS);
+ sampler.mMin = mMin;
+ sampler.mMag = mMag;
+ sampler.mWrapS = mWrapS;
+ sampler.mWrapT = mWrapT;
+ sampler.mWrapR = mWrapR;
+ sampler.mAniso = mAniso;
+ return sampler;
+ }
+ }
+
+}
+
diff --git a/androidx/renderscript/Script.java b/androidx/renderscript/Script.java
new file mode 100644
index 0000000..49c0039
--- /dev/null
+++ b/androidx/renderscript/Script.java
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.SparseArray;
+
+/**
+ * The parent class for all executable scripts. This should not be used by
+ * applications.
+ **/
+public class Script extends BaseObj {
+ /**
+ * Determine if Incremental Intrinsic Support is needed
+ *
+ */
+ private boolean mUseIncSupp;
+ protected void setIncSupp(boolean useInc) {
+ mUseIncSupp = useInc;
+ }
+ protected boolean isIncSupp() {
+ return mUseIncSupp;
+ }
+ /**
+ * An allocation for the compat context will be created when needed
+ * e.g. foreach(ain, aout), setVar(ain);
+ *
+ */
+ long getDummyAlloc(Allocation ain) {
+ long dInElement = 0;
+ long dInType = 0;
+ long dummyAlloc = 0;
+ if (ain != null) {
+ Type inType = ain.getType();
+ dInElement = inType.getElement().getDummyElement(mRS);
+ dInType = inType.getDummyType(mRS, dInElement);
+ int xBytesSize = inType.getX() * inType.getElement().getBytesSize();
+ dummyAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType, xBytesSize);
+ ain.setIncAllocID(dummyAlloc);
+ }
+
+ return dummyAlloc;
+ }
+ /**
+ * KernelID is an identifier for a Script + root function pair. It is used
+ * as an identifier for ScriptGroup creation.
+ *
+ * This class should not be directly created. Instead use the method in the
+ * reflected or intrinsic code "getKernelID_funcname()".
+ *
+ */
+ public static final class KernelID extends BaseObj {
+ android.renderscript.Script.KernelID mN;
+ Script mScript;
+ int mSlot;
+ int mSig;
+ KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
+ super(id, rs);
+ mScript = s;
+ mSlot = slot;
+ mSig = sig;
+ }
+ }
+
+ private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
+ /**
+ * Only to be used by generated reflected classes.
+ *
+ *
+ * @param slot
+ * @param sig
+ * @param ein
+ * @param eout
+ *
+ * @return KernelID
+ */
+ protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
+ KernelID k = mKIDs.get(slot);
+ if (k != null) {
+ return k;
+ }
+
+ long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp);
+ if (id == 0) {
+ throw new RSDriverException("Failed to create KernelID");
+ }
+
+ k = new KernelID(id, mRS, this, slot, sig);
+
+ mKIDs.put(slot, k);
+ return k;
+ }
+
+ /**
+ * InvokeID is an identifier for a invoke function. It is used
+ * as an identifier for ScriptGroup creation.
+ *
+ * This class should not be directly created. Instead use the method in the
+ * reflected or intrinsic code "getInvokeID_funcname()".
+ *
+ */
+ public static final class InvokeID extends BaseObj {
+ Script mScript;
+ int mSlot;
+ InvokeID(long id, RenderScript rs, Script s, int slot) {
+ super(id, rs);
+ mScript = s;
+ mSlot = slot;
+ }
+ }
+
+ private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
+ /**
+ * Only to be used by generated reflected classes.
+ */
+ protected InvokeID createInvokeID(int slot) {
+ InvokeID i = mIIDs.get(slot);
+ if (i != null) {
+ return i;
+ }
+
+ long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
+ if (id == 0) {
+ throw new RSDriverException("Failed to create KernelID");
+ }
+
+ i = new InvokeID(id, mRS, this, slot);
+ mIIDs.put(slot, i);
+ return i;
+ }
+
+ /**
+ * FieldID is an identifier for a Script + exported field pair. It is used
+ * as an identifier for ScriptGroup creation.
+ *
+ * This class should not be directly created. Instead use the method in the
+ * reflected or intrinsic code "getFieldID_funcname()".
+ *
+ */
+ public static final class FieldID extends BaseObj {
+ android.renderscript.Script.FieldID mN;
+ Script mScript;
+ int mSlot;
+ FieldID(long id, RenderScript rs, Script s, int slot) {
+ super(id, rs);
+ mScript = s;
+ mSlot = slot;
+ }
+ }
+
+ private final SparseArray<FieldID> mFIDs = new SparseArray();
+ /**
+ * Only to be used by generated reflected classes.
+ *
+ * @param slot
+ * @param e
+ *
+ * @return FieldID
+ */
+ protected FieldID createFieldID(int slot, Element e) {
+ FieldID f = mFIDs.get(slot);
+ if (f != null) {
+ return f;
+ }
+
+ long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp);
+ if (id == 0) {
+ throw new RSDriverException("Failed to create FieldID");
+ }
+
+ f = new FieldID(id, mRS, this, slot);
+ mFIDs.put(slot, f);
+ return f;
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param slot
+ */
+ protected void invoke(int slot) {
+ mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param slot
+ * @param v
+ */
+ protected void invoke(int slot, FieldPacker v) {
+ if (v != null) {
+ mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp);
+ } else {
+ mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
+ }
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param va
+ * @param slot
+ */
+ public void bindAllocation(Allocation va, int slot) {
+ mRS.validate();
+ if (va != null) {
+ mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp);
+ } else {
+ mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp);
+ }
+ }
+
+ public void setTimeZone(String timeZone) {
+ mRS.validate();
+ try {
+ mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp);
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param slot
+ * @param ain
+ * @param aout
+ * @param v
+ */
+ protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
+ if (ain == null && aout == null) {
+ throw new RSIllegalArgumentException(
+ "At least one of ain or aout is required to be non-null.");
+ }
+ long in_id = 0;
+ long out_id = 0;
+ if (ain != null) {
+ in_id = ain.getID(mRS);
+ }
+ if (aout != null) {
+ out_id = aout.getID(mRS);
+ }
+
+ byte[] params = null;
+ if (v != null) {
+ params = v.getData();
+ }
+
+ if (mUseIncSupp) {
+ long ainInc = getDummyAlloc(ain);
+ long aoutInc = getDummyAlloc(aout);
+ mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp);
+ } else {
+ mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp);
+ }
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param slot
+ * @param ain
+ * @param aout
+ * @param v
+ * @param sc
+ */
+ protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
+ if (ain == null && aout == null) {
+ throw new RSIllegalArgumentException(
+ "At least one of ain or aout is required to be non-null.");
+ }
+
+ if (sc == null) {
+ forEach(slot, ain, aout, v);
+ return;
+ }
+ long in_id = 0;
+ long out_id = 0;
+ if (ain != null) {
+ in_id = ain.getID(mRS);
+ }
+ if (aout != null) {
+ out_id = aout.getID(mRS);
+ }
+
+ byte[] params = null;
+ if (v != null) {
+ params = v.getData();
+ }
+ if (mUseIncSupp) {
+ long ainInc = getDummyAlloc(ain);
+ long aoutInc = getDummyAlloc(aout);
+ mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
+ } else {
+ mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
+ }
+ }
+
+ Script(long id, RenderScript rs) {
+ super(id, rs);
+ mUseIncSupp = false;
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @hide
+ */
+ protected void forEach(int slot, Allocation[] ains, Allocation aout,
+ FieldPacker v) {
+ forEach(slot, ains, aout, v, null);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @hide
+ */
+ protected void forEach(int slot, Allocation[] ains, Allocation aout,
+ FieldPacker v, LaunchOptions sc) {
+ // TODO: Is this necessary if nScriptForEach calls validate as well?
+ mRS.validate();
+ if (ains != null) {
+ for (Allocation ain : ains) {
+ mRS.validateObject(ain);
+ }
+ }
+ mRS.validateObject(aout);
+
+ if (ains == null && aout == null) {
+ throw new RSIllegalArgumentException(
+ "At least one of ain or aout is required to be non-null.");
+ }
+
+ long[] in_ids;
+ if (ains != null) {
+ in_ids = new long[ains.length];
+ for (int index = 0; index < ains.length; ++index) {
+ in_ids[index] = ains[index].getID(mRS);
+ }
+ } else {
+ in_ids = null;
+ }
+
+ long out_id = 0;
+ if (aout != null) {
+ out_id = aout.getID(mRS);
+ }
+
+ byte[] params = null;
+ if (v != null) {
+ params = v.getData();
+ }
+
+ int[] limits = null;
+ if (sc != null) {
+ limits = new int[6];
+
+ limits[0] = sc.xstart;
+ limits[1] = sc.xend;
+ limits[2] = sc.ystart;
+ limits[3] = sc.yend;
+ limits[4] = sc.zstart;
+ limits[5] = sc.zend;
+ }
+
+ mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
+ }
+
+ /**
+ * Only intended for use by generated reflected code. (General reduction)
+ *
+ * @hide
+ */
+ protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
+ mRS.validate();
+ if (ains == null || ains.length < 1) {
+ throw new RSIllegalArgumentException(
+ "At least one input is required.");
+ }
+ if (aout == null) {
+ throw new RSIllegalArgumentException(
+ "aout is required to be non-null.");
+ }
+ for (Allocation ain : ains) {
+ mRS.validateObject(ain);
+ }
+
+ long[] in_ids = new long[ains.length];
+ for (int index = 0; index < ains.length; ++index) {
+ in_ids[index] = ains[index].getID(mRS);
+ }
+ long out_id = aout.getID(mRS);
+
+ int[] limits = null;
+ if (sc != null) {
+ limits = new int[6];
+
+ limits[0] = sc.xstart;
+ limits[1] = sc.xend;
+ limits[2] = sc.ystart;
+ limits[3] = sc.yend;
+ limits[4] = sc.zstart;
+ limits[5] = sc.zend;
+ }
+
+ mRS.nScriptReduce(getID(mRS), slot, in_ids, out_id, limits);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, float v) {
+ mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, double v) {
+ mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, int v) {
+ mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, long v) {
+ mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, boolean v) {
+ mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param o
+ */
+ public void setVar(int index, BaseObj o) {
+ if (mUseIncSupp) {
+ long oInc = getDummyAlloc((Allocation)o);
+ mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp);
+ } else {
+ mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp);
+ }
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ */
+ public void setVar(int index, FieldPacker v) {
+ mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp);
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ * @param index
+ * @param v
+ * @param e
+ * @param dims
+ */
+ public void setVar(int index, FieldPacker v, Element e, int[] dims) {
+ if (mUseIncSupp) {
+ long dElement = e.getDummyElement(mRS);
+ mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp);
+ } else {
+ mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp);
+ }
+ }
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ */
+ public static class Builder {
+ RenderScript mRS;
+
+ Builder(RenderScript rs) {
+ mRS = rs;
+ }
+ }
+
+
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ */
+ public static class FieldBase {
+ protected Element mElement;
+ protected Allocation mAllocation;
+
+ protected void init(RenderScript rs, int dimx) {
+ mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT);
+ }
+
+ protected void init(RenderScript rs, int dimx, int usages) {
+ mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages);
+ }
+
+ protected FieldBase() {
+ }
+
+ public Element getElement() {
+ return mElement;
+ }
+
+ public Type getType() {
+ return mAllocation.getType();
+ }
+
+ public Allocation getAllocation() {
+ return mAllocation;
+ }
+
+ //@Override
+ public void updateAllocation() {
+ }
+ }
+
+
+ /**
+ * Class for specifying the specifics about how a kernel will be
+ * launched.
+ *
+ * This class can specify a potential range of cells on which to
+ * run a kernel. If no set is called for a dimension then this
+ * class will have no impact on that dimension when the kernel
+ * is executed.
+ *
+ * The forEach kernel launch will operate over the intersection of
+ * the dimensions.
+ *
+ * Example:
+ * LaunchOptions with setX(5, 15)
+ * Allocation with dimension X=10, Y=10
+ * The resulting forEach run would execute over:
+ * x = 5 to 9 (inclusive) and
+ * y = 0 to 9 (inclusive).
+ *
+ */
+ public static final class LaunchOptions {
+ private int xstart = 0;
+ private int ystart = 0;
+ private int xend = 0;
+ private int yend = 0;
+ private int zstart = 0;
+ private int zend = 0;
+ private int strategy;
+
+ /**
+ * Set the X range. xstartArg is the lowest coordinate of the range,
+ * and xendArg-1 is the highest coordinate of the range.
+ *
+ * @param xstartArg Must be >= 0
+ * @param xendArg Must be > xstartArg
+ *
+ * @return LaunchOptions
+ */
+ public LaunchOptions setX(int xstartArg, int xendArg) {
+ if (xstartArg < 0 || xendArg <= xstartArg) {
+ throw new RSIllegalArgumentException("Invalid dimensions");
+ }
+ xstart = xstartArg;
+ xend = xendArg;
+ return this;
+ }
+
+ /**
+ * Set the Y range. ystartArg is the lowest coordinate of the range,
+ * and yendArg-1 is the highest coordinate of the range.
+ *
+ * @param ystartArg Must be >= 0
+ * @param yendArg Must be > ystartArg
+ *
+ * @return LaunchOptions
+ */
+ public LaunchOptions setY(int ystartArg, int yendArg) {
+ if (ystartArg < 0 || yendArg <= ystartArg) {
+ throw new RSIllegalArgumentException("Invalid dimensions");
+ }
+ ystart = ystartArg;
+ yend = yendArg;
+ return this;
+ }
+
+ /**
+ * Set the Z range. zstartArg is the lowest coordinate of the range,
+ * and zendArg-1 is the highest coordinate of the range.
+ *
+ * @param zstartArg Must be >= 0
+ * @param zendArg Must be > zstartArg
+ *
+ * @return LaunchOptions
+ */
+ public LaunchOptions setZ(int zstartArg, int zendArg) {
+ if (zstartArg < 0 || zendArg <= zstartArg) {
+ throw new RSIllegalArgumentException("Invalid dimensions");
+ }
+ zstart = zstartArg;
+ zend = zendArg;
+ return this;
+ }
+
+
+ /**
+ * Returns the current X start
+ *
+ * @return int current value
+ */
+ public int getXStart() {
+ return xstart;
+ }
+ /**
+ * Returns the current X end
+ *
+ * @return int current value
+ */
+ public int getXEnd() {
+ return xend;
+ }
+ /**
+ * Returns the current Y start
+ *
+ * @return int current value
+ */
+ public int getYStart() {
+ return ystart;
+ }
+ /**
+ * Returns the current Y end
+ *
+ * @return int current value
+ */
+ public int getYEnd() {
+ return yend;
+ }
+ /**
+ * Returns the current Z start
+ *
+ * @return int current value
+ */
+ public int getZStart() {
+ return zstart;
+ }
+ /**
+ * Returns the current Z end
+ *
+ * @return int current value
+ */
+ public int getZEnd() {
+ return zend;
+ }
+
+ }
+}
diff --git a/androidx/renderscript/ScriptC.java b/androidx/renderscript/ScriptC.java
new file mode 100644
index 0000000..31201b1
--- /dev/null
+++ b/androidx/renderscript/ScriptC.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map.Entry;
+import java.util.HashMap;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * The superclass for all user-defined scripts. This is only
+ * intended to be used by the generated derived classes.
+ **/
+public class ScriptC extends Script {
+ private static final String TAG = "ScriptC";
+
+ /**
+ * Only intended for use by the generated derived classes.
+ *
+ * @param id
+ * @param rs
+ */
+ protected ScriptC(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Only intended for use by the generated derived classes.
+ *
+ *
+ * @param rs
+ * @param resources
+ * @param resourceID
+ */
+ protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
+ super(0, rs);
+ long id = internalCreate(rs, resources, resourceID);
+ if (id == 0) {
+ throw new RSRuntimeException("Loading of ScriptC script failed.");
+ }
+ setID(id);
+ }
+
+ /**
+ * Only intended for use by the generated derived classes.
+ *
+ * @param rs
+ * @param resName
+ * @param bitcode32
+ * @param bitcode64
+ */
+ protected ScriptC(RenderScript rs, String resName, byte[] bitcode32, byte[] bitcode64) {
+ super(0, rs);
+ long id = 0;
+ if (RenderScript.sPointerSize == 4) {
+ id = internalStringCreate(rs, resName, bitcode32);
+ } else {
+ id = internalStringCreate(rs, resName, bitcode64);
+ }
+ if (id == 0) {
+ throw new RSRuntimeException("Loading of ScriptC script failed.");
+ }
+ setID(id);
+ }
+
+ private static synchronized long internalCreate(RenderScript rs, Resources resources, int resourceID) {
+ byte[] pgm;
+ int pgmLength;
+ InputStream is = resources.openRawResource(resourceID);
+ try {
+ try {
+ pgm = new byte[1024];
+ pgmLength = 0;
+ while(true) {
+ int bytesLeft = pgm.length - pgmLength;
+ if (bytesLeft == 0) {
+ byte[] buf2 = new byte[pgm.length * 2];
+ System.arraycopy(pgm, 0, buf2, 0, pgm.length);
+ pgm = buf2;
+ bytesLeft = pgm.length - pgmLength;
+ }
+ int bytesRead = is.read(pgm, pgmLength, bytesLeft);
+ if (bytesRead <= 0) {
+ break;
+ }
+ pgmLength += bytesRead;
+ }
+ } finally {
+ is.close();
+ }
+ } catch(IOException e) {
+ throw new Resources.NotFoundException();
+ }
+
+ String resName = resources.getResourceEntryName(resourceID);
+ String cachePath = rs.getApplicationContext().getCacheDir().toString();
+
+ // Log.v(TAG, "Create script for resource = " + resName + ", " + pgmLength + ", " + pgm);
+ //Log.v(TAG, " path = " + cachePath);
+ return rs.nScriptCCreate(resName, cachePath, pgm, pgmLength);
+ }
+
+ private static synchronized long internalStringCreate(RenderScript rs, String resName, byte[] bitcode) {
+ // Log.v(TAG, "Create script for resource = " + resName);
+ String cachePath = rs.getApplicationContext().getCacheDir().toString();
+ return rs.nScriptCCreate(resName, cachePath, bitcode, bitcode.length);
+ }
+
+}
diff --git a/androidx/renderscript/ScriptGroup.java b/androidx/renderscript/ScriptGroup.java
new file mode 100644
index 0000000..ba8cf4b
--- /dev/null
+++ b/androidx/renderscript/ScriptGroup.java
@@ -0,0 +1,1180 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+import android.util.Pair;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A group of kernels that are executed
+ * together with one execution call as if they were a single kernel
+ * <p>
+ * In addition to kernels, a script group may contain invocable functions as well.
+ * A script group may take inputs and generate outputs, which are consumed and
+ * produced by its member kernels.
+ * Inside a script group, outputs from one kernel can be passed to another kernel as inputs.
+ * The API disallows cyclic dependencies among kernels in a script group,
+ * effectively making it a directed acyclic graph (DAG) of kernels.
+ * <p>
+ * Grouping kernels together allows for more efficient execution. For example,
+ * runtime and compiler optimization can be applied to reduce computation and
+ * communication overhead, and to make better use of the CPU and the GPU.
+ **/
+public final class ScriptGroup extends BaseObj {
+ //FIXME: Change 23 to the codename when that is decided.
+ private static final int MIN_API_VERSION = 23;
+ private static final String TAG = "ScriptGroup";
+ IO mOutputs[];
+ IO mInputs[];
+ private boolean mUseIncSupp = false;
+ private ArrayList<Node> mNodes = new ArrayList<Node>();
+
+ static class IO {
+ Script.KernelID mKID;
+ Allocation mAllocation;
+
+ IO(Script.KernelID s) {
+ mKID = s;
+ }
+ }
+
+ static class ConnectLine {
+ ConnectLine(Type t, Script.KernelID from, Script.KernelID to) {
+ mFrom = from;
+ mToK = to;
+ mAllocationType = t;
+ }
+
+ ConnectLine(Type t, Script.KernelID from, Script.FieldID to) {
+ mFrom = from;
+ mToF = to;
+ mAllocationType = t;
+ }
+
+ Script.FieldID mToF;
+ Script.KernelID mToK;
+ Script.KernelID mFrom;
+ Type mAllocationType;
+ Allocation mAllocation;
+ }
+
+ static class Node {
+ Script mScript;
+ ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>();
+ ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>();
+ ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>();
+ int dagNumber;
+ boolean mSeen;
+ int mOrder;
+
+ Node mNext;
+
+ Node(Script s) {
+ mScript = s;
+ }
+ }
+
+ /**
+ * An opaque class for closures
+ * <p>
+ * A closure represents a function call to a kernel or invocable function,
+ * combined with arguments and values for global variables. A closure is
+ * created using the {@link Builder2#addKernel} or
+ * {@link Builder2#addInvoke}
+ * method.
+ */
+
+ public static final class Closure extends BaseObj {
+ private Object[] mArgs;
+ private Allocation mReturnValue;
+ private Map<Script.FieldID, Object> mBindings;
+
+ private Future mReturnFuture;
+ private Map<Script.FieldID, Future> mGlobalFuture;
+
+ private FieldPacker mFP;
+
+ private static final String TAG = "Closure";
+
+ Closure(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
+ Object[] args, Map<Script.FieldID, Object> globals) {
+ super(0, rs);
+
+ if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+ throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+ }
+
+ mArgs = args;
+ mReturnValue = Allocation.createTyped(rs, returnType);
+ mBindings = globals;
+ mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+ int numValues = args.length + globals.size();
+
+ long[] fieldIDs = new long[numValues];
+ long[] values = new long[numValues];
+ int[] sizes = new int[numValues];
+ long[] depClosures = new long[numValues];
+ long[] depFieldIDs = new long[numValues];
+
+ int i;
+ for (i = 0; i < args.length; i++) {
+ fieldIDs[i] = 0;
+ retrieveValueAndDependenceInfo(rs, i, null, args[i],
+ values, sizes, depClosures, depFieldIDs);
+ }
+ for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+ Object obj = entry.getValue();
+ Script.FieldID fieldID = entry.getKey();
+ fieldIDs[i] = fieldID.getID(rs);
+ retrieveValueAndDependenceInfo(rs, i, fieldID, obj,
+ values, sizes, depClosures, depFieldIDs);
+ i++;
+ }
+
+ long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs),
+ fieldIDs, values, sizes, depClosures, depFieldIDs);
+
+ setID(id);
+ }
+
+ Closure(RenderScript rs, Script.InvokeID invokeID,
+ Object[] args, Map<Script.FieldID, Object> globals) {
+ super(0, rs);
+
+ if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+ throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+ }
+
+ mFP = FieldPacker.createFromArray(args);
+
+ mArgs = args;
+ mBindings = globals;
+ mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+ int numValues = globals.size();
+
+ long[] fieldIDs = new long[numValues];
+ long[] values = new long[numValues];
+ int[] sizes = new int[numValues];
+ long[] depClosures = new long[numValues];
+ long[] depFieldIDs = new long[numValues];
+
+ int i = 0;
+ for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+ Object obj = entry.getValue();
+ Script.FieldID fieldID = entry.getKey();
+ fieldIDs[i] = fieldID.getID(rs);
+ retrieveValueAndDependenceInfo(rs, i, fieldID, obj, values,
+ sizes, depClosures, depFieldIDs);
+ i++;
+ }
+
+ long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
+ values, sizes);
+
+ setID(id);
+ }
+
+ private void retrieveValueAndDependenceInfo(RenderScript rs,
+ int index, Script.FieldID fid, Object obj,
+ long[] values, int[] sizes,
+ long[] depClosures,
+ long[] depFieldIDs) {
+
+ if (obj instanceof Future) {
+ Future f = (Future)obj;
+ obj = f.getValue();
+ depClosures[index] = f.getClosure().getID(rs);
+ Script.FieldID fieldID = f.getFieldID();
+ depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
+ } else {
+ depClosures[index] = 0;
+ depFieldIDs[index] = 0;
+ }
+
+ if (obj instanceof Input) {
+ Input unbound = (Input)obj;
+ if (index < mArgs.length) {
+ unbound.addReference(this, index);
+ } else {
+ unbound.addReference(this, fid);
+ }
+ values[index] = 0;
+ sizes[index] = 0;
+ } else {
+ ValueAndSize vs = new ValueAndSize(rs, obj);
+ values[index] = vs.value;
+ sizes[index] = vs.size;
+ }
+ }
+
+ /**
+ * Returns the future for the return value
+ *
+ * @return a future
+ */
+
+ public Future getReturn() {
+ if (mReturnFuture == null) {
+ mReturnFuture = new Future(this, null, mReturnValue);
+ }
+
+ return mReturnFuture;
+ }
+
+ /**
+ * Returns the future for a global variable
+ *
+ * @param field the field ID for the global variable
+ * @return a future
+ */
+
+ public Future getGlobal(Script.FieldID field) {
+ Future f = mGlobalFuture.get(field);
+
+ if (f == null) {
+ // If the field is not bound to this closure, this will return a future
+ // without an associated value (reference). So this is not working for
+ // cross-module (cross-script) linking in this case where a field not
+ // explicitly bound.
+ Object obj = mBindings.get(field);
+ if (obj instanceof Future) {
+ obj = ((Future)obj).getValue();
+ }
+ f = new Future(this, field, obj);
+ mGlobalFuture.put(field, f);
+ }
+
+ return f;
+ }
+
+ void setArg(int index, Object obj) {
+ if (obj instanceof Future) {
+ obj = ((Future)obj).getValue();
+ }
+ mArgs[index] = obj;
+ ValueAndSize vs = new ValueAndSize(mRS, obj);
+ mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
+ }
+
+ void setGlobal(Script.FieldID fieldID, Object obj) {
+ if (obj instanceof Future) {
+ obj = ((Future)obj).getValue();
+ }
+ mBindings.put(fieldID, obj);
+ ValueAndSize vs = new ValueAndSize(mRS, obj);
+ mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size);
+ }
+
+ private static final class ValueAndSize {
+ public ValueAndSize(RenderScript rs, Object obj) {
+ if (obj instanceof Allocation) {
+ value = ((Allocation)obj).getID(rs);
+ size = -1;
+ } else if (obj instanceof Boolean) {
+ value = ((Boolean)obj).booleanValue() ? 1 : 0;
+ size = 4;
+ } else if (obj instanceof Integer) {
+ value = ((Integer)obj).longValue();
+ size = 4;
+ } else if (obj instanceof Long) {
+ value = ((Long)obj).longValue();
+ size = 8;
+ } else if (obj instanceof Float) {
+ value = Float.floatToRawIntBits(((Float)obj).floatValue());
+ size = 4;
+ } else if (obj instanceof Double) {
+ value = Double.doubleToRawLongBits(((Double)obj).doubleValue());
+ size = 8;
+ }
+ }
+ public long value;
+ public int size;
+ }
+ }
+
+ /**
+ * An opaque class for futures
+ * <p>
+ * A future represents an output of a closure, either the return value of
+ * the function, or the value of a global variable written by the function.
+ * A future is created by calling the {@link Closure#getReturn} or
+ * {@link Closure#getGlobal} method.
+ */
+
+ public static final class Future {
+ Closure mClosure;
+ Script.FieldID mFieldID;
+ Object mValue;
+
+ Future(Closure closure, Script.FieldID fieldID, Object value) {
+ mClosure = closure;
+ mFieldID = fieldID;
+ mValue = value;
+ }
+
+ Closure getClosure() { return mClosure; }
+ Script.FieldID getFieldID() { return mFieldID; }
+ Object getValue() { return mValue; }
+ }
+
+ /**
+ * An opaque class for unbound values (used for script group inputs)
+ * <p>
+ * Created by calling the {@link Builder2#addInput} method. The value
+ * is assigned in {@link ScriptGroup#execute(Object...)} method as
+ * one of its arguments. Arguments to the execute method should be in
+ * the same order as intputs are added using the addInput method.
+ */
+
+ public static final class Input {
+ // Either mFieldID or mArgIndex should be set but not both.
+ List<Pair<Closure, Script.FieldID>> mFieldID;
+ // -1 means unset. Legal values are 0 .. n-1, where n is the number of
+ // arguments for the referencing closure.
+ List<Pair<Closure, Integer>> mArgIndex;
+ Object mValue;
+
+ Input() {
+ mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>();
+ mArgIndex = new ArrayList<Pair<Closure, Integer>>();
+ }
+
+ void addReference(Closure closure, int index) {
+ mArgIndex.add(Pair.create(closure, Integer.valueOf(index)));
+ }
+
+ void addReference(Closure closure, Script.FieldID fieldID) {
+ mFieldID.add(Pair.create(closure, fieldID));
+ }
+
+ void set(Object value) {
+ mValue = value;
+ for (Pair<Closure, Integer> p : mArgIndex) {
+ Closure closure = p.first;
+ int index = p.second.intValue();
+ closure.setArg(index, value);
+ }
+ for (Pair<Closure, Script.FieldID> p : mFieldID) {
+ Closure closure = p.first;
+ Script.FieldID fieldID = p.second;
+ closure.setGlobal(fieldID, value);
+ }
+ }
+
+ Object get() { return mValue; }
+ }
+
+ private String mName;
+ private List<Closure> mClosures;
+ private List<Input> mInputs2;
+ private Future[] mOutputs2;
+
+ ScriptGroup(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ ScriptGroup(RenderScript rs, String name, List<Closure> closures,
+ List<Input> inputs, Future[] outputs) {
+ super(0, rs);
+
+ if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+ throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+ }
+ mName = name;
+ mClosures = closures;
+ mInputs2 = inputs;
+ mOutputs2 = outputs;
+
+ long[] closureIDs = new long[closures.size()];
+ for (int i = 0; i < closureIDs.length; i++) {
+ closureIDs[i] = closures.get(i).getID(rs);
+ }
+ String cachePath = rs.getApplicationContext().getCacheDir().toString();
+ long id = rs.nScriptGroup2Create(name, cachePath, closureIDs);
+ setID(id);
+ }
+
+ /**
+ * Executes a script group
+ *
+ * @param inputs inputs to the script group
+ * @return outputs of the script group as an array of objects
+ */
+
+ public Object[] execute(Object... inputs) {
+ if (inputs.length < mInputs2.size()) {
+ Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+ "less than expected " + mInputs2.size());
+ return null;
+ }
+
+ if (inputs.length > mInputs2.size()) {
+ Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+ "more than expected " + mInputs2.size());
+ }
+
+ for (int i = 0; i < mInputs2.size(); i++) {
+ Object obj = inputs[i];
+ if (obj instanceof Future || obj instanceof Input) {
+ Log.e(TAG, this.toString() + ": input " + i +
+ " is a future or unbound value");
+ return null;
+ }
+ Input unbound = mInputs2.get(i);
+ unbound.set(obj);
+ }
+
+ mRS.nScriptGroup2Execute(getID(mRS));
+
+ Object[] outputObjs = new Object[mOutputs2.length];
+ int i = 0;
+ for (Future f : mOutputs2) {
+ Object output = f.getValue();
+ if (output instanceof Input) {
+ output = ((Input)output).get();
+ }
+ outputObjs[i++] = output;
+ }
+ return outputObjs;
+ }
+
+ /**
+ * Sets an input of the ScriptGroup. This specifies an
+ * Allocation to be used for kernels that require an input
+ * Allocation provided from outside of the ScriptGroup.
+ *
+ * @deprecated Set arguments to {@link #execute(Object...)} instead.
+ *
+ * @param s The ID of the kernel where the allocation should be
+ * connected.
+ * @param a The allocation to connect.
+ */
+ @Deprecated
+ public void setInput(Script.KernelID s, Allocation a) {
+ for (int ct=0; ct < mInputs.length; ct++) {
+ if (mInputs[ct].mKID == s) {
+ mInputs[ct].mAllocation = a;
+ if (!mUseIncSupp) {
+ mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a));
+ }
+ return;
+ }
+ }
+ throw new RSIllegalArgumentException("Script not found");
+ }
+
+ /**
+ * Sets an output of the ScriptGroup. This specifies an
+ * Allocation to be used for the kernels that require an output
+ * Allocation visible after the ScriptGroup is executed.
+ *
+ * @deprecated Use return value of {@link #execute(Object...)} instead.
+ *
+ * @param s The ID of the kernel where the allocation should be
+ * connected.
+ * @param a The allocation to connect.
+ */
+ @Deprecated
+ public void setOutput(Script.KernelID s, Allocation a) {
+ for (int ct=0; ct < mOutputs.length; ct++) {
+ if (mOutputs[ct].mKID == s) {
+ mOutputs[ct].mAllocation = a;
+ if (!mUseIncSupp) {
+ mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a));
+ }
+ return;
+ }
+ }
+ throw new RSIllegalArgumentException("Script not found");
+ }
+
+ /**
+ * Execute the ScriptGroup. This will run all the kernels in
+ * the ScriptGroup. No internal connection results will be visible
+ * after execution of the ScriptGroup.
+ *
+ * If Incremental Support for intrinsics is needed, the execution
+ * will take the naive path: execute kernels one by one in the
+ * correct order.
+ *
+ * @deprecated Use {@link #execute} instead.
+ */
+ @Deprecated
+ public void execute() {
+ if (!mUseIncSupp) {
+ mRS.nScriptGroupExecute(getID(mRS));
+ } else {
+ // setup the allocations.
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ Node n = mNodes.get(ct);
+ for (int ct2=0; ct2 < n.mOutputs.size(); ct2++) {
+ ConnectLine l = n.mOutputs.get(ct2);
+ if (l.mAllocation !=null) {
+ continue;
+ }
+
+ //create allocation here
+ Allocation alloc = Allocation.createTyped(mRS, l.mAllocationType,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
+
+ l.mAllocation = alloc;
+ for (int ct3=ct2+1; ct3 < n.mOutputs.size(); ct3++) {
+ if (n.mOutputs.get(ct3).mFrom == l.mFrom) {
+ n.mOutputs.get(ct3).mAllocation = alloc;
+ }
+ }
+ }
+ }
+ for (Node node : mNodes) {
+ for (Script.KernelID kernel : node.mKernels) {
+ Allocation ain = null;
+ Allocation aout = null;
+
+ for (ConnectLine nodeInput : node.mInputs) {
+ if (nodeInput.mToK == kernel) {
+ ain = nodeInput.mAllocation;
+ }
+ }
+
+ for (IO sgInput : mInputs) {
+ if (sgInput.mKID == kernel) {
+ ain = sgInput.mAllocation;
+ }
+ }
+
+ for (ConnectLine nodeOutput : node.mOutputs) {
+ if (nodeOutput.mFrom == kernel) {
+ aout = nodeOutput.mAllocation;
+ }
+ }
+
+ for (IO sgOutput : mOutputs) {
+ if (sgOutput.mKID == kernel) {
+ aout = sgOutput.mAllocation;
+ }
+ }
+
+ kernel.mScript.forEach(kernel.mSlot, ain, aout, null);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Helper class to build a ScriptGroup. A ScriptGroup is
+ * created in two steps.
+ * <p>
+ * First, all kernels to be used by the ScriptGroup should be added.
+ * <p>
+ * Second, add connections between kernels. There are two types
+ * of connections: kernel to kernel and kernel to field.
+ * Kernel to kernel allows a kernel's output to be passed to
+ * another kernel as input. Kernel to field allows the output of
+ * one kernel to be bound as a script global. Kernel to kernel is
+ * higher performance and should be used where possible.
+ * <p>
+ * A ScriptGroup must contain a single directed acyclic graph (DAG); it
+ * cannot contain cycles. Currently, all kernels used in a ScriptGroup
+ * must come from different Script objects. Additionally, all kernels
+ * in a ScriptGroup must have at least one input, output, or internal
+ * connection.
+ * <p>
+ * Once all connections are made, a call to {@link #create} will
+ * return the ScriptGroup object.
+ *
+ * @deprecated Use {@link Builder2} instead.
+ *
+ */
+ @Deprecated
+ public static final class Builder {
+ private RenderScript mRS;
+ private ArrayList<Node> mNodes = new ArrayList<Node>();
+ private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>();
+ private int mKernelCount;
+ private boolean mUseIncSupp = false;
+
+ /**
+ * Create a Builder for generating a ScriptGroup.
+ *
+ *
+ * @param rs The RenderScript context.
+ */
+ public Builder(RenderScript rs) {
+ mRS = rs;
+ }
+
+ // do a DFS from original node, looking for original node
+ // any cycle that could be created must contain original node
+ private void validateCycle(Node target, Node original) {
+ for (int ct = 0; ct < target.mOutputs.size(); ct++) {
+ final ConnectLine cl = target.mOutputs.get(ct);
+ if (cl.mToK != null) {
+ Node tn = findNode(cl.mToK.mScript);
+ if (tn.equals(original)) {
+ throw new RSInvalidStateException("Loops in group not allowed.");
+ }
+ validateCycle(tn, original);
+ }
+ if (cl.mToF != null) {
+ Node tn = findNode(cl.mToF.mScript);
+ if (tn.equals(original)) {
+ throw new RSInvalidStateException("Loops in group not allowed.");
+ }
+ validateCycle(tn, original);
+ }
+ }
+ }
+
+ private void mergeDAGs(int valueUsed, int valueKilled) {
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ if (mNodes.get(ct).dagNumber == valueKilled)
+ mNodes.get(ct).dagNumber = valueUsed;
+ }
+ }
+
+ private void validateDAGRecurse(Node n, int dagNumber) {
+ // combine DAGs if this node has been seen already
+ if (n.dagNumber != 0 && n.dagNumber != dagNumber) {
+ mergeDAGs(n.dagNumber, dagNumber);
+ return;
+ }
+
+ n.dagNumber = dagNumber;
+ for (int ct=0; ct < n.mOutputs.size(); ct++) {
+ final ConnectLine cl = n.mOutputs.get(ct);
+ if (cl.mToK != null) {
+ Node tn = findNode(cl.mToK.mScript);
+ validateDAGRecurse(tn, dagNumber);
+ }
+ if (cl.mToF != null) {
+ Node tn = findNode(cl.mToF.mScript);
+ validateDAGRecurse(tn, dagNumber);
+ }
+ }
+ }
+
+ private void validateDAG() {
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ Node n = mNodes.get(ct);
+ if (n.mInputs.size() == 0) {
+ if (n.mOutputs.size() == 0 && mNodes.size() > 1) {
+ String msg = "Groups cannot contain unconnected scripts";
+ throw new RSInvalidStateException(msg);
+ }
+ validateDAGRecurse(n, ct+1);
+ }
+ }
+ int dagNumber = mNodes.get(0).dagNumber;
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ if (mNodes.get(ct).dagNumber != dagNumber) {
+ throw new RSInvalidStateException("Multiple DAGs in group not allowed.");
+ }
+ }
+ }
+
+ private Node findNode(Script s) {
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ if (s == mNodes.get(ct).mScript) {
+ return mNodes.get(ct);
+ }
+ }
+ return null;
+ }
+
+ private Node findNode(Script.KernelID k) {
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ Node n = mNodes.get(ct);
+ for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
+ if (k == n.mKernels.get(ct2)) {
+ return n;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds a Kernel to the group.
+ *
+ *
+ * @param k The kernel to add.
+ *
+ * @return Builder Returns this.
+ */
+ public Builder addKernel(Script.KernelID k) {
+ if (mLines.size() != 0) {
+ throw new RSInvalidStateException(
+ "Kernels may not be added once connections exist.");
+ }
+ if (k.mScript.isIncSupp()) {
+ mUseIncSupp = true;
+ }
+ //android.util.Log.v("RSR", "addKernel 1 k=" + k);
+ if (findNode(k) != null) {
+ return this;
+ }
+ //android.util.Log.v("RSR", "addKernel 2 ");
+ mKernelCount++;
+ Node n = findNode(k.mScript);
+ if (n == null) {
+ //android.util.Log.v("RSR", "addKernel 3 ");
+ n = new Node(k.mScript);
+ mNodes.add(n);
+ }
+ n.mKernels.add(k);
+ return this;
+ }
+
+ /**
+ * Adds a connection to the group.
+ *
+ *
+ * @param t The type of the connection. This is used to
+ * determine the kernel launch sizes on the source side
+ * of this connection.
+ * @param from The source for the connection.
+ * @param to The destination of the connection.
+ *
+ * @return Builder Returns this
+ */
+ public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) {
+ //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
+ Node nf = findNode(from);
+ if (nf == null) {
+ throw new RSInvalidStateException("From script not found.");
+ }
+
+ Node nt = findNode(to.mScript);
+ if (nt == null) {
+ throw new RSInvalidStateException("To script not found.");
+ }
+
+ ConnectLine cl = new ConnectLine(t, from, to);
+ mLines.add(new ConnectLine(t, from, to));
+
+ nf.mOutputs.add(cl);
+ nt.mInputs.add(cl);
+
+ validateCycle(nf, nf);
+ return this;
+ }
+
+ /**
+ * Adds a connection to the group.
+ *
+ *
+ * @param t The type of the connection. This is used to
+ * determine the kernel launch sizes for both sides of
+ * this connection.
+ * @param from The source for the connection.
+ * @param to The destination of the connection.
+ *
+ * @return Builder Returns this
+ */
+ public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) {
+ //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
+ Node nf = findNode(from);
+ if (nf == null) {
+ throw new RSInvalidStateException("From script not found.");
+ }
+
+ Node nt = findNode(to);
+ if (nt == null) {
+ throw new RSInvalidStateException("To script not found.");
+ }
+
+ ConnectLine cl = new ConnectLine(t, from, to);
+ mLines.add(new ConnectLine(t, from, to));
+
+ nf.mOutputs.add(cl);
+ nt.mInputs.add(cl);
+
+ validateCycle(nf, nf);
+ return this;
+ }
+
+ /**
+ * Calculate the order of each node.
+ *
+ *
+ * @return Success or Fail
+ */
+ private boolean calcOrderRecurse(Node node0, int depth) {
+ node0.mSeen = true;
+ if (node0.mOrder < depth) {
+ node0.mOrder = depth;
+ }
+ boolean ret = true;
+
+ for (ConnectLine link : node0.mOutputs) {
+ Node node1 = null;
+ if (link.mToF != null) {
+ node1 = findNode(link.mToF.mScript);
+ } else {
+ node1 = findNode(link.mToK.mScript);
+ }
+ if (node1.mSeen) {
+ return false;
+ }
+ ret &= calcOrderRecurse(node1, node0.mOrder + 1);
+ }
+
+ return ret;
+ }
+
+ private boolean calcOrder() {
+ boolean ret = true;
+ for (Node n0 : mNodes) {
+ if (n0.mInputs.size() == 0) {
+ for (Node n1 : mNodes) {
+ n1.mSeen = false;
+ }
+ ret &= calcOrderRecurse(n0, 1);
+ }
+ }
+
+ Collections.sort(mNodes, new Comparator<Node>() {
+ public int compare(Node n1, Node n2) {
+ return n1.mOrder - n2.mOrder;
+ }
+ });
+
+ return ret;
+ }
+
+ /**
+ * Creates the Script group.
+ *
+ *
+ * @return ScriptGroup The new ScriptGroup
+ */
+ public ScriptGroup create() {
+
+ if (mNodes.size() == 0) {
+ throw new RSInvalidStateException("Empty script groups are not allowed");
+ }
+
+ // reset DAG numbers in case we're building a second group
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ mNodes.get(ct).dagNumber = 0;
+ }
+ validateDAG();
+
+ ArrayList<IO> inputs = new ArrayList<IO>();
+ ArrayList<IO> outputs = new ArrayList<IO>();
+
+ long[] kernels = new long[mKernelCount];
+ int idx = 0;
+ for (int ct=0; ct < mNodes.size(); ct++) {
+ Node n = mNodes.get(ct);
+ for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
+ final Script.KernelID kid = n.mKernels.get(ct2);
+ kernels[idx++] = kid.getID(mRS);
+
+ boolean hasInput = false;
+ boolean hasOutput = false;
+ for (int ct3=0; ct3 < n.mInputs.size(); ct3++) {
+ if (n.mInputs.get(ct3).mToK == kid) {
+ hasInput = true;
+ }
+ }
+ for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) {
+ if (n.mOutputs.get(ct3).mFrom == kid) {
+ hasOutput = true;
+ }
+ }
+ if (!hasInput) {
+ inputs.add(new IO(kid));
+ }
+ if (!hasOutput) {
+ outputs.add(new IO(kid));
+ }
+ }
+ }
+ if (idx != mKernelCount) {
+ throw new RSRuntimeException("Count mismatch, should not happen.");
+ }
+
+ long id = 0;
+ if (!mUseIncSupp) {
+ long[] src = new long[mLines.size()];
+ long[] dstk = new long[mLines.size()];
+ long[] dstf = new long[mLines.size()];
+ long[] types = new long[mLines.size()];
+
+ for (int ct=0; ct < mLines.size(); ct++) {
+ ConnectLine cl = mLines.get(ct);
+ src[ct] = cl.mFrom.getID(mRS);
+ if (cl.mToK != null) {
+ dstk[ct] = cl.mToK.getID(mRS);
+ }
+ if (cl.mToF != null) {
+ dstf[ct] = cl.mToF.getID(mRS);
+ }
+ types[ct] = cl.mAllocationType.getID(mRS);
+ }
+ id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
+ if (id == 0) {
+ throw new RSRuntimeException("Object creation error, should not happen.");
+ }
+ } else {
+ //Calculate the order of the DAG so that script can run one after another.
+ calcOrder();
+ }
+
+ ScriptGroup sg = new ScriptGroup(id, mRS);
+ sg.mOutputs = new IO[outputs.size()];
+ for (int ct=0; ct < outputs.size(); ct++) {
+ sg.mOutputs[ct] = outputs.get(ct);
+ }
+
+ sg.mInputs = new IO[inputs.size()];
+ for (int ct=0; ct < inputs.size(); ct++) {
+ sg.mInputs[ct] = inputs.get(ct);
+ }
+ sg.mNodes = mNodes;
+ sg.mUseIncSupp = mUseIncSupp;
+ return sg;
+ }
+
+ }
+
+ /**
+ * Represents a binding of a value to a global variable in a
+ * kernel or invocable function. Used in closure creation.
+ */
+
+ public static final class Binding {
+ private final Script.FieldID mField;
+ private final Object mValue;
+
+ /**
+ * Returns a Binding object that binds value to field
+ *
+ * @param field the Script.FieldID of the global variable
+ * @param value the value
+ */
+
+ public Binding(Script.FieldID field, Object value) {
+ mField = field;
+ mValue = value;
+ }
+
+ /**
+ * Returns the field ID
+ */
+
+ public Script.FieldID getField() { return mField; }
+
+ /**
+ * Returns the value
+ */
+
+ public Object getValue() { return mValue; }
+ }
+
+ /**
+ * The builder class for creating script groups
+ * <p>
+ * A script group is created using closures (see class {@link Closure}).
+ * A closure is a function call to a kernel or
+ * invocable function. Each function argument or global variable accessed inside
+ * the function is bound to 1) a known value, 2) a script group input
+ * (see class {@link Input}), or 3) a
+ * future (see class {@link Future}).
+ * A future is the output of a closure, either the return value of the
+ * function or a global variable written by that function.
+ * <p>
+ * Closures are created using the {@link #addKernel} or {@link #addInvoke}
+ * methods.
+ * When a closure is created, futures from previously created closures
+ * can be used as its inputs.
+ * External script group inputs can be used as inputs to individual closures as well.
+ * An external script group input is created using the {@link #addInput} method.
+ * A script group is created by a call to the {@link #create} method, which
+ * accepts an array of futures as the outputs for the script group.
+ * <p>
+ * Closures in a script group can be evaluated in any order as long as the
+ * following conditions are met:
+ * 1) a closure must be evaluated before any other closures that take its
+ * futures as inputs;
+ * 2) all closures added before an invoke closure must be evaluated
+ * before it;
+ * and 3) all closures added after an invoke closure must be evaluated after
+ * it.
+ * As a special case, the order that the closures are added is a legal
+ * evaluation order. However, other evaluation orders are possible, including
+ * concurrently evaluating independent closures.
+ */
+
+ public static final class Builder2 {
+ RenderScript mRS;
+ List<Closure> mClosures;
+ List<Input> mInputs;
+ private static final String TAG = "ScriptGroup.Builder2";
+
+ /**
+ * Returns a Builder object
+ *
+ * @param rs the RenderScript context
+ */
+ public Builder2(RenderScript rs) {
+ mRS = rs;
+ mClosures = new ArrayList<Closure>();
+ mInputs = new ArrayList<Input>();
+ }
+
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param returnType Allocation type for the return value
+ * @param args arguments to the kernel function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+
+ private Closure addKernelInternal(Script.KernelID k, Type returnType, Object[] args,
+ Map<Script.FieldID, Object> globalBindings) {
+ Closure c = new Closure(mRS, k, returnType, args, globalBindings);
+ mClosures.add(c);
+ return c;
+ }
+
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param args arguments to the invocable function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+
+ private Closure addInvokeInternal(Script.InvokeID invoke, Object[] args,
+ Map<Script.FieldID, Object> globalBindings) {
+ Closure c = new Closure(mRS, invoke, args, globalBindings);
+ mClosures.add(c);
+ return c;
+ }
+
+ /**
+ * Adds a script group input
+ *
+ * @return a script group input, which can be used as an argument or a value to
+ * a global variable for creating closures
+ */
+
+ public Input addInput() {
+ Input unbound = new Input();
+ mInputs.add(unbound);
+ return unbound;
+ }
+
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
+ public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
+ ArrayList<Object> args = new ArrayList<Object>();
+ Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+ if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+ return null;
+ }
+ return addKernelInternal(k, returnType, args.toArray(), bindingMap);
+ }
+
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
+ public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
+ ArrayList<Object> args = new ArrayList<Object>();
+ Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+ if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+ return null;
+ }
+ return addInvokeInternal(invoke, args.toArray(), bindingMap);
+ }
+
+ /**
+ * Creates a script group
+ *
+ * @param name name for the script group. Legal names can only contain letters, digits,
+ * '-', or '_'. The name can be no longer than 100 characters.
+ * @param outputs futures intended as outputs of the script group
+ * @return a script group
+ */
+
+ public ScriptGroup create(String name, Future... outputs) {
+ if (name == null || name.isEmpty() || name.length() > 100 ||
+ !name.equals(name.replaceAll("[^a-zA-Z0-9-]", "_"))) {
+ throw new RSIllegalArgumentException("invalid script group name");
+ }
+ ScriptGroup ret = new ScriptGroup(mRS, name, mClosures, mInputs, outputs);
+ return ret;
+ }
+
+ private boolean seperateArgsAndBindings(Object[] argsAndBindings,
+ ArrayList<Object> args,
+ Map<Script.FieldID, Object> bindingMap) {
+ int i;
+ for (i = 0; i < argsAndBindings.length; i++) {
+ if (argsAndBindings[i] instanceof Binding) {
+ break;
+ }
+ args.add(argsAndBindings[i]);
+ }
+
+ for (; i < argsAndBindings.length; i++) {
+ if (!(argsAndBindings[i] instanceof Binding)) {
+ return false;
+ }
+ Binding b = (Binding)argsAndBindings[i];
+ bindingMap.put(b.getField(), b.getValue());
+ }
+
+ return true;
+ }
+
+ }
+
+}
+
+
diff --git a/androidx/renderscript/ScriptIntrinsic.java b/androidx/renderscript/ScriptIntrinsic.java
new file mode 100644
index 0000000..cf7b72e
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsic.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+/**
+ * Base class for all Intrinsic scripts. An intrinsic a script
+ * which implements a pre-defined function. Intrinsics are
+ * provided to provide effecient implemtations of common
+ * operations.
+ *
+ * Not intended for direct use.
+ **/
+public abstract class ScriptIntrinsic extends Script {
+ ScriptIntrinsic(long id, RenderScript rs) {
+ super(id, rs);
+ if (id == 0) {
+ throw new RSRuntimeException("Loading of ScriptIntrinsic failed.");
+ }
+ }
+}
diff --git a/androidx/renderscript/ScriptIntrinsic3DLUT.java b/androidx/renderscript/ScriptIntrinsic3DLUT.java
new file mode 100644
index 0000000..e7b6a07
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsic3DLUT.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ *
+ * Intrinsic for converting RGB to RGBA by using a 3D lookup table. The
+ * incoming r,g,b values are use as normalized x,y,z coordinates into a 3D
+ * allocation. The 8 nearest values are sampled and linearly interpolated. The
+ * result is placed in the output.
+ *
+ **/
+public class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
+ private Allocation mLUT;
+ private Element mElement;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ protected ScriptIntrinsic3DLUT(long id, RenderScript rs, Element e) {
+ super(id, rs);
+ mElement = e;
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8_4}
+ *
+ * The defaults tables are identity.
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for intputs and outputs
+ *
+ * @return ScriptIntrinsic3DLUT
+ */
+ public static ScriptIntrinsic3DLUT create(RenderScript rs, Element e) {
+ if (!e.isCompatible(Element.U8_4(rs))) {
+ throw new RSIllegalArgumentException("Element must be compatible with uchar4.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(8, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsic3DLUT si = new ScriptIntrinsic3DLUT(id, rs, e);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+ }
+
+ /**
+ * Sets the {@link androidx.renderscript.Allocation} to be used as
+ * the lookup table.
+ *
+ * The lookup table must use the same
+ * {@link androidx.renderscript.Element} as the intrinsic.
+ *
+ */
+
+ public void setLUT(Allocation lut) {
+ final Type t = lut.getType();
+
+ if (t.getZ() == 0) {
+ throw new RSIllegalArgumentException("LUT must be 3d.");
+ }
+
+ if (!t.getElement().isCompatible(mElement)) {
+ throw new RSIllegalArgumentException("LUT element type must match.");
+ }
+
+ mLUT = lut;
+ setVar(0, mLUT);
+ }
+
+
+ /**
+ * Invoke the kernel and apply the lookup to each cell of ain
+ * and copy to aout.
+ *
+ * @param ain Input allocation
+ * @param aout Output allocation
+ */
+ public void forEach(Allocation ain, Allocation aout) {
+ forEach(0, ain, aout, null);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 3, null, null);
+ }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicBLAS.java b/androidx/renderscript/ScriptIntrinsicBLAS.java
new file mode 100644
index 0000000..7d8e668
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBLAS.java
@@ -0,0 +1,4190 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.support.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ *
+ * ScriptIntrinsicBLAS class provides high performance RenderScript APIs to BLAS.
+ *
+ * The BLAS (Basic Linear Algebra Subprograms) are routines that provide standard
+ * building blocks for performing basic vector and matrix operations.
+ *
+ * For detailed description of BLAS, please refer to http://www.netlib.org/blas/
+ *
+ **/
+public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
+ private Allocation mLUT;
+ private static final int INTRINSIC_API_LEVEL = 23;
+
+ private ScriptIntrinsicBLAS(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ private static final int RsBlas_sdsdot = 1;
+ private static final int RsBlas_dsdot = 2;
+ private static final int RsBlas_sdot = 3;
+ private static final int RsBlas_ddot = 4;
+ private static final int RsBlas_cdotu_sub = 5;
+ private static final int RsBlas_cdotc_sub = 6;
+ private static final int RsBlas_zdotu_sub = 7;
+ private static final int RsBlas_zdotc_sub = 8;
+ private static final int RsBlas_snrm2 = 9;
+ private static final int RsBlas_sasum = 10;
+ private static final int RsBlas_dnrm2 = 11;
+ private static final int RsBlas_dasum = 12;
+ private static final int RsBlas_scnrm2 = 13;
+ private static final int RsBlas_scasum = 14;
+ private static final int RsBlas_dznrm2 = 15;
+ private static final int RsBlas_dzasum = 16;
+ private static final int RsBlas_isamax = 17;
+ private static final int RsBlas_idamax = 18;
+ private static final int RsBlas_icamax = 19;
+ private static final int RsBlas_izamax = 20;
+ private static final int RsBlas_sswap = 21;
+ private static final int RsBlas_scopy = 22;
+ private static final int RsBlas_saxpy = 23;
+ private static final int RsBlas_dswap = 24;
+ private static final int RsBlas_dcopy = 25;
+ private static final int RsBlas_daxpy = 26;
+ private static final int RsBlas_cswap = 27;
+ private static final int RsBlas_ccopy = 28;
+ private static final int RsBlas_caxpy = 29;
+ private static final int RsBlas_zswap = 30;
+ private static final int RsBlas_zcopy = 31;
+ private static final int RsBlas_zaxpy = 32;
+ private static final int RsBlas_srotg = 33;
+ private static final int RsBlas_srotmg = 34;
+ private static final int RsBlas_srot = 35;
+ private static final int RsBlas_srotm = 36;
+ private static final int RsBlas_drotg = 37;
+ private static final int RsBlas_drotmg = 38;
+ private static final int RsBlas_drot = 39;
+ private static final int RsBlas_drotm = 40;
+ private static final int RsBlas_sscal = 41;
+ private static final int RsBlas_dscal = 42;
+ private static final int RsBlas_cscal = 43;
+ private static final int RsBlas_zscal = 44;
+ private static final int RsBlas_csscal = 45;
+ private static final int RsBlas_zdscal = 46;
+ private static final int RsBlas_sgemv = 47;
+ private static final int RsBlas_sgbmv = 48;
+ private static final int RsBlas_strmv = 49;
+ private static final int RsBlas_stbmv = 50;
+ private static final int RsBlas_stpmv = 51;
+ private static final int RsBlas_strsv = 52;
+ private static final int RsBlas_stbsv = 53;
+ private static final int RsBlas_stpsv = 54;
+ private static final int RsBlas_dgemv = 55;
+ private static final int RsBlas_dgbmv = 56;
+ private static final int RsBlas_dtrmv = 57;
+ private static final int RsBlas_dtbmv = 58;
+ private static final int RsBlas_dtpmv = 59;
+ private static final int RsBlas_dtrsv = 60;
+ private static final int RsBlas_dtbsv = 61;
+ private static final int RsBlas_dtpsv = 62;
+ private static final int RsBlas_cgemv = 63;
+ private static final int RsBlas_cgbmv = 64;
+ private static final int RsBlas_ctrmv = 65;
+ private static final int RsBlas_ctbmv = 66;
+ private static final int RsBlas_ctpmv = 67;
+ private static final int RsBlas_ctrsv = 68;
+ private static final int RsBlas_ctbsv = 69;
+ private static final int RsBlas_ctpsv = 70;
+ private static final int RsBlas_zgemv = 71;
+ private static final int RsBlas_zgbmv = 72;
+ private static final int RsBlas_ztrmv = 73;
+ private static final int RsBlas_ztbmv = 74;
+ private static final int RsBlas_ztpmv = 75;
+ private static final int RsBlas_ztrsv = 76;
+ private static final int RsBlas_ztbsv = 77;
+ private static final int RsBlas_ztpsv = 78;
+ private static final int RsBlas_ssymv = 79;
+ private static final int RsBlas_ssbmv = 80;
+ private static final int RsBlas_sspmv = 81;
+ private static final int RsBlas_sger = 82;
+ private static final int RsBlas_ssyr = 83;
+ private static final int RsBlas_sspr = 84;
+ private static final int RsBlas_ssyr2 = 85;
+ private static final int RsBlas_sspr2 = 86;
+ private static final int RsBlas_dsymv = 87;
+ private static final int RsBlas_dsbmv = 88;
+ private static final int RsBlas_dspmv = 89;
+ private static final int RsBlas_dger = 90;
+ private static final int RsBlas_dsyr = 91;
+ private static final int RsBlas_dspr = 92;
+ private static final int RsBlas_dsyr2 = 93;
+ private static final int RsBlas_dspr2 = 94;
+ private static final int RsBlas_chemv = 95;
+ private static final int RsBlas_chbmv = 96;
+ private static final int RsBlas_chpmv = 97;
+ private static final int RsBlas_cgeru = 98;
+ private static final int RsBlas_cgerc = 99;
+ private static final int RsBlas_cher = 100;
+ private static final int RsBlas_chpr = 101;
+ private static final int RsBlas_cher2 = 102;
+ private static final int RsBlas_chpr2 = 103;
+ private static final int RsBlas_zhemv = 104;
+ private static final int RsBlas_zhbmv = 105;
+ private static final int RsBlas_zhpmv = 106;
+ private static final int RsBlas_zgeru = 107;
+ private static final int RsBlas_zgerc = 108;
+ private static final int RsBlas_zher = 109;
+ private static final int RsBlas_zhpr = 110;
+ private static final int RsBlas_zher2 = 111;
+ private static final int RsBlas_zhpr2 = 112;
+ private static final int RsBlas_sgemm = 113;
+ private static final int RsBlas_ssymm = 114;
+ private static final int RsBlas_ssyrk = 115;
+ private static final int RsBlas_ssyr2k = 116;
+ private static final int RsBlas_strmm = 117;
+ private static final int RsBlas_strsm = 118;
+ private static final int RsBlas_dgemm = 119;
+ private static final int RsBlas_dsymm = 120;
+ private static final int RsBlas_dsyrk = 121;
+ private static final int RsBlas_dsyr2k = 122;
+ private static final int RsBlas_dtrmm = 123;
+ private static final int RsBlas_dtrsm = 124;
+ private static final int RsBlas_cgemm = 125;
+ private static final int RsBlas_csymm = 126;
+ private static final int RsBlas_csyrk = 127;
+ private static final int RsBlas_csyr2k = 128;
+ private static final int RsBlas_ctrmm = 129;
+ private static final int RsBlas_ctrsm = 130;
+ private static final int RsBlas_zgemm = 131;
+ private static final int RsBlas_zsymm = 132;
+ private static final int RsBlas_zsyrk = 133;
+ private static final int RsBlas_zsyr2k = 134;
+ private static final int RsBlas_ztrmm = 135;
+ private static final int RsBlas_ztrsm = 136;
+ private static final int RsBlas_chemm = 137;
+ private static final int RsBlas_cherk = 138;
+ private static final int RsBlas_cher2k = 139;
+ private static final int RsBlas_zhemm = 140;
+ private static final int RsBlas_zherk = 141;
+ private static final int RsBlas_zher2k = 142;
+
+ // BLAS extensions start here
+ private static final int RsBlas_bnnm = 1000;
+
+ /**
+ * Create an intrinsic to access BLAS subroutines.
+ *
+ * @param rs The RenderScript context
+ * @return ScriptIntrinsicBLAS
+ */
+ public static ScriptIntrinsicBLAS create(RenderScript rs) {
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(13, Element.U32(rs).getID(rs), mUseIncSupp);
+ ScriptIntrinsicBLAS si = new ScriptIntrinsicBLAS(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+ }
+
+ /**
+ * @hide
+ */
+ @IntDef({NO_TRANSPOSE, TRANSPOSE, CONJ_TRANSPOSE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Transpose {}
+
+ /**
+ * @hide
+ */
+ @IntDef({UPPER, LOWER})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Uplo {}
+
+ /**
+ * @hide
+ */
+ @IntDef({NON_UNIT, UNIT})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Diag {}
+
+ /**
+ * @hide
+ */
+ @IntDef({LEFT, RIGHT})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Side {}
+
+ public static final int NO_TRANSPOSE = 111;
+ public static final int TRANSPOSE = 112;
+ public static final int CONJ_TRANSPOSE = 113;
+
+ public static final int UPPER = 121;
+ public static final int LOWER = 122;
+
+ public static final int NON_UNIT = 131;
+ public static final int UNIT = 132;
+
+ public static final int LEFT = 141;
+ public static final int RIGHT = 142;
+
+ static void validateSide(@Side int Side) {
+ if (Side != LEFT && Side != RIGHT) {
+ throw new RSRuntimeException("Invalid side passed to BLAS");
+ }
+ }
+
+ static void validateTranspose(@Transpose int Trans) {
+ if (Trans != NO_TRANSPOSE && Trans != TRANSPOSE &&
+ Trans != CONJ_TRANSPOSE) {
+ throw new RSRuntimeException("Invalid transpose passed to BLAS");
+ }
+ }
+
+ static void validateConjTranspose(@Transpose int Trans) {
+ if (Trans != NO_TRANSPOSE &&
+ Trans != CONJ_TRANSPOSE) {
+ throw new RSRuntimeException("Invalid transpose passed to BLAS");
+ }
+ }
+
+ static void validateDiag(@Diag int Diag) {
+ if (Diag != NON_UNIT && Diag != UNIT) {
+ throw new RSRuntimeException("Invalid diag passed to BLAS");
+ }
+ }
+
+ static void validateUplo(@Uplo int Uplo) {
+ if (Uplo != UPPER && Uplo != LOWER) {
+ throw new RSRuntimeException("Invalid uplo passed to BLAS");
+ }
+ }
+
+
+ /**
+ * Level 2 BLAS
+ */
+
+ static void validateGEMV(Element e, int TransA, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
+ validateTranspose(TransA);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = -1, expectedYDim = -1;
+ if (TransA == NO_TRANSPOSE) {
+ expectedXDim = 1 + (N - 1) * incX;
+ expectedYDim = 1 + (M - 1) * incY;
+ } else {
+ expectedXDim = 1 + (M - 1) * incX;
+ expectedYDim = 1 + (N - 1) * incY;
+ }
+ if (X.getType().getX() != expectedXDim ||
+ Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for GEMV");
+ }
+ }
+
+ /**
+ * SGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d58/sgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+ validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+ validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d8a/cgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+ validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZGEMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d40/zgemv_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+ validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d46/sgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+ // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+ validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
+ if (KL < 0 || KU < 0) {
+ throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+ }
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
+ }
+
+ /**
+ * DGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d3f/dgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+ // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+ validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
+ if (KL < 0 || KU < 0) {
+ throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+ }
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
+ }
+
+ /**
+ * CGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d75/cgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+ // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+ validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
+ if (KL < 0 || KU < 0) {
+ throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+ }
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
+ }
+
+ /**
+ * ZGBMV performs one of the matrix-vector operations
+ * y := alpha*A*x + beta*y or y := alpha*A**T*x + beta*y or y := alpha*A**H*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d46/zgbmv_8f.html
+ *
+ * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+ * but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+ * example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, m):
+ * for j in range(max(0, i-kl), min(i+ku+1, n)):
+ * b[i, j-i+kl] = a[i, j]
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param KL The number of sub-diagonals of the matrix A.
+ * @param KU The number of super-diagonals of the matrix A.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+ // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+ validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
+ if (KL < 0 || KU < 0) {
+ throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+ }
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
+ }
+
+ static void validateTRMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ validateTranspose(TransA);
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ int N = A.getType().getY();
+ if (A.getType().getX() != N) {
+ throw new RSRuntimeException("A must be a square matrix for TRMV");
+ }
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (incX <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for TRMV");
+ }
+ }
+
+ static int validateTPMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ validateTranspose(TransA);
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ if (!Ap.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (Ap.getType().getY() > 1) {
+ throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+ }
+
+ int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+ //is it really doing anything?
+ if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+ throw new RSRuntimeException("Invalid dimension for Ap");
+ }
+ if (incX <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for TPMV");
+ }
+
+ return N;
+ }
+
+ /**
+ * STRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d45/strmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/d7e/dtrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d78/ctrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTRMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/dd1/ztrmv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * STBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d7d/stbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBMV has the same requirements as TRMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d29/dtbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBMV has the same requirements as TRMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/dcd/ctbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBMV has the same requirements as TRMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTBMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d39/ztbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBMV has the same requirements as TRMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * STPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/db1/stpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/dcd/dtpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dbb/ctpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTPMV performs one of the matrix-vector operations
+ * x := A*x or x := A**T*x or x := A**H*x
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d9e/ztpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * STRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d2a/strsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ // TRSV is the same as TRMV
+ validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+ }
+
+ /**
+ * DTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d96/dtrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ // TRSV is the same as TRMV
+ validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+ }
+
+ /**
+ * CTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dc8/ctrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ // TRSV is the same as TRMV
+ validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+ }
+
+ /**
+ * ZTRSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d2f/ztrsv_8f.html
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+ // TRSV is the same as TRMV
+ validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+ }
+
+ /**
+ * STBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d1f/stbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBSV is the same as TRMV + K >= 0
+ validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+ if (K < 0) {
+ throw new RSRuntimeException("Number of diagonals must be positive");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/dcf/dtbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBSV is the same as TRMV + K >= 0
+ validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+ if (K < 0) {
+ throw new RSRuntimeException("Number of diagonals must be positive");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d5f/ctbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBSV is the same as TRMV + K >= 0
+ validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+ if (K < 0) {
+ throw new RSRuntimeException("Number of diagonals must be positive");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTBSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d5a/ztbsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param K The number of off-diagonals of the matrix A
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, int K, Allocation A, Allocation X, int incX) {
+ // TBSV is the same as TRMV + K >= 0
+ validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+ int N = A.getType().getY();
+ if (K < 0) {
+ throw new RSRuntimeException("Number of diagonals must be positive");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * STPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d7c/stpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ // TPSV is same as TPMV
+ int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d9/d84/dtpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ // TPSV is same as TPMV
+ int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d56/ctpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ // TPSV is same as TPMV
+ int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTPSV solves one of the systems of equations
+ * A*x = b or A**T*x = b or A**H*x = b
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/da/d57/ztpsv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ */
+ public void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+ // TPSV is same as TPMV
+ int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * Level 2, S and D only
+ */
+ static int validateSYMV(Element e, @Uplo int Uplo, Allocation A, Allocation X, Allocation Y, int incX, int incY) {
+ validateUplo(Uplo);
+ int N = A.getType().getY();
+ if (A.getType().getX() != N) {
+ throw new RSRuntimeException("A must be a square matrix for SYMV");
+ }
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e) ) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
+ }
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
+ }
+ return N;
+ }
+ static int validateSPMV(Element e, @Uplo int Uplo, Allocation Ap, Allocation X, int incX, Allocation Y, int incY) {
+ validateUplo(Uplo);
+ if (!Ap.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (Ap.getType().getY() > 1) {
+ throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+ }
+
+ int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+ if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+ throw new RSRuntimeException("Invalid dimension for Ap");
+ }
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+ }
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+ }
+
+ return N;
+ }
+ static void validateGER(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e) ) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ if (N < 1 || M < 1) {
+ throw new RSRuntimeException("M and N must be 1 or greater for GER");
+ }
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (M - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for GER");
+ }
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for GER");
+ }
+
+
+ }
+ static int validateSYR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation A) {
+ validateUplo(Uplo);
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+
+ int N = A.getType().getX();
+
+ if (X.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+ if (N != A.getType().getY()) {
+ throw new RSRuntimeException("A must be a symmetric matrix");
+ }
+ if (incX <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SYR");
+ }
+ return N;
+ }
+ static int validateSPR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Ap) {
+ validateUplo(Uplo);
+ if (!Ap.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (Ap.getType().getY() > 1) {
+ throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+ }
+
+ int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+ if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+ throw new RSRuntimeException("Invalid dimension for Ap");
+ }
+ if (incX <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SPR");
+ }
+
+ return N;
+ }
+
+ static int validateSYR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ validateUplo(Uplo);
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ int N = A.getType().getX();
+
+ if (N != A.getType().getY()) {
+ throw new RSRuntimeException("A must be a symmetric matrix");
+ }
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SYR");
+ }
+ return N;
+
+ }
+ static int validateSPR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+ validateUplo(Uplo);
+ if (!Ap.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ if (Ap.getType().getY() > 1) {
+ throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+ }
+
+ int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+ if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+ throw new RSRuntimeException("Invalid dimension for Ap");
+ }
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (N - 1) * incX;
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for SPR2");
+ }
+
+ return N;
+ }
+
+ /**
+ * SSYMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d94/ssymv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+ int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/da1/ssbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+ // SBMV is the same as SYMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d68/sspmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
+ int N = validateSPMV(Element.F32(mRS), Uplo, Ap, X, incX, Y, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SGER performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d5c/sger_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
+ public void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+ validateGER(Element.F32(mRS), X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSYR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/dac/ssyr_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
+ public void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+ int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSPR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d9b/sspr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
+ public void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+ int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSYR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d99/ssyr2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
+ public void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ int N = validateSYR2(Element.F32(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d3e/sspr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ */
+ public void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+ int N = validateSPR2(Element.F32(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/dbe/dsymv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+ int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d1e/dsbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+ // SBMV is the same as SYMV + K >= 0
+ if (K < 0) {
+ throw new RSRuntimeException("K must be greater than or equal to 0");
+ }
+ int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d85/dspmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
+ int N = validateSPMV(Element.F64(mRS), Uplo, Ap, X, incX, Y, incY);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DGER performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
+ public void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+ validateGER(Element.F64(mRS), X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d60/dsyr_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
+ public void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+ int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSPR performs the rank 1 operation
+ * A := alpha*x*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/dba/dspr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
+ public void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+ int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d41/dsyr2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
+ public void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ int N = validateSYR2(Element.F64(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**T + alpha*y*x**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d9e/dspr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ */
+ public void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+ int N = validateSPR2(Element.F64(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+
+ /**
+ * Level 2, C and Z only
+ */
+
+ static void validateGERU(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ if (!A.getType().getElement().isCompatible(e) ||
+ !X.getType().getElement().isCompatible(e) ||
+ !Y.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+ throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+ }
+
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+ if (incX <= 0 || incY <= 0) {
+ throw new RSRuntimeException("Vector increments must be greater than 0");
+ }
+ int expectedXDim = 1 + (M - 1) * incX;
+ if (X.getType().getX() != expectedXDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for GERU");
+ }
+ int expectedYDim = 1 + (N - 1) * incY;
+ if (Y.getType().getX() != expectedYDim) {
+ throw new RSRuntimeException("Incorrect vector dimensions for GERU");
+ }
+
+ }
+
+ /**
+ * CHEMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d51/chemv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+ // HEMV is the same as SYR2 validation-wise
+ int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/dc2/chbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+ // HBMV is the same as SYR2 validation-wise
+ int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+ if (K < 0) {
+ throw new RSRuntimeException("K must be 0 or greater for HBMV");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d06/chpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+ // HPMV is the same as SPR2
+ int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CGERU performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d5f/cgeru_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CGERC performs the rank 1 operation
+ * A := alpha*x*y**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d84/cgerc_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ // same as GERU
+ validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHER performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d6d/cher_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+ // same as SYR
+ int N = validateSYR(Element.F32_2(mRS), Uplo, X, incX, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHPR performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/dcd/chpr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+ // equivalent to SPR for validation
+ int N = validateSPR(Element.F32_2(mRS), Uplo, X, incX, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHER2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d87/cher2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ // same as SYR2
+ int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CHPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d44/chpr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ */
+ public void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+ // same as SPR2
+ int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHEMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/ddd/zhemv_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+ // HEMV is the same as SYR2 validation-wise
+ int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHBMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d1a/zhbmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+ * but only the region N*(K+1) will be referenced. The following subroutine can is an
+ * example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+ * for i in range(0, n):
+ * for j in range(i, min(i+k+1, n)):
+ * b[i, j-i] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+ * @param K The number of off-diagonals of the matrix A
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+ // HBMV is the same as SYR2 validation-wise
+ int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+ if (K < 0) {
+ throw new RSRuntimeException("K must be 0 or greater for HBMV");
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHPMV performs the matrix-vector operation
+ * y := alpha*A*x + beta*y
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d60/zhpmv_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+ * @param alpha The scalar alpha.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param beta The scalar beta.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ */
+ public void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+ // HPMV is the same as SPR2
+ int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZGERU performs the rank 1 operation
+ * A := alpha*x*y**T + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d12/zgeru_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZGERC performs the rank 1 operation
+ * A := alpha*x*y**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/dad/zgerc_8f.html
+ *
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ // same as GERU
+ validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
+ int M = A.getType().getY();
+ int N = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHER performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d0e/zher_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+ // same as SYR
+ int N = validateSYR(Element.F64_2(mRS), Uplo, X, incX, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHPR performs the rank 1 operation
+ * A := alpha*x*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/de1/zhpr_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+ // equivalent to SPR for validation
+ int N = validateSPR(Element.F64_2(mRS), Uplo, X, incX, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHER2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/da/d8a/zher2_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+ // same as SYR2
+ int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHPR2 performs the symmetric rank 2 operation
+ * A := alpha*x*y**H + alpha*y*x**H + A
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d5/d52/zhpr2_8f.html
+ *
+ * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+ * The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+ * 'a' to packed matrix 'b'.
+ * k = 0
+ * for i in range(0, n):
+ * for j in range(i, n):
+ * b[k++] = a[i, j]
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+ * @param alpha The scalar alpha.
+ * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+ * @param incX The increment for the elements of vector x, must be larger than zero.
+ * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+ * @param incY The increment for the elements of vector y, must be larger than zero.
+ * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+ // same as SPR2
+ int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+ boolean mUseIncSupp = isIncSupp();
+ long apID = Ap.getID(mRS);
+ long xID = X.getID(mRS);
+ long yID = Y.getID(mRS);
+ if (mUseIncSupp) {
+ apID = getDummyAlloc(Ap);
+ xID = getDummyAlloc(X);
+ yID = getDummyAlloc(Y);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+ }
+
+
+ /**
+ * Level 3 BLAS
+ */
+
+ static void validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
+ int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
+ if ((A != null && !A.getType().getElement().isCompatible(e)) ||
+ (B != null && !B.getType().getElement().isCompatible(e)) ||
+ (C != null && !C.getType().getElement().isCompatible(e))) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ if (C == null) {
+ //since matrix C is used to store the result, it cannot be null.
+ throw new RSRuntimeException("Allocation C cannot be null");
+ }
+ cM = C.getType().getY();
+ cN = C.getType().getX();
+
+ if (Side == RIGHT) {
+ if ((A == null && B != null) || (A != null && B == null)) {
+ throw new RSRuntimeException("Provided Matrix A without Matrix B, or vice versa");
+ }
+ if (B != null) {
+ bM = A.getType().getY();
+ bN = A.getType().getX();
+ }
+ if (A != null) {
+ aM = B.getType().getY();
+ aN = B.getType().getX();
+ }
+ } else {
+ if (A != null) {
+ if (TransA == TRANSPOSE || TransA == CONJ_TRANSPOSE) {
+ aN = A.getType().getY();
+ aM = A.getType().getX();
+ } else {
+ aM = A.getType().getY();
+ aN = A.getType().getX();
+ }
+ }
+ if (B != null) {
+ if (TransB == TRANSPOSE || TransB == CONJ_TRANSPOSE) {
+ bN = B.getType().getY();
+ bM = B.getType().getX();
+ } else {
+ bM = B.getType().getY();
+ bN = B.getType().getX();
+ }
+ }
+ }
+ if (A != null && B != null && C != null) {
+ if (aN != bM || aM != cM || bN != cN) {
+ throw new RSRuntimeException("Called BLAS with invalid dimensions");
+ }
+ } else if (A != null && C != null) {
+ // A and C only, for SYRK
+ if (cM != cN) {
+ throw new RSRuntimeException("Matrix C is not symmetric");
+ }
+ if (aM != cM) {
+ throw new RSRuntimeException("Called BLAS with invalid dimensions");
+ }
+ } else if (A != null && B != null) {
+ // A and B only
+ if (aN != bM) {
+ throw new RSRuntimeException("Called BLAS with invalid dimensions");
+ }
+ }
+
+ }
+
+ /**
+ * SGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/de2/sgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
+ public void SGEMM(@Transpose int TransA, @Transpose int TransB, float alpha, Allocation A,
+ Allocation B, float beta, Allocation C) {
+ validateTranspose(TransA);
+ validateTranspose(TransB);
+ validateL3(Element.F32(mRS), TransA, TransB, 0, A, B, C);
+
+ int M = -1, N = -1, K = -1;
+ if (TransA != NO_TRANSPOSE) {
+ M = A.getType().getX();
+ K = A.getType().getY();
+ } else {
+ M = A.getType().getY();
+ K = A.getType().getX();
+ }
+ if (TransB != NO_TRANSPOSE) {
+ N = B.getType().getY();
+ } else {
+ N = B.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, aID, bID,
+ beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
+ public void DGEMM(@Transpose int TransA, @Transpose int TransB, double alpha, Allocation A,
+ Allocation B, double beta, Allocation C) {
+ validateTranspose(TransA);
+ validateTranspose(TransB);
+ validateL3(Element.F64(mRS), TransA, TransB, 0, A, B, C);
+ int M = -1, N = -1, K = -1;
+ if (TransA != NO_TRANSPOSE) {
+ M = A.getType().getX();
+ K = A.getType().getY();
+ } else {
+ M = A.getType().getY();
+ K = A.getType().getX();
+ }
+ if (TransB != NO_TRANSPOSE) {
+ N = B.getType().getY();
+ } else {
+ N = B.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, aID, bID,
+ beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T or op(X) = X**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d5b/cgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CGEMM(@Transpose int TransA, @Transpose int TransB, Float2 alpha, Allocation A,
+ Allocation B, Float2 beta, Allocation C) {
+ validateTranspose(TransA);
+ validateTranspose(TransB);
+ validateL3(Element.F32_2(mRS), TransA, TransB, 0, A, B, C);
+ int M = -1, N = -1, K = -1;
+ if (TransA != NO_TRANSPOSE) {
+ M = A.getType().getX();
+ K = A.getType().getY();
+ } else {
+ M = A.getType().getY();
+ K = A.getType().getX();
+ }
+ if (TransB != NO_TRANSPOSE) {
+ N = B.getType().getY();
+ } else {
+ N = B.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha.x, alpha.y, aID, bID,
+ beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZGEMM performs one of the matrix-matrix operations
+ * C := alpha*op(A)*op(B) + beta*C where op(X) is one of op(X) = X or op(X) = X**T or op(X) = X**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d76/zgemm_8f.html
+ *
+ * @param TransA The type of transpose applied to matrix A.
+ * @param TransB The type of transpose applied to matrix B.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2
+ */
+ public void ZGEMM(@Transpose int TransA, @Transpose int TransB, Double2 alpha, Allocation A,
+ Allocation B, Double2 beta, Allocation C) {
+ validateTranspose(TransA);
+ validateTranspose(TransB);
+ validateL3(Element.F64_2(mRS), TransA, TransB, 0, A, B, C);
+ int M = -1, N = -1, K = -1;
+ if (TransA != NO_TRANSPOSE) {
+ M = A.getType().getX();
+ K = A.getType().getY();
+ } else {
+ M = A.getType().getY();
+ K = A.getType().getX();
+ }
+ if (TransB != NO_TRANSPOSE) {
+ N = B.getType().getY();
+ } else {
+ N = B.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha.x, alpha.y, aID, bID,
+ beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/d42/ssymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
+ public void SSYMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A,
+ Allocation B, float beta, Allocation C) {
+ validateSide(Side);
+ validateUplo(Uplo);
+ //For SYMM, Matrix A should be symmetric
+ if (A.getType().getX() != A.getType().getY()) {
+ throw new RSRuntimeException("Matrix A is not symmetric");
+ }
+ validateL3(Element.F32(mRS), 0, 0, Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
+ beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/db0/dsymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
+ public void DSYMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A,
+ Allocation B, double beta, Allocation C) {
+ validateSide(Side);
+ validateUplo(Uplo);
+ if (A.getType().getX() != A.getType().getY()) {
+ throw new RSRuntimeException("Matrix A is not symmetric");
+ }
+ validateL3(Element.F64(mRS), 0, 0, Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
+ beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/db/d59/csymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CSYMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A,
+ Allocation B, Float2 beta, Allocation C) {
+ validateSide(Side);
+ validateUplo(Uplo);
+ if (A.getType().getX() != A.getType().getY()) {
+ throw new RSRuntimeException("Matrix A is not symmetric");
+ }
+ validateL3(Element.F32_2(mRS), 0, 0, Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
+ beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZSYMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d51/zsymm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZSYMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A,
+ Allocation B, Double2 beta, Allocation C) {
+ validateSide(Side);
+ validateUplo(Uplo);
+ if (A.getType().getX() != A.getType().getY()) {
+ throw new RSRuntimeException("Matrix A is not symmetric");
+ }
+ validateL3(Element.F64_2(mRS), 0, 0, Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
+ beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * SSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d0/d40/ssyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
+ public void SSYRK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
+ validateTranspose(Trans);
+ validateUplo(Uplo);
+ validateL3(Element.F32(mRS), Trans, 0, 0, A, null, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dc/d05/dsyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
+ public void DSYRK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
+ validateTranspose(Trans);
+ validateUplo(Uplo);
+ validateL3(Element.F64(mRS), Trans, 0, 0, A, null, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d6a/csyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CSYRK(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Float2 beta, Allocation C) {
+ validateTranspose(Trans);
+ validateUplo(Uplo);
+ validateL3(Element.F32_2(mRS), Trans, 0, 0, A, null, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
+ C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZSYRK performs one of the symmetric rank k operations
+ * C := alpha*A*A**T + beta*C or C := alpha*A**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d54/zsyrk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Double2 beta, Allocation C) {
+ validateTranspose(Trans);
+ validateUplo(Uplo);
+ validateL3(Element.F64_2(mRS), Trans, 0, 0, A, null, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
+ C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateSYR2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
+ validateTranspose(Trans);
+ if (!A.getType().getElement().isCompatible(e) ||
+ !B.getType().getElement().isCompatible(e) ||
+ !C.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ int Cdim = -1;
+ // A is n x k if no transpose, k x n if transpose
+ // C is n x n
+ if (Trans == TRANSPOSE) {
+ // check columns versus C
+ Cdim = A.getType().getX();
+ } else {
+ // check rows versus C
+ Cdim = A.getType().getY();
+ }
+ if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
+ throw new RSRuntimeException("Invalid symmetric matrix in SYR2K");
+ }
+ // A dims == B dims
+ if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+ throw new RSRuntimeException("Invalid A and B in SYR2K");
+ }
+ }
+
+ /**
+ * SSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d3d/ssyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+ */
+ public void SSYR2K(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, Allocation B, float beta, Allocation C) {
+ validateUplo(Uplo);
+ validateSYR2K(Element.F32(mRS), Trans, A, B, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/dec/dsyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+ */
+ public void DSYR2K(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, Allocation B, double beta, Allocation C) {
+ validateUplo(Uplo);
+ validateSYR2K(Element.F64(mRS), Trans, A, B, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d7e/csyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CSYR2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
+ validateUplo(Uplo);
+ validateSYR2K(Element.F32_2(mRS), Trans, A, B, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZSYR2K performs one of the symmetric rank 2k operations
+ * C := alpha*A*B**T + alpha*B*A**T + beta*C or C := alpha*A**T*B + alpha*B**T*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d20/zsyr2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZSYR2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
+ validateUplo(Uplo);
+ validateSYR2K(Element.F64_2(mRS), Trans, A, B, C);
+ int K = -1;
+ if (Trans != NO_TRANSPOSE) {
+ K = A.getType().getY();
+ } else {
+ K = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateTRMM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
+ validateSide(Side);
+ validateTranspose(TransA);
+ int aM = -1, aN = -1, bM = -1, bN = -1;
+ if (!A.getType().getElement().isCompatible(e) ||
+ !B.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+
+ aM = A.getType().getY();
+ aN = A.getType().getX();
+ if (aM != aN) {
+ throw new RSRuntimeException("Called TRMM with a non-symmetric matrix A");
+ }
+
+ bM = B.getType().getY();
+ bN = B.getType().getX();
+ if (Side == LEFT) {
+ if (aN != bM) {
+ throw new RSRuntimeException("Called TRMM with invalid matrices");
+ }
+ } else {
+ if (bN != aM) {
+ throw new RSRuntimeException("Called TRMM with invalid matrices");
+ }
+ }
+ }
+
+ /**
+ * STRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/df/d01/strmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ */
+ public void STRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRMM(Element.F32(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha, aID, bID, 0.f, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/dd/d19/dtrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ */
+ public void DTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRMM(Element.F64(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d4/d9b/ctrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ */
+ public void CTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRMM(Element.F32_2(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTRMM performs one of the matrix-matrix operations
+ * B := alpha*op(A)*B or B := alpha*B*op(A)
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/de1/ztrmm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ */
+ public void ZTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRMM(Element.F64_2(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateTRSM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
+ int adim = -1, bM = -1, bN = -1;
+ validateSide(Side);
+ validateTranspose(TransA);
+ if (!A.getType().getElement().isCompatible(e) ||
+ !B.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ adim = A.getType().getX();
+ if (adim != A.getType().getY()) {
+ // this may be unnecessary, the restriction could potentially be relaxed
+ // A needs to contain at least that symmetric matrix but could theoretically be larger
+ // for now we assume adapters are sufficient, will reevaluate in the future
+ throw new RSRuntimeException("Called TRSM with a non-symmetric matrix A");
+ }
+ bM = B.getType().getY();
+ bN = B.getType().getX();
+ if (Side == LEFT) {
+ // A is M*M
+ if (adim != bM) {
+ throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
+ }
+ } else {
+ // A is N*N
+ if (adim != bN) {
+ throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
+ }
+ }
+ }
+
+ /**
+ * STRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d2/d8b/strsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+ */
+ public void STRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRSM(Element.F32(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * DTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/da7/dtrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+ */
+ public void DTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRSM(Element.F64(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * CTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/de/d30/ctrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ */
+ public void CTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRSM(Element.F32_2(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZTRSM solves one of the matrix equations
+ * op(A)*X := alpha*B or X*op(A) := alpha*B
+ * op(A) is one of op(A) = A or op(A) = A**T or op(A) = A**H
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d39/ztrsm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether matrix A is upper or lower triangular.
+ * @param TransA The type of transpose applied to matrix A.
+ * @param Diag Specifies whether or not A is unit triangular.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ */
+ public void ZTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
+ validateUplo(Uplo);
+ validateDiag(Diag);
+ validateTRSM(Element.F64_2(mRS), Side, TransA, A, B);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateHEMM(Element e, @Side int Side, Allocation A, Allocation B, Allocation C) {
+ validateSide(Side);
+
+ if (!A.getType().getElement().isCompatible(e) ||
+ !B.getType().getElement().isCompatible(e) ||
+ !C.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+
+ // A must be square; can potentially be relaxed similar to TRSM
+ int adim = A.getType().getX();
+ if (adim != A.getType().getY()) {
+ throw new RSRuntimeException("Called HEMM with non-square A");
+ }
+ if ((Side == LEFT && adim != B.getType().getY()) ||
+ (Side == RIGHT && adim != B.getType().getX())) {
+ throw new RSRuntimeException("Called HEMM with invalid B");
+ }
+ if (B.getType().getX() != C.getType().getX() ||
+ B.getType().getY() != C.getType().getY()) {
+ throw new RSRuntimeException("Called HEMM with mismatched B and C");
+ }
+ }
+
+ /**
+ * CHEMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d3/d66/chemm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CHEMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHEMM(Element.F32_2(mRS), Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHEMM performs one of the matrix-matrix operations
+ * C := alpha*A*B + beta*C or C := alpha*B*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d6/d3e/zhemm_8f.html
+ *
+ * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+ * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHEMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHEMM(Element.F64_2(mRS), Side, A, B, C);
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
+ alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateHERK(Element e, @Transpose int Trans, Allocation A, Allocation C) {
+ if (!A.getType().getElement().isCompatible(e) ||
+ !C.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ validateConjTranspose(Trans);
+ int cdim = C.getType().getX();
+ if (cdim != C.getType().getY()) {
+ throw new RSRuntimeException("Called HERK with non-square C");
+ }
+ if (Trans == NO_TRANSPOSE) {
+ if (cdim != A.getType().getY()) {
+ throw new RSRuntimeException("Called HERK with invalid A");
+ }
+ } else {
+ if (cdim != A.getType().getX()) {
+ throw new RSRuntimeException("Called HERK with invalid A");
+ }
+ }
+ }
+
+ /**
+ * CHERK performs one of the hermitian rank k operations
+ * C := alpha*A*A**H + beta*C or C := alpha*A**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d8/d52/cherk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CHERK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHERK(Element.F32_2(mRS), Trans, A, C);
+ int k = 0;
+ if (Trans == CONJ_TRANSPOSE) {
+ k = A.getType().getY();
+ } else {
+ k = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
+ alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHERK performs one of the hermitian rank k operations
+ * C := alpha*A*A**H + beta*C or C := alpha*A**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/db1/zherk_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHERK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHERK(Element.F64_2(mRS), Trans, A, C);
+ int k = 0;
+ if (Trans == CONJ_TRANSPOSE) {
+ k = A.getType().getY();
+ } else {
+ k = A.getType().getX();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
+ alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ static void validateHER2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
+ if (!A.getType().getElement().isCompatible(e) ||
+ !B.getType().getElement().isCompatible(e) ||
+ !C.getType().getElement().isCompatible(e)) {
+ throw new RSRuntimeException("Called BLAS with wrong Element type");
+ }
+ validateConjTranspose(Trans);
+ int cdim = C.getType().getX();
+ if (cdim != C.getType().getY()) {
+ throw new RSRuntimeException("Called HER2K with non-square C");
+ }
+ if (Trans == NO_TRANSPOSE) {
+ if (A.getType().getY() != cdim) {
+ throw new RSRuntimeException("Called HER2K with invalid matrices");
+ }
+ } else {
+ if (A.getType().getX() != cdim) {
+ throw new RSRuntimeException("Called HER2K with invalid matrices");
+ }
+ }
+ if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+ throw new RSRuntimeException("Called HER2K with invalid A and B matrices");
+ }
+ }
+
+ /**
+ * CHER2K performs one of the hermitian rank 2k operations
+ * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C or C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d1/d82/cher2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+ */
+ public void CHER2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, float beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHER2K(Element.F32_2(mRS), Trans, A, B, C);
+ int k = 0;
+ if (Trans == NO_TRANSPOSE) {
+ k = A.getType().getX();
+ } else {
+ k = A.getType().getY();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
+ A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+ /**
+ * ZHER2K performs one of the hermitian rank 2k operations
+ * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C or C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+ *
+ * Details: http://www.netlib.org/lapack/explore-html/d7/dfa/zher2k_8f.html
+ *
+ * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+ * @param Trans The type of transpose applied to the operation.
+ * @param alpha The scalar alpha.
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+ * @param beta The scalar beta.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+ */
+ public void ZHER2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, double beta, Allocation C) {
+ validateUplo(Uplo);
+ validateHER2K(Element.F64_2(mRS), Trans, A, B, C);
+ int k = 0;
+ if (Trans == NO_TRANSPOSE) {
+ k = A.getType().getX();
+ } else {
+ k = A.getType().getY();
+ }
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
+ A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+ }
+
+
+ /**
+ * 8-bit GEMM-like operation for neural networks: C = A * Transpose(B)
+ * Calculations are done in 1.10.21 fixed-point format for the final output,
+ * just before there's a shift down to drop the fractional parts. The output
+ * values are gated to 0 to 255 to fit in a byte, but the 10-bit format
+ * gives some headroom to avoid wrapping around on small overflows.
+ *
+ * @param A The input allocation contains matrix A, supported elements type {@link Element#U8}.
+ * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset. Value should be from 0 to 255.
+ * @param B The input allocation contains matrix B, supported elements type {@link Element#U8}.
+ * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset. Value should be from 0 to 255.
+ * @param C The input allocation contains matrix C, supported elements type {@link Element#U8}.
+ * @param c_offset The offset for all values in matrix C.
+ * @param c_mult The multiplier for all values in matrix C, e.g C[i,j] = (C[i,j] + c_offset) * c_mult.
+ **/
+ public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
+ validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
+
+ if (a_offset < 0 || a_offset > 255) {
+ throw new RSRuntimeException("Invalid a_offset passed to BNNM");
+ }
+ if (b_offset < 0 || b_offset > 255) {
+ throw new RSRuntimeException("Invalid b_offset passed to BNNM");
+ }
+ int M = -1, N = -1, K = -1;
+ M = A.getType().getY();
+ N = B.getType().getY();
+ K = A.getType().getX();
+
+ boolean mUseIncSupp = isIncSupp();
+ long aID = A.getID(mRS);
+ long bID = B.getID(mRS);
+ long cID = C.getID(mRS);
+ if (mUseIncSupp) {
+ aID = getDummyAlloc(A);
+ bID = getDummyAlloc(B);
+ cID = getDummyAlloc(C);
+ }
+ mRS.nScriptIntrinsicBLAS_BNNM(getID(mRS), M, N, K, aID, a_offset, bID, b_offset, cID, c_offset, c_mult, mUseIncSupp);
+
+ }
+
+}
diff --git a/androidx/renderscript/ScriptIntrinsicBlend.java b/androidx/renderscript/ScriptIntrinsicBlend.java
new file mode 100644
index 0000000..c7e174d
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBlend.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Intrinsic kernels for blending two
+ * {@link androidx.renderscript.Allocation} objects.
+ **/
+public class ScriptIntrinsicBlend extends ScriptIntrinsic {
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ ScriptIntrinsicBlend(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8_4}
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for inputs and outputs
+ *
+ * @return ScriptIntrinsicBlend
+ */
+ public static ScriptIntrinsicBlend create(RenderScript rs, Element e) {
+ // 7 comes from RS_SCRIPT_INTRINSIC_ID_BLEND in rsDefines.h
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(7, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicBlend si = new ScriptIntrinsicBlend(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+
+ }
+
+ private void blend(int id, Allocation ain, Allocation aout) {
+ if (!ain.getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Input is not of expected format.");
+ }
+ if (!aout.getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Output is not of expected format.");
+ }
+ forEach(id, ain, aout, null);
+ }
+
+ /**
+ * Sets dst = {0, 0, 0, 0}
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachClear(Allocation ain, Allocation aout) {
+ blend(0, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Clear kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDClear() {
+ return createKernelID(0, 3, null, null);
+ }
+
+
+ /**
+ * Sets dst = src
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSrc(Allocation ain, Allocation aout) {
+ blend(1, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Src kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSrc() {
+ return createKernelID(1, 3, null, null);
+ }
+
+ /**
+ * Sets dst = dst
+ *
+ * This is a NOP.
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachDst(Allocation ain, Allocation aout) {
+ // NOP
+ }
+
+ /**
+ * Get a KernelID for the Dst kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDDst() {
+ return createKernelID(2, 3, null, null);
+ }
+
+ /**
+ * Sets dst = src + dst * (1.0 - src.a)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSrcOver(Allocation ain, Allocation aout) {
+ blend(3, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the SrcOver kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSrcOver() {
+ return createKernelID(3, 3, null, null);
+ }
+
+ /**
+ * Sets dst = dst + src * (1.0 - dst.a)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachDstOver(Allocation ain, Allocation aout) {
+ blend(4, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the DstOver kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDDstOver() {
+ return createKernelID(4, 3, null, null);
+ }
+
+ /**
+ * Sets dst = src * dst.a
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSrcIn(Allocation ain, Allocation aout) {
+ blend(5, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the SrcIn kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSrcIn() {
+ return createKernelID(5, 3, null, null);
+ }
+
+ /**
+ * Sets dst = dst * src.a
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachDstIn(Allocation ain, Allocation aout) {
+ blend(6, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the DstIn kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDDstIn() {
+ return createKernelID(6, 3, null, null);
+ }
+
+ /**
+ * Sets dst = src * (1.0 - dst.a)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSrcOut(Allocation ain, Allocation aout) {
+ blend(7, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the SrcOut kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSrcOut() {
+ return createKernelID(7, 3, null, null);
+ }
+
+ /**
+ * Sets dst = dst * (1.0 - src.a)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachDstOut(Allocation ain, Allocation aout) {
+ blend(8, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the DstOut kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDDstOut() {
+ return createKernelID(8, 3, null, null);
+ }
+
+ /**
+ * dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
+ * dst.a = dst.a
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSrcAtop(Allocation ain, Allocation aout) {
+ blend(9, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the SrcAtop kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSrcAtop() {
+ return createKernelID(9, 3, null, null);
+ }
+
+ /**
+ * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
+ * dst.a = src.a
+ * Note: Before API 23, the alpha channel was not correctly set.
+ * Please use with caution when targeting older APIs.
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachDstAtop(Allocation ain, Allocation aout) {
+ blend(10, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the DstAtop kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDDstAtop() {
+ return createKernelID(10, 3, null, null);
+ }
+
+ /**
+ * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachXor(Allocation ain, Allocation aout) {
+ blend(11, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Xor kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDXor() {
+ return createKernelID(11, 3, null, null);
+ }
+
+ ////////
+/*
+ public void forEachNormal(Allocation ain, Allocation aout) {
+ blend(12, ain, aout);
+ }
+
+ public void forEachAverage(Allocation ain, Allocation aout) {
+ blend(13, ain, aout);
+ }
+*/
+ /**
+ * Sets dst = src * dst
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachMultiply(Allocation ain, Allocation aout) {
+ blend(14, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Multiply kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDMultiply() {
+ return createKernelID(14, 3, null, null);
+ }
+
+/*
+ public void forEachScreen(Allocation ain, Allocation aout) {
+ blend(15, ain, aout);
+ }
+
+ public void forEachDarken(Allocation ain, Allocation aout) {
+ blend(16, ain, aout);
+ }
+
+ public void forEachLighten(Allocation ain, Allocation aout) {
+ blend(17, ain, aout);
+ }
+
+ public void forEachOverlay(Allocation ain, Allocation aout) {
+ blend(18, ain, aout);
+ }
+
+ public void forEachHardlight(Allocation ain, Allocation aout) {
+ blend(19, ain, aout);
+ }
+
+ public void forEachSoftlight(Allocation ain, Allocation aout) {
+ blend(20, ain, aout);
+ }
+
+ public void forEachDifference(Allocation ain, Allocation aout) {
+ blend(21, ain, aout);
+ }
+
+ public void forEachNegation(Allocation ain, Allocation aout) {
+ blend(22, ain, aout);
+ }
+
+ public void forEachExclusion(Allocation ain, Allocation aout) {
+ blend(23, ain, aout);
+ }
+
+ public void forEachColorDodge(Allocation ain, Allocation aout) {
+ blend(24, ain, aout);
+ }
+
+ public void forEachInverseColorDodge(Allocation ain, Allocation aout) {
+ blend(25, ain, aout);
+ }
+
+ public void forEachSoftDodge(Allocation ain, Allocation aout) {
+ blend(26, ain, aout);
+ }
+
+ public void forEachColorBurn(Allocation ain, Allocation aout) {
+ blend(27, ain, aout);
+ }
+
+ public void forEachInverseColorBurn(Allocation ain, Allocation aout) {
+ blend(28, ain, aout);
+ }
+
+ public void forEachSoftBurn(Allocation ain, Allocation aout) {
+ blend(29, ain, aout);
+ }
+
+ public void forEachReflect(Allocation ain, Allocation aout) {
+ blend(30, ain, aout);
+ }
+
+ public void forEachGlow(Allocation ain, Allocation aout) {
+ blend(31, ain, aout);
+ }
+
+ public void forEachFreeze(Allocation ain, Allocation aout) {
+ blend(32, ain, aout);
+ }
+
+ public void forEachHeat(Allocation ain, Allocation aout) {
+ blend(33, ain, aout);
+ }
+*/
+ /**
+ * Sets dst = min(src + dst, 1.0)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachAdd(Allocation ain, Allocation aout) {
+ blend(34, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Add kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDAdd() {
+ return createKernelID(34, 3, null, null);
+ }
+
+ /**
+ * Sets dst = max(dst - src, 0.0)
+ *
+ * @param ain The source buffer
+ * @param aout The destination buffer
+ */
+ public void forEachSubtract(Allocation ain, Allocation aout) {
+ blend(35, ain, aout);
+ }
+
+ /**
+ * Get a KernelID for the Subtract kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelIDSubtract() {
+ return createKernelID(35, 3, null, null);
+ }
+
+/*
+ public void forEachStamp(Allocation ain, Allocation aout) {
+ blend(36, ain, aout);
+ }
+
+ public void forEachRed(Allocation ain, Allocation aout) {
+ blend(37, ain, aout);
+ }
+
+ public void forEachGreen(Allocation ain, Allocation aout) {
+ blend(38, ain, aout);
+ }
+
+ public void forEachBlue(Allocation ain, Allocation aout) {
+ blend(39, ain, aout);
+ }
+
+ public void forEachHue(Allocation ain, Allocation aout) {
+ blend(40, ain, aout);
+ }
+
+ public void forEachSaturation(Allocation ain, Allocation aout) {
+ blend(41, ain, aout);
+ }
+
+ public void forEachColor(Allocation ain, Allocation aout) {
+ blend(42, ain, aout);
+ }
+
+ public void forEachLuminosity(Allocation ain, Allocation aout) {
+ blend(43, ain, aout);
+ }
+*/
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicBlur.java b/androidx/renderscript/ScriptIntrinsicBlur.java
new file mode 100644
index 0000000..4024416
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBlur.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * Intrinsic Gausian blur filter. Applies a gaussian blur of the
+ * specified radius to all elements of an allocation.
+ *
+ *
+ **/
+public class ScriptIntrinsicBlur extends ScriptIntrinsic {
+ private final float[] mValues = new float[9];
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ protected ScriptIntrinsicBlur(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Create an intrinsic for applying a blur to an allocation. The
+ * default radius is 5.0.
+ *
+ * Supported elements types are {@link Element#U8},
+ * {@link Element#U8_4}.
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for inputs and outputs
+ *
+ * @return ScriptIntrinsicBlur
+ */
+ public static ScriptIntrinsicBlur create(RenderScript rs, Element e) {
+ if ((!e.isCompatible(Element.U8_4(rs))) && (!e.isCompatible(Element.U8(rs)))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(5, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicBlur si = new ScriptIntrinsicBlur(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ si.setRadius(5.f);
+
+ return si;
+ }
+
+ /**
+ * Set the input of the blur.
+ * Must match the element type supplied during create.
+ *
+ * @param ain The input allocation
+ */
+ public void setInput(Allocation ain) {
+ if (ain.getType().getY() == 0) {
+ throw new RSIllegalArgumentException("Input set to a 1D Allocation");
+ }
+ mInput = ain;
+ setVar(1, ain);
+ }
+
+ /**
+ * Set the radius of the Blur.
+ *
+ * Supported range 0 < radius <= 25
+ *
+ * @param radius The radius of the blur
+ */
+ public void setRadius(float radius) {
+ if (radius <= 0 || radius > 25) {
+ throw new RSIllegalArgumentException("Radius out of range (0 < r <= 25).");
+ }
+ setVar(0, radius);
+ }
+
+ /**
+ * Apply the filter to the input and save to the specified
+ * allocation.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ */
+ public void forEach(Allocation aout) {
+ if (aout.getType().getY() == 0) {
+ throw new RSIllegalArgumentException("Output is a 1D Allocation");
+ }
+ forEach(0, (Allocation) null, aout, null);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 2, null, null);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(1, null);
+ }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicColorMatrix.java b/androidx/renderscript/ScriptIntrinsicColorMatrix.java
new file mode 100644
index 0000000..a0a247d
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicColorMatrix.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a color matrix to allocations.
+ *
+ * This has the same effect as loading each element and
+ * converting it to a {@link Element#F32_4}, multiplying the
+ * result by the 4x4 color matrix as performed by
+ * rsMatrixMultiply() and writing it to the output after
+ * conversion back to {@link Element#U8_4}.
+ **/
+public class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
+ private final Matrix4f mMatrix = new Matrix4f();
+ private final Float4 mAdd = new Float4();
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ protected ScriptIntrinsicColorMatrix(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Create an intrinsic for applying a color matrix to an
+ * allocation.
+ *
+ * Supported elements types are {@link Element#U8_4}
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for intputs and outputs
+ *
+ * @return ScriptIntrinsicColorMatrix
+ */
+ public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
+ if (!e.isCompatible(Element.U8_4(rs))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(2, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicColorMatrix si = new ScriptIntrinsicColorMatrix(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+
+ }
+
+ private void setMatrix() {
+ FieldPacker fp = new FieldPacker(16*4);
+ fp.addMatrix(mMatrix);
+ setVar(0, fp);
+ }
+
+ /**
+ * Set the color matrix which will be applied to each cell of
+ * the image.
+ *
+ * @param m The 4x4 matrix to set.
+ */
+ public void setColorMatrix(Matrix4f m) {
+ mMatrix.load(m);
+ setMatrix();
+ }
+
+ /**
+ * Set the color matrix which will be applied to each cell of the image.
+ * This will set the alpha channel to be a copy.
+ *
+ * @param m The 3x3 matrix to set.
+ */
+ public void setColorMatrix(Matrix3f m) {
+ mMatrix.load(m);
+ setMatrix();
+ }
+
+ /**
+ * Set the value to be added after the color matrix has been
+ * applied. The default value is {0, 0, 0, 0}
+ *
+ * @param f The float4 value to be added.
+ */
+ public void setAdd(Float4 f) {
+ mAdd.x = f.x;
+ mAdd.y = f.y;
+ mAdd.z = f.z;
+ mAdd.w = f.w;
+
+ FieldPacker fp = new FieldPacker(4*4);
+ fp.addF32(f.x);
+ fp.addF32(f.y);
+ fp.addF32(f.z);
+ fp.addF32(f.w);
+ setVar(1, fp);
+ }
+
+ /**
+ * Set the value to be added after the color matrix has been
+ * applied. The default value is {0, 0, 0, 0}
+ *
+ * @param r The red add value.
+ * @param g The green add value.
+ * @param b The blue add value.
+ * @param a The alpha add value.
+ */
+ public void setAdd(float r, float g, float b, float a) {
+ mAdd.x = r;
+ mAdd.y = g;
+ mAdd.z = b;
+ mAdd.w = a;
+
+ FieldPacker fp = new FieldPacker(4*4);
+ fp.addF32(mAdd.x);
+ fp.addF32(mAdd.y);
+ fp.addF32(mAdd.z);
+ fp.addF32(mAdd.w);
+ setVar(1, fp);
+ }
+
+ /**
+ * Set a color matrix to convert from RGB to luminance. The alpha channel
+ * will be a copy.
+ *
+ */
+ public void setGreyscale() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 0.299f);
+ mMatrix.set(1, 0, 0.587f);
+ mMatrix.set(2, 0, 0.114f);
+ mMatrix.set(0, 1, 0.299f);
+ mMatrix.set(1, 1, 0.587f);
+ mMatrix.set(2, 1, 0.114f);
+ mMatrix.set(0, 2, 0.299f);
+ mMatrix.set(1, 2, 0.587f);
+ mMatrix.set(2, 2, 0.114f);
+ setMatrix();
+ }
+
+ /**
+ * Set the matrix to convert from YUV to RGB with a direct copy of the 4th
+ * channel.
+ *
+ */
+ public void setYUVtoRGB() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 1.f);
+ mMatrix.set(1, 0, 0.f);
+ mMatrix.set(2, 0, 1.13983f);
+ mMatrix.set(0, 1, 1.f);
+ mMatrix.set(1, 1, -0.39465f);
+ mMatrix.set(2, 1, -0.5806f);
+ mMatrix.set(0, 2, 1.f);
+ mMatrix.set(1, 2, 2.03211f);
+ mMatrix.set(2, 2, 0.f);
+ setMatrix();
+ }
+
+ /**
+ * Set the matrix to convert from RGB to YUV with a direct copy of the 4th
+ * channel.
+ *
+ */
+ public void setRGBtoYUV() {
+ mMatrix.loadIdentity();
+ mMatrix.set(0, 0, 0.299f);
+ mMatrix.set(1, 0, 0.587f);
+ mMatrix.set(2, 0, 0.114f);
+ mMatrix.set(0, 1, -0.14713f);
+ mMatrix.set(1, 1, -0.28886f);
+ mMatrix.set(2, 1, 0.436f);
+ mMatrix.set(0, 2, 0.615f);
+ mMatrix.set(1, 2, -0.51499f);
+ mMatrix.set(2, 2, -0.10001f);
+ setMatrix();
+ }
+
+
+ /**
+ * Invoke the kernel and apply the matrix to each cell of ain and copy to
+ * aout.
+ *
+ * @param ain Input allocation
+ * @param aout Output allocation
+ */
+ public void forEach(Allocation ain, Allocation aout) {
+ forEach(0, ain, aout, null);
+ }
+
+ /**
+ * Invoke the kernel and apply the matrix to each cell of input
+ * {@link Allocation} and copy to the output {@link Allocation}.
+ *
+ * If the vector size of the input is less than four, the
+ * remaining components are treated as zero for the matrix
+ * multiply.
+ *
+ * If the output vector size is less than four, the unused
+ * vector components are discarded.
+ *
+ *
+ * @param ain Input allocation
+ * @param aout Output allocation
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+ if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
+ !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
+ !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
+ !ain.getElement().isCompatible(Element.U8_4(mRS)) &&
+ !ain.getElement().isCompatible(Element.F32(mRS)) &&
+ !ain.getElement().isCompatible(Element.F32_2(mRS)) &&
+ !ain.getElement().isCompatible(Element.F32_3(mRS)) &&
+ !ain.getElement().isCompatible(Element.F32_4(mRS))) {
+
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+
+ if (!aout.getElement().isCompatible(Element.U8(mRS)) &&
+ !aout.getElement().isCompatible(Element.U8_2(mRS)) &&
+ !aout.getElement().isCompatible(Element.U8_3(mRS)) &&
+ !aout.getElement().isCompatible(Element.U8_4(mRS)) &&
+ !aout.getElement().isCompatible(Element.F32(mRS)) &&
+ !aout.getElement().isCompatible(Element.F32_2(mRS)) &&
+ !aout.getElement().isCompatible(Element.F32_3(mRS)) &&
+ !aout.getElement().isCompatible(Element.F32_4(mRS))) {
+
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+
+ forEach(0, ain, aout, null, opt);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 3, null, null);
+ }
+
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicConvolve3x3.java b/androidx/renderscript/ScriptIntrinsicConvolve3x3.java
new file mode 100644
index 0000000..d4e57b0
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a 3x3 convolve to an allocation.
+ *
+ **/
+public class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic {
+ private final float[] mValues = new float[9];
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ ScriptIntrinsicConvolve3x3(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8}, {@link
+ * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+ * {@link Element#F32}, {@link Element#F32_2}, {@link
+ * Element#F32_3}, and {@link Element#F32_4}.
+ *
+ * <p> The default coefficients are:
+ * <code>
+ * <p> [ 0, 0, 0 ]
+ * <p> [ 0, 1, 0 ]
+ * <p> [ 0, 0, 0 ]
+ * </code>
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for intputs and outputs
+ *
+ * @return ScriptIntrinsicConvolve3x3
+ */
+ public static ScriptIntrinsicConvolve3x3 create(RenderScript rs, Element e) {
+ float f[] = { 0, 0, 0, 0, 1, 0, 0, 0, 0};
+ if (!e.isCompatible(Element.U8(rs)) &&
+ !e.isCompatible(Element.U8_2(rs)) &&
+ !e.isCompatible(Element.U8_3(rs)) &&
+ !e.isCompatible(Element.U8_4(rs)) &&
+ !e.isCompatible(Element.F32(rs)) &&
+ !e.isCompatible(Element.F32_2(rs)) &&
+ !e.isCompatible(Element.F32_3(rs)) &&
+ !e.isCompatible(Element.F32_4(rs))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(1, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicConvolve3x3 si = new ScriptIntrinsicConvolve3x3(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ si.setCoefficients(f);
+ return si;
+ }
+
+ /**
+ * Set the input of the 3x3 convolve.
+ * Must match the element type supplied during create.
+ *
+ * @param ain The input allocation.
+ */
+ public void setInput(Allocation ain) {
+ mInput = ain;
+ setVar(1, ain);
+ }
+
+ /**
+ * Set the coefficients for the convolve.
+ *
+ * <p> The convolve layout is:
+ * <code>
+ * <p> [ 0, 1, 2 ]
+ * <p> [ 3, 4, 5 ]
+ * <p> [ 6, 7, 8 ]
+ * </code>
+ *
+ * @param v The array of coefficients to set
+ */
+ public void setCoefficients(float v[]) {
+ FieldPacker fp = new FieldPacker(9*4);
+ for (int ct=0; ct < mValues.length; ct++) {
+ mValues[ct] = v[ct];
+ fp.addF32(mValues[ct]);
+ }
+ setVar(0, fp);
+ }
+
+ /**
+ * Apply the filter to the input and save to the specified
+ * allocation.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ */
+ public void forEach(Allocation aout) {
+ forEach(0, (Allocation) null, aout, null);
+ }
+
+ /**
+ * Apply the filter to the input and save to the specified
+ * allocation.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach(Allocation aout, Script.LaunchOptions opt) {
+ forEach(0, (Allocation) null, aout, null, opt);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 2, null, null);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(1, null);
+ }
+
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicConvolve5x5.java b/androidx/renderscript/ScriptIntrinsicConvolve5x5.java
new file mode 100644
index 0000000..298596e
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a 5x5 convolve to an allocation.
+ *
+ **/
+public class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
+ private final float[] mValues = new float[25];
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ ScriptIntrinsicConvolve5x5(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8}, {@link
+ * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+ * {@link Element#F32}, {@link Element#F32_2}, {@link
+ * Element#F32_3}, and {@link Element#F32_4}.
+ *
+ * <p> The default coefficients are:
+ * <code>
+ * <p> [ 0, 0, 0, 0, 0 ]
+ * <p> [ 0, 0, 0, 0, 0 ]
+ * <p> [ 0, 0, 1, 0, 0 ]
+ * <p> [ 0, 0, 0, 0, 0 ]
+ * <p> [ 0, 0, 0, 0, 0 ]
+ * </code>
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for intputs and outputs
+ *
+ * @return ScriptIntrinsicConvolve5x5
+ */
+ public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
+ if (!e.isCompatible(Element.U8(rs)) &&
+ !e.isCompatible(Element.U8_2(rs)) &&
+ !e.isCompatible(Element.U8_3(rs)) &&
+ !e.isCompatible(Element.U8_4(rs)) &&
+ !e.isCompatible(Element.F32(rs)) &&
+ !e.isCompatible(Element.F32_2(rs)) &&
+ !e.isCompatible(Element.F32_3(rs)) &&
+ !e.isCompatible(Element.F32_4(rs))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(4, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicConvolve5x5 si = new ScriptIntrinsicConvolve5x5(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+
+ }
+
+ /**
+ * Set the input of the 5x5 convolve.
+ * Must match the element type supplied during create.
+ *
+ * @param ain The input allocation.
+ */
+ public void setInput(Allocation ain) {
+ mInput = ain;
+ setVar(1, ain);
+ }
+
+ /**
+ * Set the coefficients for the convolve.
+ *
+ * <p> The convolve layout is:
+ * <code>
+ * <p> [ 0, 1, 2, 3, 4 ]
+ * <p> [ 5, 6, 7, 8, 9 ]
+ * <p> [ 10, 11, 12, 13, 14 ]
+ * <p> [ 15, 16, 17, 18, 19 ]
+ * <p> [ 20, 21, 22, 23, 24 ]
+ * </code>
+ *
+ * @param v The array of coefficients to set
+ */
+ public void setCoefficients(float v[]) {
+ FieldPacker fp = new FieldPacker(25*4);
+ for (int ct=0; ct < mValues.length; ct++) {
+ mValues[ct] = v[ct];
+ fp.addF32(mValues[ct]);
+ }
+ setVar(0, fp);
+ }
+
+ /**
+ * Apply the filter to the input and save to the specified
+ * allocation.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ */
+ public void forEach(Allocation aout) {
+ forEach(0, (Allocation) null, aout, null);
+ }
+
+ /**
+ * Apply the filter to the input and save to the specified
+ * allocation.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach(Allocation aout, Script.LaunchOptions opt) {
+ forEach(0, (Allocation) null, aout, null, opt);
+ }
+
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 2, null, null);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(1, null);
+ }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicHistogram.java b/androidx/renderscript/ScriptIntrinsicHistogram.java
new file mode 100644
index 0000000..3437f2c
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicHistogram.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic Histogram filter.
+ *
+ *
+ **/
+public class ScriptIntrinsicHistogram extends ScriptIntrinsic {
+ private Allocation mOut;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Create an intrinsic for calculating the histogram of an uchar
+ * or uchar4 image.
+ *
+ * Supported elements types are
+ * {@link Element#U8_4}, {@link Element#U8_3},
+ * {@link Element#U8_2}, {@link Element#U8}
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for inputs
+ *
+ * @return ScriptIntrinsicHistogram
+ */
+ public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
+ if ((!e.isCompatible(Element.U8_4(rs))) &&
+ (!e.isCompatible(Element.U8_3(rs))) &&
+ (!e.isCompatible(Element.U8_2(rs))) &&
+ (!e.isCompatible(Element.U8(rs)))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+ }
+
+ /**
+ * Process an input buffer and place the histogram into the
+ * output allocation. The output allocation may be a narrower
+ * vector size than the input. In this case the vector size of
+ * the output is used to determine how many of the input
+ * channels are used in the computation. This is useful if you
+ * have an RGBA input buffer but only want the histogram for
+ * RGB.
+ *
+ * 1D and 2D input allocations are supported.
+ *
+ * @param ain The input image
+ */
+ public void forEach(Allocation ain) {
+ forEach(ain, null);
+ }
+
+ /**
+ * Process an input buffer and place the histogram into the
+ * output allocation. The output allocation may be a narrower
+ * vector size than the input. In this case the vector size of
+ * the output is used to determine how many of the input
+ * channels are used in the computation. This is useful if you
+ * have an RGBA input buffer but only want the histogram for
+ * RGB.
+ *
+ * 1D and 2D input allocations are supported.
+ *
+ * @param ain The input image
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach(Allocation ain, Script.LaunchOptions opt) {
+ if (ain.getType().getElement().getVectorSize() <
+ mOut.getType().getElement().getVectorSize()) {
+
+ throw new RSIllegalArgumentException(
+ "Input vector size must be >= output vector size.");
+ }
+ if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
+ }
+
+ forEach(0, ain, null, null, opt);
+ }
+
+
+
+ /**
+ * Set the coefficients used for the RGBA to Luminocity
+ * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
+ *
+ * Coefficients must be >= 0 and sum to 1.0 or less.
+ *
+ * @param r Red coefficient
+ * @param g Green coefficient
+ * @param b Blue coefficient
+ * @param a Alpha coefficient
+ */
+ public void setDotCoefficients(float r, float g, float b, float a) {
+ if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
+ throw new RSIllegalArgumentException("Coefficient may not be negative.");
+ }
+ if ((r + g + b + a) > 1.f) {
+ throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
+ }
+
+ FieldPacker fp = new FieldPacker(16);
+ fp.addF32(r);
+ fp.addF32(g);
+ fp.addF32(b);
+ fp.addF32(a);
+ setVar(0, fp);
+ }
+
+ /**
+ * Set the output of the histogram. 32 bit integer types are
+ * supported.
+ *
+ * @param aout The output allocation
+ */
+ public void setOutput(Allocation aout) {
+ mOut = aout;
+ if (mOut.getType().getElement() != Element.U32(mRS) &&
+ mOut.getType().getElement() != Element.U32_2(mRS) &&
+ mOut.getType().getElement() != Element.U32_3(mRS) &&
+ mOut.getType().getElement() != Element.U32_4(mRS) &&
+ mOut.getType().getElement() != Element.I32(mRS) &&
+ mOut.getType().getElement() != Element.I32_2(mRS) &&
+ mOut.getType().getElement() != Element.I32_3(mRS) &&
+ mOut.getType().getElement() != Element.I32_4(mRS)) {
+
+ throw new RSIllegalArgumentException("Output type must be U32 or I32.");
+ }
+ if ((mOut.getType().getX() != 256) ||
+ (mOut.getType().getY() != 0) ||
+ mOut.getType().hasMipmaps() ||
+ (mOut.getType().getYuv() != 0)) {
+
+ throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
+ }
+ setVar(1, aout);
+ }
+
+
+ /**
+ * Process an input buffer and place the histogram into the
+ * output allocation. The dot product of the input channel and
+ * the coefficients from 'setDotCoefficients' are used to
+ * calculate the output values.
+ *
+ * 1D and 2D input allocations are supported.
+ *
+ * @param ain The input image
+ */
+ public void forEach_Dot(Allocation ain) {
+ forEach_Dot(ain, null);
+ }
+
+ /**
+ * Process an input buffer and place the histogram into the
+ * output allocation. The dot product of the input channel and
+ * the coefficients from 'setDotCoefficients' are used to
+ * calculate the output values.
+ *
+ * 1D and 2D input allocations are supported.
+ *
+ * @param ain The input image
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
+ if (mOut.getType().getElement().getVectorSize() != 1) {
+ throw new RSIllegalArgumentException("Output vector size must be one.");
+ }
+ if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
+ !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
+ }
+
+ forEach(1, ain, null, null, opt);
+ }
+
+
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID_Separate() {
+ return createKernelID(0, 3, null, null);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(1, null);
+ }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicLUT.java b/androidx/renderscript/ScriptIntrinsicLUT.java
new file mode 100644
index 0000000..6434903
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicLUT.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a per-channel lookup table. Each
+ * channel of the input has an independant lookup table. The
+ * tables are 256 entries in size and can cover the full value
+ * range of {@link Element#U8_4}.
+ **/
+public class ScriptIntrinsicLUT extends ScriptIntrinsic {
+ private final Matrix4f mMatrix = new Matrix4f();
+ private Allocation mTables;
+ private final byte mCache[] = new byte[1024];
+ private boolean mDirty = true;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ protected ScriptIntrinsicLUT(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8_4}
+ *
+ * The defaults tables are identity.
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for intputs and outputs
+ *
+ * @return ScriptIntrinsicLUT
+ */
+ public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(3, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicLUT si = new ScriptIntrinsicLUT(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ si.mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
+ for (int ct=0; ct < 256; ct++) {
+ si.mCache[ct] = (byte)ct;
+ si.mCache[ct + 256] = (byte)ct;
+ si.mCache[ct + 512] = (byte)ct;
+ si.mCache[ct + 768] = (byte)ct;
+ }
+ si.setVar(0, si.mTables);
+ return si;
+ }
+
+
+ private void validate(int index, int value) {
+ if (index < 0 || index > 255) {
+ throw new RSIllegalArgumentException("Index out of range (0-255).");
+ }
+ if (value < 0 || value > 255) {
+ throw new RSIllegalArgumentException("Value out of range (0-255).");
+ }
+ }
+
+ /**
+ * Set an entry in the red channel lookup table
+ *
+ * @param index Must be 0-255
+ * @param value Must be 0-255
+ */
+ public void setRed(int index, int value) {
+ validate(index, value);
+ mCache[index] = (byte)value;
+ mDirty = true;
+ }
+
+ /**
+ * Set an entry in the green channel lookup table
+ *
+ * @param index Must be 0-255
+ * @param value Must be 0-255
+ */
+ public void setGreen(int index, int value) {
+ validate(index, value);
+ mCache[index+256] = (byte)value;
+ mDirty = true;
+ }
+
+ /**
+ * Set an entry in the blue channel lookup table
+ *
+ * @param index Must be 0-255
+ * @param value Must be 0-255
+ */
+ public void setBlue(int index, int value) {
+ validate(index, value);
+ mCache[index+512] = (byte)value;
+ mDirty = true;
+ }
+
+ /**
+ * Set an entry in the alpha channel lookup table
+ *
+ * @param index Must be 0-255
+ * @param value Must be 0-255
+ */
+ public void setAlpha(int index, int value) {
+ validate(index, value);
+ mCache[index+768] = (byte)value;
+ mDirty = true;
+ }
+
+
+ /**
+ * Invoke the kernel and apply the lookup to each cell of ain
+ * and copy to aout.
+ *
+ * @param ain Input allocation
+ * @param aout Output allocation
+ */
+ public void forEach(Allocation ain, Allocation aout) {
+ if (mDirty) {
+ mDirty = false;
+ mTables.copyFromUnchecked(mCache);
+ }
+ forEach(0, ain, aout, null);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 3, null, null);
+ }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicResize.java b/androidx/renderscript/ScriptIntrinsicResize.java
new file mode 100644
index 0000000..c3450f1
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicResize.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for performing a resize of a 2D allocation.
+ */
+public class ScriptIntrinsicResize extends ScriptIntrinsic {
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 21;
+
+ protected ScriptIntrinsicResize(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Supported elements types are {@link Element#U8}, {@link
+ * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4}
+ * {@link Element#F32}, {@link Element#F32_2}, {@link
+ * Element#F32_3}, {@link Element#F32_4}
+ *
+ * @param rs The RenderScript context
+ *
+ * @return ScriptIntrinsicResize
+ */
+ public static ScriptIntrinsicResize create(RenderScript rs) {
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(12, 0, mUseIncSupp);
+
+ ScriptIntrinsicResize si = new ScriptIntrinsicResize(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+
+ }
+
+ /**
+ * Set the input of the resize.
+ * Must match the element type supplied during create.
+ *
+ * @param ain The input allocation.
+ */
+ public void setInput(Allocation ain) {
+ Element e = ain.getElement();
+ if (!e.isCompatible(Element.U8(mRS)) &&
+ !e.isCompatible(Element.U8_2(mRS)) &&
+ !e.isCompatible(Element.U8_3(mRS)) &&
+ !e.isCompatible(Element.U8_4(mRS)) &&
+ !e.isCompatible(Element.F32(mRS)) &&
+ !e.isCompatible(Element.F32_2(mRS)) &&
+ !e.isCompatible(Element.F32_3(mRS)) &&
+ !e.isCompatible(Element.F32_4(mRS))) {
+ throw new RSIllegalArgumentException("Unsupported element type.");
+ }
+
+ mInput = ain;
+ setVar(0, ain);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(0, null);
+ }
+
+
+ /**
+ * Resize copy the input allocation to the output specified. The
+ * Allocation is rescaled if necessary using bi-cubic
+ * interpolation.
+ *
+ * @param aout Output allocation. Element type must match
+ * current input. Must not be same as input.
+ */
+ public void forEach_bicubic(Allocation aout) {
+ if (aout == mInput) {
+ throw new RSIllegalArgumentException("Output cannot be same as Input.");
+ }
+ forEach_bicubic(aout, null);
+ }
+
+ /**
+ * Resize copy the input allocation to the output specified. The
+ * Allocation is rescaled if necessary using bi-cubic
+ * interpolation.
+ *
+ * @param aout Output allocation. Element type must match
+ * current input.
+ * @param opt LaunchOptions for clipping
+ */
+ public void forEach_bicubic(Allocation aout, Script.LaunchOptions opt) {
+ forEach(0, (Allocation) null, aout, null, opt);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID_bicubic() {
+ return createKernelID(0, 2, null, null);
+ }
+
+
+}
diff --git a/androidx/renderscript/ScriptIntrinsicYuvToRGB.java b/androidx/renderscript/ScriptIntrinsicYuvToRGB.java
new file mode 100644
index 0000000..8749398
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+/**
+ * Intrinsic for converting an Android YUV buffer to RGB.
+ *
+ * The input allocation is supplied in NV21 format as a U8
+ * element type. The output is RGBA, the alpha channel will be
+ * set to 255.
+ */
+public class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
+ private Allocation mInput;
+ // API level for the intrinsic
+ private static final int INTRINSIC_API_LEVEL = 19;
+
+ ScriptIntrinsicYuvToRGB(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Create an intrinsic for converting YUV to RGB.
+ *
+ * Supported elements types are {@link Element#U8_4}
+ *
+ * @param rs The RenderScript context
+ * @param e Element type for output
+ *
+ * @return ScriptIntrinsicYuvToRGB
+ */
+ public static ScriptIntrinsicYuvToRGB create(RenderScript rs, Element e) {
+ // 6 comes from RS_SCRIPT_INTRINSIC_YUV_TO_RGB in rsDefines.h
+ long id;
+ boolean mUseIncSupp = rs.isUseNative() &&
+ android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+ id = rs.nScriptIntrinsicCreate(6, e.getID(rs), mUseIncSupp);
+
+ ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs);
+ si.setIncSupp(mUseIncSupp);
+ return si;
+ }
+
+
+ /**
+ * Set the input yuv allocation, must be {@link Element#U8}.
+ *
+ * @param ain The input allocation.
+ */
+ public void setInput(Allocation ain) {
+ mInput = ain;
+ setVar(0, ain);
+ }
+
+ /**
+ * Convert the image to RGB.
+ *
+ * @param aout Output allocation. Must match creation element
+ * type.
+ */
+ public void forEach(Allocation aout) {
+ forEach(0, (Allocation) null, aout, null);
+ }
+
+ /**
+ * Get a KernelID for this intrinsic kernel.
+ *
+ * @return Script.KernelID The KernelID object.
+ */
+ public Script.KernelID getKernelID() {
+ return createKernelID(0, 2, null, null);
+ }
+
+ /**
+ * Get a FieldID for the input field of this intrinsic.
+ *
+ * @return Script.FieldID The FieldID object.
+ */
+ public Script.FieldID getFieldID_Input() {
+ return createFieldID(0, null);
+ }
+}
diff --git a/androidx/renderscript/Short2.java b/androidx/renderscript/Short2.java
new file mode 100644
index 0000000..f06d746
--- /dev/null
+++ b/androidx/renderscript/Short2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript Short2 type back to the Android system.
+ *
+ **/
+public class Short2 {
+ public Short2() {
+ }
+
+ public Short2(short initX, short initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public short x;
+ public short y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Short3.java b/androidx/renderscript/Short3.java
new file mode 100644
index 0000000..fbf9a89
--- /dev/null
+++ b/androidx/renderscript/Short3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript short3 type back to the Android system.
+ *
+ **/
+public class Short3 {
+ public Short3() {
+ }
+
+ public Short3(short initX, short initY, short initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public short x;
+ public short y;
+ public short z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Short4.java b/androidx/renderscript/Short4.java
new file mode 100644
index 0000000..1e479d2
--- /dev/null
+++ b/androidx/renderscript/Short4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript short4 type back to the Android system.
+ *
+ **/
+public class Short4 {
+ public Short4() {
+ }
+
+ public Short4(short initX, short initY, short initZ, short initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public short x;
+ public short y;
+ public short z;
+ public short w;
+}
+
+
+
diff --git a/androidx/renderscript/Type.java b/androidx/renderscript/Type.java
new file mode 100644
index 0000000..cec834c
--- /dev/null
+++ b/androidx/renderscript/Type.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.renderscript;
+
+
+import java.lang.reflect.Field;
+
+import android.graphics.ImageFormat;
+import android.util.Log;
+
+/**
+ * <p>A Type describes the {@link androidx.renderscript.Element} and
+ * dimensions used for an {@link androidx.renderscript.Allocation} or
+ * a parallel operation. Types are created through
+ * {@link androidx.renderscript.Type.Builder}.</p>
+ *
+ * <p>A Type always includes an {@link androidx.renderscript.Element}
+ * and an X dimension. A Type may be multidimensional, up to three dimensions.
+ * A nonzero value in the Y or Z dimensions indicates that the dimension is
+ * present. Note that a Type with only a given X dimension and a Type with the
+ * same X dimension but Y = 1 are not equivalent.</p>
+ *
+ * <p>A Type also supports inclusion of level of detail (LOD) or cube map
+ * faces. LOD and cube map faces are booleans to indicate present or not
+ * present. </p>
+ *
+ * <p>A Type also supports YUV format information to support an {@link
+ * androidx.renderscript.Allocation} in a YUV format. The YUV formats
+ * supported are {@link android.graphics.ImageFormat#YV12} and {@link
+ * android.graphics.ImageFormat#NV21}.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript,
+ * read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Type extends BaseObj {
+ int mDimX;
+ int mDimY;
+ int mDimZ;
+ boolean mDimMipmaps;
+ boolean mDimFaces;
+ int mDimYuv;
+ int mElementCount;
+ Element mElement;
+
+ public enum CubemapFace {
+ POSITIVE_X (0),
+ NEGATIVE_X (1),
+ POSITIVE_Y (2),
+ NEGATIVE_Y (3),
+ POSITIVE_Z (4),
+ NEGATIVE_Z (5);
+
+ int mID;
+ CubemapFace(int id) {
+ mID = id;
+ }
+ }
+
+ /**
+ * Return the element associated with this Type.
+ *
+ * @return Element
+ */
+ public Element getElement() {
+ return mElement;
+ }
+
+ /**
+ * Return the value of the X dimension.
+ *
+ * @return int
+ */
+ public int getX() {
+ return mDimX;
+ }
+
+ /**
+ * Return the value of the Y dimension or 0 for a 1D allocation.
+ *
+ * @return int
+ */
+ public int getY() {
+ return mDimY;
+ }
+
+ /**
+ * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
+ *
+ * @return int
+ */
+ public int getZ() {
+ return mDimZ;
+ }
+
+ /**
+ * Get the YUV format
+ *
+ * @return int
+ */
+ public int getYuv() {
+ return mDimYuv;
+ }
+
+ /**
+ * Return if the Type has a mipmap chain.
+ *
+ * @return boolean
+ */
+ public boolean hasMipmaps() {
+ return mDimMipmaps;
+ }
+
+ /**
+ * Return if the Type is a cube map.
+ *
+ * @return boolean
+ */
+ public boolean hasFaces() {
+ return mDimFaces;
+ }
+
+ /**
+ * Return the total number of accessable cells in the Type.
+ *
+ * @return int
+ */
+ public int getCount() {
+ return mElementCount;
+ }
+
+ void calcElementCount() {
+ boolean hasLod = hasMipmaps();
+ int x = getX();
+ int y = getY();
+ int z = getZ();
+ int faces = 1;
+ if (hasFaces()) {
+ faces = 6;
+ }
+ if (x == 0) {
+ x = 1;
+ }
+ if (y == 0) {
+ y = 1;
+ }
+ if (z == 0) {
+ z = 1;
+ }
+
+ int count = x * y * z * faces;
+
+ while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
+ if(x > 1) {
+ x >>= 1;
+ }
+ if(y > 1) {
+ y >>= 1;
+ }
+ if(z > 1) {
+ z >>= 1;
+ }
+
+ count += x * y * z * faces;
+ }
+ mElementCount = count;
+ }
+
+
+ Type(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /*
+ * Get an identical dummy Type for Compat Context
+ *
+ */
+ public long getDummyType(RenderScript mRS, long eid) {
+ return mRS.nIncTypeCreate(eid, mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mDimYuv);
+ }
+
+ /**
+ * Utility function for creating basic 1D types. The type is
+ * created without mipmaps enabled.
+ *
+ * @param rs The RenderScript context
+ * @param e The Element for the Type
+ * @param dimX The X dimension, must be > 0
+ *
+ * @return Type
+ */
+ static public Type createX(RenderScript rs, Element e, int dimX) {
+ if (dimX < 1) {
+ throw new RSInvalidStateException("Dimension must be >= 1.");
+ }
+
+ long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
+ Type t = new Type(id, rs);
+ t.mElement = e;
+ t.mDimX = dimX;
+ t.calcElementCount();
+ return t;
+ }
+
+ /**
+ * Utility function for creating basic 2D types. The type is
+ * created without mipmaps or cubemaps.
+ *
+ * @param rs The RenderScript context
+ * @param e The Element for the Type
+ * @param dimX The X dimension, must be > 0
+ * @param dimY The Y dimension, must be > 0
+ *
+ * @return Type
+ */
+ static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
+ if ((dimX < 1) || (dimY < 1)) {
+ throw new RSInvalidStateException("Dimension must be >= 1.");
+ }
+
+ long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
+ Type t = new Type(id, rs);
+ t.mElement = e;
+ t.mDimX = dimX;
+ t.mDimY = dimY;
+ t.calcElementCount();
+ return t;
+ }
+
+ /**
+ * Utility function for creating basic 3D types. The type is
+ * created without mipmaps.
+ *
+ * @param rs The RenderScript context
+ * @param e The Element for the Type
+ * @param dimX The X dimension, must be > 0
+ * @param dimY The Y dimension, must be > 0
+ * @param dimZ The Z dimension, must be > 0
+ *
+ * @return Type
+ */
+ static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
+ if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
+ throw new RSInvalidStateException("Dimension must be >= 1.");
+ }
+
+ long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
+ Type t = new Type(id, rs);
+ t.mElement = e;
+ t.mDimX = dimX;
+ t.mDimY = dimY;
+ t.mDimZ = dimZ;
+ t.calcElementCount();
+ return t;
+ }
+
+ /**
+ * Builder class for Type.
+ *
+ */
+ public static class Builder {
+ RenderScript mRS;
+ int mDimX = 1;
+ int mDimY;
+ int mDimZ;
+ boolean mDimMipmaps;
+ boolean mDimFaces;
+ int mYuv;
+
+ Element mElement;
+
+ /**
+ * Create a new builder object.
+ *
+ * @param rs
+ * @param e The element for the type to be created.
+ */
+ public Builder(RenderScript rs, Element e) {
+ e.checkValid();
+ mRS = rs;
+ mElement = e;
+ }
+
+ /**
+ * Add a dimension to the Type.
+ *
+ *
+ * @param value
+ */
+ public Builder setX(int value) {
+ if(value < 1) {
+ throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
+ }
+ mDimX = value;
+ return this;
+ }
+
+ public Builder setY(int value) {
+ if(value < 1) {
+ throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
+ }
+ mDimY = value;
+ return this;
+ }
+
+ public Builder setZ(int value) {
+ if(value < 1) {
+ throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
+ }
+ mDimZ = value;
+ return this;
+ }
+
+ public Builder setMipmaps(boolean value) {
+ mDimMipmaps = value;
+ return this;
+ }
+
+ public Builder setFaces(boolean value) {
+ mDimFaces = value;
+ return this;
+ }
+
+ /**
+ * Set the YUV layout for a Type.
+ *
+ * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
+ */
+ public Builder setYuvFormat(int yuvFormat) {
+ switch (yuvFormat) {
+ case android.graphics.ImageFormat.NV21:
+ case android.graphics.ImageFormat.YV12:
+ break;
+
+ default:
+ throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
+ }
+
+ mYuv = yuvFormat;
+ return this;
+ }
+
+
+ /**
+ * Validate structure and create a new Type.
+ *
+ * @return Type
+ */
+ public Type create() {
+ if (mDimZ > 0) {
+ if ((mDimX < 1) || (mDimY < 1)) {
+ throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
+ }
+ if (mDimFaces) {
+ throw new RSInvalidStateException("Cube maps not supported with 3D types.");
+ }
+ }
+ if (mDimY > 0) {
+ if (mDimX < 1) {
+ throw new RSInvalidStateException("X dimension required when Y is present.");
+ }
+ }
+ if (mDimFaces) {
+ if (mDimY < 1) {
+ throw new RSInvalidStateException("Cube maps require 2D Types.");
+ }
+ }
+
+ if (mYuv != 0) {
+ if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
+ throw new RSInvalidStateException("YUV only supports basic 2D.");
+ }
+ }
+
+ Type t;
+ long id = mRS.nTypeCreate(mElement.getID(mRS),
+ mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
+ t = new Type(id, mRS);
+
+ t.mElement = mElement;
+ t.mDimX = mDimX;
+ t.mDimY = mDimY;
+ t.mDimZ = mDimZ;
+ t.mDimMipmaps = mDimMipmaps;
+ t.mDimFaces = mDimFaces;
+ t.mDimYuv = mYuv;
+
+ t.calcElementCount();
+ return t;
+ }
+ }
+
+}