Add API 31 sources Test: None Change-Id: Ie45894f7a232b2a15e2439b2527ca1813f334cc5
diff --git a/androidx/renderscript/Allocation.java b/androidx/renderscript/Allocation.java new file mode 100644 index 0000000..a37eff6 --- /dev/null +++ b/androidx/renderscript/Allocation.java
@@ -0,0 +1,3037 @@ +/* + * 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> + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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 placeholder 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..b7f9d9e --- /dev/null +++ b/androidx/renderscript/BaseObj.java
@@ -0,0 +1,159 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..b2f029e --- /dev/null +++ b/androidx/renderscript/Byte2.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 byte2 type back to the Android system. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..1e12dec --- /dev/null +++ b/androidx/renderscript/Byte3.java
@@ -0,0 +1,48 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..1ad22c7 --- /dev/null +++ b/androidx/renderscript/Byte4.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..66d54ae --- /dev/null +++ b/androidx/renderscript/Double2.java
@@ -0,0 +1,47 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..98cf8c6 --- /dev/null +++ b/androidx/renderscript/Double3.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..b10ed05 --- /dev/null +++ b/androidx/renderscript/Double4.java
@@ -0,0 +1,50 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..6376681 --- /dev/null +++ b/androidx/renderscript/Element.java
@@ -0,0 +1,1025 @@ +/* + * 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> + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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 placeholder 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..f3d1a44 --- /dev/null +++ b/androidx/renderscript/FieldPacker.java
@@ -0,0 +1,950 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..b743beb --- /dev/null +++ b/androidx/renderscript/Float2.java
@@ -0,0 +1,46 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..63c5c89 --- /dev/null +++ b/androidx/renderscript/Float3.java
@@ -0,0 +1,47 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..d65a1ab --- /dev/null +++ b/androidx/renderscript/Float4.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..b841f8b --- /dev/null +++ b/androidx/renderscript/Int2.java
@@ -0,0 +1,46 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..8ff4dce --- /dev/null +++ b/androidx/renderscript/Int3.java
@@ -0,0 +1,48 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..449e996 --- /dev/null +++ b/androidx/renderscript/Int4.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..76419b5 --- /dev/null +++ b/androidx/renderscript/Long2.java
@@ -0,0 +1,46 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..cee3f55 --- /dev/null +++ b/androidx/renderscript/Long3.java
@@ -0,0 +1,48 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..2f5e5b9 --- /dev/null +++ b/androidx/renderscript/Long4.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..d2733c4 --- /dev/null +++ b/androidx/renderscript/Matrix2f.java
@@ -0,0 +1,200 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..83435d4 --- /dev/null +++ b/androidx/renderscript/Matrix3f.java
@@ -0,0 +1,325 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..0addfa0 --- /dev/null +++ b/androidx/renderscript/Matrix4f.java
@@ -0,0 +1,498 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..514bee0 --- /dev/null +++ b/androidx/renderscript/RSDriverException.java
@@ -0,0 +1,36 @@ +/* + * 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 + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..13d212d --- /dev/null +++ b/androidx/renderscript/RSIllegalArgumentException.java
@@ -0,0 +1,35 @@ +/* + * 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 + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..f75d63d --- /dev/null +++ b/androidx/renderscript/RSInvalidStateException.java
@@ -0,0 +1,36 @@ +/* + * 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 + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..12a3b0f --- /dev/null +++ b/androidx/renderscript/RSRuntimeException.java
@@ -0,0 +1,35 @@ +/* + * 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 + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..b789f2c --- /dev/null +++ b/androidx/renderscript/RenderScript.java
@@ -0,0 +1,1753 @@ +/* + * 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> + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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 mDenyList = ""; + /** + * Sets the denylist of Models to only use support lib runtime. + * Should be used before context create. + * + * @param denylist User provided denylist string. + * + * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..." + * e.g. : To Denylist Nexus 7(2013) and Nexus 5. + * mDenyList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)"; + */ + static public void setDenyList(String denyList) { + if (denyList != null) { + mDenyList = denyList; + } + } + /** + * 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 denylist + if (mDenyList.length() > 0) { + String deviceInfo = '(' + + android.os.Build.MANUFACTURER + + ':' + + android.os.Build.PRODUCT + + ':' + + android.os.Build.MODEL + + ')'; + if (mDenyList.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 placeholder 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; + //Placeholder 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..2e5ae15 --- /dev/null +++ b/androidx/renderscript/Sampler.java
@@ -0,0 +1,351 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..3d4ba01 --- /dev/null +++ b/androidx/renderscript/Script.java
@@ -0,0 +1,706 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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 placeholderAlloc = 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(); + placeholderAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType, xBytesSize); + ain.setIncAllocID(placeholderAlloc); + } + + return placeholderAlloc; + } + /** + * 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..4fd626e --- /dev/null +++ b/androidx/renderscript/ScriptC.java
@@ -0,0 +1,136 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..f5096e5 --- /dev/null +++ b/androidx/renderscript/ScriptGroup.java
@@ -0,0 +1,1185 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..c9a616d --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsic.java
@@ -0,0 +1,39 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..5d5bc4c --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsic3DLUT.java
@@ -0,0 +1,114 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..d6acc27 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicBLAS.java
@@ -0,0 +1,4194 @@ +/* + * 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/ + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..534de8a --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicBlend.java
@@ -0,0 +1,482 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..09114cd --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicBlur.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; + +/** + * Intrinsic Gausian blur filter. Applies a gaussian blur of the + * specified radius to all elements of an allocation. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..cb17244 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicColorMatrix.java
@@ -0,0 +1,267 @@ +/* + * 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}. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..87149b3 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicConvolve3x3.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; + +/** + * Intrinsic for applying a 3x3 convolve to an allocation. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..7105847 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -0,0 +1,158 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..821a1de --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicHistogram.java
@@ -0,0 +1,235 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..0418334 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicLUT.java
@@ -0,0 +1,157 @@ +/* + * 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}. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..6ef32a1 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicResize.java
@@ -0,0 +1,132 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..0a09074 --- /dev/null +++ b/androidx/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -0,0 +1,102 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + */ +@Deprecated +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..679ea8a --- /dev/null +++ b/androidx/renderscript/Short2.java
@@ -0,0 +1,46 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..e6e76c2 --- /dev/null +++ b/androidx/renderscript/Short3.java
@@ -0,0 +1,48 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..0826e5f --- /dev/null +++ b/androidx/renderscript/Short4.java
@@ -0,0 +1,49 @@ +/* + * 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. + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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..a0c225d --- /dev/null +++ b/androidx/renderscript/Type.java
@@ -0,0 +1,416 @@ +/* + * 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> + * + * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a + * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration + * guide</a> for the proposed alternatives. + **/ +@Deprecated +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 placeholder 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; + } + } + +}