diff options
author | Tim Murray <timmurray@google.com> | 2013-12-17 13:28:17 -0800 |
---|---|---|
committer | Tim Murray <timmurray@google.com> | 2014-01-31 12:35:17 -0800 |
commit | 355707e4f665904e31d9f5fcff1e3921f7db8cdd (patch) | |
tree | 0e5c36c10cd720a2e6f7f14e7e7572ba85bfc0d3 /rs | |
parent | 7a629fac82f88126642081b4474879f6a883e313 (diff) | |
download | frameworks_base-355707e4f665904e31d9f5fcff1e3921f7db8cdd.zip frameworks_base-355707e4f665904e31d9f5fcff1e3921f7db8cdd.tar.gz frameworks_base-355707e4f665904e31d9f5fcff1e3921f7db8cdd.tar.bz2 |
Move RenderScript from graphics/ to new fw/base subdirectory rs.
Change-Id: I30b6633578f063840e1bdbcc9ba513b727912a6d
Diffstat (limited to 'rs')
63 files changed, 23697 insertions, 0 deletions
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java new file mode 100644 index 0000000..98fabce --- /dev/null +++ b/rs/java/android/renderscript/Allocation.java @@ -0,0 +1,1863 @@ +/* + * 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 android.renderscript; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import android.content.res.Resources; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.view.Surface; +import android.util.Log; +import android.util.TypedValue; +import android.graphics.Canvas; +import android.os.Trace; + +/** + * <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 android.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 + * android.renderscript.Sampler}. A developer must synchronize across these + * different usages using {@link android.renderscript.Allocation#syncAll} in + * order to ensure that different users of the Allocation have a consistent view + * of memory. For example, in the case where an Allocation is used as the output + * of one kernel and as Sampler input in a later kernel, a developer must call + * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the + * second kernel to ensure correctness. + * + * <p>An Allocation can be populated with the {@link #copyFrom} routines. For + * more complex Element types, the {@link #copyFromUnchecked} methods can be + * used to copy from byte arrays or similar constructs.</p> + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + **/ +public class Allocation extends BaseObj { + Type mType; + Bitmap mBitmap; + int mUsage; + Allocation mAdaptedAllocation; + int mSize; + + boolean mConstrainedLOD; + boolean mConstrainedFace; + boolean mConstrainedY; + boolean mConstrainedZ; + boolean mReadAllowed = true; + boolean mWriteAllowed = true; + int mSelectedY; + int mSelectedZ; + int mSelectedLOD; + Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; + + int mCurrentDimX; + int mCurrentDimY; + int mCurrentDimZ; + int mCurrentCount; + static HashMap<Long, Allocation> mAllocationMap = + new HashMap<Long, Allocation>(); + OnBufferAvailableListener mBufferNotifier; + + /** + * 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 graphics mesh. + * + * This was deprecated in API level 16. + * + */ + public static final int USAGE_GRAPHICS_VERTEX = 0x0004; + + + /** + * The Allocation will be used as the source of shader constants by one or + * more programs. + * + * This was deprecated in API level 16. + * + */ + public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; + + /** + * The Allocation will be used as a target for offscreen rendering + * + * This was deprecated in API level 16. + * + */ + public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010; + + /** + * The Allocation will be used as a {@link android.view.Surface} + * 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.view.Surface} + * producer. The dimensions and format of the {@link + * android.view.Surface} 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; + } + } + + + private long getIDSafe() { + if (mAdaptedAllocation != null) { + return mAdaptedAllocation.getID(mRS); + } + return getID(mRS); + } + + + /** + * Get the {@link android.renderscript.Element} of the {@link + * android.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; + } + + /** + * Get the size of the Allocation in bytes. + * + * @return size of the Allocation in bytes. + * + */ + public int getBytesSize() { + 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_GRAPHICS_VERTEX | + USAGE_GRAPHICS_CONSTANTS | + USAGE_GRAPHICS_RENDER_TARGET | + 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; + + 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); + } + 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 { + RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize); + super.finalize(); + } + + 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 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) || + (mType.mElement.mType == Element.DataType.RS_MESH) || + (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) || + (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) || + (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) || + (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) { + return; + } + throw new RSIllegalArgumentException( + "Object source does not match allocation type " + mType.mElement.mType); + } + + @Override + void updateFromNative() { + super.updateFromNative(); + long typeID = mRS.nAllocationGetType(getID(mRS)); + if(typeID != 0) { + mType = new Type(typeID, mRS); + mType.updateFromNative(); + updateCacheInfo(mType); + } + } + + /** + * Get the {@link android.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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll"); + switch (srcLocation) { + case USAGE_GRAPHICS_TEXTURE: + case USAGE_SCRIPT: + if ((mUsage & USAGE_SHARED) != 0) { + copyFrom(mBitmap); + } + break; + case USAGE_GRAPHICS_CONSTANTS: + case USAGE_GRAPHICS_VERTEX: + break; + case USAGE_SHARED: + if ((mUsage & USAGE_SHARED) != 0) { + copyTo(mBitmap); + } + break; + default: + throw new RSIllegalArgumentException("Source must be exactly one usage type."); + } + mRS.validate(); + mRS.nAllocationSyncAll(getIDSafe(), srcLocation); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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() { + Trace.traceBegin(RenderScript.TRACE_TAG, "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)); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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() { + Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive"); + if ((mUsage & USAGE_IO_INPUT) == 0) { + throw new RSIllegalArgumentException( + "Can only receive if IO_INPUT usage specified."); + } + mRS.validate(); + mRS.nAllocationIoReceive(getID(mRS)); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array of RS objects to the Allocation. + * + * @param d Source array. + */ + public void copyFrom(BaseObj[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + validateIsObject(); + if (d.length != mCurrentCount) { + throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + + mCurrentCount + ", array length = " + d.length); + } + // FIXME: requires 64-bit path + + 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); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + 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"); + } + } + + /** + * 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. + * + * @param d the source data array + */ + public void copyFromUnchecked(int[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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. + * + * @param d the source data array + */ + public void copyFromUnchecked(short[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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. + * + * @param d the source data array + */ + public void copyFromUnchecked(byte[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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. + * + * @param d the source data array + */ + public void copyFromUnchecked(float[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFromUnchecked(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + + /** + * Copy into this Allocation from an array. This variant is type checked + * and will generate exceptions if the Allocation's {@link + * android.renderscript.Element} is not a 32 bit integer type. + * + * @param d the source data array + */ + public void copyFrom(int[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy into this Allocation from an array. This variant is type checked + * and will generate exceptions if the Allocation's {@link + * android.renderscript.Element} is not a 16 bit integer type. + * + * @param d the source data array + */ + public void copyFrom(short[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy into this Allocation from an array. This variant is type checked + * and will generate exceptions if the Allocation's {@link + * android.renderscript.Element} is not an 8 bit integer type. + * + * @param d the source data array + */ + public void copyFrom(byte[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy into this Allocation from an array. This variant is type checked + * and will generate exceptions if the Allocation's {@link + * android.renderscript.Element} is not a 32 bit float type. + * + * @param d the source data array + */ + public void copyFrom(float[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + if (mCurrentDimZ > 0) { + copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); + } else if (mCurrentDimY > 0) { + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); + } else { + copy1DRangeFrom(0, mCurrentCount, d); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + 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); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an Allocation from an Allocation. The types of both allocations + * must be identical. + * + * @param a the source allocation + */ + public void copyFrom(Allocation a) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); + mRS.validate(); + if (!mType.equals(a.getType())) { + throw new RSIllegalArgumentException("Types of allocations must match."); + } + copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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 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 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); + } + + private void data1DChecks(int off, int count, int len, int dataSize) { + 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(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)); + } + + /** + * Copy an array into part of this Allocation. This method does not + * guarantee that the Allocation is compatible with the input buffer. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFromUnchecked(int off, int count, int[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); + int dataSize = mType.mElement.getBytesSize() * count; + data1DChecks(off, count, d.length * 4, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This method does not + * guarantee that the Allocation is compatible with the input buffer. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFromUnchecked(int off, int count, short[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); + int dataSize = mType.mElement.getBytesSize() * count; + data1DChecks(off, count, d.length * 2, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_16); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This method does not + * guarantee that the Allocation is compatible with the input buffer. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); + int dataSize = mType.mElement.getBytesSize() * count; + data1DChecks(off, count, d.length, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_8); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This method does not + * guarantee that the Allocation is compatible with the input buffer. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFromUnchecked(int off, int count, float[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); + int dataSize = mType.mElement.getBytesSize() * count; + data1DChecks(off, count, d.length * 4, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.FLOAT_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This variant is type checked + * and will generate exceptions if the Allocation type is not a 32 bit + * integer type. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFrom(int off, int count, int[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); + validateIsInt32(); + copy1DRangeFromUnchecked(off, count, d); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This variant is type checked + * and will generate exceptions if the Allocation type is not a 16 bit + * integer type. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFrom(int off, int count, short[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); + validateIsInt16(); + copy1DRangeFromUnchecked(off, count, d); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This variant is type checked + * and will generate exceptions if the Allocation type is not an 8 bit + * integer type. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array + */ + public void copy1DRangeFrom(int off, int count, byte[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); + validateIsInt8(); + copy1DRangeFromUnchecked(off, count, d); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy an array into part of this Allocation. This variant is type checked + * and will generate exceptions if the Allocation type is not a 32 bit float + * type. + * + * @param off The offset of the first element to be copied. + * @param count The number of elements to be copied. + * @param d the source data array. + */ + public void copy1DRangeFrom(int off, int count, float[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); + validateIsFloat32(); + copy1DRangeFromUnchecked(off, count, d); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + /** + * 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); + 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, byte[] data) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); + mRS.validate(); + validate2DRange(xoff, yoff, w, h); + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + w, h, data, data.length, Element.DataType.SIGNED_8); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); + mRS.validate(); + validate2DRange(xoff, yoff, w, h); + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + w, h, data, data.length * 2, Element.DataType.SIGNED_16); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); + mRS.validate(); + validate2DRange(xoff, yoff, w, h); + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + w, h, data, data.length * 4, Element.DataType.SIGNED_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); + mRS.validate(); + validate2DRange(xoff, yoff, w, h); + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + w, h, data, data.length * 4, Element.DataType.FLOAT_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from an array into a rectangular region in this Allocation. The + * array is assumed to be tightly packed. + * + * @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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + validateIsInt8(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from an array into a rectangular region in this Allocation. The + * array is assumed to be tightly packed. + * + * @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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + validateIsInt16(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from an array into a rectangular region in this Allocation. The + * array is assumed to be tightly packed. + * + * @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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + validateIsInt32(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from an array into a rectangular region in this Allocation. The + * array is assumed to be tightly packed. + * + * @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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + validateIsFloat32(); + copy2DRangeFromUnchecked(xoff, yoff, w, h, data); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + 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); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); + 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); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + 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."); + } + } + } + + /** + * @hide + * + */ + void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) { + mRS.validate(); + validate3DRange(xoff, yoff, zoff, w, h, d); + mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, + w, h, d, data, data.length, Element.DataType.SIGNED_8); + } + + /** + * @hide + * + */ + void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) { + mRS.validate(); + validate3DRange(xoff, yoff, zoff, w, h, d); + mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, + w, h, d, data, data.length * 2, Element.DataType.SIGNED_16); + } + + /** + * @hide + * + */ + void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) { + mRS.validate(); + validate3DRange(xoff, yoff, zoff, w, h, d); + mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, + w, h, d, data, data.length * 4, Element.DataType.SIGNED_32); + } + + /** + * @hide + * + */ + void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) { + mRS.validate(); + validate3DRange(xoff, yoff, zoff, w, h, d); + mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, + w, h, d, data, data.length * 4, Element.DataType.FLOAT_32); + } + + + /** + * @hide + * Copy a rectangular region from the array into the allocation. + * The array is assumed to be tightly packed. + * + * @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 to be placed into the allocation + */ + public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) { + validateIsInt8(); + copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); + } + + /** + * @hide + * + */ + public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) { + validateIsInt16(); + copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); + } + + /** + * @hide + * + */ + public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) { + validateIsInt32(); + copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); + } + + /** + * @hide + * + */ + public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) { + validateIsFloat32(); + copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); + } + + /** + * @hide + * 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); + mRS.validate(); + validateBitmapFormat(b); + validateBitmapSize(b); + mRS.nAllocationCopyToBitmap(getID(mRS), b); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from the Allocation into a byte array. The array must be at least + * as large as the Allocation. The allocation must be of an 8 bit integer + * {@link android.renderscript.Element} type. + * + * @param d The array to be set from the Allocation. + */ + public void copyTo(byte[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); + validateIsInt8(); + mRS.validate(); + mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_8); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from the Allocation into a short array. The array must be at least + * as large as the Allocation. The allocation must be of an 16 bit integer + * {@link android.renderscript.Element} type. + * + * @param d The array to be set from the Allocation. + */ + public void copyTo(short[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); + validateIsInt16(); + mRS.validate(); + mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_16); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from the Allocation into a int array. The array must be at least as + * large as the Allocation. The allocation must be of an 32 bit integer + * {@link android.renderscript.Element} type. + * + * @param d The array to be set from the Allocation. + */ + public void copyTo(int[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); + validateIsInt32(); + mRS.validate(); + mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Copy from the Allocation into a float array. The array must be at least + * as large as the Allocation. The allocation must be of an 32 bit float + * {@link android.renderscript.Element} type. + * + * @param d The array to be set from the Allocation. + */ + public void copyTo(float[] d) { + Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); + validateIsFloat32(); + mRS.validate(); + mRS.nAllocationRead(getID(mRS), d, Element.DataType.FLOAT_32); + Trace.traceEnd(RenderScript.TRACE_TAG); + } + + /** + * Resize a 1D allocation. The contents of the allocation are preserved. + * If new elements are allocated objects are created with null contents and + * the new region is otherwise undefined. + * + * <p>If the new region is smaller the references of any objects outside the + * new region will be released.</p> + * + * <p>A new type will be created with the new dimension.</p> + * + * @param dimX The new size of the allocation. + * + * @deprecated RenderScript objects should be immutable once created. The + * replacement is to create a new allocation and copy the contents. + */ + public synchronized void resize(int dimX) { + if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { + throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); + } + mRS.nAllocationResize1D(getID(mRS), dimX); + mRS.finish(); // Necessary because resize is fifoed and update is async. + + long typeID = mRS.nAllocationGetType(getID(mRS)); + mType = new Type(typeID, mRS); + mType.updateFromNative(); + updateCacheInfo(mType); + } + + + // creation + + static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); + static { + mBitmapOptions.inScaled = false; + } + + /** + * Creates a new Allocation with the given {@link + * android.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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped"); + rs.validate(); + if (type.getID(rs) == 0) { + throw new RSInvalidStateException("Bad Type"); + } + long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); + if (id == 0) { + throw new RSRuntimeException("Allocation creation failed."); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + 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 + * android.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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "createSized"); + 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."); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + 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) { + Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap"); + 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."); + } + Trace.traceEnd(RenderScript.TRACE_TAG); + return new Allocation(id, rs, t, usage); + } + + /** + * Returns the handle to a raw buffer that is being managed by the screen + * compositor. This operation is only valid for Allocations with {@link + * #USAGE_IO_INPUT}. + * + * @return Surface object associated with allocation + * + */ + public Surface getSurface() { + if ((mUsage & USAGE_IO_INPUT) == 0) { + throw new RSInvalidStateException("Allocation is not a surface texture."); + } + return mRS.nAllocationGetSurface(getID(mRS)); + } + + /** + * 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>With target API version 18 or greater, this Allocation will be created + * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link + * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this + * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</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) { + if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { + return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, + USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); + } + return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, + 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; + } + + /** + * 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>With target API version 18 or greater, this allocation will be created + * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With + * target API version 17 or lower, this allocation will be created with + * {@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) { + if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { + return createFromBitmapResource(rs, res, id, + MipmapControl.MIPMAP_NONE, + USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); + } + return createFromBitmapResource(rs, res, id, + MipmapControl.MIPMAP_NONE, + 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."); + } + } + + /** + * Interface to handle notification when new buffers are available via + * {@link #USAGE_IO_INPUT}. An application will receive one notification + * when a buffer is available. Additional buffers will not trigger new + * notifications until a buffer is processed. + */ + public interface OnBufferAvailableListener { + public void onBufferAvailable(Allocation a); + } + + /** + * Set a notification handler for {@link #USAGE_IO_INPUT}. + * + * @param callback instance of the OnBufferAvailableListener + * class to be called when buffer arrive. + */ + public void setOnBufferAvailableListener(OnBufferAvailableListener callback) { + synchronized(mAllocationMap) { + mAllocationMap.put(new Long(getID(mRS)), this); + mBufferNotifier = callback; + } + } + + static void sendBufferNotification(int id) { + synchronized(mAllocationMap) { + Allocation a = mAllocationMap.get(new Long(id)); + + if ((a != null) && (a.mBufferNotifier != null)) { + a.mBufferNotifier.onBufferAvailable(a); + } + } + } + +} + diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java new file mode 100644 index 0000000..b77d087 --- /dev/null +++ b/rs/java/android/renderscript/AllocationAdapter.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.TypedValue; + +/** + * Only intended for use by generated reflected code. + * + **/ +public class AllocationAdapter extends Allocation { + AllocationAdapter(long id, RenderScript rs, Allocation alloc) { + super(id, rs, alloc.mType, alloc.mUsage); + mAdaptedAllocation = alloc; + } + + long getID(RenderScript rs) { + throw new RSInvalidStateException( + "This operation is not supported with adapters at this time."); + } + + /** + * @hide + */ + public void subData(int xoff, FieldPacker fp) { + super.setFromFieldPacker(xoff, fp); + } + /** + * @hide + */ + public void subElementData(int xoff, int component_number, FieldPacker fp) { + super.setFromFieldPacker(xoff, component_number, fp); + } + /** + * @hide + */ + public void subData1D(int off, int count, int[] d) { + super.copy1DRangeFrom(off, count, d); + } + /** + * @hide + */ + public void subData1D(int off, int count, short[] d) { + super.copy1DRangeFrom(off, count, d); + } + /** + * @hide + */ + public void subData1D(int off, int count, byte[] d) { + super.copy1DRangeFrom(off, count, d); + } + /** + * @hide + */ + public void subData1D(int off, int count, float[] d) { + super.copy1DRangeFrom(off, count, d); + } + /** + * @hide + */ + public void subData2D(int xoff, int yoff, int w, int h, int[] d) { + super.copy2DRangeFrom(xoff, yoff, w, h, d); + } + /** + * @hide + */ + public void subData2D(int xoff, int yoff, int w, int h, float[] d) { + super.copy2DRangeFrom(xoff, yoff, w, h, d); + } + /** + * @hide + */ + public void readData(int[] d) { + super.copyTo(d); + } + /** + * @hide + */ + public void readData(float[] d) { + super.copyTo(d); + } + + void initLOD(int lod) { + if (lod < 0) { + throw new RSIllegalArgumentException("Attempting to set negative lod (" + lod + ")."); + } + + int tx = mAdaptedAllocation.mType.getX(); + int ty = mAdaptedAllocation.mType.getY(); + int tz = mAdaptedAllocation.mType.getZ(); + + for (int ct=0; ct < lod; ct++) { + if ((tx==1) && (ty == 1) && (tz == 1)) { + throw new RSIllegalArgumentException("Attempting to set lod (" + lod + ") out of range."); + } + + if (tx > 1) tx >>= 1; + if (ty > 1) ty >>= 1; + if (tz > 1) tz >>= 1; + } + + mCurrentDimX = tx; + mCurrentDimY = ty; + mCurrentDimZ = tz; + mCurrentCount = mCurrentDimX; + if (mCurrentDimY > 1) { + mCurrentCount *= mCurrentDimY; + } + if (mCurrentDimZ > 1) { + mCurrentCount *= mCurrentDimZ; + } + mSelectedY = 0; + mSelectedZ = 0; + } + + /** + * Set the active LOD. The LOD must be within the range for the + * type being adapted. The base allocation must have mipmaps. + * + * Because this changes the dimensions of the adapter the + * current Y and Z will be reset. + * + * @param lod The LOD to make active. + */ + public void setLOD(int lod) { + if (!mAdaptedAllocation.getType().hasMipmaps()) { + throw new RSInvalidStateException("Cannot set LOD when the allocation type does not include mipmaps."); + } + if (!mConstrainedLOD) { + throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps."); + } + + initLOD(lod); + } + + /** + * Set the active Face. The base allocation must be of a type + * that includes faces. + * + * @param cf The face to make active. + */ + public void setFace(Type.CubemapFace cf) { + if (!mAdaptedAllocation.getType().hasFaces()) { + throw new RSInvalidStateException("Cannot set Face when the allocation type does not include faces."); + } + if (!mConstrainedFace) { + throw new RSInvalidStateException("Cannot set LOD when the adapter includes mipmaps."); + } + if (cf == null) { + throw new RSIllegalArgumentException("Cannot set null face."); + } + + mSelectedFace = cf; + } + + /** + * Set the active Y. The y value must be within the range for + * the allocation being adapted. The base allocation must + * contain the Y dimension. + * + * @param y The y to make active. + */ + public void setY(int y) { + if (mAdaptedAllocation.getType().getY() == 0) { + throw new RSInvalidStateException("Cannot set Y when the allocation type does not include Y dim."); + } + if (mAdaptedAllocation.getType().getY() <= y) { + throw new RSInvalidStateException("Cannot set Y greater than dimension of allocation."); + } + if (!mConstrainedY) { + throw new RSInvalidStateException("Cannot set Y when the adapter includes Y."); + } + + mSelectedY = y; + } + + /** + * Set the active Z. The z value must be within the range for + * the allocation being adapted. The base allocation must + * contain the Z dimension. + * + * @param z The z to make active. + */ + public void setZ(int z) { + if (mAdaptedAllocation.getType().getZ() == 0) { + throw new RSInvalidStateException("Cannot set Z when the allocation type does not include Z dim."); + } + if (mAdaptedAllocation.getType().getZ() <= z) { + throw new RSInvalidStateException("Cannot set Z greater than dimension of allocation."); + } + if (!mConstrainedZ) { + throw new RSInvalidStateException("Cannot set Z when the adapter includes Z."); + } + + mSelectedZ = z; + } + + static public AllocationAdapter create1D(RenderScript rs, Allocation a) { + rs.validate(); + AllocationAdapter aa = new AllocationAdapter(0, rs, a); + aa.mConstrainedLOD = true; + aa.mConstrainedFace = true; + aa.mConstrainedY = true; + aa.mConstrainedZ = true; + aa.initLOD(0); + return aa; + } + + static public AllocationAdapter create2D(RenderScript rs, Allocation a) { + android.util.Log.e("rs", "create2d " + a); + rs.validate(); + AllocationAdapter aa = new AllocationAdapter(0, rs, a); + aa.mConstrainedLOD = true; + aa.mConstrainedFace = true; + aa.mConstrainedY = false; + aa.mConstrainedZ = true; + aa.initLOD(0); + return aa; + } + + + /** + * Override the Allocation resize. Resizing adapters is not + * allowed and will throw a RSInvalidStateException. + * + * @param dimX ignored. + */ + public synchronized void resize(int dimX) { + throw new RSInvalidStateException("Resize not allowed for Adapters."); + } + +} + + diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java new file mode 100644 index 0000000..41159b9 --- /dev/null +++ b/rs/java/android/renderscript/BaseObj.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + +import android.util.Log; + +/** + * BaseObj is the base class for all RenderScript objects owned by a RS context. + * It is responsible for lifetime management and resource tracking. This class + * should not be used by a user application. + * + **/ +public class BaseObj { + BaseObj(long id, RenderScript rs) { + rs.validate(); + mRS = rs; + mID = id; + mDestroyed = false; + } + + void setID(int 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; + } + + void checkValid() { + if (mID == 0) { + throw new RSIllegalArgumentException("Invalid object."); + } + } + + private long mID; + private boolean mDestroyed; + private String mName; + RenderScript mRS; + + /** + * setName assigns a name to an object. This object can later be looked up + * by this name. + * + * @param name The name to assign to the object. + */ + public void setName(String name) { + if (name == null) { + throw new RSIllegalArgumentException( + "setName requires a string of non-zero length."); + } + if(name.length() < 1) { + throw new RSIllegalArgumentException( + "setName does not accept a zero length string."); + } + if(mName != null) { + throw new RSIllegalArgumentException( + "setName object already has a name."); + } + + try { + byte[] bytes = name.getBytes("UTF-8"); + mRS.nAssignName(mID, bytes); + mName = name; + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /** + * @return name of the renderscript object + */ + public String getName() { + return mName; + } + + protected void finalize() throws Throwable { + if (!mDestroyed) { + if(mID != 0 && mRS.isAlive()) { + mRS.nObjDestroy(mID); + } + mRS = null; + mID = 0; + mDestroyed = true; + //Log.v(RenderScript.LOG_TAG, getClass() + + // " auto finalizing object without having released the RS reference."); + } + 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. + */ + synchronized public void destroy() { + if(mDestroyed) { + throw new RSInvalidStateException("Object already destroyed."); + } + mDestroyed = true; + mRS.nObjDestroy(mID); + } + + /** + * If an object came from an a3d file, java fields need to be + * created with objects from the native layer + */ + void updateFromNative() { + mRS.validate(); + mName = mRS.nGetName(getID(mRS)); + } + + /** + * 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 (getClass() != obj.getClass()) { + return false; + } + + BaseObj b = (BaseObj) obj; + return mID == b.mID; + } +} + diff --git a/rs/java/android/renderscript/Byte2.java b/rs/java/android/renderscript/Byte2.java new file mode 100644 index 0000000..f796de3 --- /dev/null +++ b/rs/java/android/renderscript/Byte2.java @@ -0,0 +1,394 @@ +/* + * 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 android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript byte2 type back to the Android system. + * + **/ +public class Byte2 { + public byte x; + public byte y; + + public Byte2() { + } + + public Byte2(byte initX, byte initY) { + x = initX; + y = initY; + } + + /** @hide */ + public Byte2(Byte2 source) { + this.x = source.x; + this.y = source.y; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Byte2 a) { + this.x += a.x; + this.y += a.y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte2 add(Byte2 a, Byte2 b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x + b.x); + result.y = (byte)(a.y + b.y); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(byte value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte2 add(Byte2 a, byte b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x + b); + result.y = (byte)(a.y + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Byte2 a) { + this.x -= a.x; + this.y -= a.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte2 sub(Byte2 a, Byte2 b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x - b.x); + result.y = (byte)(a.y - b.y); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(byte value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte2 sub(Byte2 a, byte b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x - b); + result.y = (byte)(a.y - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Byte2 a) { + this.x *= a.x; + this.y *= a.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte2 mul(Byte2 a, Byte2 b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x * b.x); + result.y = (byte)(a.y * b.y); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(byte value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte2 mul(Byte2 a, byte b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x * b); + result.y = (byte)(a.y * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Byte2 a) { + this.x /= a.x; + this.y /= a.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte2 div(Byte2 a, Byte2 b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x / b.x); + result.y = (byte)(a.y / b.y); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(byte value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte2 div(Byte2 a, byte b) { + Byte2 result = new Byte2(); + result.x = (byte)(a.x / b); + result.y = (byte)(a.y / b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public byte length() { + return 2; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (byte)(-x); + this.y = (byte)(-y); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public byte dotProduct(Byte2 a) { + return (byte)((x * a.x) + (y * a.y)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static byte dotProduct(Byte2 a, Byte2 b) { + return (byte)((b.x * a.x) + (b.y * a.y)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Byte2 a, byte factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * set vector value by Byte2 + * + * @param a + */ + public void set(Byte2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * set the vector field value by Char + * + * @param a + * @param b + */ + public void setValues(byte a, byte b) { + this.x = a; + this.y = b; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public byte elementSum() { + return (byte)(x + y); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public byte get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, byte value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, byte value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to Char array + * + * @param data + * @param offset + */ + public void copyTo(byte[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + } + +} + + + + diff --git a/rs/java/android/renderscript/Byte3.java b/rs/java/android/renderscript/Byte3.java new file mode 100644 index 0000000..f2a95ac --- /dev/null +++ b/rs/java/android/renderscript/Byte3.java @@ -0,0 +1,426 @@ +/* + * 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 android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript byte3 type back to the Android system. + * + **/ +public class Byte3 { + public byte x; + public byte y; + public byte z; + + public Byte3() { + } + + public Byte3(byte initX, byte initY, byte initZ) { + x = initX; + y = initY; + z = initZ; + } + + /** @hide */ + public Byte3(Byte3 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Byte3 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte3 add(Byte3 a, Byte3 b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x + b.x); + result.y = (byte)(a.y + b.y); + result.z = (byte)(a.z + b.z); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(byte value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte3 add(Byte3 a, byte b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x + b); + result.y = (byte)(a.y + b); + result.z = (byte)(a.z + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Byte3 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte3 sub(Byte3 a, Byte3 b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x - b.x); + result.y = (byte)(a.y - b.y); + result.z = (byte)(a.z - b.z); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(byte value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte3 sub(Byte3 a, byte b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x - b); + result.y = (byte)(a.y - b); + result.z = (byte)(a.z - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Byte3 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte3 mul(Byte3 a, Byte3 b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x * b.x); + result.y = (byte)(a.y * b.y); + result.z = (byte)(a.z * b.z); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(byte value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte3 mul(Byte3 a, byte b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x * b); + result.y = (byte)(a.y * b); + result.z = (byte)(a.z * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Byte3 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte3 div(Byte3 a, Byte3 b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x / b.x); + result.y = (byte)(a.y / b.y); + result.z = (byte)(a.z / b.z); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(byte value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte3 div(Byte3 a, byte b) { + Byte3 result = new Byte3(); + result.x = (byte)(a.x / b); + result.y = (byte)(a.y / b); + result.z = (byte)(a.z / b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public byte length() { + return 3; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (byte)(-x); + this.y = (byte)(-y); + this.z = (byte)(-z); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public byte dotProduct(Byte3 a) { + return (byte)((byte)((byte)(x * a.x) + (byte)(y * a.y)) + (byte)(z * a.z)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static byte dotProduct(Byte3 a, Byte3 b) { + return (byte)((byte)((byte)(b.x * a.x) + (byte)(b.y * a.y)) + (byte)(b.z * a.z)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Byte3 a, byte factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * set vector value by Byte3 + * + * @param a + */ + public void set(Byte3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * set the vector field value by Char + * + * @param a + * @param b + * @param c + */ + public void setValues(byte a, byte b, byte c) { + this.x = a; + this.y = b; + this.z = c; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public byte elementSum() { + return (byte)(x + y + z); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public byte get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, byte value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, byte value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to Char array + * + * @param data + * @param offset + */ + public void copyTo(byte[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + } +} + + + + diff --git a/rs/java/android/renderscript/Byte4.java b/rs/java/android/renderscript/Byte4.java new file mode 100644 index 0000000..b8a8a6b --- /dev/null +++ b/rs/java/android/renderscript/Byte4.java @@ -0,0 +1,457 @@ +/* + * 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 android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript byte4 type back to the Android system. + * + **/ +public class Byte4 { + public byte x; + public byte y; + public byte z; + public byte w; + + public Byte4() { + } + + public Byte4(byte initX, byte initY, byte initZ, byte initW) { + x = initX; + y = initY; + z = initZ; + w = initW; + } + /** @hide */ + public Byte4(Byte4 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Byte4 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + this.w += a.w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte4 add(Byte4 a, Byte4 b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x + b.x); + result.y = (byte)(a.y + b.y); + result.z = (byte)(a.z + b.z); + result.w = (byte)(a.w + b.w); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(byte value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Byte4 add(Byte4 a, byte b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x + b); + result.y = (byte)(a.y + b); + result.z = (byte)(a.z + b); + result.w = (byte)(a.w + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Byte4 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + this.w -= a.w; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte4 sub(Byte4 a, Byte4 b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x - b.x); + result.y = (byte)(a.y - b.y); + result.z = (byte)(a.z - b.z); + result.w = (byte)(a.w - b.w); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(byte value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Byte4 sub(Byte4 a, byte b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x - b); + result.y = (byte)(a.y - b); + result.z = (byte)(a.z - b); + result.w = (byte)(a.w - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Byte4 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + this.w *= a.w; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte4 mul(Byte4 a, Byte4 b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x * b.x); + result.y = (byte)(a.y * b.y); + result.z = (byte)(a.z * b.z); + result.w = (byte)(a.w * b.w); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(byte value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Byte4 mul(Byte4 a, byte b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x * b); + result.y = (byte)(a.y * b); + result.z = (byte)(a.z * b); + result.w = (byte)(a.w * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Byte4 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + this.w /= a.w; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte4 div(Byte4 a, Byte4 b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x / b.x); + result.y = (byte)(a.y / b.y); + result.z = (byte)(a.z / b.z); + result.w = (byte)(a.w / b.w); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(byte value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Byte4 div(Byte4 a, byte b) { + Byte4 result = new Byte4(); + result.x = (byte)(a.x / b); + result.y = (byte)(a.y / b); + result.z = (byte)(a.z / b); + result.w = (byte)(a.w / b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public byte length() { + return 4; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (byte)(-x); + this.y = (byte)(-y); + this.z = (byte)(-z); + this.w = (byte)(-w); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public byte dotProduct(Byte4 a) { + return (byte)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static byte dotProduct(Byte4 a, Byte4 b) { + return (byte)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Byte4 a, byte factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * set vector value by Byte4 + * + * @param a + */ + public void set(Byte4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * set the vector field values + * + * @param a + * @param b + * @param c + * @param d + */ + public void setValues(byte a, byte b, byte c, byte d) { + this.x = a; + this.y = b; + this.z = c; + this.w = d; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public byte elementSum() { + return (byte)(x + y + z + w); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public byte get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, byte value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, byte value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to Char array + * + * @param data + * @param offset + */ + public void copyTo(byte[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + data[offset + 3] = w; + } +} + + + diff --git a/rs/java/android/renderscript/Double2.java b/rs/java/android/renderscript/Double2.java new file mode 100644 index 0000000..4c7319d --- /dev/null +++ b/rs/java/android/renderscript/Double2.java @@ -0,0 +1,385 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic double type. + * Provides two double fields packed. + */ +public class Double2 { + public double x; + public double y; + + public Double2() { + } + + /** @hide */ + public Double2(Double2 data) { + this.x = data.x; + this.y = data.y; + } + + public Double2(double x, double y) { + this.x = x; + this.y = y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double2 add(Double2 a, Double2 b) { + Double2 res = new Double2(); + res.x = a.x + b.x; + res.y = a.y + b.y; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Double2 value) { + x += value.x; + y += value.y; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(double value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double2 add(Double2 a, double b) { + Double2 res = new Double2(); + res.x = a.x + b; + res.y = a.y + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Double2 value) { + x -= value.x; + y -= value.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double2 sub(Double2 a, Double2 b) { + Double2 res = new Double2(); + res.x = a.x - b.x; + res.y = a.y - b.y; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(double value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double2 sub(Double2 a, double b) { + Double2 res = new Double2(); + res.x = a.x - b; + res.y = a.y - b; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Double2 value) { + x *= value.x; + y *= value.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double2 mul(Double2 a, Double2 b) { + Double2 res = new Double2(); + res.x = a.x * b.x; + res.y = a.y * b.y; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(double value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double2 mul(Double2 a, double b) { + Double2 res = new Double2(); + res.x = a.x * b; + res.y = a.y * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Double2 value) { + x /= value.x; + y /= value.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double2 div(Double2 a, Double2 b) { + Double2 res = new Double2(); + res.x = a.x / b.x; + res.y = a.y / b.y; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(double value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double2 div(Double2 a, double b) { + Double2 res = new Double2(); + res.x = a.x / b; + res.y = a.y / b; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public double dotProduct(Double2 a) { + return (x * a.x) + (y * a.y); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static Double dotProduct(Double2 a, Double2 b) { + return (b.x * a.x) + (b.y * a.y); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Double2 a, double factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * Set vector value by double2 + * + * @param a + */ + public void set(Double2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * Set vector negate + */ + public void negate() { + x = -x; + y = -y; + } + + /** @hide + * Get vector length + * + * @return + */ + public int length() { + return 2; + } + + /** @hide + * Return the element sum of vector + * + * @return + */ + public double elementSum() { + return x + y; + } + + /** @hide + * Get the vector field value by index + * + * @param i + * @return + */ + public double get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, double value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, double value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value + * + * @param x + * @param y + */ + public void setValues(double x, double y) { + this.x = x; + this.y = y; + } + + /** @hide + * Copy the vector to double array + * + * @param data + * @param offset + */ + public void copyTo(double[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + } +} diff --git a/rs/java/android/renderscript/Double3.java b/rs/java/android/renderscript/Double3.java new file mode 100644 index 0000000..b819716 --- /dev/null +++ b/rs/java/android/renderscript/Double3.java @@ -0,0 +1,417 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic double type. + * Provides three double fields packed. + */ +public class Double3 { + public double x; + public double y; + public double z; + + public Double3() { + } + /** @hide */ + public Double3(Double3 data) { + this.x = data.x; + this.y = data.y; + this.z = data.z; + } + + public Double3(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double3 add(Double3 a, Double3 b) { + Double3 res = new Double3(); + res.x = a.x + b.x; + res.y = a.y + b.y; + res.z = a.z + b.z; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Double3 value) { + x += value.x; + y += value.y; + z += value.z; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(double value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double3 add(Double3 a, double b) { + Double3 res = new Double3(); + res.x = a.x + b; + res.y = a.y + b; + res.z = a.z + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Double3 value) { + x -= value.x; + y -= value.y; + z -= value.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double3 sub(Double3 a, Double3 b) { + Double3 res = new Double3(); + res.x = a.x - b.x; + res.y = a.y - b.y; + res.z = a.z - b.z; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(double value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double3 sub(Double3 a, double b) { + Double3 res = new Double3(); + res.x = a.x - b; + res.y = a.y - b; + res.z = a.z - b; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Double3 value) { + x *= value.x; + y *= value.y; + z *= value.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double3 mul(Double3 a, Double3 b) { + Double3 res = new Double3(); + res.x = a.x * b.x; + res.y = a.y * b.y; + res.z = a.z * b.z; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(double value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double3 mul(Double3 a, double b) { + Double3 res = new Double3(); + res.x = a.x * b; + res.y = a.y * b; + res.z = a.z * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Double3 value) { + x /= value.x; + y /= value.y; + z /= value.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double3 div(Double3 a, Double3 b) { + Double3 res = new Double3(); + res.x = a.x / b.x; + res.y = a.y / b.y; + res.z = a.z / b.z; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(double value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double3 div(Double3 a, double b) { + Double3 res = new Double3(); + res.x = a.x / b; + res.y = a.y / b; + res.z = a.z / b; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public double dotProduct(Double3 a) { + return (x * a.x) + (y * a.y) + (z * a.z); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static double dotProduct(Double3 a, Double3 b) { + return (b.x * a.x) + (b.y * a.y) + (b.z * a.z); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Double3 a, double factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * Set vector value by double3 + * + * @param a + */ + public void set(Double3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * Set vector negate + */ + public void negate() { + x = -x; + y = -y; + z = -z; + } + + /** @hide + * Get vector length + * + * @return + */ + public int length() { + return 3; + } + + /** @hide + * Return the element sum of vector + * + * @return + */ + public double elementSum() { + return x + y + z; + } + + /** @hide + * Get the vector field value by index + * + * @param i + * @return + */ + public double get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, double value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, double value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value + * + * @param x + * @param y + * @param z + */ + public void setValues(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide + * Copy the vector to double array + * + * @param data + * @param offset + */ + public void copyTo(double[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + } +} diff --git a/rs/java/android/renderscript/Double4.java b/rs/java/android/renderscript/Double4.java new file mode 100644 index 0000000..e4829f7 --- /dev/null +++ b/rs/java/android/renderscript/Double4.java @@ -0,0 +1,450 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic double type. + * Provides four double fields packed. + */ +public class Double4 { + public double x; + public double y; + public double z; + public double w; + + public Double4() { + } + /** @hide */ + public Double4(Double4 data) { + this.x = data.x; + this.y = data.y; + this.z = data.z; + this.w = data.w; + } + + public Double4(double x, double y, double z, double w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double4 add(Double4 a, Double4 b) { + Double4 res = new Double4(); + res.x = a.x + b.x; + res.y = a.y + b.y; + res.z = a.z + b.z; + res.w = a.w + b.w; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Double4 value) { + x += value.x; + y += value.y; + z += value.z; + w += value.w; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(double value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Double4 add(Double4 a, double b) { + Double4 res = new Double4(); + res.x = a.x + b; + res.y = a.y + b; + res.z = a.z + b; + res.w = a.w + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Double4 value) { + x -= value.x; + y -= value.y; + z -= value.z; + w -= value.w; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(double value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double4 sub(Double4 a, double b) { + Double4 res = new Double4(); + res.x = a.x - b; + res.y = a.y - b; + res.z = a.z - b; + res.w = a.w - b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Double4 sub(Double4 a, Double4 b) { + Double4 res = new Double4(); + res.x = a.x - b.x; + res.y = a.y - b.y; + res.z = a.z - b.z; + res.w = a.w - b.w; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Double4 value) { + x *= value.x; + y *= value.y; + z *= value.z; + w *= value.w; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(double value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double4 mul(Double4 a, Double4 b) { + Double4 res = new Double4(); + res.x = a.x * b.x; + res.y = a.y * b.y; + res.z = a.z * b.z; + res.w = a.w * b.w; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Double4 mul(Double4 a, double b) { + Double4 res = new Double4(); + res.x = a.x * b; + res.y = a.y * b; + res.z = a.z * b; + res.w = a.w * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Double4 value) { + x /= value.x; + y /= value.y; + z /= value.z; + w /= value.w; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(double value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double4 div(Double4 a, double b) { + Double4 res = new Double4(); + res.x = a.x / b; + res.y = a.y / b; + res.z = a.z / b; + res.w = a.w / b; + + return res; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Double4 div(Double4 a, Double4 b) { + Double4 res = new Double4(); + res.x = a.x / b.x; + res.y = a.y / b.y; + res.z = a.z / b.z; + res.w = a.w / b.w; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public double dotProduct(Double4 a) { + return (x * a.x) + (y * a.y) + (z * a.z) + (w * a.w); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static double dotProduct(Double4 a, Double4 b) { + return (b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Double4 a, double factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * Set vector value by double4 + * + * @param a + */ + public void set(Double4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * Set vector negate + */ + public void negate() { + x = -x; + y = -y; + z = -z; + w = -w; + } + + /** @hide + * Get vector length + * + * @return + */ + public int length() { + return 4; + } + + /** @hide + * Return the element sum of vector + * + * @return + */ + public double elementSum() { + return x + y + z + w; + } + + /** @hide + * Get the vector field value by index + * + * @param i + * @return + */ + public double get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, double value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, double value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * Set the vector field value + * + * @param x + * @param y + * @param z + * @param w + */ + public void setValues(double x, double y, double z, double w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide + * Copy the vector to double array + * + * @param data + * @param offset + */ + public void copyTo(double[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + data[offset + 3] = w; + } +} diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java new file mode 100644 index 0000000..2932770 --- /dev/null +++ b/rs/java/android/renderscript/Element.java @@ -0,0 +1,1103 @@ +/* + * 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 android.renderscript; + +import java.lang.reflect.Field; +import android.util.Log; + +/** + * <p>An Element represents one item within an {@link + * android.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 + * android.renderscript.Element.DataType} and a {@link + * android.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 android.renderscript.Sampler}. Note that {@link + * android.renderscript.Allocation} objects with DataKind {@link + * android.renderscript.Element.DataKind#USER} cannot be used as input for a + * {@link android.renderscript.Sampler}. In general, {@link + * android.renderscript.Allocation} objects that are intended for use with a + * {@link android.renderscript.Sampler} should use bitmap-derived Elements such + * as {@link android.renderscript.Element#RGBA_8888} or {@link + * android.renderscript#Element.A_8}.</p> + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + **/ +public class Element extends BaseObj { + int mSize; + Element[] mElements; + String[] mElementNames; + int[] mArraySizes; + int[] mOffsetInBytes; + + int[] mVisibleElementMap; + + DataType mType; + DataKind mKind; + boolean mNormalized; + int mVectorSize; + + private void updateVisibleSubElements() { + if (mElements == null) { + return; + } + + int noPaddingFieldCount = 0; + int fieldCount = mElementNames.length; + // Find out how many elements are not padding + for (int ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].charAt(0) != '#') { + noPaddingFieldCount ++; + } + } + mVisibleElementMap = new int[noPaddingFieldCount]; + + // Make a map that points us at non-padding elements + for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].charAt(0) != '#') { + mVisibleElementMap[ctNoPadding ++] = ct; + } + } + } + + /** + * @return element size in bytes + */ + public int getBytesSize() {return mSize;} + + /** + * Returns the number of vector components. 2 for float2, 4 for + * float4, etc. + * @return element vector size + */ + public int getVectorSize() {return mVectorSize;} + + + /** + * DataType represents the basic type information for a basic element. The + * naming convention follows. For numeric types it is FLOAT, + * SIGNED, or UNSIGNED followed by the _BITS where BITS is the + * size of the data. BOOLEAN is a true / false (1,0) + * represented in an 8 bit container. The UNSIGNED variants + * with multiple bit definitions are for packed graphical data + * formats and represent vectors with per vector member sizes + * which are treated as a single unit for packing and alignment + * purposes. + * + * MATRIX the three matrix types contain FLOAT_32 elements and are treated + * as 32 bits for alignment purposes. + * + * RS_* objects. 32 bit opaque handles. + */ + public enum DataType { + NONE (0, 0), + //FLOAT_16 (1, 2), + FLOAT_32 (2, 4), + FLOAT_64 (3, 8), + SIGNED_8 (4, 1), + SIGNED_16 (5, 2), + SIGNED_32 (6, 4), + SIGNED_64 (7, 8), + UNSIGNED_8 (8, 1), + UNSIGNED_16 (9, 2), + UNSIGNED_32 (10, 4), + UNSIGNED_64 (11, 8), + + BOOLEAN(12, 1), + + UNSIGNED_5_6_5 (13, 2), + UNSIGNED_5_5_5_1 (14, 2), + UNSIGNED_4_4_4_4 (15, 2), + + MATRIX_4X4 (16, 64), + MATRIX_3X3 (17, 36), + MATRIX_2X2 (18, 16), + + RS_ELEMENT (1000, 4), + RS_TYPE (1001, 4), + RS_ALLOCATION (1002, 4), + RS_SAMPLER (1003, 4), + RS_SCRIPT (1004, 4), + RS_MESH (1005, 4), + RS_PROGRAM_FRAGMENT (1006, 4), + RS_PROGRAM_VERTEX (1007, 4), + RS_PROGRAM_RASTER (1008, 4), + RS_PROGRAM_STORE (1009, 4), + RS_FONT (1010, 4); + + int mID; + int mSize; + DataType(int id, int size) { + mID = id; + mSize = size; + } + } + + /** + * 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 MESH(RenderScript rs) { + if(rs.mElement_MESH == null) { + rs.mElement_MESH = createUser(rs, DataType.RS_MESH); + } + return rs.mElement_MESH; + } + + public static Element PROGRAM_FRAGMENT(RenderScript rs) { + if(rs.mElement_PROGRAM_FRAGMENT == null) { + rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT); + } + return rs.mElement_PROGRAM_FRAGMENT; + } + + public static Element PROGRAM_VERTEX(RenderScript rs) { + if(rs.mElement_PROGRAM_VERTEX == null) { + rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX); + } + return rs.mElement_PROGRAM_VERTEX; + } + + public static Element PROGRAM_RASTER(RenderScript rs) { + if(rs.mElement_PROGRAM_RASTER == null) { + rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER); + } + return rs.mElement_PROGRAM_RASTER; + } + + public static Element PROGRAM_STORE(RenderScript rs) { + if(rs.mElement_PROGRAM_STORE == null) { + rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE); + } + return rs.mElement_PROGRAM_STORE; + } + + public static Element FONT(RenderScript rs) { + if(rs.mElement_FONT == null) { + rs.mElement_FONT = createUser(rs, DataType.RS_FONT); + } + return rs.mElement_FONT; + } + + + 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 YUV(RenderScript rs) { + if (rs.mElement_YUV == null) { + rs.mElement_YUV = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_YUV); + } + return rs.mElement_YUV; + } + + 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; + } + + /** @deprecated use MATRIX_4X4 + */ + public static Element MATRIX4X4(RenderScript rs) { + return MATRIX_4X4(rs); + } + + 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); + } + + @Override + void updateFromNative() { + super.updateFromNative(); + + // FIXME: updateFromNative is broken in JNI for 64-bit + + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + int[] dataBuffer = new int[5]; + mRS.nElementGetNativeData(getID(mRS), dataBuffer); + + mNormalized = dataBuffer[2] == 1 ? true : false; + mVectorSize = dataBuffer[3]; + mSize = 0; + for (DataType dt: DataType.values()) { + if(dt.mID == dataBuffer[0]){ + mType = dt; + mSize = mType.mSize * mVectorSize; + } + } + for (DataKind dk: DataKind.values()) { + if(dk.mID == dataBuffer[1]){ + mKind = dk; + } + } + + int numSubElements = dataBuffer[4]; + if(numSubElements > 0) { + mElements = new Element[numSubElements]; + mElementNames = new String[numSubElements]; + mArraySizes = new int[numSubElements]; + mOffsetInBytes = new int[numSubElements]; + + int[] subElementIds = new int[numSubElements]; + mRS.nElementGetSubElements(getID(mRS), subElementIds, mElementNames, mArraySizes); + for(int i = 0; i < numSubElements; i ++) { + mElements[i] = new Element(subElementIds[i], mRS); + mElements[i].updateFromNative(); + mOffsetInBytes[i] = mSize; + mSize += mElements[i].mSize * mArraySizes[i]; + } + } + updateVisibleSubElements(); + } + + /** + * 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; + case PIXEL_DEPTH: + size = 2; + 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); + + // FIXME: broken for 64-bit + int[] ids = new int[ein.length]; + for (int ct = 0; ct < ein.length; ct++ ) { + ids[ct] = (int)ein[ct].getID(mRS); + } + long id = mRS.nElementCreate2(ids, sin, asin); + return new Element(id, mRS, ein, sin, asin); + } + } +} + diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java new file mode 100644 index 0000000..cf20e63 --- /dev/null +++ b/rs/java/android/renderscript/FieldPacker.java @@ -0,0 +1,602 @@ +/* + * 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 android.renderscript; + +import android.util.Log; +import java.util.BitSet; + +/** + * Utility class for packing arguments and structures from Android system objects to + * RenderScript objects. + * + * This class is only intended to be used to support the + * reflected code generated by the RS tool chain. It should not + * be called directly. + * + **/ +public class FieldPacker { + public FieldPacker(int len) { + mPos = 0; + mLen = len; + mData = new byte[len]; + mAlignment = new BitSet(); + } + + public FieldPacker(byte[] data) { + mPos = 0; + mLen = data.length; + mData = data; + mAlignment = new BitSet(); + } + + 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) { + // FIXME: this is fine for 32-bit but needs a path for 64-bit + addI32((int)obj.getID(null)); + } 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; + } + + private final byte mData[]; + private int mPos; + private int mLen; + private BitSet mAlignment; + +} + + diff --git a/rs/java/android/renderscript/FileA3D.java b/rs/java/android/renderscript/FileA3D.java new file mode 100644 index 0000000..cdcaff7 --- /dev/null +++ b/rs/java/android/renderscript/FileA3D.java @@ -0,0 +1,314 @@ +/* + * 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 android.renderscript; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; +import android.util.TypedValue; + +/** + * @hide + * @deprecated in API 16 + * FileA3D allows users to load RenderScript objects from files + * or resources stored on disk. It could be used to load items + * such as 3D geometry data converted to a RenderScript format from + * content creation tools. Currently only meshes are supported + * in FileA3D. + * + * When successfully loaded, FileA3D will contain a list of + * index entries for all the objects stored inside it. + * + **/ +public class FileA3D extends BaseObj { + + /** + * @deprecated in API 16 + * Specifies what renderscript object type is contained within + * the FileA3D IndexEntry + **/ + public enum EntryType { + + /** + * @deprecated in API 16 + * Unknown or or invalid object, nothing will be loaded + **/ + UNKNOWN (0), + /** + * @deprecated in API 16 + * RenderScript Mesh object + **/ + MESH (1); + + int mID; + EntryType(int id) { + mID = id; + } + + static EntryType toEntryType(int intID) { + return EntryType.values()[intID]; + } + } + + /** + * @deprecated in API 16 + * IndexEntry contains information about one of the RenderScript + * objects inside the file's index. It could be used to query the + * object's type and also name and load the object itself if + * necessary. + */ + public static class IndexEntry { + RenderScript mRS; + int mIndex; + long mID; + String mName; + EntryType mEntryType; + BaseObj mLoadedObj; + + /** + * @deprecated in API 16 + * Returns the name of a renderscript object the index entry + * describes + * + * @return name of a renderscript object the index entry + * describes + * + */ + public String getName() { + return mName; + } + + /** + * @deprecated in API 16 + * Returns the type of a renderscript object the index entry + * describes + * @return type of a renderscript object the index entry + * describes + */ + public EntryType getEntryType() { + return mEntryType; + } + + /** + * @deprecated in API 16 + * Used to load the object described by the index entry + * @return base renderscript object described by the entry + */ + public BaseObj getObject() { + mRS.validate(); + BaseObj obj = internalCreate(mRS, this); + return obj; + } + + /** + * @deprecated in API 16 + * Used to load the mesh described by the index entry, object + * described by the index entry must be a renderscript mesh + * + * @return renderscript mesh object described by the entry + */ + public Mesh getMesh() { + return (Mesh)getObject(); + } + + static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) { + if(entry.mLoadedObj != null) { + return entry.mLoadedObj; + } + + // to be purged on cleanup + if(entry.mEntryType == EntryType.UNKNOWN) { + return null; + } + + int objectID = rs.nFileA3DGetEntryByIndex(entry.mID, entry.mIndex); + if(objectID == 0) { + return null; + } + + switch (entry.mEntryType) { + case MESH: + entry.mLoadedObj = new Mesh(objectID, rs); + break; + } + + entry.mLoadedObj.updateFromNative(); + return entry.mLoadedObj; + } + + IndexEntry(RenderScript rs, int index, long id, String name, EntryType type) { + mRS = rs; + mIndex = index; + mID = id; + mName = name; + mEntryType = type; + mLoadedObj = null; + } + } + + IndexEntry[] mFileEntries; + InputStream mInputStream; + + FileA3D(long id, RenderScript rs, InputStream stream) { + super(id, rs); + mInputStream = stream; + } + + private void initEntries() { + int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID(mRS)); + if(numFileEntries <= 0) { + return; + } + + mFileEntries = new IndexEntry[numFileEntries]; + int[] ids = new int[numFileEntries]; + String[] names = new String[numFileEntries]; + + mRS.nFileA3DGetIndexEntries(getID(mRS), numFileEntries, ids, names); + + for(int i = 0; i < numFileEntries; i ++) { + mFileEntries[i] = new IndexEntry(mRS, i, getID(mRS), names[i], EntryType.toEntryType(ids[i])); + } + } + + /** + * @deprecated in API 16 + * Returns the number of objects stored inside the a3d file + * + * @return the number of objects stored inside the a3d file + */ + public int getIndexEntryCount() { + if(mFileEntries == null) { + return 0; + } + return mFileEntries.length; + } + + /** + * @deprecated in API 16 + * Returns an index entry from the list of all objects inside + * FileA3D + * + * @param index number of the entry from the list to return + * + * @return entry in the a3d file described by the index + */ + public IndexEntry getIndexEntry(int index) { + if(getIndexEntryCount() == 0 || index < 0 || index >= mFileEntries.length) { + return null; + } + return mFileEntries[index]; + } + + /** + * @deprecated in API 16 + * Creates a FileA3D object from an asset stored on disk + * + * @param rs Context to which the object will belong. + * @param mgr asset manager used to load asset + * @param path location of the file to load + * + * @return a3d file containing renderscript objects + */ + static public FileA3D createFromAsset(RenderScript rs, AssetManager mgr, String path) { + rs.validate(); + long fileId = rs.nFileA3DCreateFromAsset(mgr, path); + + if(fileId == 0) { + throw new RSRuntimeException("Unable to create a3d file from asset " + path); + } + FileA3D fa3d = new FileA3D(fileId, rs, null); + fa3d.initEntries(); + return fa3d; + } + + /** + * @deprecated in API 16 + * Creates a FileA3D object from a file stored on disk + * + * @param rs Context to which the object will belong. + * @param path location of the file to load + * + * @return a3d file containing renderscript objects + */ + static public FileA3D createFromFile(RenderScript rs, String path) { + long fileId = rs.nFileA3DCreateFromFile(path); + + if(fileId == 0) { + throw new RSRuntimeException("Unable to create a3d file from " + path); + } + FileA3D fa3d = new FileA3D(fileId, rs, null); + fa3d.initEntries(); + return fa3d; + } + + /** + * @deprecated in API 16 + * Creates a FileA3D object from a file stored on disk + * + * @param rs Context to which the object will belong. + * @param path location of the file to load + * + * @return a3d file containing renderscript objects + */ + static public FileA3D createFromFile(RenderScript rs, File path) { + return createFromFile(rs, path.getAbsolutePath()); + } + + /** + * @deprecated in API 16 + * Creates a FileA3D object from an application resource + * + * @param rs Context to which the object will belong. + * @param res resource manager used for loading + * @param id resource to create FileA3D from + * + * @return a3d file containing renderscript objects + */ + static public FileA3D createFromResource(RenderScript rs, Resources res, int id) { + + rs.validate(); + InputStream is = null; + try { + is = res.openRawResource(id); + } catch (Exception e) { + throw new RSRuntimeException("Unable to open resource " + id); + } + + long fileId = 0; + if (is instanceof AssetManager.AssetInputStream) { + int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); + fileId = rs.nFileA3DCreateFromAssetStream(asset); + } else { + throw new RSRuntimeException("Unsupported asset stream"); + } + + if(fileId == 0) { + throw new RSRuntimeException("Unable to create a3d file from resource " + id); + } + FileA3D fa3d = new FileA3D(fileId, rs, is); + fa3d.initEntries(); + return fa3d; + + } +} diff --git a/rs/java/android/renderscript/Float2.java b/rs/java/android/renderscript/Float2.java new file mode 100644 index 0000000..26193d2 --- /dev/null +++ b/rs/java/android/renderscript/Float2.java @@ -0,0 +1,384 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic float type. + * Provides two float fields packed. + */ +public class Float2 { + public float x; + public float y; + + public Float2() { + } + /** @hide */ + public Float2(Float2 data) { + this.x = data.x; + this.y = data.y; + } + + public Float2(float x, float y) { + this.x = x; + this.y = y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float2 add(Float2 a, Float2 b) { + Float2 res = new Float2(); + res.x = a.x + b.x; + res.y = a.y + b.y; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Float2 value) { + x += value.x; + y += value.y; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(float value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float2 add(Float2 a, float b) { + Float2 res = new Float2(); + res.x = a.x + b; + res.y = a.y + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Float2 value) { + x -= value.x; + y -= value.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float2 sub(Float2 a, Float2 b) { + Float2 res = new Float2(); + res.x = a.x - b.x; + res.y = a.y - b.y; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(float value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float2 sub(Float2 a, float b) { + Float2 res = new Float2(); + res.x = a.x - b; + res.y = a.y - b; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Float2 value) { + x *= value.x; + y *= value.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float2 mul(Float2 a, Float2 b) { + Float2 res = new Float2(); + res.x = a.x * b.x; + res.y = a.y * b.y; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(float value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float2 mul(Float2 a, float b) { + Float2 res = new Float2(); + res.x = a.x * b; + res.y = a.y * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Float2 value) { + x /= value.x; + y /= value.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float2 div(Float2 a, Float2 b) { + Float2 res = new Float2(); + res.x = a.x / b.x; + res.y = a.y / b.y; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(float value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float2 div(Float2 a, float b) { + Float2 res = new Float2(); + res.x = a.x / b; + res.y = a.y / b; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public float dotProduct(Float2 a) { + return (x * a.x) + (y * a.y); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static float dotProduct(Float2 a, Float2 b) { + return (b.x * a.x) + (b.y * a.y); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Float2 a, float factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * set vector value by float2 + * + * @param a + */ + public void set(Float2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * set vector negate + */ + public void negate() { + x = -x; + y = -y; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 2; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public float elementSum() { + return x + y; + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public float get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, float value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, float value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value + * + * @param x + * @param y + */ + public void setValues(float x, float y) { + this.x = x; + this.y = y; + } + + /** @hide + * copy the vector to float array + * + * @param data + * @param offset + */ + public void copyTo(float[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + } +} diff --git a/rs/java/android/renderscript/Float3.java b/rs/java/android/renderscript/Float3.java new file mode 100644 index 0000000..555bdf6 --- /dev/null +++ b/rs/java/android/renderscript/Float3.java @@ -0,0 +1,417 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic float type. + * Provides three float fields packed. + */ +public class Float3 { + public float x; + public float y; + public float z; + + public Float3() { + } + /** @hide */ + public Float3(Float3 data) { + this.x = data.x; + this.y = data.y; + this.z = data.z; + } + + public Float3(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float3 add(Float3 a, Float3 b) { + Float3 res = new Float3(); + res.x = a.x + b.x; + res.y = a.y + b.y; + res.z = a.z + b.z; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Float3 value) { + x += value.x; + y += value.y; + z += value.z; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(float value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float3 add(Float3 a, float b) { + Float3 res = new Float3(); + res.x = a.x + b; + res.y = a.y + b; + res.z = a.z + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Float3 value) { + x -= value.x; + y -= value.y; + z -= value.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float3 sub(Float3 a, Float3 b) { + Float3 res = new Float3(); + res.x = a.x - b.x; + res.y = a.y - b.y; + res.z = a.z - b.z; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(float value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float3 sub(Float3 a, float b) { + Float3 res = new Float3(); + res.x = a.x - b; + res.y = a.y - b; + res.z = a.z - b; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Float3 value) { + x *= value.x; + y *= value.y; + z *= value.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float3 mul(Float3 a, Float3 b) { + Float3 res = new Float3(); + res.x = a.x * b.x; + res.y = a.y * b.y; + res.z = a.z * b.z; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(float value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float3 mul(Float3 a, float b) { + Float3 res = new Float3(); + res.x = a.x * b; + res.y = a.y * b; + res.z = a.z * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Float3 value) { + x /= value.x; + y /= value.y; + z /= value.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float3 div(Float3 a, Float3 b) { + Float3 res = new Float3(); + res.x = a.x / b.x; + res.y = a.y / b.y; + res.z = a.z / b.z; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(float value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float3 div(Float3 a, float b) { + Float3 res = new Float3(); + res.x = a.x / b; + res.y = a.y / b; + res.z = a.z / b; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public Float dotProduct(Float3 a) { + return new Float((x * a.x) + (y * a.y) + (z * a.z)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static Float dotProduct(Float3 a, Float3 b) { + return new Float((b.x * a.x) + (b.y * a.y) + (b.z * a.z)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Float3 a, float factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * set vector value by float3 + * + * @param a + */ + public void set(Float3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * set vector negate + */ + public void negate() { + x = -x; + y = -y; + z = -z; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 3; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public Float elementSum() { + return new Float(x + y + z); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public float get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, float value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, float value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value + * + * @param x + * @param y + * @param z + */ + public void setValues(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide + * copy the vector to float array + * + * @param data + * @param offset + */ + public void copyTo(float[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + } +} diff --git a/rs/java/android/renderscript/Float4.java b/rs/java/android/renderscript/Float4.java new file mode 100644 index 0000000..6541b2e --- /dev/null +++ b/rs/java/android/renderscript/Float4.java @@ -0,0 +1,450 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic float type. + * Provides four float fields packed. + */ +public class Float4 { + public float x; + public float y; + public float z; + public float w; + + public Float4() { + } + /** @hide */ + public Float4(Float4 data) { + this.x = data.x; + this.y = data.y; + this.z = data.z; + this.w = data.w; + } + + public Float4(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float4 add(Float4 a, Float4 b) { + Float4 res = new Float4(); + res.x = a.x + b.x; + res.y = a.y + b.y; + res.z = a.z + b.z; + res.w = a.w + b.w; + + return res; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(Float4 value) { + x += value.x; + y += value.y; + z += value.z; + w += value.w; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(float value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Float4 add(Float4 a, float b) { + Float4 res = new Float4(); + res.x = a.x + b; + res.y = a.y + b; + res.z = a.z + b; + res.w = a.w + b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(Float4 value) { + x -= value.x; + y -= value.y; + z -= value.z; + w -= value.w; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(float value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float4 sub(Float4 a, float b) { + Float4 res = new Float4(); + res.x = a.x - b; + res.y = a.y - b; + res.z = a.z - b; + res.w = a.w - b; + + return res; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Float4 sub(Float4 a, Float4 b) { + Float4 res = new Float4(); + res.x = a.x - b.x; + res.y = a.y - b.y; + res.z = a.z - b.z; + res.w = a.w - b.w; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(Float4 value) { + x *= value.x; + y *= value.y; + z *= value.z; + w *= value.w; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(float value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float4 mul(Float4 a, Float4 b) { + Float4 res = new Float4(); + res.x = a.x * b.x; + res.y = a.y * b.y; + res.z = a.z * b.z; + res.w = a.w * b.w; + + return res; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Float4 mul(Float4 a, float b) { + Float4 res = new Float4(); + res.x = a.x * b; + res.y = a.y * b; + res.z = a.z * b; + res.w = a.w * b; + + return res; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(Float4 value) { + x /= value.x; + y /= value.y; + z /= value.z; + w /= value.w; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(float value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float4 div(Float4 a, float b) { + Float4 res = new Float4(); + res.x = a.x / b; + res.y = a.y / b; + res.z = a.z / b; + res.w = a.w / b; + + return res; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Float4 div(Float4 a, Float4 b) { + Float4 res = new Float4(); + res.x = a.x / b.x; + res.y = a.y / b.y; + res.z = a.z / b.z; + res.w = a.w / b.w; + + return res; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public float dotProduct(Float4 a) { + return (x * a.x) + (y * a.y) + (z * a.z) + (w * a.w); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static float dotProduct(Float4 a, Float4 b) { + return (b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Float4 a, float factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * set vector value by float4 + * + * @param a + */ + public void set(Float4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * set vector negate + */ + public void negate() { + x = -x; + y = -y; + z = -z; + w = -w; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 4; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public float elementSum() { + return x + y + z + w; + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public float get(int i) { + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, float value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, float value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value + * + * @param x + * @param y + * @param z + * @param w + */ + public void setValues(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide + * copy the vector to float array + * + * @param data + * @param offset + */ + public void copyTo(float[] data, int offset) { + data[offset] = x; + data[offset + 1] = y; + data[offset + 2] = z; + data[offset + 3] = w; + } +} diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java new file mode 100644 index 0000000..0375d2b --- /dev/null +++ b/rs/java/android/renderscript/Font.java @@ -0,0 +1,248 @@ +/* + * 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 android.renderscript; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import android.os.Environment; + +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.util.Log; +import android.util.TypedValue; + +/** + * @hide + * @deprecated in API 16 + * <p>This class gives users a simple way to draw hardware accelerated text. + * Internally, the glyphs are rendered using the Freetype library and an internal cache of + * rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface, + * and point size. You can create multiple font objects to represent styles such as bold or italic text, + * faces, and different font sizes. During creation, the Android system quieries device's screen DPI to + * ensure proper sizing across multiple device configurations.</p> + * <p>Fonts are rendered using screen-space positions and no state setup beyond binding a + * font to the RenderScript is required. A note of caution on performance, though the state changes + * are transparent to the user, they do happen internally, and it is more efficient to + * render large batches of text in sequence. It is also more efficient to render multiple + * characters at once instead of one by one to improve draw call batching.</p> + * <p>Font color and transparency are not part of the font object and you can freely modify + * them in the script to suit the user's rendering needs. Font colors work as a state machine. + * Every new call to draw text uses the last color set in the script.</p> + **/ +public class Font extends BaseObj { + + //These help us create a font by family name + private static final String[] sSansNames = { + "sans-serif", "arial", "helvetica", "tahoma", "verdana" + }; + + private static final String[] sSerifNames = { + "serif", "times", "times new roman", "palatino", "georgia", "baskerville", + "goudy", "fantasy", "cursive", "ITC Stone Serif" + }; + + private static final String[] sMonoNames = { + "monospace", "courier", "courier new", "monaco" + }; + + private static class FontFamily { + String[] mNames; + String mNormalFileName; + String mBoldFileName; + String mItalicFileName; + String mBoldItalicFileName; + } + + private static Map<String, FontFamily> sFontFamilyMap; + + /** + * @deprecated in API 16 + */ + public enum Style { + /** + * @deprecated in API 16 + */ + NORMAL, + /** + * @deprecated in API 16 + */ + BOLD, + /** + * @deprecated in API 16 + */ + ITALIC, + /** + * @deprecated in API 16 + */ + BOLD_ITALIC; + } + + private static void addFamilyToMap(FontFamily family) { + for(int i = 0; i < family.mNames.length; i ++) { + sFontFamilyMap.put(family.mNames[i], family); + } + } + + private static void initFontFamilyMap() { + sFontFamilyMap = new HashMap<String, FontFamily>(); + + FontFamily sansFamily = new FontFamily(); + sansFamily.mNames = sSansNames; + sansFamily.mNormalFileName = "Roboto-Regular.ttf"; + sansFamily.mBoldFileName = "Roboto-Bold.ttf"; + sansFamily.mItalicFileName = "Roboto-Italic.ttf"; + sansFamily.mBoldItalicFileName = "Roboto-BoldItalic.ttf"; + addFamilyToMap(sansFamily); + + FontFamily serifFamily = new FontFamily(); + serifFamily.mNames = sSerifNames; + serifFamily.mNormalFileName = "DroidSerif-Regular.ttf"; + serifFamily.mBoldFileName = "DroidSerif-Bold.ttf"; + serifFamily.mItalicFileName = "DroidSerif-Italic.ttf"; + serifFamily.mBoldItalicFileName = "DroidSerif-BoldItalic.ttf"; + addFamilyToMap(serifFamily); + + FontFamily monoFamily = new FontFamily(); + monoFamily.mNames = sMonoNames; + monoFamily.mNormalFileName = "DroidSansMono.ttf"; + monoFamily.mBoldFileName = "DroidSansMono.ttf"; + monoFamily.mItalicFileName = "DroidSansMono.ttf"; + monoFamily.mBoldItalicFileName = "DroidSansMono.ttf"; + addFamilyToMap(monoFamily); + } + + static { + initFontFamilyMap(); + } + + static String getFontFileName(String familyName, Style style) { + FontFamily family = sFontFamilyMap.get(familyName); + if(family != null) { + switch(style) { + case NORMAL: + return family.mNormalFileName; + case BOLD: + return family.mBoldFileName; + case ITALIC: + return family.mItalicFileName; + case BOLD_ITALIC: + return family.mBoldItalicFileName; + } + } + // Fallback if we could not find the desired family + return "DroidSans.ttf"; + } + + Font(int id, RenderScript rs) { + super(id, rs); + } + + /** + * @deprecated in API 16 + * Takes a specific file name as an argument + */ + static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize) { + rs.validate(); + int dpi = res.getDisplayMetrics().densityDpi; + int fontId = rs.nFontCreateFromFile(path, pointSize, dpi); + + if(fontId == 0) { + throw new RSRuntimeException("Unable to create font from file " + path); + } + Font rsFont = new Font(fontId, rs); + + return rsFont; + } + + /** + * @deprecated in API 16 + */ + static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize) { + return createFromFile(rs, res, path.getAbsolutePath(), pointSize); + } + + /** + * @deprecated in API 16 + */ + static public Font createFromAsset(RenderScript rs, Resources res, String path, float pointSize) { + rs.validate(); + AssetManager mgr = res.getAssets(); + int dpi = res.getDisplayMetrics().densityDpi; + + int fontId = rs.nFontCreateFromAsset(mgr, path, pointSize, dpi); + if(fontId == 0) { + throw new RSRuntimeException("Unable to create font from asset " + path); + } + Font rsFont = new Font(fontId, rs); + return rsFont; + } + + /** + * @deprecated in API 16 + */ + static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize) { + String name = "R." + Integer.toString(id); + + rs.validate(); + InputStream is = null; + try { + is = res.openRawResource(id); + } catch (Exception e) { + throw new RSRuntimeException("Unable to open resource " + id); + } + + int dpi = res.getDisplayMetrics().densityDpi; + + int fontId = 0; + if (is instanceof AssetManager.AssetInputStream) { + int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); + fontId = rs.nFontCreateFromAssetStream(name, pointSize, dpi, asset); + } else { + throw new RSRuntimeException("Unsupported asset stream created"); + } + + if(fontId == 0) { + throw new RSRuntimeException("Unable to create font from resource " + id); + } + Font rsFont = new Font(fontId, rs); + return rsFont; + } + + /** + * @deprecated in API 16 + * Accepts one of the following family names as an argument + * and will attempt to produce the best match with a system font: + * + * "sans-serif" "arial" "helvetica" "tahoma" "verdana" + * "serif" "times" "times new roman" "palatino" "georgia" "baskerville" + * "goudy" "fantasy" "cursive" "ITC Stone Serif" + * "monospace" "courier" "courier new" "monaco" + * + * Returns default font if no match could be found. + */ + static public Font create(RenderScript rs, Resources res, String familyName, Style fontStyle, float pointSize) { + String fileName = getFontFileName(familyName, fontStyle); + String fontPath = Environment.getRootDirectory().getAbsolutePath(); + fontPath += "/fonts/" + fileName; + return createFromFile(rs, res, fontPath, pointSize); + } + +} diff --git a/rs/java/android/renderscript/Int2.java b/rs/java/android/renderscript/Int2.java new file mode 100644 index 0000000..120957b --- /dev/null +++ b/rs/java/android/renderscript/Int2.java @@ -0,0 +1,440 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic int type. + * Provides two int fields packed. + */ +public class Int2 { + public int x; + public int y; + + public Int2() { + } + + /** @hide */ + public Int2(int i) { + this.x = this.y = i; + } + + public Int2(int x, int y) { + this.x = x; + this.y = y; + } + + /** @hide */ + public Int2(Int2 source) { + this.x = source.x; + this.y = source.y; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Int2 a) { + this.x += a.x; + this.y += a.y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int2 add(Int2 a, Int2 b) { + Int2 result = new Int2(); + result.x = a.x + b.x; + result.y = a.y + b.y; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(int value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int2 add(Int2 a, int b) { + Int2 result = new Int2(); + result.x = a.x + b; + result.y = a.y + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Int2 a) { + this.x -= a.x; + this.y -= a.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int2 sub(Int2 a, Int2 b) { + Int2 result = new Int2(); + result.x = a.x - b.x; + result.y = a.y - b.y; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(int value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int2 sub(Int2 a, int b) { + Int2 result = new Int2(); + result.x = a.x - b; + result.y = a.y - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Int2 a) { + this.x *= a.x; + this.y *= a.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int2 mul(Int2 a, Int2 b) { + Int2 result = new Int2(); + result.x = a.x * b.x; + result.y = a.y * b.y; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(int value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int2 mul(Int2 a, int b) { + Int2 result = new Int2(); + result.x = a.x * b; + result.y = a.y * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Int2 a) { + this.x /= a.x; + this.y /= a.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int2 div(Int2 a, Int2 b) { + Int2 result = new Int2(); + result.x = a.x / b.x; + result.y = a.y / b.y; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(int value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int2 div(Int2 a, int b) { + Int2 result = new Int2(); + result.x = a.x / b; + result.y = a.y / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Int2 a) { + this.x %= a.x; + this.y %= a.y; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int2 mod(Int2 a, Int2 b) { + Int2 result = new Int2(); + result.x = a.x % b.x; + result.y = a.y % b.y; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(int value) { + x %= value; + y %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int2 mod(Int2 a, int b) { + Int2 result = new Int2(); + result.x = a.x % b; + result.y = a.y % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 2; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public int dotProduct(Int2 a) { + return (int)((x * a.x) + (y * a.y)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static int dotProduct(Int2 a, Int2 b) { + return (int)((b.x * a.x) + (b.y * a.y)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Int2 a, int factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * set vector value by Int2 + * + * @param a + */ + public void set(Int2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * set the vector field value by Int + * + * @param a + * @param b + */ + public void setValues(int a, int b) { + this.x = a; + this.y = b; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public int elementSum() { + return (int)(x + y); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public int get(int i) { + switch (i) { + case 0: + return (int)(x); + case 1: + return (int)(y); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, int value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, int value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to int array + * + * @param data + * @param offset + */ + public void copyTo(int[] data, int offset) { + data[offset] = (int)(x); + data[offset + 1] = (int)(y); + } +} diff --git a/rs/java/android/renderscript/Int3.java b/rs/java/android/renderscript/Int3.java new file mode 100644 index 0000000..c770395 --- /dev/null +++ b/rs/java/android/renderscript/Int3.java @@ -0,0 +1,477 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic int type. + * Provides three int fields packed. + */ +public class Int3 { + public int x; + public int y; + public int z; + + public Int3() { + } + + /** @hide */ + public Int3(int i) { + this.x = this.y = this.z = i; + } + + public Int3(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide */ + public Int3(Int3 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Int3 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int3 add(Int3 a, Int3 b) { + Int3 result = new Int3(); + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(int value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int3 add(Int3 a, int b) { + Int3 result = new Int3(); + result.x = a.x + b; + result.y = a.y + b; + result.z = a.z + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Int3 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int3 sub(Int3 a, Int3 b) { + Int3 result = new Int3(); + result.x = a.x - b.x; + result.y = a.y - b.y; + result.z = a.z - b.z; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(int value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int3 sub(Int3 a, int b) { + Int3 result = new Int3(); + result.x = a.x - b; + result.y = a.y - b; + result.z = a.z - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Int3 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int3 mul(Int3 a, Int3 b) { + Int3 result = new Int3(); + result.x = a.x * b.x; + result.y = a.y * b.y; + result.z = a.z * b.z; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(int value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int3 mul(Int3 a, int b) { + Int3 result = new Int3(); + result.x = a.x * b; + result.y = a.y * b; + result.z = a.z * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Int3 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int3 div(Int3 a, Int3 b) { + Int3 result = new Int3(); + result.x = a.x / b.x; + result.y = a.y / b.y; + result.z = a.z / b.z; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(int value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int3 div(Int3 a, int b) { + Int3 result = new Int3(); + result.x = a.x / b; + result.y = a.y / b; + result.z = a.z / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Int3 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int3 mod(Int3 a, Int3 b) { + Int3 result = new Int3(); + result.x = a.x % b.x; + result.y = a.y % b.y; + result.z = a.z % b.z; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(int value) { + x %= value; + y %= value; + z %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int3 mod(Int3 a, int b) { + Int3 result = new Int3(); + result.x = a.x % b; + result.y = a.y % b; + result.z = a.z % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 3; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + this.z = -z; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public int dotProduct(Int3 a) { + return (int)((x * a.x) + (y * a.y) + (z * a.z)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static int dotProduct(Int3 a, Int3 b) { + return (int)((b.x * a.x) + (b.y * a.y) + (b.z * a.z)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Int3 a, int factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * set vector value by Int3 + * + * @param a + */ + public void set(Int3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * set the vector field value by Int + * + * @param a + * @param b + * @param c + */ + public void setValues(int a, int b, int c) { + this.x = a; + this.y = b; + this.z = c; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public int elementSum() { + return (int)(x + y + z); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public int get(int i) { + switch (i) { + case 0: + return (int)(x); + case 1: + return (int)(y); + case 2: + return (int)(z); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, int value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, int value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to int array + * + * @param data + * @param offset + */ + public void copyTo(int[] data, int offset) { + data[offset] = (int)(x); + data[offset + 1] = (int)(y); + data[offset + 2] = (int)(z); + } +} diff --git a/rs/java/android/renderscript/Int4.java b/rs/java/android/renderscript/Int4.java new file mode 100644 index 0000000..1c0e2e2 --- /dev/null +++ b/rs/java/android/renderscript/Int4.java @@ -0,0 +1,514 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic int type. + * Provides four int fields packed. + */ +public class Int4 { + public int x; + public int y; + public int z; + public int w; + + public Int4() { + } + + /** @hide */ + public Int4(int i) { + this.x = this.y = this.z = this.w = i; + } + + public Int4(int x, int y, int z, int w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide */ + public Int4(Int4 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Int4 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + this.w += a.w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int4 add(Int4 a, Int4 b) { + Int4 result = new Int4(); + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + result.w = a.w + b.w; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(int value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Int4 add(Int4 a, int b) { + Int4 result = new Int4(); + result.x = a.x + b; + result.y = a.y + b; + result.z = a.z + b; + result.w = a.w + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Int4 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + this.w -= a.w; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int4 sub(Int4 a, Int4 b) { + Int4 result = new Int4(); + result.x = a.x - b.x; + result.y = a.y - b.y; + result.z = a.z - b.z; + result.w = a.w - b.w; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(int value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Int4 sub(Int4 a, int b) { + Int4 result = new Int4(); + result.x = a.x - b; + result.y = a.y - b; + result.z = a.z - b; + result.w = a.w - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Int4 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + this.w *= a.w; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int4 mul(Int4 a, Int4 b) { + Int4 result = new Int4(); + result.x = a.x * b.x; + result.y = a.y * b.y; + result.z = a.z * b.z; + result.w = a.w * b.w; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(int value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Int4 mul(Int4 a, int b) { + Int4 result = new Int4(); + result.x = a.x * b; + result.y = a.y * b; + result.z = a.z * b; + result.w = a.w * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Int4 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + this.w /= a.w; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int4 div(Int4 a, Int4 b) { + Int4 result = new Int4(); + result.x = a.x / b.x; + result.y = a.y / b.y; + result.z = a.z / b.z; + result.w = a.w / b.w; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(int value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Int4 div(Int4 a, int b) { + Int4 result = new Int4(); + result.x = a.x / b; + result.y = a.y / b; + result.z = a.z / b; + result.w = a.w / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Int4 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + this.w %= a.w; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int4 mod(Int4 a, Int4 b) { + Int4 result = new Int4(); + result.x = a.x % b.x; + result.y = a.y % b.y; + result.z = a.z % b.z; + result.w = a.w % b.w; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(int value) { + x %= value; + y %= value; + z %= value; + w %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Int4 mod(Int4 a, int b) { + Int4 result = new Int4(); + result.x = a.x % b; + result.y = a.y % b; + result.z = a.z % b; + result.w = a.w % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public int length() { + return 4; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + this.z = -z; + this.w = -w; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public int dotProduct(Int4 a) { + return (int)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static int dotProduct(Int4 a, Int4 b) { + return (int)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Int4 a, int factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * set vector value by Int4 + * + * @param a + */ + public void set(Int4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * set the vector field value by Int + * + * @param a + * @param b + * @param c + * @param d + */ + public void setValues(int a, int b, int c, int d) { + this.x = a; + this.y = b; + this.z = c; + this.w = d; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public int elementSum() { + return (int)(x + y + z + w); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public int get(int i) { + switch (i) { + case 0: + return (int)(x); + case 1: + return (int)(y); + case 2: + return (int)(z); + case 3: + return (int)(w); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, int value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, int value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to int array + * + * @param data + * @param offset + */ + public void copyTo(int[] data, int offset) { + data[offset] = (int)(x); + data[offset + 1] = (int)(y); + data[offset + 2] = (int)(z); + data[offset + 3] = (int)(w); + } +} diff --git a/rs/java/android/renderscript/Long2.java b/rs/java/android/renderscript/Long2.java new file mode 100644 index 0000000..fabf204 --- /dev/null +++ b/rs/java/android/renderscript/Long2.java @@ -0,0 +1,440 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic long type. + * Provides two long fields packed. + */ +public class Long2 { + public long x; + public long y; + + public Long2() { + } + + /** @hide */ + public Long2(long i) { + this.x = this.y = i; + } + + public Long2(long x, long y) { + this.x = x; + this.y = y; + } + + /** @hide */ + public Long2(Long2 source) { + this.x = source.x; + this.y = source.y; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Long2 a) { + this.x += a.x; + this.y += a.y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long2 add(Long2 a, Long2 b) { + Long2 result = new Long2(); + result.x = a.x + b.x; + result.y = a.y + b.y; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(long value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long2 add(Long2 a, long b) { + Long2 result = new Long2(); + result.x = a.x + b; + result.y = a.y + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Long2 a) { + this.x -= a.x; + this.y -= a.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long2 sub(Long2 a, Long2 b) { + Long2 result = new Long2(); + result.x = a.x - b.x; + result.y = a.y - b.y; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(long value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long2 sub(Long2 a, long b) { + Long2 result = new Long2(); + result.x = a.x - b; + result.y = a.y - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Long2 a) { + this.x *= a.x; + this.y *= a.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long2 mul(Long2 a, Long2 b) { + Long2 result = new Long2(); + result.x = a.x * b.x; + result.y = a.y * b.y; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(long value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long2 mul(Long2 a, long b) { + Long2 result = new Long2(); + result.x = a.x * b; + result.y = a.y * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Long2 a) { + this.x /= a.x; + this.y /= a.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long2 div(Long2 a, Long2 b) { + Long2 result = new Long2(); + result.x = a.x / b.x; + result.y = a.y / b.y; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(long value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long2 div(Long2 a, long b) { + Long2 result = new Long2(); + result.x = a.x / b; + result.y = a.y / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Long2 a) { + this.x %= a.x; + this.y %= a.y; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long2 mod(Long2 a, Long2 b) { + Long2 result = new Long2(); + result.x = a.x % b.x; + result.y = a.y % b.y; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(long value) { + x %= value; + y %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long2 mod(Long2 a, long b) { + Long2 result = new Long2(); + result.x = a.x % b; + result.y = a.y % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public long length() { + return 2; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public long dotProduct(Long2 a) { + return (long)((x * a.x) + (y * a.y)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static long dotProduct(Long2 a, Long2 b) { + return (long)((b.x * a.x) + (b.y * a.y)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Long2 a, long factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * set vector value by Long2 + * + * @param a + */ + public void set(Long2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * set the vector field value by Long + * + * @param a + * @param b + */ + public void setValues(long a, long b) { + this.x = a; + this.y = b; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public long elementSum() { + return (long)(x + y); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public long get(int i) { + switch (i) { + case 0: + return (long)(x); + case 1: + return (long)(y); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, long value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, long value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to long array + * + * @param data + * @param offset + */ + public void copyTo(long[] data, int offset) { + data[offset] = (long)(x); + data[offset + 1] = (long)(y); + } +} diff --git a/rs/java/android/renderscript/Long3.java b/rs/java/android/renderscript/Long3.java new file mode 100644 index 0000000..88ff855 --- /dev/null +++ b/rs/java/android/renderscript/Long3.java @@ -0,0 +1,477 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic long type. + * Provides three long fields packed. + */ +public class Long3 { + public long x; + public long y; + public long z; + + public Long3() { + } + + /** @hide */ + public Long3(long i) { + this.x = this.y = this.z = i; + } + + public Long3(long x, long y, long z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide */ + public Long3(Long3 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Long3 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long3 add(Long3 a, Long3 b) { + Long3 result = new Long3(); + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(long value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long3 add(Long3 a, long b) { + Long3 result = new Long3(); + result.x = a.x + b; + result.y = a.y + b; + result.z = a.z + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Long3 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long3 sub(Long3 a, Long3 b) { + Long3 result = new Long3(); + result.x = a.x - b.x; + result.y = a.y - b.y; + result.z = a.z - b.z; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(long value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long3 sub(Long3 a, long b) { + Long3 result = new Long3(); + result.x = a.x - b; + result.y = a.y - b; + result.z = a.z - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Long3 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long3 mul(Long3 a, Long3 b) { + Long3 result = new Long3(); + result.x = a.x * b.x; + result.y = a.y * b.y; + result.z = a.z * b.z; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(long value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long3 mul(Long3 a, long b) { + Long3 result = new Long3(); + result.x = a.x * b; + result.y = a.y * b; + result.z = a.z * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Long3 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long3 div(Long3 a, Long3 b) { + Long3 result = new Long3(); + result.x = a.x / b.x; + result.y = a.y / b.y; + result.z = a.z / b.z; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(long value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long3 div(Long3 a, long b) { + Long3 result = new Long3(); + result.x = a.x / b; + result.y = a.y / b; + result.z = a.z / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Long3 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long3 mod(Long3 a, Long3 b) { + Long3 result = new Long3(); + result.x = a.x % b.x; + result.y = a.y % b.y; + result.z = a.z % b.z; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(long value) { + x %= value; + y %= value; + z %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long3 mod(Long3 a, long b) { + Long3 result = new Long3(); + result.x = a.x % b; + result.y = a.y % b; + result.z = a.z % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public long length() { + return 3; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + this.z = -z; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public long dotProduct(Long3 a) { + return (long)((x * a.x) + (y * a.y) + (z * a.z)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static long dotProduct(Long3 a, Long3 b) { + return (long)((b.x * a.x) + (b.y * a.y) + (b.z * a.z)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Long3 a, long factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * set vector value by Long3 + * + * @param a + */ + public void set(Long3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * set the vector field value by Long + * + * @param a + * @param b + * @param c + */ + public void setValues(long a, long b, long c) { + this.x = a; + this.y = b; + this.z = c; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public long elementSum() { + return (long)(x + y + z); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public long get(int i) { + switch (i) { + case 0: + return (long)(x); + case 1: + return (long)(y); + case 2: + return (long)(z); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, long value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, long value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to long array + * + * @param data + * @param offset + */ + public void copyTo(long[] data, int offset) { + data[offset] = (long)(x); + data[offset + 1] = (long)(y); + data[offset + 2] = (long)(z); + } +} diff --git a/rs/java/android/renderscript/Long4.java b/rs/java/android/renderscript/Long4.java new file mode 100644 index 0000000..757b910 --- /dev/null +++ b/rs/java/android/renderscript/Long4.java @@ -0,0 +1,514 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic long type. + * Provides four long fields packed. + */ +public class Long4 { + public long x; + public long y; + public long z; + public long w; + + public Long4() { + } + + /** @hide */ + public Long4(long i) { + this.x = this.y = this.z = this.w = i; + } + + public Long4(long x, long y, long z, long w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide */ + public Long4(Long4 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Long4 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + this.w += a.w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long4 add(Long4 a, Long4 b) { + Long4 result = new Long4(); + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + result.w = a.w + b.w; + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(long value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Long4 add(Long4 a, long b) { + Long4 result = new Long4(); + result.x = a.x + b; + result.y = a.y + b; + result.z = a.z + b; + result.w = a.w + b; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Long4 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + this.w -= a.w; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long4 sub(Long4 a, Long4 b) { + Long4 result = new Long4(); + result.x = a.x - b.x; + result.y = a.y - b.y; + result.z = a.z - b.z; + result.w = a.w - b.w; + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(long value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Long4 sub(Long4 a, long b) { + Long4 result = new Long4(); + result.x = a.x - b; + result.y = a.y - b; + result.z = a.z - b; + result.w = a.w - b; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Long4 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + this.w *= a.w; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long4 mul(Long4 a, Long4 b) { + Long4 result = new Long4(); + result.x = a.x * b.x; + result.y = a.y * b.y; + result.z = a.z * b.z; + result.w = a.w * b.w; + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(long value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Long4 mul(Long4 a, long b) { + Long4 result = new Long4(); + result.x = a.x * b; + result.y = a.y * b; + result.z = a.z * b; + result.w = a.w * b; + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Long4 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + this.w /= a.w; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long4 div(Long4 a, Long4 b) { + Long4 result = new Long4(); + result.x = a.x / b.x; + result.y = a.y / b.y; + result.z = a.z / b.z; + result.w = a.w / b.w; + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(long value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Long4 div(Long4 a, long b) { + Long4 result = new Long4(); + result.x = a.x / b; + result.y = a.y / b; + result.z = a.z / b; + result.w = a.w / b; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Long4 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + this.w %= a.w; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long4 mod(Long4 a, Long4 b) { + Long4 result = new Long4(); + result.x = a.x % b.x; + result.y = a.y % b.y; + result.z = a.z % b.z; + result.w = a.w % b.w; + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(long value) { + x %= value; + y %= value; + z %= value; + w %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Long4 mod(Long4 a, long b) { + Long4 result = new Long4(); + result.x = a.x % b; + result.y = a.y % b; + result.z = a.z % b; + result.w = a.w % b; + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public long length() { + return 4; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = -x; + this.y = -y; + this.z = -z; + this.w = -w; + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public long dotProduct(Long4 a) { + return (long)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static long dotProduct(Long4 a, Long4 b) { + return (long)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Long4 a, long factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * set vector value by Long4 + * + * @param a + */ + public void set(Long4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * set the vector field value by Long + * + * @param a + * @param b + * @param c + * @param d + */ + public void setValues(long a, long b, long c, long d) { + this.x = a; + this.y = b; + this.z = c; + this.w = d; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public long elementSum() { + return (long)(x + y + z + w); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public long get(int i) { + switch (i) { + case 0: + return (long)(x); + case 1: + return (long)(y); + case 2: + return (long)(z); + case 3: + return (long)(w); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, long value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, long value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to long array + * + * @param data + * @param offset + */ + public void copyTo(Long[] data, int offset) { + data[offset] = (long)(x); + data[offset + 1] = (long)(y); + data[offset + 2] = (long)(z); + data[offset + 3] = (long)(w); + } +} diff --git a/rs/java/android/renderscript/Matrix2f.java b/rs/java/android/renderscript/Matrix2f.java new file mode 100644 index 0000000..d3621fa --- /dev/null +++ b/rs/java/android/renderscript/Matrix2f.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2009-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system. + * + **/ +public class Matrix2f { + + /** + * Creates a new identity 2x2 matrix + */ + public Matrix2f() { + mMat = new float[4]; + loadIdentity(); + } + + /** + * Creates a new matrix and sets its values from the given + * parameter + * + * @param dataArray values to set the matrix to, must be 4 + * floats long + */ + public Matrix2f(float[] dataArray) { + mMat = new float[4]; + System.arraycopy(dataArray, 0, mMat, 0, mMat.length); + } + + /** + * Return a reference to the internal array representing matrix + * values. Modifying this array will also change the matrix + * + * @return internal array representing the matrix + */ + public float[] getArray() { + return mMat; + } + + /** + * Returns the value for a given row and column + * + * @param x column of the value to return + * @param y row of the value to return + * + * @return value in the yth row and xth column + */ + public float get(int x, int y) { + return mMat[x*2 + y]; + } + + /** + * Sets the value for a given row and column + * + * @param x column of the value to set + * @param y row of the value to set + */ + public void set(int x, int y, float v) { + mMat[x*2 + y] = v; + } + + /** + * Sets the matrix values to identity + */ + public void loadIdentity() { + mMat[0] = 1; + mMat[1] = 0; + + mMat[2] = 0; + mMat[3] = 1; + } + + /** + * Sets the values of the matrix to those of the parameter + * + * @param src matrix to load the values from + */ + public void load(Matrix2f src) { + System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length); + } + + /** + * Sets current values to be a rotation matrix of given angle + * + * @param rot rotation angle + */ + public void loadRotate(float rot) { + float c, s; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + mMat[0] = c; + mMat[1] = -s; + mMat[2] = s; + mMat[3] = c; + } + + /** + * Sets current values to be a scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + */ + public void loadScale(float x, float y) { + loadIdentity(); + mMat[0] = x; + mMat[3] = y; + } + + /** + * Sets current values to be the result of multiplying two given + * matrices + * + * @param lhs left hand side matrix + * @param rhs right hand side matrix + */ + public void loadMultiply(Matrix2f lhs, Matrix2f rhs) { + for (int i=0 ; i<2 ; i++) { + float ri0 = 0; + float ri1 = 0; + for (int j=0 ; j<2 ; j++) { + float rhs_ij = rhs.get(i,j); + ri0 += lhs.get(j,0) * rhs_ij; + ri1 += lhs.get(j,1) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + } + } + + /** + * Post-multiplies the current matrix by a given parameter + * + * @param rhs right hand side to multiply by + */ + public void multiply(Matrix2f rhs) { + Matrix2f tmp = new Matrix2f(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + /** + * Modifies the current matrix by post-multiplying it with a + * rotation matrix of given angle + * + * @param rot angle of rotation + */ + public void rotate(float rot) { + Matrix2f tmp = new Matrix2f(); + tmp.loadRotate(rot); + multiply(tmp); + } + /** + * Modifies the current matrix by post-multiplying it with a + * scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + */ + public void scale(float x, float y) { + Matrix2f tmp = new Matrix2f(); + tmp.loadScale(x, y); + multiply(tmp); + } + /** + * Sets the current matrix to its transpose + */ + public void transpose() { + float temp = mMat[1]; + mMat[1] = mMat[2]; + mMat[2] = temp; + } + + final float[] mMat; +} + + + diff --git a/rs/java/android/renderscript/Matrix3f.java b/rs/java/android/renderscript/Matrix3f.java new file mode 100644 index 0000000..8c3c330 --- /dev/null +++ b/rs/java/android/renderscript/Matrix3f.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2009-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system. + * + **/ +public class Matrix3f { + + /** + * Creates a new identity 3x3 matrix + */ + public Matrix3f() { + mMat = new float[9]; + loadIdentity(); + } + + /** + * Creates a new matrix and sets its values from the given + * parameter + * + * @param dataArray values to set the matrix to, must be 9 + * floats long + */ + public Matrix3f(float[] dataArray) { + mMat = new float[9]; + System.arraycopy(dataArray, 0, mMat, 0, mMat.length); + } + + /** + * Return a reference to the internal array representing matrix + * values. Modifying this array will also change the matrix + * + * @return internal array representing the matrix + */ + public float[] getArray() { + return mMat; + } + + /** + * Returns the value for a given row and column + * + * @param x column of the value to return + * @param y row of the value to return + * + * @return value in the yth row and xth column + */ + public float get(int x, int y) { + return mMat[x*3 + y]; + } + + /** + * Sets the value for a given row and column + * + * @param x column of the value to set + * @param y row of the value to set + */ + public void set(int x, int y, float v) { + mMat[x*3 + y] = v; + } + + /** + * Sets the matrix values to identity + */ + public void loadIdentity() { + mMat[0] = 1; + mMat[1] = 0; + mMat[2] = 0; + + mMat[3] = 0; + mMat[4] = 1; + mMat[5] = 0; + + mMat[6] = 0; + mMat[7] = 0; + mMat[8] = 1; + } + + /** + * Sets the values of the matrix to those of the parameter + * + * @param src matrix to load the values from + */ + public void load(Matrix3f src) { + System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length); + } + + /** + * Sets current values to be a rotation matrix of certain angle + * about a given axis + * + * @param rot angle of rotation + * @param x rotation axis x + * @param y rotation axis y + * @param z rotation axis z + */ + public void loadRotate(float rot, float x, float y, float z) { + float c, s; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + + float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z); + if (!(len != 1)) { + float recipLen = 1.f / len; + x *= recipLen; + y *= recipLen; + z *= recipLen; + } + float nc = 1.0f - c; + float xy = x * y; + float yz = y * z; + float zx = z * x; + float xs = x * s; + float ys = y * s; + float zs = z * s; + mMat[0] = x*x*nc + c; + mMat[3] = xy*nc - zs; + mMat[6] = zx*nc + ys; + mMat[1] = xy*nc + zs; + mMat[4] = y*y*nc + c; + mMat[7] = yz*nc - xs; + mMat[2] = zx*nc - ys; + mMat[5] = yz*nc + xs; + mMat[8] = z*z*nc + c; + } + + /** + * Makes the upper 2x2 a rotation matrix of the given angle + * + * @param rot rotation angle + */ + public void loadRotate(float rot) { + loadIdentity(); + float c, s; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + mMat[0] = c; + mMat[1] = -s; + mMat[3] = s; + mMat[4] = c; + } + + /** + * Makes the upper 2x2 a scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + */ + public void loadScale(float x, float y) { + loadIdentity(); + mMat[0] = x; + mMat[4] = y; + } + + /** + * Sets current values to be a scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + * @param z scale component z + */ + public void loadScale(float x, float y, float z) { + loadIdentity(); + mMat[0] = x; + mMat[4] = y; + mMat[8] = z; + } + + /** + * Sets current values to be a translation matrix of given + * dimensions + * + * @param x translation component x + * @param y translation component y + */ + public void loadTranslate(float x, float y) { + loadIdentity(); + mMat[6] = x; + mMat[7] = y; + } + + /** + * Sets current values to be the result of multiplying two given + * matrices + * + * @param lhs left hand side matrix + * @param rhs right hand side matrix + */ + public void loadMultiply(Matrix3f lhs, Matrix3f rhs) { + for (int i=0 ; i<3 ; i++) { + float ri0 = 0; + float ri1 = 0; + float ri2 = 0; + for (int j=0 ; j<3 ; j++) { + float rhs_ij = rhs.get(i,j); + ri0 += lhs.get(j,0) * rhs_ij; + ri1 += lhs.get(j,1) * rhs_ij; + ri2 += lhs.get(j,2) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + set(i,2, ri2); + } + } + + /** + * Post-multiplies the current matrix by a given parameter + * + * @param rhs right hand side to multiply by + */ + public void multiply(Matrix3f rhs) { + Matrix3f tmp = new Matrix3f(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + + /** + * Modifies the current matrix by post-multiplying it with a + * rotation matrix of certain angle about a given axis + * + * @param rot angle of rotation + * @param x rotation axis x + * @param y rotation axis y + * @param z rotation axis z + */ + public void rotate(float rot, float x, float y, float z) { + Matrix3f tmp = new Matrix3f(); + tmp.loadRotate(rot, x, y, z); + multiply(tmp); + } + + /** + * Modifies the upper 2x2 of the current matrix by + * post-multiplying it with a rotation matrix of given angle + * + * @param rot angle of rotation + */ + public void rotate(float rot) { + Matrix3f tmp = new Matrix3f(); + tmp.loadRotate(rot); + multiply(tmp); + } + + /** + * Modifies the upper 2x2 of the current matrix by + * post-multiplying it with a scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + */ + public void scale(float x, float y) { + Matrix3f tmp = new Matrix3f(); + tmp.loadScale(x, y); + multiply(tmp); + } + + /** + * Modifies the current matrix by post-multiplying it with a + * scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + * @param z scale component z + */ + public void scale(float x, float y, float z) { + Matrix3f tmp = new Matrix3f(); + tmp.loadScale(x, y, z); + multiply(tmp); + } + + /** + * Modifies the current matrix by post-multiplying it with a + * translation matrix of given dimensions + * + * @param x translation component x + * @param y translation component y + */ + public void translate(float x, float y) { + Matrix3f tmp = new Matrix3f(); + tmp.loadTranslate(x, y); + multiply(tmp); + } + + /** + * Sets the current matrix to its transpose + */ + public void transpose() { + for(int i = 0; i < 2; ++i) { + for(int j = i + 1; j < 3; ++j) { + float temp = mMat[i*3 + j]; + mMat[i*3 + j] = mMat[j*3 + i]; + mMat[j*3 + i] = temp; + } + } + } + + final float[] mMat; +} + + diff --git a/rs/java/android/renderscript/Matrix4f.java b/rs/java/android/renderscript/Matrix4f.java new file mode 100644 index 0000000..cd18e30 --- /dev/null +++ b/rs/java/android/renderscript/Matrix4f.java @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2009-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system. + * + **/ +public class Matrix4f { + + /** + * Creates a new identity 4x4 matrix + */ + public Matrix4f() { + mMat = new float[16]; + loadIdentity(); + } + + /** + * Creates a new matrix and sets its values from the given + * parameter + * + * @param dataArray values to set the matrix to, must be 16 + * floats long + */ + public Matrix4f(float[] dataArray) { + mMat = new float[16]; + System.arraycopy(dataArray, 0, mMat, 0, mMat.length); + } + + /** + * Return a reference to the internal array representing matrix + * values. Modifying this array will also change the matrix + * + * @return internal array representing the matrix + */ + public float[] getArray() { + return mMat; + } + + /** + * Returns the value for a given row and column + * + * @param x column of the value to return + * @param y row of the value to return + * + * @return value in the yth row and xth column + */ + public float get(int x, int y) { + return mMat[x*4 + y]; + } + + /** + * Sets the value for a given row and column + * + * @param x column of the value to set + * @param y row of the value to set + */ + public void set(int x, int y, float v) { + mMat[x*4 + y] = v; + } + + /** + * Sets the matrix values to identity + */ + public void loadIdentity() { + mMat[0] = 1; + mMat[1] = 0; + mMat[2] = 0; + mMat[3] = 0; + + mMat[4] = 0; + mMat[5] = 1; + mMat[6] = 0; + mMat[7] = 0; + + mMat[8] = 0; + mMat[9] = 0; + mMat[10] = 1; + mMat[11] = 0; + + mMat[12] = 0; + mMat[13] = 0; + mMat[14] = 0; + mMat[15] = 1; + } + + /** + * Sets the values of the matrix to those of the parameter + * + * @param src matrix to load the values from + */ + public void load(Matrix4f src) { + System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length); + } + + /** + * Sets the values of the matrix to those of the parameter + * + * @param src matrix to load the values from + * @hide + */ + public void load(Matrix3f src) { + mMat[0] = src.mMat[0]; + mMat[1] = src.mMat[1]; + mMat[2] = src.mMat[2]; + mMat[3] = 0; + + mMat[4] = src.mMat[3]; + mMat[5] = src.mMat[4]; + mMat[6] = src.mMat[5]; + mMat[7] = 0; + + mMat[8] = src.mMat[6]; + mMat[9] = src.mMat[7]; + mMat[10] = src.mMat[8]; + mMat[11] = 0; + + mMat[12] = 0; + mMat[13] = 0; + mMat[14] = 0; + mMat[15] = 1; + } + + /** + * Sets current values to be a rotation matrix of certain angle + * about a given axis + * + * @param rot angle of rotation + * @param x rotation axis x + * @param y rotation axis y + * @param z rotation axis z + */ + public void loadRotate(float rot, float x, float y, float z) { + float c, s; + mMat[3] = 0; + mMat[7] = 0; + mMat[11]= 0; + mMat[12]= 0; + mMat[13]= 0; + mMat[14]= 0; + mMat[15]= 1; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + + float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z); + if (!(len != 1)) { + float recipLen = 1.f / len; + x *= recipLen; + y *= recipLen; + z *= recipLen; + } + float nc = 1.0f - c; + float xy = x * y; + float yz = y * z; + float zx = z * x; + float xs = x * s; + float ys = y * s; + float zs = z * s; + mMat[ 0] = x*x*nc + c; + mMat[ 4] = xy*nc - zs; + mMat[ 8] = zx*nc + ys; + mMat[ 1] = xy*nc + zs; + mMat[ 5] = y*y*nc + c; + mMat[ 9] = yz*nc - xs; + mMat[ 2] = zx*nc - ys; + mMat[ 6] = yz*nc + xs; + mMat[10] = z*z*nc + c; + } + + /** + * Sets current values to be a scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + * @param z scale component z + */ + public void loadScale(float x, float y, float z) { + loadIdentity(); + mMat[0] = x; + mMat[5] = y; + mMat[10] = z; + } + + /** + * Sets current values to be a translation matrix of given + * dimensions + * + * @param x translation component x + * @param y translation component y + * @param z translation component z + */ + public void loadTranslate(float x, float y, float z) { + loadIdentity(); + mMat[12] = x; + mMat[13] = y; + mMat[14] = z; + } + + /** + * Sets current values to be the result of multiplying two given + * matrices + * + * @param lhs left hand side matrix + * @param rhs right hand side matrix + */ + public void loadMultiply(Matrix4f lhs, Matrix4f rhs) { + for (int i=0 ; i<4 ; i++) { + float ri0 = 0; + float ri1 = 0; + float ri2 = 0; + float ri3 = 0; + for (int j=0 ; j<4 ; j++) { + float rhs_ij = rhs.get(i,j); + ri0 += lhs.get(j,0) * rhs_ij; + ri1 += lhs.get(j,1) * rhs_ij; + ri2 += lhs.get(j,2) * rhs_ij; + ri3 += lhs.get(j,3) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + set(i,2, ri2); + set(i,3, ri3); + } + } + + /** + * Set current values to be an orthographic projection matrix + * + * @param l location of the left vertical clipping plane + * @param r location of the right vertical clipping plane + * @param b location of the bottom horizontal clipping plane + * @param t location of the top horizontal clipping plane + * @param n location of the near clipping plane + * @param f location of the far clipping plane + */ + public void loadOrtho(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + mMat[0] = 2 / (r - l); + mMat[5] = 2 / (t - b); + mMat[10]= -2 / (f - n); + mMat[12]= -(r + l) / (r - l); + mMat[13]= -(t + b) / (t - b); + mMat[14]= -(f + n) / (f - n); + } + + /** + * Set current values to be an orthographic projection matrix + * with the right and bottom clipping planes set to the given + * values. Left and top clipping planes are set to 0. Near and + * far are set to -1, 1 respectively + * + * @param w location of the right vertical clipping plane + * @param h location of the bottom horizontal clipping plane + * + */ + public void loadOrthoWindow(int w, int h) { + loadOrtho(0,w, h,0, -1,1); + } + + /** + * Sets current values to be a perspective projection matrix + * + * @param l location of the left vertical clipping plane + * @param r location of the right vertical clipping plane + * @param b location of the bottom horizontal clipping plane + * @param t location of the top horizontal clipping plane + * @param n location of the near clipping plane, must be positive + * @param f location of the far clipping plane, must be positive + * + */ + public void loadFrustum(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + mMat[0] = 2 * n / (r - l); + mMat[5] = 2 * n / (t - b); + mMat[8] = (r + l) / (r - l); + mMat[9] = (t + b) / (t - b); + mMat[10]= -(f + n) / (f - n); + mMat[11]= -1; + mMat[14]= -2*f*n / (f - n); + mMat[15]= 0; + } + + /** + * Sets current values to be a perspective projection matrix + * + * @param fovy vertical field of view angle in degrees + * @param aspect aspect ratio of the screen + * @param near near cliping plane, must be positive + * @param far far clipping plane, must be positive + */ + public void loadPerspective(float fovy, float aspect, float near, float far) { + float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f)); + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + loadFrustum(left, right, bottom, top, near, far); + } + + /** + * Helper function to set the current values to a perspective + * projection matrix with aspect ratio defined by the parameters + * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0 + * + * @param w screen width + * @param h screen height + */ + public void loadProjectionNormalized(int w, int h) { + // range -1,1 in the narrow axis at z = 0. + Matrix4f m1 = new Matrix4f(); + Matrix4f m2 = new Matrix4f(); + + if(w > h) { + float aspect = ((float)w) / h; + m1.loadFrustum(-aspect,aspect, -1,1, 1,100); + } else { + float aspect = ((float)h) / w; + m1.loadFrustum(-1,1, -aspect,aspect, 1,100); + } + + m2.loadRotate(180, 0, 1, 0); + m1.loadMultiply(m1, m2); + + m2.loadScale(-2, 2, 1); + m1.loadMultiply(m1, m2); + + m2.loadTranslate(0, 0, 2); + m1.loadMultiply(m1, m2); + + load(m1); + } + + /** + * Post-multiplies the current matrix by a given parameter + * + * @param rhs right hand side to multiply by + */ + public void multiply(Matrix4f rhs) { + Matrix4f tmp = new Matrix4f(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + /** + * Modifies the current matrix by post-multiplying it with a + * rotation matrix of certain angle about a given axis + * + * @param rot angle of rotation + * @param x rotation axis x + * @param y rotation axis y + * @param z rotation axis z + */ + public void rotate(float rot, float x, float y, float z) { + Matrix4f tmp = new Matrix4f(); + tmp.loadRotate(rot, x, y, z); + multiply(tmp); + } + + /** + * Modifies the current matrix by post-multiplying it with a + * scale matrix of given dimensions + * + * @param x scale component x + * @param y scale component y + * @param z scale component z + */ + public void scale(float x, float y, float z) { + Matrix4f tmp = new Matrix4f(); + tmp.loadScale(x, y, z); + multiply(tmp); + } + + /** + * Modifies the current matrix by post-multiplying it with a + * translation matrix of given dimensions + * + * @param x translation component x + * @param y translation component y + * @param z translation component z + */ + public void translate(float x, float y, float z) { + Matrix4f tmp = new Matrix4f(); + tmp.loadTranslate(x, y, z); + multiply(tmp); + } + private float computeCofactor(int i, int j) { + int c0 = (i+1) % 4; + int c1 = (i+2) % 4; + int c2 = (i+3) % 4; + int r0 = (j+1) % 4; + int r1 = (j+2) % 4; + int r2 = (j+3) % 4; + + float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] - + mMat[c1 + 4*r2] * mMat[c2 + 4*r1])) + - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] - + mMat[c1 + 4*r2] * mMat[c2 + 4*r0])) + + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] - + mMat[c1 + 4*r1] * mMat[c2 + 4*r0])); + + float cofactor = ((i+j) & 1) != 0 ? -minor : minor; + return cofactor; + } + + /** + * Sets the current matrix to its inverse + */ + public boolean inverse() { + + Matrix4f result = new Matrix4f(); + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.mMat[4*i + j] = computeCofactor(i, j); + } + } + + // Dot product of 0th column of source and 0th row of result + float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] + + mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3]; + + if (Math.abs(det) < 1e-6) { + return false; + } + + det = 1.0f / det; + for (int i = 0; i < 16; ++i) { + mMat[i] = result.mMat[i] * det; + } + + return true; + } + + /** + * Sets the current matrix to its inverse transpose + */ + public boolean inverseTranspose() { + + Matrix4f result = new Matrix4f(); + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.mMat[4*j + i] = computeCofactor(i, j); + } + } + + float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] + + mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12]; + + if (Math.abs(det) < 1e-6) { + return false; + } + + det = 1.0f / det; + for (int i = 0; i < 16; ++i) { + mMat[i] = result.mMat[i] * det; + } + + return true; + } + + /** + * Sets the current matrix to its transpose + */ + public void transpose() { + for(int i = 0; i < 3; ++i) { + for(int j = i + 1; j < 4; ++j) { + float temp = mMat[i*4 + j]; + mMat[i*4 + j] = mMat[j*4 + i]; + mMat[j*4 + i] = temp; + } + } + } + + final float[] mMat; +} diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java new file mode 100644 index 0000000..9ce3fb2 --- /dev/null +++ b/rs/java/android/renderscript/Mesh.java @@ -0,0 +1,830 @@ +/* + * 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 android.renderscript; + +import java.util.Vector; + +import android.util.Log; + +/** + * @hide + * @deprecated in API 16 + * <p>This class is a container for geometric data displayed with + * RenderScript. Internally, a mesh is a collection of allocations that + * represent vertex data (positions, normals, texture + * coordinates) and index data such as triangles and lines. </p> + * <p> + * Vertex data could either be interleaved within one + * allocation that is provided separately, as multiple allocation + * objects, or done as a combination of both. When a + * vertex channel name matches an input in the vertex program, + * RenderScript automatically connects the two together. + * </p> + * <p> + * Parts of the mesh can be rendered with either explicit + * index sets or primitive types. + * </p> + **/ +public class Mesh extends BaseObj { + + /** + * @deprecated in API 16 + * Describes the way mesh vertex data is interpreted when rendering + * + **/ + public enum Primitive { + /** + * @deprecated in API 16 + * Vertex data will be rendered as a series of points + */ + POINT (0), + /** + * @deprecated in API 16 + * Vertex pairs will be rendered as lines + */ + LINE (1), + /** + * @deprecated in API 16 + * Vertex data will be rendered as a connected line strip + */ + LINE_STRIP (2), + /** + * @deprecated in API 16 + * Vertices will be rendered as individual triangles + */ + TRIANGLE (3), + /** + * @deprecated in API 16 + * Vertices will be rendered as a connected triangle strip + * defined by the first three vertices with each additional + * triangle defined by a new vertex + */ + TRIANGLE_STRIP (4), + /** + * @deprecated in API 16 + * Vertices will be rendered as a sequence of triangles that all + * share first vertex as the origin + */ + TRIANGLE_FAN (5); + + int mID; + Primitive(int id) { + mID = id; + } + } + + Allocation[] mVertexBuffers; + Allocation[] mIndexBuffers; + Primitive[] mPrimitives; + + Mesh(long id, RenderScript rs) { + super(id, rs); + } + + /** + * @deprecated in API 16 + * @return number of allocations containing vertex data + * + **/ + public int getVertexAllocationCount() { + if(mVertexBuffers == null) { + return 0; + } + return mVertexBuffers.length; + } + /** + * @deprecated in API 16 + * @param slot index in the list of allocations to return + * @return vertex data allocation at the given index + * + **/ + public Allocation getVertexAllocation(int slot) { + return mVertexBuffers[slot]; + } + + /** + * @deprecated in API 16 + * @return number of primitives or index sets in the mesh + * + **/ + public int getPrimitiveCount() { + if(mIndexBuffers == null) { + return 0; + } + return mIndexBuffers.length; + } + + /** + * @deprecated in API 16 + * @param slot locaton within the list of index set allocation + * @return allocation containing primtive index data or null if + * the index data is not specified explicitly + * + **/ + public Allocation getIndexSetAllocation(int slot) { + return mIndexBuffers[slot]; + } + /** + * @deprecated in API 16 + * @param slot locaiton within the list of index set primitives + * @return index set primitive type + * + **/ + public Primitive getPrimitive(int slot) { + return mPrimitives[slot]; + } + + @Override + void updateFromNative() { + super.updateFromNative(); + int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS)); + int idxCount = mRS.nMeshGetIndexCount(getID(mRS)); + + int[] vtxIDs = new int[vtxCount]; + int[] idxIDs = new int[idxCount]; + int[] primitives = new int[idxCount]; + + mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount); + mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount); + + mVertexBuffers = new Allocation[vtxCount]; + mIndexBuffers = new Allocation[idxCount]; + mPrimitives = new Primitive[idxCount]; + + for(int i = 0; i < vtxCount; i ++) { + if(vtxIDs[i] != 0) { + mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT); + mVertexBuffers[i].updateFromNative(); + } + } + + for(int i = 0; i < idxCount; i ++) { + if(idxIDs[i] != 0) { + mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT); + mIndexBuffers[i].updateFromNative(); + } + mPrimitives[i] = Primitive.values()[primitives[i]]; + } + } + + /** + * @deprecated in API 16 + * Mesh builder object. It starts empty and requires you to + * add the types necessary to create vertex and index + * allocations. + * + */ + public static class Builder { + RenderScript mRS; + int mUsage; + + class Entry { + Type t; + Element e; + int size; + Primitive prim; + int usage; + } + + int mVertexTypeCount; + Entry[] mVertexTypes; + Vector mIndexTypes; + + /** + * @deprecated in API 16 + * Creates builder object + * @param rs Context to which the mesh will belong. + * @param usage specifies how the mesh allocations are to be + * handled, whether they need to be uploaded to a + * buffer on the gpu, maintain a cpu copy, etc + */ + public Builder(RenderScript rs, int usage) { + mRS = rs; + mUsage = usage; + mVertexTypeCount = 0; + mVertexTypes = new Entry[16]; + mIndexTypes = new Vector(); + } + + /** + * @deprecated in API 16 + * @return internal index of the last vertex buffer type added to + * builder + **/ + public int getCurrentVertexTypeIndex() { + return mVertexTypeCount - 1; + } + + /** + * @deprecated in API 16 + * @return internal index of the last index set added to the + * builder + **/ + public int getCurrentIndexSetIndex() { + return mIndexTypes.size() - 1; + } + + /** + * @deprecated in API 16 + * Adds a vertex data type to the builder object + * + * @param t type of the vertex data allocation to be created + * + * @return this + **/ + public Builder addVertexType(Type t) throws IllegalStateException { + if (mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].t = t; + mVertexTypes[mVertexTypeCount].e = null; + mVertexTypeCount++; + return this; + } + + /** + * @deprecated in API 16 + * Adds a vertex data type to the builder object + * + * @param e element describing the vertex data layout + * @param size number of elements in the buffer + * + * @return this + **/ + public Builder addVertexType(Element e, int size) throws IllegalStateException { + if (mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].t = null; + mVertexTypes[mVertexTypeCount].e = e; + mVertexTypes[mVertexTypeCount].size = size; + mVertexTypeCount++; + return this; + } + + /** + * @deprecated in API 16 + * Adds an index set data type to the builder object + * + * @param t type of the index set data, could be null + * @param p primitive type + * + * @return this + **/ + public Builder addIndexSetType(Type t, Primitive p) { + Entry indexType = new Entry(); + indexType.t = t; + indexType.e = null; + indexType.size = 0; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return this; + } + + /** + * @deprecated in API 16 + * Adds an index set primitive type to the builder object + * + * @param p primitive type + * + * @return this + **/ + public Builder addIndexSetType(Primitive p) { + Entry indexType = new Entry(); + indexType.t = null; + indexType.e = null; + indexType.size = 0; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return this; + } + + /** + * @deprecated in API 16 + * Adds an index set data type to the builder object + * + * @param e element describing the index set data layout + * @param size number of elements in the buffer + * @param p primitive type + * + * @return this + **/ + public Builder addIndexSetType(Element e, int size, Primitive p) { + Entry indexType = new Entry(); + indexType.t = null; + indexType.e = e; + indexType.size = size; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return this; + } + + Type newType(Element e, int size) { + Type.Builder tb = new Type.Builder(mRS, e); + tb.setX(size); + return tb.create(); + } + + /** + * @deprecated in API 16 + * Create a Mesh object from the current state of the builder + * + **/ + public Mesh create() { + mRS.validate(); + int[] vtx = new int[mVertexTypeCount]; + int[] idx = new int[mIndexTypes.size()]; + int[] prim = new int[mIndexTypes.size()]; + + Allocation[] vertexBuffers = new Allocation[mVertexTypeCount]; + Allocation[] indexBuffers = new Allocation[mIndexTypes.size()]; + Primitive[] primitives = new Primitive[mIndexTypes.size()]; + + for(int ct = 0; ct < mVertexTypeCount; ct ++) { + Allocation alloc = null; + Entry entry = mVertexTypes[ct]; + if (entry.t != null) { + alloc = Allocation.createTyped(mRS, entry.t, mUsage); + } else if(entry.e != null) { + alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage); + } + vertexBuffers[ct] = alloc; + vtx[ct] = (int)alloc.getID(mRS); + } + + for(int ct = 0; ct < mIndexTypes.size(); ct ++) { + Allocation alloc = null; + Entry entry = (Entry)mIndexTypes.elementAt(ct); + if (entry.t != null) { + alloc = Allocation.createTyped(mRS, entry.t, mUsage); + } else if(entry.e != null) { + alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage); + } + long allocID = (alloc == null) ? 0 : alloc.getID(mRS); + indexBuffers[ct] = alloc; + primitives[ct] = entry.prim; + + idx[ct] = (int)allocID; + prim[ct] = entry.prim.mID; + } + + long id = mRS.nMeshCreate(vtx, idx, prim); + Mesh newMesh = new Mesh(id, mRS); + newMesh.mVertexBuffers = vertexBuffers; + newMesh.mIndexBuffers = indexBuffers; + newMesh.mPrimitives = primitives; + + return newMesh; + } + } + + /** + * @deprecated in API 16 + * Mesh builder object. It starts empty and requires the user to + * add all the vertex and index allocations that comprise the + * mesh + * + */ + public static class AllocationBuilder { + RenderScript mRS; + + class Entry { + Allocation a; + Primitive prim; + } + + int mVertexTypeCount; + Entry[] mVertexTypes; + + Vector mIndexTypes; + + /** + * @deprecated in API 16 + **/ + public AllocationBuilder(RenderScript rs) { + mRS = rs; + mVertexTypeCount = 0; + mVertexTypes = new Entry[16]; + mIndexTypes = new Vector(); + } + + /** + * @deprecated in API 16 + * @return internal index of the last vertex buffer type added to + * builder + **/ + public int getCurrentVertexTypeIndex() { + return mVertexTypeCount - 1; + } + + /** + * @deprecated in API 16 + * @return internal index of the last index set added to the + * builder + **/ + public int getCurrentIndexSetIndex() { + return mIndexTypes.size() - 1; + } + + /** + * @deprecated in API 16 + * Adds an allocation containing vertex buffer data to the + * builder + * + * @param a vertex data allocation + * + * @return this + **/ + public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException { + if (mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].a = a; + mVertexTypeCount++; + return this; + } + + /** + * @deprecated in API 16 + * Adds an allocation containing index buffer data and index type + * to the builder + * + * @param a index set data allocation, could be null + * @param p index set primitive type + * + * @return this + **/ + public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) { + Entry indexType = new Entry(); + indexType.a = a; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return this; + } + + /** + * @deprecated in API 16 + * Adds an index set type to the builder + * + * @param p index set primitive type + * + * @return this + **/ + public AllocationBuilder addIndexSetType(Primitive p) { + Entry indexType = new Entry(); + indexType.a = null; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return this; + } + + /** + * @deprecated in API 16 + * Create a Mesh object from the current state of the builder + * + **/ + public Mesh create() { + mRS.validate(); + + int[] vtx = new int[mVertexTypeCount]; + int[] idx = new int[mIndexTypes.size()]; + int[] prim = new int[mIndexTypes.size()]; + + Allocation[] indexBuffers = new Allocation[mIndexTypes.size()]; + Primitive[] primitives = new Primitive[mIndexTypes.size()]; + Allocation[] vertexBuffers = new Allocation[mVertexTypeCount]; + + for(int ct = 0; ct < mVertexTypeCount; ct ++) { + Entry entry = mVertexTypes[ct]; + vertexBuffers[ct] = entry.a; + vtx[ct] = (int)entry.a.getID(mRS); + } + + for(int ct = 0; ct < mIndexTypes.size(); ct ++) { + Entry entry = (Entry)mIndexTypes.elementAt(ct); + long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS); + indexBuffers[ct] = entry.a; + primitives[ct] = entry.prim; + + idx[ct] = (int)allocID; + prim[ct] = entry.prim.mID; + } + + long id = mRS.nMeshCreate(vtx, idx, prim); + Mesh newMesh = new Mesh(id, mRS); + newMesh.mVertexBuffers = vertexBuffers; + newMesh.mIndexBuffers = indexBuffers; + newMesh.mPrimitives = primitives; + + return newMesh; + } + } + + /** + * @deprecated in API 16 + * Builder that allows creation of a mesh object point by point + * and triangle by triangle + * + **/ + public static class TriangleMeshBuilder { + float mVtxData[]; + int mVtxCount; + int mMaxIndex; + short mIndexData[]; + int mIndexCount; + RenderScript mRS; + Element mElement; + + float mNX = 0; + float mNY = 0; + float mNZ = -1; + float mS0 = 0; + float mT0 = 0; + float mR = 1; + float mG = 1; + float mB = 1; + float mA = 1; + + int mVtxSize; + int mFlags; + + /** + * @deprecated in API 16 + **/ + public static final int COLOR = 0x0001; + /** + * @deprecated in API 16 + **/ + public static final int NORMAL = 0x0002; + /** + * @deprecated in API 16 + **/ + public static final int TEXTURE_0 = 0x0100; + + /** + * @deprecated in API 16 + * @param rs Context to which the mesh will belong. + * @param vtxSize specifies whether the vertex is a float2 or + * float3 + * @param flags bitfield that is a combination of COLOR, NORMAL, + * and TEXTURE_0 that specifies what vertex data + * channels are present in the mesh + * + **/ + public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) { + mRS = rs; + mVtxCount = 0; + mMaxIndex = 0; + mIndexCount = 0; + mVtxData = new float[128]; + mIndexData = new short[128]; + mVtxSize = vtxSize; + mFlags = flags; + + if (vtxSize < 2 || vtxSize > 3) { + throw new IllegalArgumentException("Vertex size out of range."); + } + } + + private void makeSpace(int count) { + if ((mVtxCount + count) >= mVtxData.length) { + float t[] = new float[mVtxData.length * 2]; + System.arraycopy(mVtxData, 0, t, 0, mVtxData.length); + mVtxData = t; + } + } + + private void latch() { + if ((mFlags & COLOR) != 0) { + makeSpace(4); + mVtxData[mVtxCount++] = mR; + mVtxData[mVtxCount++] = mG; + mVtxData[mVtxCount++] = mB; + mVtxData[mVtxCount++] = mA; + } + if ((mFlags & TEXTURE_0) != 0) { + makeSpace(2); + mVtxData[mVtxCount++] = mS0; + mVtxData[mVtxCount++] = mT0; + } + if ((mFlags & NORMAL) != 0) { + makeSpace(4); + mVtxData[mVtxCount++] = mNX; + mVtxData[mVtxCount++] = mNY; + mVtxData[mVtxCount++] = mNZ; + mVtxData[mVtxCount++] = 0.0f; + } + mMaxIndex ++; + } + + /** + * @deprecated in API 16 + * Adds a float2 vertex to the mesh + * + * @param x position x + * @param y position y + * + * @return this + * + **/ + public TriangleMeshBuilder addVertex(float x, float y) { + if (mVtxSize != 2) { + throw new IllegalStateException("add mistmatch with declared components."); + } + makeSpace(2); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + latch(); + return this; + } + + /** + * @deprecated in API 16 + * Adds a float3 vertex to the mesh + * + * @param x position x + * @param y position y + * @param z position z + * + * @return this + * + **/ + public TriangleMeshBuilder addVertex(float x, float y, float z) { + if (mVtxSize != 3) { + throw new IllegalStateException("add mistmatch with declared components."); + } + makeSpace(4); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = z; + mVtxData[mVtxCount++] = 1.0f; + latch(); + return this; + } + + /** + * @deprecated in API 16 + * Sets the texture coordinate for the vertices that are added after this method call. + * + * @param s texture coordinate s + * @param t texture coordinate t + * + * @return this + **/ + public TriangleMeshBuilder setTexture(float s, float t) { + if ((mFlags & TEXTURE_0) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mS0 = s; + mT0 = t; + return this; + } + + /** + * @deprecated in API 16 + * Sets the normal vector for the vertices that are added after this method call. + * + * @param x normal vector x + * @param y normal vector y + * @param z normal vector z + * + * @return this + **/ + public TriangleMeshBuilder setNormal(float x, float y, float z) { + if ((mFlags & NORMAL) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mNX = x; + mNY = y; + mNZ = z; + return this; + } + + /** + * @deprecated in API 16 + * Sets the color for the vertices that are added after this method call. + * + * @param r red component + * @param g green component + * @param b blue component + * @param a alpha component + * + * @return this + **/ + public TriangleMeshBuilder setColor(float r, float g, float b, float a) { + if ((mFlags & COLOR) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mR = r; + mG = g; + mB = b; + mA = a; + return this; + } + + /** + * @deprecated in API 16 + * Adds a new triangle to the mesh builder + * + * @param idx1 index of the first vertex in the triangle + * @param idx2 index of the second vertex in the triangle + * @param idx3 index of the third vertex in the triangle + * + * @return this + **/ + public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) { + if((idx1 >= mMaxIndex) || (idx1 < 0) || + (idx2 >= mMaxIndex) || (idx2 < 0) || + (idx3 >= mMaxIndex) || (idx3 < 0)) { + throw new IllegalStateException("Index provided greater than vertex count."); + } + if ((mIndexCount + 3) >= mIndexData.length) { + short t[] = new short[mIndexData.length * 2]; + System.arraycopy(mIndexData, 0, t, 0, mIndexData.length); + mIndexData = t; + } + mIndexData[mIndexCount++] = (short)idx1; + mIndexData[mIndexCount++] = (short)idx2; + mIndexData[mIndexCount++] = (short)idx3; + return this; + } + + /** + * @deprecated in API 16 + * Creates the mesh object from the current state of the builder + * + * @param uploadToBufferObject specifies whether the vertex data + * is to be uploaded into the buffer + * object indicating that it's likely + * not going to be modified and + * rendered many times. + * Alternatively, it indicates the + * mesh data will be updated + * frequently and remain in script + * accessible memory + * + **/ + public Mesh create(boolean uploadToBufferObject) { + Element.Builder b = new Element.Builder(mRS); + b.add(Element.createVector(mRS, + Element.DataType.FLOAT_32, + mVtxSize), "position"); + if ((mFlags & COLOR) != 0) { + b.add(Element.F32_4(mRS), "color"); + } + if ((mFlags & TEXTURE_0) != 0) { + b.add(Element.F32_2(mRS), "texture0"); + } + if ((mFlags & NORMAL) != 0) { + b.add(Element.F32_3(mRS), "normal"); + } + mElement = b.create(); + + int usage = Allocation.USAGE_SCRIPT; + if (uploadToBufferObject) { + usage |= Allocation.USAGE_GRAPHICS_VERTEX; + } + + Builder smb = new Builder(mRS, usage); + smb.addVertexType(mElement, mMaxIndex); + smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE); + + Mesh sm = smb.create(); + + sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData); + if(uploadToBufferObject) { + if (uploadToBufferObject) { + sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT); + } + } + + sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData); + if (uploadToBufferObject) { + sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT); + } + + return sm; + } + } +} + diff --git a/rs/java/android/renderscript/Path.java b/rs/java/android/renderscript/Path.java new file mode 100644 index 0000000..5cc67de --- /dev/null +++ b/rs/java/android/renderscript/Path.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + +import java.util.Vector; +import android.util.Log; + +/** + * @hide + * + */ +public class Path extends BaseObj { + + public enum Primitive { + QUADRATIC_BEZIER(0), + CUBIC_BEZIER(1); + + int mID; + Primitive(int id) { + mID = id; + } + } + + Allocation mVertexBuffer; + Allocation mLoopBuffer; + Primitive mPrimitive; + float mQuality; + boolean mCoverageToAlpha; + + Path(long id, RenderScript rs, Primitive p, Allocation vtx, Allocation loop, float q) { + super(id, rs); + mVertexBuffer = vtx; + mLoopBuffer = loop; + mPrimitive = p; + mQuality = q; + } + + public Allocation getVertexAllocation() { + return mVertexBuffer; + } + + public Allocation getLoopAllocation() { + return mLoopBuffer; + } + + public Primitive getPrimitive() { + return mPrimitive; + } + + @Override + void updateFromNative() { + } + + + public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx) { + long id = rs.nPathCreate(p.mID, false, vtx.getID(rs), 0, quality); + Path newPath = new Path(id, rs, p, null, null, quality); + return newPath; + } + + public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx, Allocation loops) { + return null; + } + + public static Path createDynamicPath(RenderScript rs, Primitive p, float quality, Allocation vtx) { + return null; + } + + public static Path createDynamicPath(RenderScript rs, Primitive p, float quality, Allocation vtx, Allocation loops) { + return null; + } + + +} + + diff --git a/rs/java/android/renderscript/Program.java b/rs/java/android/renderscript/Program.java new file mode 100644 index 0000000..3eb9b75 --- /dev/null +++ b/rs/java/android/renderscript/Program.java @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import android.content.res.Resources; +import android.util.Log; + + +/** + * @hide + * + * Program is a base class for all the objects that modify + * various stages of the graphics pipeline + * + **/ +public class Program extends BaseObj { + static final int MAX_INPUT = 8; + static final int MAX_OUTPUT = 8; + static final int MAX_CONSTANT = 8; + static final int MAX_TEXTURE = 8; + + /** + * + * TextureType specifies what textures are attached to Program + * objects + * + **/ + public enum TextureType { + TEXTURE_2D (0), + TEXTURE_CUBE (1); + + int mID; + TextureType(int id) { + mID = id; + } + } + + enum ProgramParam { + INPUT (0), + OUTPUT (1), + CONSTANT (2), + TEXTURE_TYPE (3); + + int mID; + ProgramParam(int id) { + mID = id; + } + }; + + Element mInputs[]; + Element mOutputs[]; + Type mConstants[]; + TextureType mTextures[]; + String mTextureNames[]; + int mTextureCount; + String mShader; + + Program(long id, RenderScript rs) { + super(id, rs); + } + + /** + * Program object can have zero or more constant allocations + * associated with it. This method returns the total count. + * @return number of constant input types + */ + public int getConstantCount() { + return mConstants != null ? mConstants.length : 0; + } + + /** + * Returns the type of the constant buffer used in the program + * object. It could be used to query internal elements or create + * an allocation to store constant data. + * @param slot index of the constant input type to return + * @return constant input type + */ + public Type getConstant(int slot) { + if (slot < 0 || slot >= mConstants.length) { + throw new IllegalArgumentException("Slot ID out of range."); + } + return mConstants[slot]; + } + + /** + * Returns the number of textures used in this program object + * @return number of texture inputs + */ + public int getTextureCount() { + return mTextureCount; + } + + /** + * Returns the type of texture at a given slot. e.g. 2D or Cube + * @param slot index of the texture input + * @return texture input type + */ + public TextureType getTextureType(int slot) { + if ((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + return mTextures[slot]; + } + + /** + * Returns the name of the texture input at a given slot. e.g. + * tex0, diffuse, spec + * @param slot index of the texture input + * @return texture input name + */ + public String getTextureName(int slot) { + if ((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + return mTextureNames[slot]; + } + + /** + * Binds a constant buffer to be used as uniform inputs to the + * program + * + * @param a allocation containing uniform data + * @param slot index within the program's list of constant + * buffer allocations + */ + public void bindConstants(Allocation a, int slot) { + if (slot < 0 || slot >= mConstants.length) { + throw new IllegalArgumentException("Slot ID out of range."); + } + if (a != null && + a.getType().getID(mRS) != mConstants[slot].getID(mRS)) { + throw new IllegalArgumentException("Allocation type does not match slot type."); + } + long id = a != null ? a.getID(mRS) : 0; + mRS.nProgramBindConstants(getID(mRS), slot, id); + } + + /** + * Binds a texture to be used in the program + * + * @param va allocation containing texture data + * @param slot index within the program's list of textures + * + */ + public void bindTexture(Allocation va, int slot) + throws IllegalArgumentException { + mRS.validate(); + if ((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + if (va != null && va.getType().hasFaces() && + mTextures[slot] != TextureType.TEXTURE_CUBE) { + throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot"); + } + + long id = va != null ? va.getID(mRS) : 0; + mRS.nProgramBindTexture(getID(mRS), slot, id); + } + + /** + * Binds an object that describes how a texture at the + * corresponding location is sampled + * + * @param vs sampler for a corresponding texture + * @param slot index within the program's list of textures to + * use the sampler on + * + */ + public void bindSampler(Sampler vs, int slot) + throws IllegalArgumentException { + mRS.validate(); + if ((slot < 0) || (slot >= mTextureCount)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + long id = vs != null ? vs.getID(mRS) : 0; + mRS.nProgramBindSampler(getID(mRS), slot, id); + } + + + public static class BaseProgramBuilder { + RenderScript mRS; + Element mInputs[]; + Element mOutputs[]; + Type mConstants[]; + Type mTextures[]; + TextureType mTextureTypes[]; + String mTextureNames[]; + int mInputCount; + int mOutputCount; + int mConstantCount; + int mTextureCount; + String mShader; + + + protected BaseProgramBuilder(RenderScript rs) { + mRS = rs; + mInputs = new Element[MAX_INPUT]; + mOutputs = new Element[MAX_OUTPUT]; + mConstants = new Type[MAX_CONSTANT]; + mInputCount = 0; + mOutputCount = 0; + mConstantCount = 0; + mTextureCount = 0; + mTextureTypes = new TextureType[MAX_TEXTURE]; + mTextureNames = new String[MAX_TEXTURE]; + } + + /** + * Sets the GLSL shader code to be used in the program + * + * @param s GLSL shader string + * @return self + */ + public BaseProgramBuilder setShader(String s) { + mShader = s; + return this; + } + + /** + * Sets the GLSL shader code to be used in the program + * + * @param resources application resources + * @param resourceID id of the file containing GLSL shader code + * + * @return self + */ + public BaseProgramBuilder setShader(Resources resources, int resourceID) { + byte[] str; + int strLength; + InputStream is = resources.openRawResource(resourceID); + try { + try { + str = new byte[1024]; + strLength = 0; + while(true) { + int bytesLeft = str.length - strLength; + if (bytesLeft == 0) { + byte[] buf2 = new byte[str.length * 2]; + System.arraycopy(str, 0, buf2, 0, str.length); + str = buf2; + bytesLeft = str.length - strLength; + } + int bytesRead = is.read(str, strLength, bytesLeft); + if (bytesRead <= 0) { + break; + } + strLength += bytesRead; + } + } finally { + is.close(); + } + } catch(IOException e) { + throw new Resources.NotFoundException(); + } + + try { + mShader = new String(str, 0, strLength, "UTF-8"); + } catch (UnsupportedEncodingException e) { + Log.e("RenderScript shader creation", "Could not decode shader string"); + } + + return this; + } + + /** + * Queries the index of the last added constant buffer type + * + */ + public int getCurrentConstantIndex() { + return mConstantCount - 1; + } + + /** + * Queries the index of the last added texture type + * + */ + public int getCurrentTextureIndex() { + return mTextureCount - 1; + } + + /** + * Adds constant (uniform) inputs to the program + * + * @param t Type that describes the layout of the Allocation + * object to be used as constant inputs to the Program + * @return self + */ + public BaseProgramBuilder addConstant(Type t) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mConstantCount >= MAX_CONSTANT) { + throw new RSIllegalArgumentException("Max input count exceeded."); + } + if (t.getElement().isComplex()) { + throw new RSIllegalArgumentException("Complex elements not allowed."); + } + mConstants[mConstantCount] = t; + mConstantCount++; + return this; + } + + /** + * Adds a texture input to the Program + * + * @param texType describes that the texture to append it (2D, + * Cubemap, etc.) + * @return self + */ + public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException { + addTexture(texType, "Tex" + mTextureCount); + return this; + } + + /** + * Adds a texture input to the Program + * + * @param texType describes that the texture to append it (2D, + * Cubemap, etc.) + * @param texName what the texture should be called in the + * shader + * @return self + */ + public BaseProgramBuilder addTexture(TextureType texType, String texName) + throws IllegalArgumentException { + if(mTextureCount >= MAX_TEXTURE) { + throw new IllegalArgumentException("Max texture count exceeded."); + } + mTextureTypes[mTextureCount] = texType; + mTextureNames[mTextureCount] = texName; + mTextureCount ++; + return this; + } + + protected void initProgram(Program p) { + p.mInputs = new Element[mInputCount]; + System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount); + p.mOutputs = new Element[mOutputCount]; + System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount); + p.mConstants = new Type[mConstantCount]; + System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount); + p.mTextureCount = mTextureCount; + p.mTextures = new TextureType[mTextureCount]; + System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount); + p.mTextureNames = new String[mTextureCount]; + System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount); + } + } + +} + + diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java new file mode 100644 index 0000000..5e886a3 --- /dev/null +++ b/rs/java/android/renderscript/ProgramFragment.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + + +import android.util.Log; + + +/** + * @hide + * @deprecated in API 16 + * <p>The RenderScript fragment program, also known as fragment shader is responsible + * for manipulating pixel data in a user defined way. It's constructed from a GLSL + * shader string containing the program body, textures inputs, and a Type object + * that describes the constants used by the program. Similar to the vertex programs, + * when an allocation with constant input values is bound to the shader, its values + * are sent to the graphics program automatically.</p> + * <p> The values inside the allocation are not explicitly tracked. If they change between two draw + * calls using the same program object, the runtime needs to be notified of that + * change by calling rsgAllocationSyncAll so it could send the new values to hardware. + * Communication between the vertex and fragment programs is handled internally in the + * GLSL code. For example, if the fragment program is expecting a varying input called + * varTex0, the GLSL code inside the program vertex must provide it. + * </p> + * + **/ +public class ProgramFragment extends Program { + ProgramFragment(long id, RenderScript rs) { + super(id, rs); + } + + /** + * @deprecated in API 16 + */ + public static class Builder extends BaseProgramBuilder { + /** + * @deprecated in API 16 + * Create a builder object. + * + * @param rs Context to which the program will belong. + */ + public Builder(RenderScript rs) { + super(rs); + } + + /** + * @deprecated in API 16 + * Creates ProgramFragment from the current state of the builder + * + * @return ProgramFragment + */ + public ProgramFragment create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2]; + String[] texNames = new String[mTextureCount]; + int idx = 0; + + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = ProgramParam.INPUT.mID; + tmp[idx++] = (int)mInputs[i].getID(mRS); + } + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = ProgramParam.OUTPUT.mID; + tmp[idx++] = (int)mOutputs[i].getID(mRS); + } + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = ProgramParam.CONSTANT.mID; + tmp[idx++] = (int)mConstants[i].getID(mRS); + } + for (int i=0; i < mTextureCount; i++) { + tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; + tmp[idx++] = (int)mTextureTypes[i].mID; + texNames[i] = mTextureNames[i]; + } + + long id = mRS.nProgramFragmentCreate(mShader, texNames, tmp); + ProgramFragment pf = new ProgramFragment(id, mRS); + initProgram(pf); + return pf; + } + } +} + + + diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java new file mode 100644 index 0000000..22aed0a --- /dev/null +++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java @@ -0,0 +1,335 @@ +/* + * 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 android.renderscript; + + +import android.util.Log; + + +/** + * @hide + * @deprecated in API 16 + * <p>ProgramFragmentFixedFunction is a helper class that provides + * a way to make a simple fragment shader without writing any + * GLSL code. This class allows for display of constant color, interpolated + * color from the vertex shader, or combinations of the both + * blended with results of up to two texture lookups.</p + * + **/ +public class ProgramFragmentFixedFunction extends ProgramFragment { + ProgramFragmentFixedFunction(long id, RenderScript rs) { + super(id, rs); + } + + static class InternalBuilder extends BaseProgramBuilder { + /** + * @deprecated in API 16 + */ + public InternalBuilder(RenderScript rs) { + super(rs); + } + + /** + * @deprecated in API 16 + * Creates ProgramFragmentFixedFunction from the current state + * of the builder + * + * @return ProgramFragmentFixedFunction + */ + public ProgramFragmentFixedFunction create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2]; + String[] texNames = new String[mTextureCount]; + int idx = 0; + + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = ProgramParam.INPUT.mID; + tmp[idx++] = (int)mInputs[i].getID(mRS); + } + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = ProgramParam.OUTPUT.mID; + tmp[idx++] = (int)mOutputs[i].getID(mRS); + } + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = ProgramParam.CONSTANT.mID; + tmp[idx++] = (int)mConstants[i].getID(mRS); + } + for (int i=0; i < mTextureCount; i++) { + tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; + tmp[idx++] = (int)mTextureTypes[i].mID; + texNames[i] = mTextureNames[i]; + } + + long id = mRS.nProgramFragmentCreate(mShader, texNames, tmp); + ProgramFragmentFixedFunction pf = new ProgramFragmentFixedFunction(id, mRS); + initProgram(pf); + return pf; + } + } + + /** + * @deprecated in API 16 + */ + public static class Builder { + /** + * @deprecated in API 16 + */ + public static final int MAX_TEXTURE = 2; + int mNumTextures; + boolean mPointSpriteEnable; + boolean mVaryingColorEnable; + String mShader; + RenderScript mRS; + + /** + * @deprecated in API 16 + * EnvMode describes how textures are combined with the existing + * color in the fixed function fragment shader + * + **/ + public enum EnvMode { + /** + * @deprecated in API 16 + **/ + REPLACE (1), + /** + * @deprecated in API 16 + **/ + MODULATE (2), + /** + * @deprecated in API 16 + **/ + DECAL (3); + + int mID; + EnvMode(int id) { + mID = id; + } + } + + /** + * @deprecated in API 16 + * Format describes the pixel format of textures in the fixed + * function fragment shader and how they are sampled + * + **/ + public enum Format { + /** + * @deprecated in API 16 + **/ + ALPHA (1), + /** + * @deprecated in API 16 + **/ + LUMINANCE_ALPHA (2), + /** + * @deprecated in API 16 + **/ + RGB (3), + /** + * @deprecated in API 16 + **/ + RGBA (4); + + int mID; + Format(int id) { + mID = id; + } + } + + private class Slot { + EnvMode env; + Format format; + Slot(EnvMode _env, Format _fmt) { + env = _env; + format = _fmt; + } + } + Slot[] mSlots; + + private void buildShaderString() { + mShader = "//rs_shader_internal\n"; + mShader += "varying lowp vec4 varColor;\n"; + mShader += "varying vec2 varTex0;\n"; + + mShader += "void main() {\n"; + if (mVaryingColorEnable) { + mShader += " lowp vec4 col = varColor;\n"; + } else { + mShader += " lowp vec4 col = UNI_Color;\n"; + } + + if (mNumTextures != 0) { + if (mPointSpriteEnable) { + mShader += " vec2 t0 = gl_PointCoord;\n"; + } else { + mShader += " vec2 t0 = varTex0.xy;\n"; + } + } + + for(int i = 0; i < mNumTextures; i ++) { + switch(mSlots[i].env) { + case REPLACE: + switch (mSlots[i].format) { + case ALPHA: + mShader += " col.a = texture2D(UNI_Tex0, t0).a;\n"; + break; + case LUMINANCE_ALPHA: + mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n"; + break; + case RGB: + mShader += " col.rgb = texture2D(UNI_Tex0, t0).rgb;\n"; + break; + case RGBA: + mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n"; + break; + } + break; + case MODULATE: + switch (mSlots[i].format) { + case ALPHA: + mShader += " col.a *= texture2D(UNI_Tex0, t0).a;\n"; + break; + case LUMINANCE_ALPHA: + mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n"; + break; + case RGB: + mShader += " col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n"; + break; + case RGBA: + mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n"; + break; + } + break; + case DECAL: + mShader += " col = texture2D(UNI_Tex0, t0);\n"; + break; + } + } + + mShader += " gl_FragColor = col;\n"; + mShader += "}\n"; + } + + /** + * @deprecated + * Creates a builder for fixed function fragment program + * + * @param rs Context to which the program will belong. + */ + public Builder(RenderScript rs) { + mRS = rs; + mSlots = new Slot[MAX_TEXTURE]; + mPointSpriteEnable = false; + } + + /** + * @deprecated in API 16 + * Adds a texture to be fetched as part of the fixed function + * fragment program + * + * @param env specifies how the texture is combined with the + * current color + * @param fmt specifies the format of the texture and how its + * components will be used to combine with the + * current color + * @param slot index of the texture to apply the operations on + * + * @return this + */ + public Builder setTexture(EnvMode env, Format fmt, int slot) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_TEXTURE)) { + throw new IllegalArgumentException("MAX_TEXTURE exceeded."); + } + mSlots[slot] = new Slot(env, fmt); + return this; + } + + /** + * @deprecated in API 16 + * Specifies whether the texture coordinate passed from the + * vertex program is replaced with an openGL internal point + * sprite texture coordinate + * + **/ + public Builder setPointSpriteTexCoordinateReplacement(boolean enable) { + mPointSpriteEnable = enable; + return this; + } + + /** + * @deprecated in API 16 + * Specifies whether the varying color passed from the vertex + * program or the constant color set on the fragment program is + * used in the final color calculation in the fixed function + * fragment shader + * + **/ + public Builder setVaryingColor(boolean enable) { + mVaryingColorEnable = enable; + return this; + } + + /** + * @deprecated in API 16 + * Creates the fixed function fragment program from the current + * state of the builder. + * + */ + public ProgramFragmentFixedFunction create() { + InternalBuilder sb = new InternalBuilder(mRS); + mNumTextures = 0; + for(int i = 0; i < MAX_TEXTURE; i ++) { + if(mSlots[i] != null) { + mNumTextures ++; + } + } + buildShaderString(); + sb.setShader(mShader); + + Type constType = null; + if (!mVaryingColorEnable) { + Element.Builder b = new Element.Builder(mRS); + b.add(Element.F32_4(mRS), "Color"); + Type.Builder typeBuilder = new Type.Builder(mRS, b.create()); + typeBuilder.setX(1); + constType = typeBuilder.create(); + sb.addConstant(constType); + } + for (int i = 0; i < mNumTextures; i ++) { + sb.addTexture(TextureType.TEXTURE_2D); + } + + ProgramFragmentFixedFunction pf = sb.create(); + pf.mTextureCount = MAX_TEXTURE; + if (!mVaryingColorEnable) { + Allocation constantData = Allocation.createTyped(mRS,constType); + FieldPacker fp = new FieldPacker(16); + Float4 f4 = new Float4(1.f, 1.f, 1.f, 1.f); + fp.addF32(f4); + constantData.setFromFieldPacker(0, fp); + pf.bindConstants(constantData, 0); + } + return pf; + } + } +} + + + + diff --git a/rs/java/android/renderscript/ProgramRaster.java b/rs/java/android/renderscript/ProgramRaster.java new file mode 100644 index 0000000..e294b05 --- /dev/null +++ b/rs/java/android/renderscript/ProgramRaster.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + + +import android.util.Log; + + +/** + * @hide + * @deprecated in API 16 + * Program raster is primarily used to specify whether point sprites are enabled and to control + * the culling mode. By default, back faces are culled. + **/ +public class ProgramRaster extends BaseObj { + + /** + * @deprecated in API 16 + **/ + public enum CullMode { + /** + * @deprecated in API 16 + **/ + BACK (0), + /** + * @deprecated in API 16 + **/ + FRONT (1), + /** + * @deprecated in API 16 + **/ + NONE (2); + + int mID; + CullMode(int id) { + mID = id; + } + } + + boolean mPointSprite; + CullMode mCullMode; + + ProgramRaster(long id, RenderScript rs) { + super(id, rs); + + mPointSprite = false; + mCullMode = CullMode.BACK; + } + + /** + * @deprecated in API 16 + * Specifies whether vertices are rendered as screen aligned + * elements of a specified size + * @return whether point sprites are enabled + */ + public boolean isPointSpriteEnabled() { + return mPointSprite; + } + + /** + * @deprecated in API 16 + * Specifies how triangles are culled based on their orientation + * @return cull mode + */ + public CullMode getCullMode() { + return mCullMode; + } + + /** + * @deprecated in API 16 + */ + public static ProgramRaster CULL_BACK(RenderScript rs) { + if(rs.mProgramRaster_CULL_BACK == null) { + ProgramRaster.Builder builder = new ProgramRaster.Builder(rs); + builder.setCullMode(CullMode.BACK); + rs.mProgramRaster_CULL_BACK = builder.create(); + } + return rs.mProgramRaster_CULL_BACK; + } + + /** + * @deprecated in API 16 + */ + public static ProgramRaster CULL_FRONT(RenderScript rs) { + if(rs.mProgramRaster_CULL_FRONT == null) { + ProgramRaster.Builder builder = new ProgramRaster.Builder(rs); + builder.setCullMode(CullMode.FRONT); + rs.mProgramRaster_CULL_FRONT = builder.create(); + } + return rs.mProgramRaster_CULL_FRONT; + } + + /** + * @deprecated in API 16 + */ + public static ProgramRaster CULL_NONE(RenderScript rs) { + if(rs.mProgramRaster_CULL_NONE == null) { + ProgramRaster.Builder builder = new ProgramRaster.Builder(rs); + builder.setCullMode(CullMode.NONE); + rs.mProgramRaster_CULL_NONE = builder.create(); + } + return rs.mProgramRaster_CULL_NONE; + } + + /** + * @deprecated in API 16 + */ + public static class Builder { + RenderScript mRS; + boolean mPointSprite; + CullMode mCullMode; + + /** + * @deprecated in API 16 + */ + public Builder(RenderScript rs) { + mRS = rs; + mPointSprite = false; + mCullMode = CullMode.BACK; + } + + /** + * @deprecated in API 16 + */ + public Builder setPointSpriteEnabled(boolean enable) { + mPointSprite = enable; + return this; + } + + /** + * @deprecated in API 16 + */ + public Builder setCullMode(CullMode m) { + mCullMode = m; + return this; + } + + /** + * @deprecated in API 16 + */ + public ProgramRaster create() { + mRS.validate(); + long id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID); + ProgramRaster programRaster = new ProgramRaster(id, mRS); + programRaster.mPointSprite = mPointSprite; + programRaster.mCullMode = mCullMode; + return programRaster; + } + } + +} + + + + + + diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java new file mode 100644 index 0000000..dac9e76 --- /dev/null +++ b/rs/java/android/renderscript/ProgramStore.java @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + + +import android.util.Log; + + +/** + * @hide + * <p>ProgramStore contains a set of parameters that control how + * the graphics hardware handles writes to the framebuffer. + * It could be used to:</p> + * <ul> + * <li>enable/disable depth testing</li> + * <li>specify wheather depth writes are performed</li> + * <li>setup various blending modes for use in effects like + * transparency</li> + * <li>define write masks for color components written into the + * framebuffer</li> + * </ul> + * + **/ +public class ProgramStore extends BaseObj { + /** + * Specifies the function used to determine whether a fragment + * will be drawn during the depth testing stage in the rendering + * pipeline by comparing its value with that already in the depth + * buffer. DepthFunc is only valid when depth buffer is present + * and depth testing is enabled + */ + public enum DepthFunc { + + /** + * Always drawn + */ + ALWAYS (0), + /** + * Drawn if the incoming depth value is less than that in the + * depth buffer + */ + LESS (1), + /** + * Drawn if the incoming depth value is less or equal to that in + * the depth buffer + */ + LESS_OR_EQUAL (2), + /** + * Drawn if the incoming depth value is greater than that in the + * depth buffer + */ + GREATER (3), + /** + * Drawn if the incoming depth value is greater or equal to that + * in the depth buffer + */ + GREATER_OR_EQUAL (4), + /** + * Drawn if the incoming depth value is equal to that in the + * depth buffer + */ + EQUAL (5), + /** + * Drawn if the incoming depth value is not equal to that in the + * depth buffer + */ + NOT_EQUAL (6); + + int mID; + DepthFunc(int id) { + mID = id; + } + } + + /** + * Specifies the functions used to combine incoming pixels with + * those already in the frame buffer. + * + * BlendSrcFunc describes how the coefficient used to scale the + * source pixels during the blending operation is computed + * + */ + public enum BlendSrcFunc { + ZERO (0), + ONE (1), + DST_COLOR (2), + ONE_MINUS_DST_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPHA (7), + SRC_ALPHA_SATURATE (8); + + int mID; + BlendSrcFunc(int id) { + mID = id; + } + } + + /** + * Specifies the functions used to combine incoming pixels with + * those already in the frame buffer. + * + * BlendDstFunc describes how the coefficient used to scale the + * pixels already in the framebuffer is computed during the + * blending operation + * + */ + public enum BlendDstFunc { + ZERO (0), + ONE (1), + SRC_COLOR (2), + ONE_MINUS_SRC_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPHA (7); + + int mID; + BlendDstFunc(int id) { + mID = id; + } + } + + DepthFunc mDepthFunc; + boolean mDepthMask; + boolean mColorMaskR; + boolean mColorMaskG; + boolean mColorMaskB; + boolean mColorMaskA; + BlendSrcFunc mBlendSrc; + BlendDstFunc mBlendDst; + boolean mDither; + + ProgramStore(int id, RenderScript rs) { + super(id, rs); + } + + /** + * Returns the function used to test writing into the depth + * buffer + * @return depth function + */ + public DepthFunc getDepthFunc() { + return mDepthFunc; + } + + /** + * Queries whether writes are enabled into the depth buffer + * @return depth mask + */ + public boolean isDepthMaskEnabled() { + return mDepthMask; + } + + /** + * Queries whether red channel is written + * @return red color channel mask + */ + public boolean isColorMaskRedEnabled() { + return mColorMaskR; + } + + /** + * Queries whether green channel is written + * @return green color channel mask + */ + public boolean isColorMaskGreenEnabled() { + return mColorMaskG; + } + + /** + * Queries whether blue channel is written + * @return blue color channel mask + */ + public boolean isColorMaskBlueEnabled() { + return mColorMaskB; + } + + /** + * Queries whether alpha channel is written + * @return alpha channel mask + */ + public boolean isColorMaskAlphaEnabled() { + return mColorMaskA; + } + + /** + * Specifies how the source blending factor is computed + * @return source blend function + */ + public BlendSrcFunc getBlendSrcFunc() { + return mBlendSrc; + } + + /** + * Specifies how the destination blending factor is computed + * @return destination blend function + */ + public BlendDstFunc getBlendDstFunc() { + return mBlendDst; + } + + /** + * Specifies whether colors are dithered before writing into the + * framebuffer + * @return whether dither is enabled + */ + public boolean isDitherEnabled() { + return mDither; + } + + /** + * Returns a pre-defined program store object with the following + * characteristics: + * - incoming pixels are drawn if their depth value is less than + * the stored value in the depth buffer. If the pixel is + * drawn, its value is also stored in the depth buffer + * - incoming pixels override the value stored in the color + * buffer if it passes the depth test + * + * @param rs Context to which the program will belong. + **/ + public static ProgramStore BLEND_NONE_DEPTH_TEST(RenderScript rs) { + if(rs.mProgramStore_BLEND_NONE_DEPTH_TEST == null) { + ProgramStore.Builder builder = new ProgramStore.Builder(rs); + builder.setDepthFunc(ProgramStore.DepthFunc.LESS); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); + builder.setDitherEnabled(false); + builder.setDepthMaskEnabled(true); + rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create(); + } + return rs.mProgramStore_BLEND_NONE_DEPTH_TEST; + } + /** + * Returns a pre-defined program store object with the following + * characteristics: + * - incoming pixels always pass the depth test and their value + * is not stored in the depth buffer + * - incoming pixels override the value stored in the color + * buffer + * + * @param rs Context to which the program will belong. + **/ + public static ProgramStore BLEND_NONE_DEPTH_NONE(RenderScript rs) { + if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) { + ProgramStore.Builder builder = new ProgramStore.Builder(rs); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); + builder.setDitherEnabled(false); + builder.setDepthMaskEnabled(false); + rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create(); + } + return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH; + } + /** + * Returns a pre-defined program store object with the following + * characteristics: + * - incoming pixels are drawn if their depth value is less than + * the stored value in the depth buffer. If the pixel is + * drawn, its value is also stored in the depth buffer + * - if the incoming (Source) pixel passes depth test, its value + * is combined with the stored color (Dest) using the + * following formula + * Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A) + * + * @param rs Context to which the program will belong. + **/ + public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) { + if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) { + ProgramStore.Builder builder = new ProgramStore.Builder(rs); + builder.setDepthFunc(ProgramStore.DepthFunc.LESS); + builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDitherEnabled(false); + builder.setDepthMaskEnabled(true); + rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create(); + } + return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST; + } + /** + * Returns a pre-defined program store object with the following + * characteristics: + * - incoming pixels always pass the depth test and their value + * is not stored in the depth buffer + * - incoming pixel's value is combined with the stored color + * (Dest) using the following formula + * Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A) + * + * @param rs Context to which the program will belong. + **/ + public static ProgramStore BLEND_ALPHA_DEPTH_NONE(RenderScript rs) { + if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) { + ProgramStore.Builder builder = new ProgramStore.Builder(rs); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDitherEnabled(false); + builder.setDepthMaskEnabled(false); + rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create(); + } + return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH; + } + + /** + * Builder class for ProgramStore object. If the builder is left + * empty, the equivalent of BLEND_NONE_DEPTH_NONE would be + * returned + */ + public static class Builder { + RenderScript mRS; + DepthFunc mDepthFunc; + boolean mDepthMask; + boolean mColorMaskR; + boolean mColorMaskG; + boolean mColorMaskB; + boolean mColorMaskA; + BlendSrcFunc mBlendSrc; + BlendDstFunc mBlendDst; + boolean mDither; + + public Builder(RenderScript rs) { + mRS = rs; + mDepthFunc = DepthFunc.ALWAYS; + mDepthMask = false; + mColorMaskR = true; + mColorMaskG = true; + mColorMaskB = true; + mColorMaskA = true; + mBlendSrc = BlendSrcFunc.ONE; + mBlendDst = BlendDstFunc.ZERO; + } + + /** + * Specifies the depth testing behavior + * + * @param func function used for depth testing + * + * @return this + */ + public Builder setDepthFunc(DepthFunc func) { + mDepthFunc = func; + return this; + } + + /** + * Enables writes into the depth buffer + * + * @param enable specifies whether depth writes are + * enabled or disabled + * + * @return this + */ + public Builder setDepthMaskEnabled(boolean enable) { + mDepthMask = enable; + return this; + } + + /** + * Enables writes into the color buffer + * + * @param r specifies whether red channel is written + * @param g specifies whether green channel is written + * @param b specifies whether blue channel is written + * @param a specifies whether alpha channel is written + * + * @return this + */ + public Builder setColorMaskEnabled(boolean r, boolean g, boolean b, boolean a) { + mColorMaskR = r; + mColorMaskG = g; + mColorMaskB = b; + mColorMaskA = a; + return this; + } + + /** + * Specifies how incoming pixels are combined with the pixels + * stored in the framebuffer + * + * @param src specifies how the source blending factor is + * computed + * @param dst specifies how the destination blending factor is + * computed + * + * @return this + */ + public Builder setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) { + mBlendSrc = src; + mBlendDst = dst; + return this; + } + + /** + * Enables dithering + * + * @param enable specifies whether dithering is enabled or + * disabled + * + * @return this + */ + public Builder setDitherEnabled(boolean enable) { + mDither = enable; + return this; + } + + /** + * Creates a program store from the current state of the builder + */ + public ProgramStore create() { + mRS.validate(); + int id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA, + mDepthMask, mDither, + mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID); + ProgramStore programStore = new ProgramStore(id, mRS); + programStore.mDepthFunc = mDepthFunc; + programStore.mDepthMask = mDepthMask; + programStore.mColorMaskR = mColorMaskR; + programStore.mColorMaskG = mColorMaskG; + programStore.mColorMaskB = mColorMaskB; + programStore.mColorMaskA = mColorMaskA; + programStore.mBlendSrc = mBlendSrc; + programStore.mBlendDst = mBlendDst; + programStore.mDither = mDither; + return programStore; + } + } + +} + + + + diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java new file mode 100644 index 0000000..b6886e1 --- /dev/null +++ b/rs/java/android/renderscript/ProgramVertex.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008 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. + */ + +/** + * @hide + * <p>The RenderScript vertex program, also known as a vertex shader, describes a stage in + * the graphics pipeline responsible for manipulating geometric data in a user-defined way. + * The object is constructed by providing the RenderScript system with the following data:</p> + * <ul> + * <li>Element describing its varying inputs or attributes</li> + * <li>GLSL shader string that defines the body of the program</li> + * <li>a Type that describes the layout of an Allocation containing constant or uniform inputs</li> + * </ul> + * + * <p>Once the program is created, you bind it to the graphics context, RenderScriptGL, and it will be used for + * all subsequent draw calls until you bind a new program. If the program has constant inputs, + * the user needs to bind an allocation containing those inputs. The allocation's type must match + * the one provided during creation. The RenderScript library then does all the necessary plumbing + * to send those constants to the graphics hardware. Varying inputs to the shader, such as position, normal, + * and texture coordinates are matched by name between the input Element and the Mesh object being drawn. + * The signatures don't have to be exact or in any strict order. As long as the input name in the shader + * matches a channel name and size available on the mesh, the runtime takes care of connecting the + * two. Unlike OpenGL, there is no need to link the vertex and fragment programs.</p> + * + **/ +package android.renderscript; + + +import android.graphics.Matrix; +import android.util.Log; + + +/** + * @hide + * @deprecated in API 16 + * ProgramVertex, also know as a vertex shader, describes a + * stage in the graphics pipeline responsible for manipulating + * geometric data in a user-defined way. + * + **/ +public class ProgramVertex extends Program { + + ProgramVertex(long id, RenderScript rs) { + super(id, rs); + } + + /** + * @deprecated in API 16 + * @return number of input attribute elements + */ + public int getInputCount() { + return mInputs != null ? mInputs.length : 0; + } + + /** + * @deprecated in API 16 + * @param slot location of the input to return + * @return input attribute element + */ + public Element getInput(int slot) { + if (slot < 0 || slot >= mInputs.length) { + throw new IllegalArgumentException("Slot ID out of range."); + } + return mInputs[slot]; + } + + /** + * @hide + * @deprecated in API 16 + * Builder class for creating ProgramVertex objects. + * The builder starts empty and the user must minimally provide + * the GLSL shader code, and the varying inputs. Constant, or + * uniform parameters to the shader may optionally be provided as + * well. + * + **/ + public static class Builder extends BaseProgramBuilder { + /** + * @deprecated in API 16 + * Create a builder object. + * + * @param rs Context to which the program will belong. + */ + public Builder(RenderScript rs) { + super(rs); + } + + /** + * @deprecated in API 16 + * Add varying inputs to the program + * + * @param e element describing the layout of the varying input + * structure + * @return self + */ + public Builder addInput(Element e) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mInputCount >= MAX_INPUT) { + throw new RSIllegalArgumentException("Max input count exceeded."); + } + if (e.isComplex()) { + throw new RSIllegalArgumentException("Complex elements not allowed."); + } + mInputs[mInputCount++] = e; + return this; + } + + /** + * @deprecated in API 16 + * Creates ProgramVertex from the current state of the builder + * + * @return ProgramVertex + */ + public ProgramVertex create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2]; + String[] texNames = new String[mTextureCount]; + int idx = 0; + + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = ProgramParam.INPUT.mID; + tmp[idx++] = (int)mInputs[i].getID(mRS); + } + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = ProgramParam.OUTPUT.mID; + tmp[idx++] = (int)mOutputs[i].getID(mRS); + } + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = ProgramParam.CONSTANT.mID; + tmp[idx++] = (int)mConstants[i].getID(mRS); + } + for (int i=0; i < mTextureCount; i++) { + tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; + tmp[idx++] = (int)mTextureTypes[i].mID; + texNames[i] = mTextureNames[i]; + } + + long id = mRS.nProgramVertexCreate(mShader, texNames, tmp); + ProgramVertex pv = new ProgramVertex(id, mRS); + initProgram(pv); + return pv; + } + } + +} diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java new file mode 100644 index 0000000..c479c77 --- /dev/null +++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java @@ -0,0 +1,291 @@ +/* + * 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 android.renderscript; + + +import android.graphics.Matrix; +import android.util.Log; + + +/** + * @hide + * @deprecated in API 16 + * ProgramVertexFixedFunction is a helper class that provides a + * simple way to create a fixed function emulation vertex shader + * without writing any GLSL code. + * + **/ +public class ProgramVertexFixedFunction extends ProgramVertex { + + ProgramVertexFixedFunction(long id, RenderScript rs) { + super(id, rs); + } + + /** + * @deprecated in API 16 + * Binds the constant buffer containing fixed function emulation + * matrices + * + * @param va allocation containing fixed function matrices + */ + public void bindConstants(Constants va) { + mRS.validate(); + bindConstants(va.getAllocation(), 0); + } + + static class InternalBuilder extends BaseProgramBuilder { + /** + * @deprecated in API 16 + */ + public InternalBuilder(RenderScript rs) { + super(rs); + } + + /** + * @deprecated in API 16 + */ + public InternalBuilder addInput(Element e) throws IllegalStateException { + // Should check for consistant and non-conflicting names... + if(mInputCount >= MAX_INPUT) { + throw new RSIllegalArgumentException("Max input count exceeded."); + } + if (e.isComplex()) { + throw new RSIllegalArgumentException("Complex elements not allowed."); + } + mInputs[mInputCount++] = e; + return this; + } + + /** + * @deprecated in API 16 + * Creates ProgramVertexFixedFunction from the current state of + * the builder + * + * @return ProgramVertexFixedFunction + */ + public ProgramVertexFixedFunction create() { + mRS.validate(); + int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2]; + String[] texNames = new String[mTextureCount]; + int idx = 0; + + for (int i=0; i < mInputCount; i++) { + tmp[idx++] = ProgramParam.INPUT.mID; + tmp[idx++] = (int)mInputs[i].getID(mRS); + } + for (int i=0; i < mOutputCount; i++) { + tmp[idx++] = ProgramParam.OUTPUT.mID; + tmp[idx++] = (int)mOutputs[i].getID(mRS); + } + for (int i=0; i < mConstantCount; i++) { + tmp[idx++] = ProgramParam.CONSTANT.mID; + tmp[idx++] = (int)mConstants[i].getID(mRS); + } + for (int i=0; i < mTextureCount; i++) { + tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; + tmp[idx++] = (int)mTextureTypes[i].mID; + texNames[i] = mTextureNames[i]; + } + + long id = mRS.nProgramVertexCreate(mShader, texNames, tmp); + ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS); + initProgram(pv); + return pv; + } + } + + /** + * @deprecated in API 16 + */ + public static class Builder { + boolean mTextureMatrixEnable; + String mShader; + RenderScript mRS; + + /** + * @deprecated in API 16 + * Creates a builder for fixed function vertex program + * + * @param rs Context to which the program will belong. + */ + public Builder(RenderScript rs) { + mRS = rs; + } + + /** + * @deprecated in API 16 + * Specifies whether texture matrix calculations are to be added + * to the shader + * + */ + public Builder setTextureMatrixEnable(boolean enable) { + mTextureMatrixEnable = enable; + return this; + } + static Type getConstantInputType(RenderScript rs) { + Element.Builder b = new Element.Builder(rs); + b.add(Element.MATRIX4X4(rs), "MV"); + b.add(Element.MATRIX4X4(rs), "P"); + b.add(Element.MATRIX4X4(rs), "TexMatrix"); + b.add(Element.MATRIX4X4(rs), "MVP"); + + Type.Builder typeBuilder = new Type.Builder(rs, b.create()); + typeBuilder.setX(1); + return typeBuilder.create(); + } + + private void buildShaderString() { + + mShader = "//rs_shader_internal\n"; + mShader += "varying vec4 varColor;\n"; + mShader += "varying vec2 varTex0;\n"; + + mShader += "void main() {\n"; + mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n"; + mShader += " gl_PointSize = 1.0;\n"; + + mShader += " varColor = ATTRIB_color;\n"; + if (mTextureMatrixEnable) { + mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n"; + } else { + mShader += " varTex0 = ATTRIB_texture0;\n"; + } + mShader += "}\n"; + } + + /** + * @deprecated in API 16 + * Creates ProgramVertexFixedFunction from the current state of + * the builder + * + * @return Fixed function emulation ProgramVertex + */ + public ProgramVertexFixedFunction create() { + buildShaderString(); + + InternalBuilder sb = new InternalBuilder(mRS); + sb.setShader(mShader); + sb.addConstant(getConstantInputType(mRS)); + + Element.Builder b = new Element.Builder(mRS); + b.add(Element.F32_4(mRS), "position"); + b.add(Element.F32_4(mRS), "color"); + b.add(Element.F32_3(mRS), "normal"); + b.add(Element.F32_2(mRS), "texture0"); + sb.addInput(b.create()); + + return sb.create(); + } + } + + /** + * @deprecated in API 16 + * Helper class to store modelview, projection and texture + * matrices for ProgramVertexFixedFunction + * + */ + public static class Constants { + static final int MODELVIEW_OFFSET = 0; + static final int PROJECTION_OFFSET = 16; + static final int TEXTURE_OFFSET = 32; + + Matrix4f mModel; + Matrix4f mProjection; + Matrix4f mTexture; + + Allocation mAlloc; + Allocation getAllocation() { + return mAlloc; + } + private FieldPacker mIOBuffer; + + /** + * @deprecated in API 16 + * Creates a buffer to store fixed function emulation matrices + * + * @param rs Context to which the allocation will belong. + **/ + public Constants(RenderScript rs) { + Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs); + mAlloc = Allocation.createTyped(rs, constInputType); + int bufferSize = constInputType.getElement().getBytesSize()* + constInputType.getCount(); + mIOBuffer = new FieldPacker(bufferSize); + mModel = new Matrix4f(); + mProjection = new Matrix4f(); + mTexture = new Matrix4f(); + setModelview(new Matrix4f()); + setProjection(new Matrix4f()); + setTexture(new Matrix4f()); + } + + /** + * @deprecated in API 16 + * Forces deallocation of memory backing the contant matrices. + * Normally, this is unnecessary and will be garbage collected + * + */ + public void destroy() { + mAlloc.destroy(); + mAlloc = null; + } + + private void addToBuffer(int offset, Matrix4f m) { + mIOBuffer.reset(offset); + for(int i = 0; i < 16; i ++) { + mIOBuffer.addF32(m.mMat[i]); + } + mAlloc.setFromFieldPacker(0, mIOBuffer); + } + + /** + * @deprecated in API 16 + * Sets the modelview matrix in the fixed function matrix buffer + * + * @param m modelview matrix + */ + public void setModelview(Matrix4f m) { + mModel.load(m); + addToBuffer(MODELVIEW_OFFSET*4, m); + } + + /** + * @deprecated in API 16 + * Sets the projection matrix in the fixed function matrix buffer + * + * @param m projection matrix + */ + public void setProjection(Matrix4f m) { + mProjection.load(m); + addToBuffer(PROJECTION_OFFSET*4, m); + } + + /** + * @deprecated in API 16 + * Sets the texture matrix in the fixed function matrix buffer. + * Texture matrix must be enabled in the + * ProgramVertexFixedFunction builder for the shader to utilize + * it. + * + * @param m modelview matrix + */ + public void setTexture(Matrix4f m) { + mTexture.load(m); + addToBuffer(TEXTURE_OFFSET*4, m); + } + } +} diff --git a/rs/java/android/renderscript/RSDriverException.java b/rs/java/android/renderscript/RSDriverException.java new file mode 100644 index 0000000..9e6507f --- /dev/null +++ b/rs/java/android/renderscript/RSDriverException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +/** + * Base class for all exceptions thrown by the Android + * RenderScript + */ +public class RSDriverException extends RSRuntimeException { + public RSDriverException(String string) { + super(string); + } +} + + + diff --git a/rs/java/android/renderscript/RSIllegalArgumentException.java b/rs/java/android/renderscript/RSIllegalArgumentException.java new file mode 100644 index 0000000..5c68594 --- /dev/null +++ b/rs/java/android/renderscript/RSIllegalArgumentException.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +/** + * Base class for all exceptions thrown by the Android + * RenderScript + */ +public class RSIllegalArgumentException extends RSRuntimeException { + public RSIllegalArgumentException(String string) { + super(string); + } +} + + diff --git a/rs/java/android/renderscript/RSInvalidStateException.java b/rs/java/android/renderscript/RSInvalidStateException.java new file mode 100644 index 0000000..c881898 --- /dev/null +++ b/rs/java/android/renderscript/RSInvalidStateException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +/** + * Base class for all exceptions thrown by the Android + * RenderScript + */ +public class RSInvalidStateException extends RSRuntimeException { + public RSInvalidStateException(String string) { + super(string); + } +} + + + diff --git a/rs/java/android/renderscript/RSRuntimeException.java b/rs/java/android/renderscript/RSRuntimeException.java new file mode 100644 index 0000000..b4b629e --- /dev/null +++ b/rs/java/android/renderscript/RSRuntimeException.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +/** + * Base class for all exceptions thrown by the Android + * RenderScript + */ +public class RSRuntimeException + extends java.lang.RuntimeException { + public RSRuntimeException(String string) { + super(string); + } +} + diff --git a/rs/java/android/renderscript/RSSurfaceView.java b/rs/java/android/renderscript/RSSurfaceView.java new file mode 100644 index 0000000..308d97a --- /dev/null +++ b/rs/java/android/renderscript/RSSurfaceView.java @@ -0,0 +1,173 @@ +/* + * 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 android.renderscript; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * @hide + * @deprecated in API 16 + * The Surface View for a graphics renderscript (RenderScriptGL) to draw on. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + */ +public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private SurfaceHolder mSurfaceHolder; + private RenderScriptGL mRS; + + /** + * @deprecated in API 16 + * Standard View constructor. In order to render something, you + * must call {@link android.opengl.GLSurfaceView#setRenderer} to + * register a renderer. + */ + public RSSurfaceView(Context context) { + super(context); + init(); + //Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + /** + * @deprecated in API 16 + * Standard View constructor. In order to render something, you + * must call {@link android.opengl.GLSurfaceView#setRenderer} to + * register a renderer. + */ + public RSSurfaceView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + //Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + private void init() { + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed + SurfaceHolder holder = getHolder(); + holder.addCallback(this); + } + + /** + * @deprecated in API 16 + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceCreated(SurfaceHolder holder) { + mSurfaceHolder = holder; + } + + /** + * @deprecated in API 16 + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceDestroyed(SurfaceHolder holder) { + synchronized (this) { + // Surface will be destroyed when we return + if (mRS != null) { + mRS.setSurface(null, 0, 0); + } + } + } + + /** + * @deprecated in API 16 + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + synchronized (this) { + if (mRS != null) { + mRS.setSurface(holder, w, h); + } + } + } + + /** + * @deprecated in API 16 + * Inform the view that the activity is paused. The owner of this view must + * call this method when the activity is paused. Calling this method will + * pause the rendering thread. + * Must not be called before a renderer has been set. + */ + public void pause() { + if(mRS != null) { + mRS.pause(); + } + } + + /** + * @deprecated in API 16 + * Inform the view that the activity is resumed. The owner of this view must + * call this method when the activity is resumed. Calling this method will + * recreate the OpenGL display and resume the rendering + * thread. + * Must not be called before a renderer has been set. + */ + public void resume() { + if(mRS != null) { + mRS.resume(); + } + } + + /** + * @deprecated in API 16 + **/ + public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) { + RenderScriptGL rs = new RenderScriptGL(this.getContext(), sc); + setRenderScriptGL(rs); + return rs; + } + + /** + * @deprecated in API 16 + **/ + public void destroyRenderScriptGL() { + synchronized (this) { + mRS.destroy(); + mRS = null; + } + } + + /** + * @deprecated in API 16 + **/ + public void setRenderScriptGL(RenderScriptGL rs) { + mRS = rs; + } + + /** + * @deprecated in API 16 + **/ + public RenderScriptGL getRenderScriptGL() { + return mRS; + } +} diff --git a/rs/java/android/renderscript/RSTextureView.java b/rs/java/android/renderscript/RSTextureView.java new file mode 100644 index 0000000..7eeeeae --- /dev/null +++ b/rs/java/android/renderscript/RSTextureView.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2011 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 android.renderscript; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.content.Context; +import android.graphics.SurfaceTexture; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.TextureView; + +/** + * @hide + * @deprecated in API 16 + * The Texture View for a graphics renderscript (RenderScriptGL) + * to draw on. + * + */ +public class RSTextureView extends TextureView implements TextureView.SurfaceTextureListener { + private RenderScriptGL mRS; + private SurfaceTexture mSurfaceTexture; + + /** + * @deprecated in API 16 + * Standard View constructor. In order to render something, you + * must call {@link android.opengl.GLSurfaceView#setRenderer} to + * register a renderer. + */ + public RSTextureView(Context context) { + super(context); + init(); + //Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + /** + * @deprecated in API 16 + * Standard View constructor. In order to render something, you + * must call {@link android.opengl.GLSurfaceView#setRenderer} to + * register a renderer. + */ + public RSTextureView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + //Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + private void init() { + setSurfaceTextureListener(this); + //android.util.Log.e("rs", "getSurfaceTextureListerner " + getSurfaceTextureListener()); + } + + /** + * @deprecated in API 16 + */ + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureAvailable"); + mSurfaceTexture = surface; + + if (mRS != null) { + mRS.setSurfaceTexture(mSurfaceTexture, width, height); + } + } + + /** + * @deprecated in API 16 + */ + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureSizeChanged"); + mSurfaceTexture = surface; + + if (mRS != null) { + mRS.setSurfaceTexture(mSurfaceTexture, width, height); + } + } + + /** + * @deprecated in API 16 + */ + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureDestroyed"); + mSurfaceTexture = surface; + + if (mRS != null) { + mRS.setSurfaceTexture(null, 0, 0); + } + + return true; + } + + /** + * @deprecated in API 16 + */ + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + //Log.e(RenderScript.LOG_TAG, "onSurfaceTextureUpdated"); + mSurfaceTexture = surface; + } + + /** + * @deprecated in API 16 + * Inform the view that the activity is paused. The owner of this view must + * call this method when the activity is paused. Calling this method will + * pause the rendering thread. + * Must not be called before a renderer has been set. + */ + public void pause() { + if(mRS != null) { + mRS.pause(); + } + } + + /** + * @deprecated in API 16 + * Inform the view that the activity is resumed. The owner of this view must + * call this method when the activity is resumed. Calling this method will + * recreate the OpenGL display and resume the rendering + * thread. + * Must not be called before a renderer has been set. + */ + public void resume() { + if(mRS != null) { + mRS.resume(); + } + } + + /** + * @deprecated in API 16 + * Create a new RenderScriptGL object and attach it to the + * TextureView if present. + * + * + * @param sc The RS surface config to create. + * + * @return RenderScriptGL The new object created. + */ + public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) { + RenderScriptGL rs = new RenderScriptGL(this.getContext(), sc); + setRenderScriptGL(rs); + if (mSurfaceTexture != null) { + mRS.setSurfaceTexture(mSurfaceTexture, getWidth(), getHeight()); + } + return rs; + } + + /** + * @deprecated in API 16 + * Destroy the RenderScriptGL object associated with this + * TextureView. + */ + public void destroyRenderScriptGL() { + mRS.destroy(); + mRS = null; + } + + /** + * @deprecated in API 16 + * Set a new RenderScriptGL object. This also will attach the + * new object to the TextureView if present. + * + * @param rs The new RS object. + */ + public void setRenderScriptGL(RenderScriptGL rs) { + mRS = rs; + if (mSurfaceTexture != null) { + mRS.setSurfaceTexture(mSurfaceTexture, getWidth(), getHeight()); + } + } + + /** + * @deprecated in API 16 + * Returns the previously set RenderScriptGL object. + * + * @return RenderScriptGL + */ + public RenderScriptGL getRenderScriptGL() { + return mRS; + } +} + diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java new file mode 100644 index 0000000..147ac15 --- /dev/null +++ b/rs/java/android/renderscript/RenderScript.java @@ -0,0 +1,1217 @@ +/* + * 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 android.renderscript; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +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.graphics.SurfaceTexture; +import android.os.Process; +import android.util.Log; +import android.view.Surface; +import android.os.SystemProperties; +import android.os.Trace; + +/** + * This class provides access to a RenderScript context, which controls RenderScript + * initialization, resource management, and teardown. An instance of the RenderScript + * class must be created before any other RS objects can be created. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + **/ +public class RenderScript { + static final long TRACE_TAG = Trace.TRACE_TAG_RS; + + static final String LOG_TAG = "RenderScript_jni"; + static final boolean DEBUG = false; + @SuppressWarnings({"UnusedDeclaration", "deprecation"}) + static final boolean LOG_ENABLED = false; + + private Context mApplicationContext; + + /* + * We use a class initializer to allow the native code to cache some + * field offsets. + */ + @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove? + static boolean sInitialized; + native static void _nInit(); + + static Object sRuntime; + static Method registerNativeAllocation; + static Method registerNativeFree; + + static { + sInitialized = false; + if (!SystemProperties.getBoolean("config.disable_renderscript", false)) { + try { + Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); + Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); + sRuntime = get_runtime.invoke(null); + registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE); + registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE); + } catch (Exception e) { + Log.e(LOG_TAG, "Error loading GC methods: " + e); + throw new RSRuntimeException("Error loading GC methods: " + e); + } + try { + System.loadLibrary("rs_jni"); + _nInit(); + sInitialized = true; + } catch (UnsatisfiedLinkError e) { + Log.e(LOG_TAG, "Error loading RS jni library: " + e); + throw new RSRuntimeException("Error loading RS jni library: " + e); + } + } + } + + // Non-threadsafe functions. + 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 File mCacheDir; + + /** + * 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) { + if (!sInitialized) { + Log.e(LOG_TAG, "RenderScript.setupDiskCache() called when disabled"); + return; + } + + // Defer creation of cache path to nScriptCCreate(). + mCacheDir = cacheDir; + } + + /** + * 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 rsnContextCreateGL(long dev, int ver, int sdkVer, + int colorMin, int colorPref, + int alphaMin, int alphaPref, + int depthMin, int depthPref, + int stencilMin, int stencilPref, + int samplesMin, int samplesPref, float samplesQ, int dpi); + synchronized long nContextCreateGL(long dev, int ver, int sdkVer, + int colorMin, int colorPref, + int alphaMin, int alphaPref, + int depthMin, int depthPref, + int stencilMin, int stencilPref, + int samplesMin, int samplesPref, float samplesQ, int dpi) { + return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref, + alphaMin, alphaPref, depthMin, depthPref, + stencilMin, stencilPref, + samplesMin, samplesPref, samplesQ, dpi); + } + native long rsnContextCreate(long dev, int ver, int sdkVer, int contextType); + synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType) { + return rsnContextCreate(dev, ver, sdkVer, contextType); + } + native void rsnContextDestroy(long con); + synchronized void nContextDestroy() { + validate(); + rsnContextDestroy(mContext); + } + native void rsnContextSetSurface(long con, int w, int h, Surface sur); + synchronized void nContextSetSurface(int w, int h, Surface sur) { + validate(); + rsnContextSetSurface(mContext, w, h, sur); + } + native void rsnContextSetSurfaceTexture(long con, int w, int h, SurfaceTexture sur); + synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) { + validate(); + rsnContextSetSurfaceTexture(mContext, w, h, sur); + } + 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); + } + + native void rsnContextBindRootScript(long con, int script); + synchronized void nContextBindRootScript(int script) { + validate(); + rsnContextBindRootScript(mContext, script); + } + native void rsnContextBindSampler(long con, int sampler, int slot); + synchronized void nContextBindSampler(int sampler, int slot) { + validate(); + rsnContextBindSampler(mContext, sampler, slot); + } + native void rsnContextBindProgramStore(long con, int pfs); + synchronized void nContextBindProgramStore(int pfs) { + validate(); + rsnContextBindProgramStore(mContext, pfs); + } + native void rsnContextBindProgramFragment(long con, int pf); + synchronized void nContextBindProgramFragment(int pf) { + validate(); + rsnContextBindProgramFragment(mContext, pf); + } + native void rsnContextBindProgramVertex(long con, int pv); + synchronized void nContextBindProgramVertex(int pv) { + validate(); + rsnContextBindProgramVertex(mContext, pv); + } + native void rsnContextBindProgramRaster(long con, int pr); + synchronized void nContextBindProgramRaster(int pr) { + validate(); + rsnContextBindProgramRaster(mContext, pr); + } + native void rsnContextPause(long con); + synchronized void nContextPause() { + validate(); + rsnContextPause(mContext); + } + native void rsnContextResume(long con); + synchronized void nContextResume() { + validate(); + rsnContextResume(mContext); + } + + native void rsnAssignName(long con, long obj, byte[] name); + synchronized void nAssignName(long obj, byte[] name) { + validate(); + rsnAssignName(mContext, obj, name); + } + native String rsnGetName(long con, long obj); + synchronized String nGetName(long obj) { + validate(); + return rsnGetName(mContext, obj); + } + native void rsnObjDestroy(long con, long id); + synchronized 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, int[]elements, String[] names, int[] arraySizes); + synchronized long nElementCreate2(int[] 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, + int[] IDs, String[] names, int[] arraySizes); + synchronized void nElementGetSubElements(long id, int[] 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, int[] typeData); + synchronized void nTypeGetNativeData(long id, int[] typeData) { + validate(); + rsnTypeGetNativeData(mContext, id, typeData); + } + + native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, int pointer); + synchronized long nAllocationCreateTyped(long type, int mip, int usage, int 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 Surface rsnAllocationGetSurface(long con, long alloc); + synchronized Surface nAllocationGetSurface(long alloc) { + validate(); + return rsnAllocationGetSurface(mContext, alloc); + } + 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 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); + synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt) { + validate(); + rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID); + } + + 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 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); + synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, + int w, int h, Object d, int sizeBytes, Element.DataType dt) { + validate(); + rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID); + } + + 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); + 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) { + validate(); + rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID); + } + + native void rsnAllocationRead(long con, long id, Object d, int dt); + synchronized void nAllocationRead(long id, Object d, Element.DataType dt) { + validate(); + rsnAllocationRead(mContext, id, d, dt.mID); + } + + native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d, + int sizeBytes, int dt); + synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d, + int sizeBytes, Element.DataType dt) { + validate(); + rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID); + } + + 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); + synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face, + int w, int h, Object d, int sizeBytes, Element.DataType dt) { + validate(); + rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID); + } + + 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 long rsnFileA3DCreateFromAssetStream(long con, int assetStream); + synchronized long nFileA3DCreateFromAssetStream(int assetStream) { + validate(); + return rsnFileA3DCreateFromAssetStream(mContext, assetStream); + } + native long rsnFileA3DCreateFromFile(long con, String path); + synchronized long nFileA3DCreateFromFile(String path) { + validate(); + return rsnFileA3DCreateFromFile(mContext, path); + } + native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path); + synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) { + validate(); + return rsnFileA3DCreateFromAsset(mContext, mgr, path); + } + native int rsnFileA3DGetNumIndexEntries(long con, long fileA3D); + synchronized int nFileA3DGetNumIndexEntries(long fileA3D) { + validate(); + return rsnFileA3DGetNumIndexEntries(mContext, fileA3D); + } + native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names); + synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) { + validate(); + rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names); + } + native int rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index); + synchronized int nFileA3DGetEntryByIndex(long fileA3D, int index) { + validate(); + return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index); + } + + native int rsnFontCreateFromFile(long con, String fileName, float size, int dpi); + synchronized int nFontCreateFromFile(String fileName, float size, int dpi) { + validate(); + return rsnFontCreateFromFile(mContext, fileName, size, dpi); + } + native int rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, int assetStream); + synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) { + validate(); + return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream); + } + native int rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi); + synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) { + validate(); + return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi); + } + + + native void rsnScriptBindAllocation(long con, long script, long alloc, int slot); + synchronized void nScriptBindAllocation(long script, long alloc, int slot) { + validate(); + rsnScriptBindAllocation(mContext, script, alloc, slot); + } + native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone); + synchronized void nScriptSetTimeZone(long script, byte[] timeZone) { + validate(); + rsnScriptSetTimeZone(mContext, script, timeZone); + } + native void rsnScriptInvoke(long con, long id, int slot); + synchronized void nScriptInvoke(long id, int slot) { + validate(); + rsnScriptInvoke(mContext, id, slot); + } + native void rsnScriptForEach(long con, long id, int slot, long ain, long aout, byte[] params); + native void rsnScriptForEach(long con, long id, int slot, long ain, long aout); + native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout, byte[] params, + int xstart, int xend, int ystart, int yend, int zstart, int zend); + native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout, + int xstart, int xend, int ystart, int yend, int zstart, int zend); + synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params) { + validate(); + if (params == null) { + rsnScriptForEach(mContext, id, slot, ain, aout); + } else { + rsnScriptForEach(mContext, id, slot, ain, aout, params); + } + } + + 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) { + validate(); + if (params == null) { + rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend); + } else { + rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend); + } + } + + native void rsnScriptInvokeV(long con, long id, int slot, byte[] params); + synchronized void nScriptInvokeV(long id, int slot, byte[] params) { + validate(); + rsnScriptInvokeV(mContext, id, slot, params); + } + + native void rsnScriptSetVarI(long con, long id, int slot, int val); + synchronized void nScriptSetVarI(long id, int slot, int val) { + validate(); + rsnScriptSetVarI(mContext, id, slot, val); + } + native int rsnScriptGetVarI(long con, long id, int slot); + synchronized int nScriptGetVarI(long id, int slot) { + validate(); + return rsnScriptGetVarI(mContext, id, slot); + } + + native void rsnScriptSetVarJ(long con, long id, int slot, long val); + synchronized void nScriptSetVarJ(long id, int slot, long val) { + validate(); + rsnScriptSetVarJ(mContext, id, slot, val); + } + native long rsnScriptGetVarJ(long con, long id, int slot); + synchronized long nScriptGetVarJ(long id, int slot) { + validate(); + return rsnScriptGetVarJ(mContext, id, slot); + } + + native void rsnScriptSetVarF(long con, long id, int slot, float val); + synchronized void nScriptSetVarF(long id, int slot, float val) { + validate(); + rsnScriptSetVarF(mContext, id, slot, val); + } + native float rsnScriptGetVarF(long con, long id, int slot); + synchronized float nScriptGetVarF(long id, int slot) { + validate(); + return rsnScriptGetVarF(mContext, id, slot); + } + native void rsnScriptSetVarD(long con, long id, int slot, double val); + synchronized void nScriptSetVarD(long id, int slot, double val) { + validate(); + rsnScriptSetVarD(mContext, id, slot, val); + } + native double rsnScriptGetVarD(long con, long id, int slot); + synchronized double nScriptGetVarD(long id, int slot) { + validate(); + return rsnScriptGetVarD(mContext, id, slot); + } + native void rsnScriptSetVarV(long con, long id, int slot, byte[] val); + synchronized void nScriptSetVarV(long id, int slot, byte[] val) { + validate(); + rsnScriptSetVarV(mContext, id, slot, val); + } + native void rsnScriptGetVarV(long con, long id, int slot, byte[] val); + synchronized void nScriptGetVarV(long id, int slot, byte[] val) { + validate(); + rsnScriptGetVarV(mContext, id, slot, val); + } + native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val, + long e, int[] dims); + synchronized void nScriptSetVarVE(long id, int slot, byte[] val, + long e, int[] dims) { + validate(); + rsnScriptSetVarVE(mContext, id, slot, val, e, dims); + } + native void rsnScriptSetVarObj(long con, long id, int slot, long val); + synchronized void nScriptSetVarObj(long id, int slot, long val) { + validate(); + rsnScriptSetVarObj(mContext, id, slot, val); + } + + native int rsnScriptCCreate(long con, String resName, String cacheDir, + byte[] script, int length); + synchronized int 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); + synchronized long nScriptIntrinsicCreate(int id, long eid) { + validate(); + return rsnScriptIntrinsicCreate(mContext, id, eid); + } + + native long rsnScriptKernelIDCreate(long con, long sid, int slot, int sig); + synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) { + validate(); + return rsnScriptKernelIDCreate(mContext, sid, slot, sig); + } + + native long rsnScriptFieldIDCreate(long con, long sid, int slot); + synchronized long nScriptFieldIDCreate(long sid, int slot) { + validate(); + return rsnScriptFieldIDCreate(mContext, sid, slot); + } + + native long rsnScriptGroupCreate(long con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types); + synchronized long nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] 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 int rsnSamplerCreate(long con, int magFilter, int minFilter, + int wrapS, int wrapT, int wrapR, float aniso); + synchronized int nSamplerCreate(int magFilter, int minFilter, + int wrapS, int wrapT, int wrapR, float aniso) { + validate(); + return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso); + } + + native int rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a, + boolean depthMask, boolean dither, + int srcMode, int dstMode, int depthFunc); + synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a, + boolean depthMask, boolean dither, + int srcMode, int dstMode, int depthFunc) { + validate(); + return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode, + dstMode, depthFunc); + } + + native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode); + synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) { + validate(); + return rsnProgramRasterCreate(mContext, pointSprite, cullMode); + } + + native void rsnProgramBindConstants(long con, long pv, int slot, long mID); + synchronized void nProgramBindConstants(long pv, int slot, long mID) { + validate(); + rsnProgramBindConstants(mContext, pv, slot, mID); + } + native void rsnProgramBindTexture(long con, long vpf, int slot, long a); + synchronized void nProgramBindTexture(long vpf, int slot, long a) { + validate(); + rsnProgramBindTexture(mContext, vpf, slot, a); + } + native void rsnProgramBindSampler(long con, long vpf, int slot, long s); + synchronized void nProgramBindSampler(long vpf, int slot, long s) { + validate(); + rsnProgramBindSampler(mContext, vpf, slot, s); + } + native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, int[] params); + synchronized long nProgramFragmentCreate(String shader, String[] texNames, int[] params) { + validate(); + return rsnProgramFragmentCreate(mContext, shader, texNames, params); + } + native long rsnProgramVertexCreate(long con, String shader, String[] texNames, int[] params); + synchronized long nProgramVertexCreate(String shader, String[] texNames, int[] params) { + validate(); + return rsnProgramVertexCreate(mContext, shader, texNames, params); + } + + native long rsnMeshCreate(long con, int[] vtx, int[] idx, int[] prim); + synchronized long nMeshCreate(int[] vtx, int[] idx, int[] prim) { + validate(); + return rsnMeshCreate(mContext, vtx, idx, prim); + } + native int rsnMeshGetVertexBufferCount(long con, long id); + synchronized int nMeshGetVertexBufferCount(long id) { + validate(); + return rsnMeshGetVertexBufferCount(mContext, id); + } + native int rsnMeshGetIndexCount(long con, long id); + synchronized int nMeshGetIndexCount(long id) { + validate(); + return rsnMeshGetIndexCount(mContext, id); + } + native void rsnMeshGetVertices(long con, long id, int[] vtxIds, int vtxIdCount); + synchronized void nMeshGetVertices(long id, int[] vtxIds, int vtxIdCount) { + validate(); + rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount); + } + native void rsnMeshGetIndices(long con, long id, int[] idxIds, int[] primitives, int vtxIdCount); + synchronized void nMeshGetIndices(long id, int[] idxIds, int[] primitives, int vtxIdCount) { + validate(); + rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount); + } + + native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, int loop, float q); + synchronized long nPathCreate(int prim, boolean isStatic, long vtx, int loop, float q) { + validate(); + return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q); + } + + long mDev; + long mContext; + @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_MESH; + Element mElement_PROGRAM_FRAGMENT; + Element mElement_PROGRAM_VERTEX; + Element mElement_PROGRAM_RASTER; + Element mElement_PROGRAM_STORE; + Element mElement_FONT; + + 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_YUV; + + 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; + + ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST; + ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH; + ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST; + ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH; + + ProgramRaster mProgramRaster_CULL_BACK; + ProgramRaster mProgramRaster_CULL_FRONT; + ProgramRaster mProgramRaster_CULL_NONE; + + /////////////////////////////////////////////////////////////////////////////////// + // + + /** + * 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 + * android.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 validate() { + if (mContext == 0) { + throw new RSInvalidStateException("Calling RS with no Context active."); + } + } + + + /** + * 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_MESSAGE_TO_CLIENT_NEW_BUFFER = 5; + + static final int RS_ERROR_FATAL_DEBUG = 0x0800; + 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); + + // 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))) { + 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; + } + + if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) { + Allocation.sendBufferNotification(subID); + 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(); + } + } + + /** + * Gets the application context associated with the RenderScript context. + * + * @return The application context. + */ + public final Context getApplicationContext() { + return mApplicationContext; + } + + /** + * @hide + */ + public static RenderScript create(Context ctx, int sdkVersion) { + return create(ctx, sdkVersion, ContextType.NORMAL); + } + + /** + * Create a RenderScript context. + * + * @hide + * @param ctx The context. + * @return RenderScript + */ + public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) { + if (!sInitialized) { + Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash"); + return null; + } + + RenderScript rs = new RenderScript(ctx); + + rs.mDev = rs.nDeviceCreate(); + rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID); + rs.mContextType = ct; + 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. + * + * @param ctx The context. + * @return RenderScript + */ + public static RenderScript create(Context ctx) { + return create(ctx, ContextType.NORMAL); + } + + /** + * Create a RenderScript context. + * + * + * @param ctx The context. + * @param ct The type of context to be created. + * @return RenderScript + */ + public static RenderScript create(Context ctx, ContextType ct) { + int v = ctx.getApplicationInfo().targetSdkVersion; + return create(ctx, v, ct); + } + + /** + * 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(); + } + + /** + * Destroys this RenderScript context. Once this function is called, + * using this context or any objects belonging to this context is + * illegal. + * + */ + public void destroy() { + validate(); + nContextDeinitToClient(mContext); + mMessageThread.mRun = false; + try { + mMessageThread.join(); + } catch(InterruptedException e) { + } + + nContextDestroy(); + mContext = 0; + + nDeviceDestroy(mDev); + mDev = 0; + } + + boolean isAlive() { + return mContext != 0; + } + + long safeID(BaseObj o) { + if(o != null) { + return o.getID(this); + } + return 0; + } +} diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java new file mode 100644 index 0000000..c9cbe3e --- /dev/null +++ b/rs/java/android/renderscript/RenderScriptGL.java @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + +import java.lang.reflect.Field; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.SurfaceTexture; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * @hide + * @deprecated in API 16 + * The Graphics derivitive of RenderScript. Extends the basic context to add a + * root script which is the display window for graphical output. When the + * system needs to update the display the currently bound root script will be + * called. This script is expected to issue the rendering commands to repaint + * the screen. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + **/ +public class RenderScriptGL extends RenderScript { + int mWidth; + int mHeight; + + /** + * @deprecated in API 16 + * Class which is used to describe a pixel format for a graphical buffer. + * This is used to describe the intended format of the display surface. + * + * The configuration is described by pairs of minimum and preferred bit + * depths for each component within the config and additional structural + * information. + */ + public static class SurfaceConfig { + int mDepthMin = 0; + int mDepthPref = 0; + int mStencilMin = 0; + int mStencilPref = 0; + int mColorMin = 8; + int mColorPref = 8; + int mAlphaMin = 0; + int mAlphaPref = 0; + int mSamplesMin = 1; + int mSamplesPref = 1; + float mSamplesQ = 1.f; + + /** + * @deprecated in API 16 + */ + public SurfaceConfig() { + } + + /** + * @deprecated in API 16 + */ + public SurfaceConfig(SurfaceConfig sc) { + mDepthMin = sc.mDepthMin; + mDepthPref = sc.mDepthPref; + mStencilMin = sc.mStencilMin; + mStencilPref = sc.mStencilPref; + mColorMin = sc.mColorMin; + mColorPref = sc.mColorPref; + mAlphaMin = sc.mAlphaMin; + mAlphaPref = sc.mAlphaPref; + mSamplesMin = sc.mSamplesMin; + mSamplesPref = sc.mSamplesPref; + mSamplesQ = sc.mSamplesQ; + } + + private void validateRange(int umin, int upref, int rmin, int rmax) { + if (umin < rmin || umin > rmax) { + throw new RSIllegalArgumentException("Minimum value provided out of range."); + } + if (upref < umin) { + throw new RSIllegalArgumentException("preferred must be >= Minimum."); + } + } + + /** + * @deprecated in API 16 + * Set the per-component bit depth for color (red, green, blue). This + * configures the surface for an unsigned integer buffer type. + * + * @param minimum + * @param preferred + */ + public void setColor(int minimum, int preferred) { + validateRange(minimum, preferred, 5, 8); + mColorMin = minimum; + mColorPref = preferred; + } + + /** + * @deprecated in API 16 + * Set the bit depth for alpha. This configures the surface for + * an unsigned integer buffer type. + * + * @param minimum + * @param preferred + */ + public void setAlpha(int minimum, int preferred) { + validateRange(minimum, preferred, 0, 8); + mAlphaMin = minimum; + mAlphaPref = preferred; + } + + /** + * @deprecated in API 16 + * Set the bit depth for the depth buffer. This configures the + * surface for an unsigned integer buffer type. If a minimum of 0 + * is specified then its possible no depth buffer will be + * allocated. + * + * @param minimum + * @param preferred + */ + public void setDepth(int minimum, int preferred) { + validateRange(minimum, preferred, 0, 24); + mDepthMin = minimum; + mDepthPref = preferred; + } + + /** + * @deprecated in API 16 + * Configure the multisample rendering. + * + * @param minimum The required number of samples, must be at least 1. + * @param preferred The targe number of samples, must be at least + * minimum + * @param Q The quality of samples, range 0-1. Used to decide between + * different formats which have the same number of samples but + * different rendering quality. + */ + public void setSamples(int minimum, int preferred, float Q) { + validateRange(minimum, preferred, 1, 32); + if (Q < 0.0f || Q > 1.0f) { + throw new RSIllegalArgumentException("Quality out of 0-1 range."); + } + mSamplesMin = minimum; + mSamplesPref = preferred; + mSamplesQ = Q; + } + }; + + SurfaceConfig mSurfaceConfig; + + /** + * @deprecated in API 16 + * Construct a new RenderScriptGL context. + * + * @param ctx The context. + * @param sc The desired format of the primary rendering surface. + */ + public RenderScriptGL(Context ctx, SurfaceConfig sc) { + super(ctx); + mSurfaceConfig = new SurfaceConfig(sc); + + int sdkVersion = ctx.getApplicationInfo().targetSdkVersion; + + mWidth = 0; + mHeight = 0; + mDev = nDeviceCreate(); + int dpi = ctx.getResources().getDisplayMetrics().densityDpi; + mContext = nContextCreateGL(mDev, 0, sdkVersion, + mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref, + mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref, + mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref, + mSurfaceConfig.mStencilMin, mSurfaceConfig.mStencilPref, + mSurfaceConfig.mSamplesMin, mSurfaceConfig.mSamplesPref, + mSurfaceConfig.mSamplesQ, dpi); + if (mContext == 0) { + throw new RSDriverException("Failed to create RS context."); + } + mMessageThread = new MessageThread(this); + mMessageThread.start(); + } + + /** + * @deprecated in API 16 + * Bind an os surface + * + * + * @param w + * @param h + * @param sur + */ + public void setSurface(SurfaceHolder sur, int w, int h) { + validate(); + Surface s = null; + if (sur != null) { + s = sur.getSurface(); + } + mWidth = w; + mHeight = h; + nContextSetSurface(w, h, s); + } + + /** + * @deprecated in API 16 + * Bind an os surface + * + * @param w + * @param h + * @param sur + */ + public void setSurfaceTexture(SurfaceTexture sur, int w, int h) { + validate(); + //android.util.Log.v("rs", "set surface " + sur + " w=" + w + ", h=" + h); + + mWidth = w; + mHeight = h; + nContextSetSurfaceTexture(w, h, sur); + } + + /** + * @deprecated in API 16 + * return the height of the last set surface. + * + * @return int + */ + public int getHeight() { + return mHeight; + } + + /** + * @deprecated in API 16 + * return the width of the last set surface. + * + * @return int + */ + public int getWidth() { + return mWidth; + } + + /** + * @deprecated in API 16 + * Temporarly halt calls to the root rendering script. + * + */ + public void pause() { + validate(); + nContextPause(); + } + + /** + * @deprecated in API 16 + * Resume calls to the root rendering script. + * + */ + public void resume() { + validate(); + nContextResume(); + } + + + /** + * @deprecated in API 16 + * Set the script to handle calls to render the primary surface. + * + * @param s Graphics script to process rendering requests. + */ + public void bindRootScript(Script s) { + validate(); + nContextBindRootScript((int)safeID(s)); + } + + /** + * @deprecated in API 16 + * Set the default ProgramStore object seen as the parent state by the root + * rendering script. + * + * @param p + */ + public void bindProgramStore(ProgramStore p) { + validate(); + nContextBindProgramStore((int)safeID(p)); + } + + /** + * @deprecated in API 16 + * Set the default ProgramFragment object seen as the parent state by the + * root rendering script. + * + * @param p + */ + public void bindProgramFragment(ProgramFragment p) { + validate(); + nContextBindProgramFragment((int)safeID(p)); + } + + /** + * @deprecated in API 16 + * Set the default ProgramRaster object seen as the parent state by the + * root rendering script. + * + * @param p + */ + public void bindProgramRaster(ProgramRaster p) { + validate(); + nContextBindProgramRaster((int)safeID(p)); + } + + /** + * @deprecated in API 16 + * Set the default ProgramVertex object seen as the parent state by the + * root rendering script. + * + * @param p + */ + public void bindProgramVertex(ProgramVertex p) { + validate(); + nContextBindProgramVertex((int)safeID(p)); + } + +} diff --git a/rs/java/android/renderscript/Sampler.java b/rs/java/android/renderscript/Sampler.java new file mode 100644 index 0000000..623055f --- /dev/null +++ b/rs/java/android/renderscript/Sampler.java @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2008 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 android.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 + * android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a Sampler on + * an {@link android.renderscript.Allocation} that was not created with {@link + * android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is undefined. + **/ +public class Sampler extends BaseObj { + public enum Value { + NEAREST (0), + LINEAR (1), + LINEAR_MIP_LINEAR (2), + LINEAR_MIP_NEAREST (5), + WRAP (3), + CLAMP (4), + MIRRORED_REPEAT (6); + + int mID; + Value(int id) { + mID = id; + } + } + + Value mMin; + Value mMag; + Value mWrapS; + Value mWrapT; + Value mWrapR; + float mAniso; + + Sampler(int 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; + } + + /** + * 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_MIP_LINEAR(RenderScript rs) { + if(rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR == null) { + Builder b = new Builder(rs); + b.setMinification(Value.LINEAR_MIP_LINEAR); + b.setMagnification(Value.LINEAR); + b.setWrapS(Value.MIRRORED_REPEAT); + b.setWrapT(Value.MIRRORED_REPEAT); + rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR = b.create(); + } + return rs.mSampler_MIRRORED_REPEAT_LINEAR_MIP_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(); + int 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/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java new file mode 100644 index 0000000..5ab18f7 --- /dev/null +++ b/rs/java/android/renderscript/Script.java @@ -0,0 +1,464 @@ +/* + * 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 android.renderscript; + +import android.util.SparseArray; + +/** + * The parent class for all executable scripts. This should not be used by + * applications. + **/ +public class Script extends BaseObj { + + /** + * 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 { + 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. + */ + 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); + if (id == 0) { + throw new RSDriverException("Failed to create KernelID"); + } + + k = new KernelID(id, mRS, this, slot, sig); + mKIDs.put(slot, k); + return k; + } + + /** + * 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 { + 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. + */ + protected FieldID createFieldID(int slot, Element e) { + FieldID f = mFIDs.get(slot); + if (f != null) { + return f; + } + + long id = mRS.nScriptFieldIDCreate(getID(mRS), slot); + 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. + * + */ + protected void invoke(int slot) { + mRS.nScriptInvoke(getID(mRS), slot); + } + + /** + * Only intended for use by generated reflected code. + * + */ + protected void invoke(int slot, FieldPacker v) { + if (v != null) { + mRS.nScriptInvokeV(getID(mRS), slot, v.getData()); + } else { + mRS.nScriptInvoke(getID(mRS), slot); + } + } + + /** + * Only intended for use by generated reflected code. + * + */ + 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; + if (ain != null) { + in_id = ain.getID(mRS); + } + long out_id = 0; + if (aout != null) { + out_id = aout.getID(mRS); + } + byte[] params = null; + if (v != null) { + params = v.getData(); + } + mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params); + } + + /** + * Only intended for use by generated reflected code. + * + */ + 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; + if (ain != null) { + in_id = ain.getID(mRS); + } + long out_id = 0; + if (aout != null) { + out_id = aout.getID(mRS); + } + byte[] params = null; + if (v != null) { + params = v.getData(); + } + mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend); + } + + Script(long id, RenderScript rs) { + super(id, rs); + } + + + /** + * Only intended for use by generated reflected code. + * + */ + public void bindAllocation(Allocation va, int slot) { + mRS.validate(); + if (va != null) { + mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot); + } else { + mRS.nScriptBindAllocation(getID(mRS), 0, slot); + } + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, float v) { + mRS.nScriptSetVarF(getID(mRS), index, v); + } + public float getVarF(int index) { + return mRS.nScriptGetVarF(getID(mRS), index); + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, double v) { + mRS.nScriptSetVarD(getID(mRS), index, v); + } + public double getVarD(int index) { + return mRS.nScriptGetVarD(getID(mRS), index); + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, int v) { + mRS.nScriptSetVarI(getID(mRS), index, v); + } + public int getVarI(int index) { + return mRS.nScriptGetVarI(getID(mRS), index); + } + + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, long v) { + mRS.nScriptSetVarJ(getID(mRS), index, v); + } + public long getVarJ(int index) { + return mRS.nScriptGetVarJ(getID(mRS), index); + } + + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, boolean v) { + mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0); + } + public boolean getVarB(int index) { + return mRS.nScriptGetVarI(getID(mRS), index) > 0 ? true : false; + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, BaseObj o) { + mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS)); + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, FieldPacker v) { + mRS.nScriptSetVarV(getID(mRS), index, v.getData()); + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void setVar(int index, FieldPacker v, Element e, int[] dims) { + mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims); + } + + /** + * Only intended for use by generated reflected code. + * + */ + public void getVarV(int index, FieldPacker v) { + mRS.nScriptGetVarV(getID(mRS), index, v.getData()); + } + + public void setTimeZone(String timeZone) { + mRS.validate(); + try { + mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8")); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /** + * 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 used to specify clipping for a kernel launch. + * + */ + 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. If the end value is set to 0 the X dimension is not + * clipped. + * + * @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. If the end value is set to 0 the Y dimension is not + * clipped. + * + * @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. If the end value is set to 0 the Z dimension is not + * clipped. + * + * @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/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java new file mode 100644 index 0000000..b0a5759 --- /dev/null +++ b/rs/java/android/renderscript/ScriptC.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008 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 android.renderscript; + +import android.content.Context; +import android.content.res.Resources; +import android.util.Log; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map.Entry; +import java.util.HashMap; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + * The superclass for all user-defined scripts. This is only + * intended to be used by the generated derived classes. + **/ +public class ScriptC extends Script { + private static final String TAG = "ScriptC"; + + /** + * Only intended for use by the generated derived classes. + * + * @param id + * @param rs + */ + protected ScriptC(int 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); + int id = internalCreate(rs, resources, resourceID); + if (id == 0) { + throw new RSRuntimeException("Loading of ScriptC script failed."); + } + setID(id); + } + + /** + * Name of the file that holds the object cache. + */ + private static final String CACHE_PATH = "com.android.renderscript.cache"; + + static String mCachePath; + + private static synchronized int 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); + + // Create the RS cache path if we haven't done so already. + if (mCachePath == null) { + File f = new File(rs.mCacheDir, CACHE_PATH); + mCachePath = f.getAbsolutePath(); + f.mkdirs(); + } + // Log.v(TAG, "Create script for resource = " + resName); + return rs.nScriptCCreate(resName, mCachePath, pgm, pgmLength); + } +} diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java new file mode 100644 index 0000000..48dba30 --- /dev/null +++ b/rs/java/android/renderscript/ScriptGroup.java @@ -0,0 +1,472 @@ +/* + * 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 android.renderscript; + +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * ScriptGroup creates a group of kernels that are executed + * together with one execution call as if they were a single kernel. + * The kernels may be connected internally or to an external allocation. + * The intermediate results for internal connections are not observable + * after the execution of the script. + * <p> + * External connections are grouped into inputs and outputs. + * All outputs are produced by a script kernel and placed into a + * user-supplied allocation. Inputs provide the input of a kernel. + * Inputs bound to script globals are set directly upon the script. + * <p> + * A ScriptGroup must contain at least one kernel. A ScriptGroup + * must contain only a single directed acyclic graph (DAG) of + * script kernels and connections. Attempting to create a + * ScriptGroup with multiple DAGs or attempting to create + * a cycle within a ScriptGroup will throw an exception. + * <p> + * Currently, all kernels in a ScriptGroup must be from separate + * Script objects. Attempting to use multiple kernels from the same + * Script object will result in an {@link android.renderscript.RSInvalidStateException}. + * + **/ +public final class ScriptGroup extends BaseObj { + IO mOutputs[]; + IO mInputs[]; + + 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; + } + + 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; + + Node mNext; + + Node(Script s) { + mScript = s; + } + } + + + ScriptGroup(long id, RenderScript rs) { + super(id, rs); + } + + /** + * 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. + * + * @param s The ID of the kernel where the allocation should be + * connected. + * @param a The allocation to connect. + */ + 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; + 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. + * + * @param s The ID of the kernel where the allocation should be + * connected. + * @param a The allocation to connect. + */ + 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; + 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. + */ + public void execute() { + mRS.nScriptGroupExecute(getID(mRS)); + } + + + /** + * 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. + * + */ + 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; + + /** + * 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) { + throw new RSInvalidStateException("Groups cannot contain unconnected scripts"); + } + 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."); + } + + //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; + } + + + + /** + * Creates the Script group. + * + * + * @return ScriptGroup The new ScriptGroup + */ + public ScriptGroup create() { + // FIXME: this is broken for 64-bit + + 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>(); + + int[] kernels = new int[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++] = (int)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."); + } + + int[] src = new int[mLines.size()]; + int[] dstk = new int[mLines.size()]; + int[] dstf = new int[mLines.size()]; + int[] types = new int[mLines.size()]; + + for (int ct=0; ct < mLines.size(); ct++) { + ConnectLine cl = mLines.get(ct); + src[ct] = (int)cl.mFrom.getID(mRS); + if (cl.mToK != null) { + dstk[ct] = (int)cl.mToK.getID(mRS); + } + if (cl.mToF != null) { + dstf[ct] = (int)cl.mToF.getID(mRS); + } + types[ct] = (int)cl.mAllocationType.getID(mRS); + } + + long id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types); + if (id == 0) { + throw new RSRuntimeException("Object creation error, should not happen."); + } + + 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); + } + + return sg; + } + + } + + +} + + diff --git a/rs/java/android/renderscript/ScriptIntrinsic.java b/rs/java/android/renderscript/ScriptIntrinsic.java new file mode 100644 index 0000000..8719e01 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsic.java @@ -0,0 +1,31 @@ +/* + * 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 android.renderscript; + +/** + * Base class for all Intrinsic scripts. An intrinsic a script + * which implements a pre-defined function. Intrinsics are + * provided to provide effecient implemtations of common + * operations. + * + * Not intended for direct use. + **/ +public abstract class ScriptIntrinsic extends Script { + ScriptIntrinsic(long id, RenderScript rs) { + super(id, rs); + } +} diff --git a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java new file mode 100644 index 0000000..96ec875 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java @@ -0,0 +1,101 @@ +/* + * 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 android.renderscript; + +import android.util.Log; + +/** + * + * Intrinsic for converting RGB to RGBA by using a 3D lookup table. The + * incoming r,g,b values are use as normalized x,y,z coordinates into a 3D + * allocation. The 8 nearest values are sampled and linearly interpolated. The + * result is placed in the output. + * + **/ +public final class ScriptIntrinsic3DLUT extends ScriptIntrinsic { + private Allocation mLUT; + private Element mElement; + + private 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) { + long id = rs.nScriptIntrinsicCreate(8, e.getID(rs)); + + if (!e.isCompatible(Element.U8_4(rs))) { + throw new RSIllegalArgumentException("Element must be compatible with uchar4."); + } + + return new ScriptIntrinsic3DLUT(id, rs, e); + } + + /** + * Sets the {@link android.renderscript.Allocation} to be used as the lookup table. + * + * The lookup table must use the same {@link android.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/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java new file mode 100644 index 0000000..40f1a3e --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java @@ -0,0 +1,464 @@ +/* + * 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 android.renderscript; + + +/** + * Intrinsic kernels for blending two {@link android.renderscript.Allocation} objects. + **/ +public class ScriptIntrinsicBlend extends ScriptIntrinsic { + 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 = rs.nScriptIntrinsicCreate(7, e.getID(rs)); + return new ScriptIntrinsicBlend(id, rs); + + } + + 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 + * + * @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/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java new file mode 100644 index 0000000..d1a6fed --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java @@ -0,0 +1,112 @@ +/* + * 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 android.renderscript; + +import android.content.Context; +import android.content.res.Resources; +import android.util.Log; + +/** + * Intrinsic Gausian blur filter. Applies a gaussian blur of the + * specified radius to all elements of an allocation. + * + * + **/ +public final class ScriptIntrinsicBlur extends ScriptIntrinsic { + private final float[] mValues = new float[9]; + private Allocation mInput; + + private 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_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("Unsuported element type."); + } + long id = rs.nScriptIntrinsicCreate(5, e.getID(rs)); + ScriptIntrinsicBlur sib = new ScriptIntrinsicBlur(id, rs); + sib.setRadius(5.f); + return sib; + } + + /** + * Set the input of the blur. + * 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 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) { + forEach(0, 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/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java new file mode 100644 index 0000000..601db17 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java @@ -0,0 +1,265 @@ +/* + * 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 android.renderscript; + +import android.util.Log; + +/** + * Intrinsic for applying a color matrix to allocations. + * + * If the element type is {@link Element.DataType#UNSIGNED_8}, + * it is converted to {@link Element.DataType#FLOAT_32} and + * normalized from (0-255) to (0-1). If the incoming vector size + * is less than four, a {@link Element#F32_4} is created by + * filling the missing vector channels with zero. This value is + * then multiplied by the 4x4 color matrix as performed by + * rsMatrixMultiply(), adding a {@link Element#F32_4}, and then + * writing it to the output {@link Allocation}. + * + * If the ouptut type is unsigned, the value is normalized from + * (0-1) to (0-255) and converted. If the output vector size is + * less than four, the unused channels are discarded. + * + * 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}. + **/ +public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic { + private final Matrix4f mMatrix = new Matrix4f(); + private final Float4 mAdd = new Float4(); + + private ScriptIntrinsicColorMatrix(long id, RenderScript rs) { + super(id, rs); + } + + /** + * Create an intrinsic for applying a color matrix to an + * allocation. + * + * @param rs The RenderScript context + * @param e Element type for inputs and outputs, As of API 19, + * this parameter is ignored. The Element type check is + * performed in the kernel launch. + * + * @deprecated Use the single argument version as Element is now + * ignored. + * + * @return ScriptIntrinsicColorMatrix + */ + @Deprecated + public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) { + return create(rs); + } + + /** + * Create an intrinsic for applying a color matrix to an + * allocation. + * + * @param rs The RenderScript context + * + * @return ScriptIntrinsicColorMatrix + */ + public static ScriptIntrinsicColorMatrix create(RenderScript rs) { + long id = rs.nScriptIntrinsicCreate(2, 0); + return new ScriptIntrinsicColorMatrix(id, rs); + + } + + 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 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 + */ + public void forEach(Allocation ain, Allocation aout) { + 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("Unsuported 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("Unsuported element type."); + } + + 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/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java new file mode 100644 index 0000000..25f3ee8 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java @@ -0,0 +1,133 @@ +/* + * 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 android.renderscript; + +import android.util.Log; + +/** + * Intrinsic for applying a 3x3 convolve to an allocation. + * + **/ +public final class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic { + private final float[] mValues = new float[9]; + private Allocation mInput; + + private 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} + * + * 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("Unsuported element type."); + } + long id = rs.nScriptIntrinsicCreate(1, e.getID(rs)); + ScriptIntrinsicConvolve3x3 si = new ScriptIntrinsicConvolve3x3(id, rs); + si.setCoefficients(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) { + mInput = ain; + setVar(1, ain); + } + + /** + * Set the coefficients for the convolve. + * + * 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, 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/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java new file mode 100644 index 0000000..71ea4cb --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java @@ -0,0 +1,133 @@ +/* + * 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 android.renderscript; + +import android.util.Log; + +/** + * Intrinsic for applying a 5x5 convolve to an allocation. + * + **/ +public final class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic { + private final float[] mValues = new float[25]; + private Allocation mInput; + + private 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} + * + * 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("Unsuported element type."); + } + + long id = rs.nScriptIntrinsicCreate(4, e.getID(rs)); + return new ScriptIntrinsicConvolve5x5(id, rs); + + } + + /** + * Set the input of the blur. + * 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. + * + * 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, 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/rs/java/android/renderscript/ScriptIntrinsicHistogram.java b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java new file mode 100644 index 0000000..42e4d04 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java @@ -0,0 +1,186 @@ +/* + * 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 android.renderscript; + +import android.content.Context; +import android.content.res.Resources; +import android.util.Log; + +/** + * Intrinsic Histogram filter. + * + * + **/ +public final class ScriptIntrinsicHistogram extends ScriptIntrinsic { + private Allocation mOut; + + private 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("Unsuported element type."); + } + long id = rs.nScriptIntrinsicCreate(9, e.getID(rs)); + ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs); + return sib; + } + + /** + * 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) { + 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_4(mRS))) { + throw new RSIllegalArgumentException("Output type must be U32 or I32."); + } + + forEach(0, ain, null, null); + } + + /** + * 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) { + 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_4(mRS))) { + throw new RSIllegalArgumentException("Output type must be U32 or I32."); + } + + forEach(1, ain, null, null); + } + + + + /** + * 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/rs/java/android/renderscript/ScriptIntrinsicLUT.java b/rs/java/android/renderscript/ScriptIntrinsicLUT.java new file mode 100644 index 0000000..c45c015 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicLUT.java @@ -0,0 +1,144 @@ +/* + * 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 android.renderscript; + +import android.util.Log; + +/** + * Intrinsic for applying a per-channel lookup table. Each + * channel of the input has an independant lookup table. The + * tables are 256 entries in size and can cover the full value + * range of {@link Element#U8_4}. + **/ +public final class ScriptIntrinsicLUT extends ScriptIntrinsic { + private final Matrix4f mMatrix = new Matrix4f(); + private Allocation mTables; + private final byte mCache[] = new byte[1024]; + private boolean mDirty = true; + + private ScriptIntrinsicLUT(long id, RenderScript rs) { + super(id, rs); + mTables = Allocation.createSized(rs, Element.U8(rs), 1024); + for (int ct=0; ct < 256; ct++) { + mCache[ct] = (byte)ct; + mCache[ct + 256] = (byte)ct; + mCache[ct + 512] = (byte)ct; + mCache[ct + 768] = (byte)ct; + } + setVar(0, mTables); + } + + /** + * 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 = rs.nScriptIntrinsicCreate(3, e.getID(rs)); + return new ScriptIntrinsicLUT(id, rs); + + } + + + 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/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java new file mode 100644 index 0000000..f942982 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java @@ -0,0 +1,89 @@ +/* + * 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 android.renderscript; + + +/** + * Intrinsic for converting an Android YUV buffer to RGB. + * + * The input allocation should be supplied in a supported YUV format + * as a YUV element Allocation. The output is RGBA; the alpha channel + * will be set to 255. + */ +public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic { + private Allocation mInput; + + 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 = rs.nScriptIntrinsicCreate(6, e.getID(rs)); + ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs); + 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, 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/rs/java/android/renderscript/Short2.java b/rs/java/android/renderscript/Short2.java new file mode 100644 index 0000000..070d608 --- /dev/null +++ b/rs/java/android/renderscript/Short2.java @@ -0,0 +1,440 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic short type. + * Provides two short fields packed. + */ +public class Short2 { + public short x; + public short y; + + public Short2() { + } + + /** @hide */ + public Short2(short i) { + this.x = this.y = i; + } + + public Short2(short x, short y) { + this.x = x; + this.y = y; + } + + /** @hide */ + public Short2(Short2 source) { + this.x = source.x; + this.y = source.y; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Short2 a) { + this.x += a.x; + this.y += a.y; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short2 add(Short2 a, Short2 b) { + Short2 result = new Short2(); + result.x = (short)(a.x + b.x); + result.y = (short)(a.y + b.y); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(short value) { + x += value; + y += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short2 add(Short2 a, short b) { + Short2 result = new Short2(); + result.x = (short)(a.x + b); + result.y = (short)(a.y + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Short2 a) { + this.x -= a.x; + this.y -= a.y; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short2 sub(Short2 a, Short2 b) { + Short2 result = new Short2(); + result.x = (short)(a.x - b.x); + result.y = (short)(a.y - b.y); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(short value) { + x -= value; + y -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short2 sub(Short2 a, short b) { + Short2 result = new Short2(); + result.x = (short)(a.x - b); + result.y = (short)(a.y - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Short2 a) { + this.x *= a.x; + this.y *= a.y; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short2 mul(Short2 a, Short2 b) { + Short2 result = new Short2(); + result.x = (short)(a.x * b.x); + result.y = (short)(a.y * b.y); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(short value) { + x *= value; + y *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short2 mul(Short2 a, short b) { + Short2 result = new Short2(); + result.x = (short)(a.x * b); + result.y = (short)(a.y * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Short2 a) { + this.x /= a.x; + this.y /= a.y; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short2 div(Short2 a, Short2 b) { + Short2 result = new Short2(); + result.x = (short)(a.x / b.x); + result.y = (short)(a.y / b.y); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(short value) { + x /= value; + y /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short2 div(Short2 a, short b) { + Short2 result = new Short2(); + result.x = (short)(a.x / b); + result.y = (short)(a.y / b); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Short2 a) { + this.x %= a.x; + this.y %= a.y; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short2 mod(Short2 a, Short2 b) { + Short2 result = new Short2(); + result.x = (short)(a.x % b.x); + result.y = (short)(a.y % b.y); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(short value) { + x %= value; + y %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short2 mod(Short2 a, short b) { + Short2 result = new Short2(); + result.x = (short)(a.x % b); + result.y = (short)(a.y % b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public short length() { + return 2; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (short)(-x); + this.y = (short)(-y); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public short dotProduct(Short2 a) { + return (short)((x * a.x) + (y * a.y)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static short dotProduct(Short2 a, Short2 b) { + return (short)((b.x * a.x) + (b.y * a.y)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Short2 a, short factor) { + x += a.x * factor; + y += a.y * factor; + } + + /** @hide + * set vector value by Short2 + * + * @param a + */ + public void set(Short2 a) { + this.x = a.x; + this.y = a.y; + } + + /** @hide + * set the vector field value by Short + * + * @param a + * @param b + */ + public void setValues(short a, short b) { + this.x = a; + this.y = b; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public short elementSum() { + return (short)(x + y); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public short get(int i) { + switch (i) { + case 0: + return (short)(x); + case 1: + return (short)(y); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, short value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, short value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to short array + * + * @param data + * @param offset + */ + public void copyTo(short[] data, int offset) { + data[offset] = (short)(x); + data[offset + 1] = (short)(y); + } +} diff --git a/rs/java/android/renderscript/Short3.java b/rs/java/android/renderscript/Short3.java new file mode 100644 index 0000000..661db0a --- /dev/null +++ b/rs/java/android/renderscript/Short3.java @@ -0,0 +1,477 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic short type. + * Provides three short fields packed. + */ +public class Short3 { + public short x; + public short y; + public short z; + + public Short3() { + } + + /** @hide */ + public Short3(short i) { + this.x = this.y = this.z = i; + } + + public Short3(short x, short y, short z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** @hide */ + public Short3(Short3 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Short3 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short3 add(Short3 a, Short3 b) { + Short3 result = new Short3(); + result.x = (short)(a.x + b.x); + result.y = (short)(a.y + b.y); + result.z = (short)(a.z + b.z); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(short value) { + x += value; + y += value; + z += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short3 add(Short3 a, short b) { + Short3 result = new Short3(); + result.x = (short)(a.x + b); + result.y = (short)(a.y + b); + result.z = (short)(a.z + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Short3 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short3 sub(Short3 a, Short3 b) { + Short3 result = new Short3(); + result.x = (short)(a.x - b.x); + result.y = (short)(a.y - b.y); + result.z = (short)(a.z - b.z); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(short value) { + x -= value; + y -= value; + z -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short3 sub(Short3 a, short b) { + Short3 result = new Short3(); + result.x = (short)(a.x - b); + result.y = (short)(a.y - b); + result.z = (short)(a.z - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Short3 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short3 mul(Short3 a, Short3 b) { + Short3 result = new Short3(); + result.x = (short)(a.x * b.x); + result.y = (short)(a.y * b.y); + result.z = (short)(a.z * b.z); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(short value) { + x *= value; + y *= value; + z *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short3 mul(Short3 a, short b) { + Short3 result = new Short3(); + result.x = (short)(a.x * b); + result.y = (short)(a.y * b); + result.z = (short)(a.z * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Short3 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short3 div(Short3 a, Short3 b) { + Short3 result = new Short3(); + result.x = (short)(a.x / b.x); + result.y = (short)(a.y / b.y); + result.z = (short)(a.z / b.z); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(short value) { + x /= value; + y /= value; + z /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short3 div(Short3 a, short b) { + Short3 result = new Short3(); + result.x = (short)(a.x / b); + result.y = (short)(a.y / b); + result.z = (short)(a.z / b); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Short3 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short3 mod(Short3 a, Short3 b) { + Short3 result = new Short3(); + result.x = (short)(a.x % b.x); + result.y = (short)(a.y % b.y); + result.z = (short)(a.z % b.z); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(short value) { + x %= value; + y %= value; + z %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short3 mod(Short3 a, short b) { + Short3 result = new Short3(); + result.x = (short)(a.x % b); + result.y = (short)(a.y % b); + result.z = (short)(a.z % b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public short length() { + return 3; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (short)(-x); + this.y = (short)(-y); + this.z = (short)(-z); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public short dotProduct(Short3 a) { + return (short)((x * a.x) + (y * a.y) + (z * a.z)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static short dotProduct(Short3 a, Short3 b) { + return (short)((b.x * a.x) + (b.y * a.y) + (b.z * a.z)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Short3 a, short factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + } + + /** @hide + * set vector value by Short3 + * + * @param a + */ + public void set(Short3 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + } + + /** @hide + * set the vector field value by Short + * + * @param a + * @param b + * @param c + */ + public void setValues(short a, short b, short c) { + this.x = a; + this.y = b; + this.z = c; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public short elementSum() { + return (short)(x + y + z); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public short get(int i) { + switch (i) { + case 0: + return (short)(x); + case 1: + return (short)(y); + case 2: + return (short)(z); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, short value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, short value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to short array + * + * @param data + * @param offset + */ + public void copyTo(short[] data, int offset) { + data[offset] = (short)(x); + data[offset + 1] = (short)(y); + data[offset + 2] = (short)(z); + } +} diff --git a/rs/java/android/renderscript/Short4.java b/rs/java/android/renderscript/Short4.java new file mode 100644 index 0000000..a2d74f2 --- /dev/null +++ b/rs/java/android/renderscript/Short4.java @@ -0,0 +1,514 @@ +/* + * 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 android.renderscript; + +/** + * Vector version of the basic short type. + * Provides four short fields packed. + */ +public class Short4 { + public short x; + public short y; + public short z; + public short w; + + public Short4() { + } + + /** @hide */ + public Short4(short i) { + this.x = this.y = this.z = this.w = i; + } + + public Short4(short x, short y, short z, short w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** @hide */ + public Short4(Short4 source) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + } + + /** @hide + * Vector add + * + * @param a + */ + public void add(Short4 a) { + this.x += a.x; + this.y += a.y; + this.z += a.z; + this.w += a.w; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short4 add(Short4 a, Short4 b) { + Short4 result = new Short4(); + result.x = (short)(a.x + b.x); + result.y = (short)(a.y + b.y); + result.z = (short)(a.z + b.z); + result.w = (short)(a.w + b.w); + + return result; + } + + /** @hide + * Vector add + * + * @param value + */ + public void add(short value) { + x += value; + y += value; + z += value; + w += value; + } + + /** @hide + * Vector add + * + * @param a + * @param b + * @return + */ + public static Short4 add(Short4 a, short b) { + Short4 result = new Short4(); + result.x = (short)(a.x + b); + result.y = (short)(a.y + b); + result.z = (short)(a.z + b); + result.w = (short)(a.w + b); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param a + */ + public void sub(Short4 a) { + this.x -= a.x; + this.y -= a.y; + this.z -= a.z; + this.w -= a.w; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short4 sub(Short4 a, Short4 b) { + Short4 result = new Short4(); + result.x = (short)(a.x - b.x); + result.y = (short)(a.y - b.y); + result.z = (short)(a.z - b.z); + result.w = (short)(a.w - b.w); + + return result; + } + + /** @hide + * Vector subtraction + * + * @param value + */ + public void sub(short value) { + x -= value; + y -= value; + z -= value; + w -= value; + } + + /** @hide + * Vector subtraction + * + * @param a + * @param b + * @return + */ + public static Short4 sub(Short4 a, short b) { + Short4 result = new Short4(); + result.x = (short)(a.x - b); + result.y = (short)(a.y - b); + result.z = (short)(a.z - b); + result.w = (short)(a.w - b); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param a + */ + public void mul(Short4 a) { + this.x *= a.x; + this.y *= a.y; + this.z *= a.z; + this.w *= a.w; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short4 mul(Short4 a, Short4 b) { + Short4 result = new Short4(); + result.x = (short)(a.x * b.x); + result.y = (short)(a.y * b.y); + result.z = (short)(a.z * b.z); + result.w = (short)(a.w * b.w); + + return result; + } + + /** @hide + * Vector multiplication + * + * @param value + */ + public void mul(short value) { + x *= value; + y *= value; + z *= value; + w *= value; + } + + /** @hide + * Vector multiplication + * + * @param a + * @param b + * @return + */ + public static Short4 mul(Short4 a, short b) { + Short4 result = new Short4(); + result.x = (short)(a.x * b); + result.y = (short)(a.y * b); + result.z = (short)(a.z * b); + result.w = (short)(a.w * b); + + return result; + } + + /** @hide + * Vector division + * + * @param a + */ + public void div(Short4 a) { + this.x /= a.x; + this.y /= a.y; + this.z /= a.z; + this.w /= a.w; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short4 div(Short4 a, Short4 b) { + Short4 result = new Short4(); + result.x = (short)(a.x / b.x); + result.y = (short)(a.y / b.y); + result.z = (short)(a.z / b.z); + result.w = (short)(a.w / b.w); + + return result; + } + + /** @hide + * Vector division + * + * @param value + */ + public void div(short value) { + x /= value; + y /= value; + z /= value; + w /= value; + } + + /** @hide + * Vector division + * + * @param a + * @param b + * @return + */ + public static Short4 div(Short4 a, short b) { + Short4 result = new Short4(); + result.x = (short)(a.x / b); + result.y = (short)(a.y / b); + result.z = (short)(a.z / b); + result.w = (short)(a.w / b); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param a + */ + public void mod(Short4 a) { + this.x %= a.x; + this.y %= a.y; + this.z %= a.z; + this.w %= a.w; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short4 mod(Short4 a, Short4 b) { + Short4 result = new Short4(); + result.x = (short)(a.x % b.x); + result.y = (short)(a.y % b.y); + result.z = (short)(a.z % b.z); + result.w = (short)(a.w % b.w); + + return result; + } + + /** @hide + * Vector Modulo + * + * @param value + */ + public void mod(short value) { + x %= value; + y %= value; + z %= value; + w %= value; + } + + /** @hide + * Vector Modulo + * + * @param a + * @param b + * @return + */ + public static Short4 mod(Short4 a, short b) { + Short4 result = new Short4(); + result.x = (short)(a.x % b); + result.y = (short)(a.y % b); + result.z = (short)(a.z % b); + result.w = (short)(a.w % b); + + return result; + } + + /** @hide + * get vector length + * + * @return + */ + public short length() { + return 4; + } + + /** @hide + * set vector negate + */ + public void negate() { + this.x = (short)(-x); + this.y = (short)(-y); + this.z = (short)(-z); + this.w = (short)(-w); + } + + /** @hide + * Vector dot Product + * + * @param a + * @return + */ + public short dotProduct(Short4 a) { + return (short)((x * a.x) + (y * a.y) + (z * a.z) + (w * a.w)); + } + + /** @hide + * Vector dot Product + * + * @param a + * @param b + * @return + */ + public static short dotProduct(Short4 a, Short4 b) { + return (short)((b.x * a.x) + (b.y * a.y) + (b.z * a.z) + (b.w * a.w)); + } + + /** @hide + * Vector add Multiple + * + * @param a + * @param factor + */ + public void addMultiple(Short4 a, short factor) { + x += a.x * factor; + y += a.y * factor; + z += a.z * factor; + w += a.w * factor; + } + + /** @hide + * set vector value by Short4 + * + * @param a + */ + public void set(Short4 a) { + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = a.w; + } + + /** @hide + * set the vector field value by Short + * + * @param a + * @param b + * @param c + * @param d + */ + public void setValues(short a, short b, short c, short d) { + this.x = a; + this.y = b; + this.z = c; + this.w = d; + } + + /** @hide + * return the element sum of vector + * + * @return + */ + public short elementSum() { + return (short)(x + y + z + w); + } + + /** @hide + * get the vector field value by index + * + * @param i + * @return + */ + public short get(int i) { + switch (i) { + case 0: + return (short)(x); + case 1: + return (short)(y); + case 2: + return (short)(z); + case 3: + return (short)(w); + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * set the vector field value by index + * + * @param i + * @param value + */ + public void setAt(int i, short value) { + switch (i) { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + case 3: + w = value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * add the vector field value by index + * + * @param i + * @param value + */ + public void addAt(int i, short value) { + switch (i) { + case 0: + x += value; + return; + case 1: + y += value; + return; + case 2: + z += value; + return; + case 3: + w += value; + return; + default: + throw new IndexOutOfBoundsException("Index: i"); + } + } + + /** @hide + * copy the vector to short array + * + * @param data + * @param offset + */ + public void copyTo(short[] data, int offset) { + data[offset] = (short)(x); + data[offset + 1] = (short)(y); + data[offset + 2] = (short)(z); + data[offset + 3] = (short)(w); + } +} diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java new file mode 100644 index 0000000..7283814 --- /dev/null +++ b/rs/java/android/renderscript/Type.java @@ -0,0 +1,432 @@ +/* + * 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 android.renderscript; + + +import java.lang.reflect.Field; + +import android.graphics.ImageFormat; +import android.util.Log; + +/** + * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link + * android.renderscript.Allocation} or a parallel operation. Types are created through {@link + * android.renderscript.Type.Builder}.</p> + * + * <p>A Type always includes an {@link android.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 android.renderscript.Allocation} in a YUV format. The YUV formats + * supported are {@link android.graphics.ImageFormat#YV12}, + * {@link android.graphics.ImageFormat#NV21}, and + * {@link android.graphics.ImageFormat#YUV_420_888}</p> + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating an application that uses RenderScript, read the + * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> + * </div> + **/ +public class Type extends BaseObj { + int mDimX; + int mDimY; + int mDimZ; + boolean mDimMipmaps; + boolean mDimFaces; + int mDimYuv; + int mElementCount; + Element mElement; + + public enum CubemapFace { + POSITIVE_X (0), + NEGATIVE_X (1), + POSITIVE_Y (2), + NEGATIVE_Y (3), + POSITIVE_Z (4), + NEGATIVE_Z (5), + @Deprecated + POSITVE_X (0), + @Deprecated + POSITVE_Y (2), + @Deprecated + POSITVE_Z (4); + + 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); + } + + @Override + void updateFromNative() { + // FIXME: rsaTypeGetNativeData needs 32-bit and 64-bit paths + + // We have 6 integer to obtain mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; + int[] dataBuffer = new int[6]; + mRS.nTypeGetNativeData((int)getID(mRS), dataBuffer); + + mDimX = dataBuffer[0]; + mDimY = dataBuffer[1]; + mDimZ = dataBuffer[2]; + mDimMipmaps = dataBuffer[3] == 1 ? true : false; + mDimFaces = dataBuffer[4] == 1 ? true : false; + + int elementID = dataBuffer[5]; + if(elementID != 0) { + mElement = new Element(elementID, mRS); + mElement.updateFromNative(); + } + calcElementCount(); + } + + /** + * 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}, {@link android.graphics.ImageFormat#NV21}, or + * {@link android.graphics.ImageFormat#YUV_420_888}. + */ + public Builder setYuvFormat(int yuvFormat) { + switch (yuvFormat) { + case android.graphics.ImageFormat.NV21: + case android.graphics.ImageFormat.YV12: + case android.graphics.ImageFormat.YUV_420_888: + break; + + default: + throw new RSIllegalArgumentException( + "Only ImageFormat.NV21, .YV12, and .YUV_420_888 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."); + } + } + + long id = mRS.nTypeCreate(mElement.getID(mRS), + mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv); + Type 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; + } + } + +} diff --git a/rs/java/android/renderscript/package.html b/rs/java/android/renderscript/package.html new file mode 100644 index 0000000..eb178c1 --- /dev/null +++ b/rs/java/android/renderscript/package.html @@ -0,0 +1,10 @@ +<HTML> +<BODY> +<p>RenderScript provides support for high-performance computation across heterogeneous processors.</p> + +<p>For more information, see the +<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> +{@more} + +</BODY> +</HTML> diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk new file mode 100644 index 0000000..cbb5b3b --- /dev/null +++ b/rs/jni/Android.mk @@ -0,0 +1,38 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + android_renderscript_RenderScript.cpp + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + libandroidfw \ + libnativehelper \ + libRS \ + libcutils \ + liblog \ + libskia \ + libutils \ + libui \ + libgui + +LOCAL_STATIC_LIBRARIES := + +rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRS,,) + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) \ + frameworks/rs \ + $(rs_generated_include_dir) \ + $(call include-path-for, corecg graphics) + +LOCAL_CFLAGS += -Wno-unused-parameter + +LOCAL_LDLIBS := -lpthread +LOCAL_ADDITIONAL_DEPENDENCIES := $(addprefix $(rs_generated_include_dir)/,rsgApiFuncDecl.h) +LOCAL_MODULE:= librs_jni +LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source) +LOCAL_MODULE_TAGS := optional +LOCAL_REQUIRED_MODULES := libRS libRSDriver + +include $(BUILD_SHARED_LIBRARY) diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp new file mode 100644 index 0000000..7032742 --- /dev/null +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -0,0 +1,1660 @@ +/* + * Copyright (C) 2011-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. + */ + +#define LOG_TAG "libRS_jni" + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <math.h> +#include <utils/misc.h> + +#include <core/SkBitmap.h> +#include <core/SkPixelRef.h> +#include <core/SkStream.h> +#include <core/SkTemplates.h> + +#include <androidfw/Asset.h> +#include <androidfw/AssetManager.h> +#include <androidfw/ResourceTypes.h> + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" +#include "android_runtime/android_view_Surface.h" +#include "android_runtime/android_util_AssetManager.h" + +#include <rs.h> +#include <rsEnv.h> +#include <gui/Surface.h> +#include <gui/GLConsumer.h> +#include <gui/Surface.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> + +//#define LOG_API ALOGE +#define LOG_API(...) + +using namespace android; + +#define PER_ARRAY_TYPE(flag, fnc, ...) { \ + jint len = 0; \ + void *ptr = NULL; \ + size_t typeBytes = 0; \ + switch(dataType) { \ + case RS_TYPE_FLOAT_32: \ + len = _env->GetArrayLength((jfloatArray)data); \ + ptr = _env->GetFloatArrayElements((jfloatArray)data, flag); \ + typeBytes = 4; \ + fnc(__VA_ARGS__); \ + _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, JNI_ABORT); \ + return; \ + case RS_TYPE_FLOAT_64: \ + len = _env->GetArrayLength((jdoubleArray)data); \ + ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag); \ + typeBytes = 8; \ + fnc(__VA_ARGS__); \ + _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, JNI_ABORT);\ + return; \ + case RS_TYPE_SIGNED_8: \ + case RS_TYPE_UNSIGNED_8: \ + len = _env->GetArrayLength((jbyteArray)data); \ + ptr = _env->GetByteArrayElements((jbyteArray)data, flag); \ + typeBytes = 1; \ + fnc(__VA_ARGS__); \ + _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, JNI_ABORT); \ + return; \ + case RS_TYPE_SIGNED_16: \ + case RS_TYPE_UNSIGNED_16: \ + len = _env->GetArrayLength((jshortArray)data); \ + ptr = _env->GetShortArrayElements((jshortArray)data, flag); \ + typeBytes = 2; \ + fnc(__VA_ARGS__); \ + _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, JNI_ABORT); \ + return; \ + case RS_TYPE_SIGNED_32: \ + case RS_TYPE_UNSIGNED_32: \ + len = _env->GetArrayLength((jintArray)data); \ + ptr = _env->GetIntArrayElements((jintArray)data, flag); \ + typeBytes = 4; \ + fnc(__VA_ARGS__); \ + _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, JNI_ABORT); \ + return; \ + case RS_TYPE_SIGNED_64: \ + case RS_TYPE_UNSIGNED_64: \ + len = _env->GetArrayLength((jlongArray)data); \ + ptr = _env->GetLongArrayElements((jlongArray)data, flag); \ + typeBytes = 8; \ + fnc(__VA_ARGS__); \ + _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, JNI_ABORT); \ + return; \ + default: \ + break; \ + } \ +} + + +class AutoJavaStringToUTF8 { +public: + AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) { + fCStr = env->GetStringUTFChars(str, NULL); + fLength = env->GetStringUTFLength(str); + } + ~AutoJavaStringToUTF8() { + fEnv->ReleaseStringUTFChars(fJStr, fCStr); + } + const char* c_str() const { return fCStr; } + jsize length() const { return fLength; } + +private: + JNIEnv* fEnv; + jstring fJStr; + const char* fCStr; + jsize fLength; +}; + +class AutoJavaStringArrayToUTF8 { +public: + AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength) + : mEnv(env), mStrings(strings), mStringsLength(stringsLength) { + mCStrings = NULL; + mSizeArray = NULL; + if (stringsLength > 0) { + mCStrings = (const char **)calloc(stringsLength, sizeof(char *)); + mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t)); + for (jsize ct = 0; ct < stringsLength; ct ++) { + jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct); + mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL); + mSizeArray[ct] = mEnv->GetStringUTFLength(s); + } + } + } + ~AutoJavaStringArrayToUTF8() { + for (jsize ct=0; ct < mStringsLength; ct++) { + jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct); + mEnv->ReleaseStringUTFChars(s, mCStrings[ct]); + } + free(mCStrings); + free(mSizeArray); + } + const char **c_str() const { return mCStrings; } + size_t *c_str_len() const { return mSizeArray; } + jsize length() const { return mStringsLength; } + +private: + JNIEnv *mEnv; + jobjectArray mStrings; + const char **mCStrings; + size_t *mSizeArray; + jsize mStringsLength; +}; + +// --------------------------------------------------------------------------- + +static jfieldID gContextId = 0; +static jfieldID gNativeBitmapID = 0; +static jfieldID gTypeNativeCache = 0; + +static void _nInit(JNIEnv *_env, jclass _this) +{ + gContextId = _env->GetFieldID(_this, "mContext", "J"); + + jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); + gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "J"); +} + +// --------------------------------------------------------------------------- + +static void +nContextFinish(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextFinish, con(%p)", con); + rsContextFinish((RsContext)con); +} + +static void +nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str) +{ + LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj); + jint len = _env->GetArrayLength(str); + jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); + rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len); + _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); +} + +static jstring +nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj) +{ + LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj); + const char *name = NULL; + rsaGetName((RsContext)con, (void *)obj, &name); + if(name == NULL || strlen(name) == 0) { + return NULL; + } + return _env->NewStringUTF(name); +} + +static void +nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj) +{ + LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj); + rsObjDestroy((RsContext)con, (void *)obj); +} + +// --------------------------------------------------------------------------- + +static jlong +nDeviceCreate(JNIEnv *_env, jobject _this) +{ + LOG_API("nDeviceCreate"); + return (jint)rsDeviceCreate(); +} + +static void +nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev) +{ + LOG_API("nDeviceDestroy"); + return rsDeviceDestroy((RsDevice)dev); +} + +static void +nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value) +{ + LOG_API("nDeviceSetConfig dev(%p), param(%i), value(%i)", (void *)dev, p, value); + return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value); +} + +static jlong +nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, jint ct) +{ + LOG_API("nContextCreate"); + return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0); +} + +static jlong +nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, + int colorMin, int colorPref, + int alphaMin, int alphaPref, + int depthMin, int depthPref, + int stencilMin, int stencilPref, + int samplesMin, int samplesPref, float samplesQ, + int dpi) +{ + RsSurfaceConfig sc; + sc.alphaMin = alphaMin; + sc.alphaPref = alphaPref; + sc.colorMin = colorMin; + sc.colorPref = colorPref; + sc.depthMin = depthMin; + sc.depthPref = depthPref; + sc.samplesMin = samplesMin; + sc.samplesPref = samplesPref; + sc.samplesQ = samplesQ; + + LOG_API("nContextCreateGL"); + return (jint)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi); +} + +static void +nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p) +{ + LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p); + rsContextSetPriority((RsContext)con, p); +} + + + +static void +nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd) +{ + LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)wnd); + + ANativeWindow * window = NULL; + if (wnd == NULL) { + + } else { + window = android_view_Surface_getNativeWindow(_env, wnd).get(); + } + + rsContextSetSurface((RsContext)con, width, height, window); +} + +static void +nContextDestroy(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextDestroy, con(%p)", con); + rsContextDestroy((RsContext)con); +} + +static void +nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits) +{ + LOG_API("nContextDump, con(%p) bits(%i)", (RsContext)con, bits); + rsContextDump((RsContext)con, bits); +} + +static void +nContextPause(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextPause, con(%p)", con); + rsContextPause((RsContext)con); +} + +static void +nContextResume(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextResume, con(%p)", con); + rsContextResume((RsContext)con); +} + + +static jstring +nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextGetErrorMessage, con(%p)", con); + char buf[1024]; + + size_t receiveLen; + uint32_t subID; + int id = rsContextGetMessage((RsContext)con, + buf, sizeof(buf), + &receiveLen, sizeof(receiveLen), + &subID, sizeof(subID)); + if (!id && receiveLen) { + ALOGV("message receive buffer too small. %i", receiveLen); + } + return _env->NewStringUTF(buf); +} + +static jint +nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data) +{ + jint len = _env->GetArrayLength(data); + LOG_API("nContextGetMessage, con(%p), len(%i)", con, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + size_t receiveLen; + uint32_t subID; + int id = rsContextGetMessage((RsContext)con, + ptr, len * 4, + &receiveLen, sizeof(receiveLen), + &subID, sizeof(subID)); + if (!id && receiveLen) { + ALOGV("message receive buffer too small. %i", receiveLen); + } + _env->ReleaseIntArrayElements(data, ptr, 0); + return id; +} + +static jint +nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData) +{ + LOG_API("nContextPeekMessage, con(%p)", con); + jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL); + size_t receiveLen; + uint32_t subID; + int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen), + &subID, sizeof(subID)); + auxDataPtr[0] = (jint)subID; + auxDataPtr[1] = (jint)receiveLen; + _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0); + return id; +} + +static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextInitToClient, con(%p)", con); + rsContextInitToClient((RsContext)con); +} + +static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con) +{ + LOG_API("nContextDeinitToClient, con(%p)", con); + rsContextDeinitToClient((RsContext)con); +} + +static void +nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data) +{ + jint *ptr = NULL; + jint len = 0; + if (data) { + len = _env->GetArrayLength(data); + ptr = _env->GetIntArrayElements(data, NULL); + } + LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", con, id, len); + rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int)); + if (data) { + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); + } +} + + + +static jlong +nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size) +{ + LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size); + return (jlong)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size); +} + +static jlong +nElementCreate2(JNIEnv *_env, jobject _this, jlong con, + jintArray _ids, jobjectArray _names, jintArray _arraySizes) +{ + int fieldCount = _env->GetArrayLength(_ids); + LOG_API("nElementCreate2, con(%p)", con); + + jint *ids = _env->GetIntArrayElements(_ids, NULL); + jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL); + + AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount); + + const char **nameArray = names.c_str(); + size_t *sizeArray = names.c_str_len(); + + jlong id = (jlong)rsElementCreate2((RsContext)con, + (RsElement *)ids, fieldCount, + nameArray, fieldCount * sizeof(size_t), sizeArray, + (const uint32_t *)arraySizes, fieldCount); + + _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT); + _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT); + return (jint)id; +} + +static void +nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData) +{ + int dataSize = _env->GetArrayLength(_elementData); + LOG_API("nElementGetNativeData, con(%p)", con); + + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + assert(dataSize == 5); + + uint32_t elementData[5]; + rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize); + + for(jint i = 0; i < dataSize; i ++) { + _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]); + } +} + + +static void +nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id, + jintArray _IDs, + jobjectArray _names, + jintArray _arraySizes) +{ + int dataSize = _env->GetArrayLength(_IDs); + LOG_API("nElementGetSubElements, con(%p)", con); + + uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t)); + const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *)); + uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t)); + + rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize); + + for(jint i = 0; i < dataSize; i++) { + _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i])); + _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]); + _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]); + } + + free(ids); + free(names); + free(arraySizes); +} + +// ----------------------------------- + +static jlong +nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid, + jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv) +{ + LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)", + con, eid, dimx, dimy, dimz, mips, faces, yuv); + + return (jlong)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv); +} + +static void +nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _typeData) +{ + // We are packing 6 items: mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; into typeData + int elementCount = _env->GetArrayLength(_typeData); + + assert(elementCount == 6); + LOG_API("nTypeCreate, con(%p)", con); + + uint32_t typeData[6]; + rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6); + + for(jint i = 0; i < elementCount; i ++) { + _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]); + } +} + +// ----------------------------------- + +static jlong +nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jint pointer) +{ + LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer); + return (jint) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer); +} + +static void +nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits) +{ + LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits); + rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits); +} + +static jobject +nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a) +{ + LOG_API("nAllocationGetSurface, con(%p), a(%p)", con, (RsAllocation)a); + + IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a); + sp<IGraphicBufferProducer> bp = v; + v->decStrong(NULL); + + jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp); + return o; +} + +static void +nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur) +{ + LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", + con, alloc, (Surface *)sur); + + sp<Surface> s; + if (sur != 0) { + s = android_view_Surface_getSurface(_env, sur); + } + + rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, static_cast<ANativeWindow *>(s.get())); +} + +static void +nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc) +{ + LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc); + rsAllocationIoSend((RsContext)con, (RsAllocation)alloc); +} + +static void +nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc) +{ + LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc); + rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc); +} + + +static void +nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc) +{ + LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc); + rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc); +} + +static jlong +nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage) +{ + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + + bitmap.lockPixels(); + const void* ptr = bitmap.getPixels(); + jlong id = (jlong)rsAllocationCreateFromBitmap((RsContext)con, + (RsType)type, (RsAllocationMipmapControl)mip, + ptr, bitmap.getSize(), usage); + bitmap.unlockPixels(); + return id; +} + +static jlong +nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage) +{ + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + + bitmap.lockPixels(); + const void* ptr = bitmap.getPixels(); + jlong id = (jlong)rsAllocationCreateTyped((RsContext)con, + (RsType)type, (RsAllocationMipmapControl)mip, + (uint32_t)usage, (size_t)ptr); + bitmap.unlockPixels(); + return id; +} + +static jlong +nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage) +{ + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + + bitmap.lockPixels(); + const void* ptr = bitmap.getPixels(); + jlong id = (jlong)rsAllocationCubeCreateFromBitmap((RsContext)con, + (RsType)type, (RsAllocationMipmapControl)mip, + ptr, bitmap.getSize(), usage); + bitmap.unlockPixels(); + return id; +} + +static void +nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap) +{ + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + int w = bitmap.width(); + int h = bitmap.height(); + + bitmap.lockPixels(); + const void* ptr = bitmap.getPixels(); + rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, + 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, + w, h, ptr, bitmap.getSize(), 0); + bitmap.unlockPixels(); +} + +static void +nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap) +{ + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + + bitmap.lockPixels(); + void* ptr = bitmap.getPixels(); + rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize()); + bitmap.unlockPixels(); + bitmap.notifyPixelsChanged(); +} + +static void ReleaseBitmapCallback(void *bmp) +{ + SkBitmap const * nativeBitmap = (SkBitmap const *)bmp; + nativeBitmap->unlockPixels(); +} + + +static void +nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod, + jint count, jobject data, int sizeBytes, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i), dataType(%i)", + con, alloc, offset, count, len, sizeBytes, dataType); + PER_ARRAY_TYPE(NULL, rsAllocation1DData, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes); +} + +static void +// native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes); +nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes) +{ + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsAllocation1DElementData((RsContext)con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face, + jint w, jint h, jobject data, int sizeBytes, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face; + LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)", + con, alloc, xoff, yoff, w, h, sizeBytes, dataType); + PER_ARRAY_TYPE(NULL, rsAllocation2DData, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0); +} + +static void +nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con, + jlong dstAlloc, jint dstXoff, jint dstYoff, + jint dstMip, jint dstFace, + jint width, jint height, + jlong srcAlloc, jint srcXoff, jint srcYoff, + jint srcMip, jint srcFace) +{ + LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i)," + " dstMip(%i), dstFace(%i), width(%i), height(%i)," + " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)", + con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace, + width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace); + + rsAllocationCopy2DRange((RsContext)con, + (RsAllocation)dstAlloc, + dstXoff, dstYoff, + dstMip, dstFace, + width, height, + (RsAllocation)srcAlloc, + srcXoff, srcYoff, + srcMip, srcFace); +} + +static void +nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod, + jint w, jint h, jint d, jobject data, int sizeBytes, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i), h(%i), d(%i), sizeBytes(%i)", + con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, sizeBytes); + PER_ARRAY_TYPE(NULL, rsAllocation3DData, (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0); +} + +static void +nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con, + jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff, + jint dstMip, + jint width, jint height, jint depth, + jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff, + jint srcMip) +{ + LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i)," + " dstMip(%i), width(%i), height(%i)," + " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)", + con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace, + width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace); + + rsAllocationCopy3DRange((RsContext)con, + (RsAllocation)dstAlloc, + dstXoff, dstYoff, dstZoff, dstMip, + width, height, depth, + (RsAllocation)srcAlloc, + srcXoff, srcYoff, srcZoff, srcMip); +} + + +static void +nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + LOG_API("nAllocationRead, con(%p), alloc(%p)", con, (RsAllocation)alloc); + PER_ARRAY_TYPE(0, rsAllocationRead, (RsContext)con, alloc, ptr, len * typeBytes); +} + +static void +nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod, + jint count, jobject data, int sizeBytes, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i), dataType(%i)", + con, alloc, offset, count, len, sizeBytes, dataType); + PER_ARRAY_TYPE(0, rsAllocation1DRead, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes); +} + +static void +nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face, + jint w, jint h, jobject data, int sizeBytes, int dataType) +{ + RsAllocation *alloc = (RsAllocation *)_alloc; + RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face; + LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)", + con, alloc, xoff, yoff, w, h, sizeBytes, dataType); + PER_ARRAY_TYPE(0, rsAllocation2DRead, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0); +} + +static jlong +nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a) +{ + LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a); + return (jlong) rsaAllocationGetType((RsContext)con, (RsAllocation)a); +} + +static void +nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX) +{ + LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX); + rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX); +} + +// ----------------------------------- + +static jlong +nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset) +{ + ALOGV("______nFileA3D %u", (uint32_t) native_asset); + + Asset* asset = reinterpret_cast<Asset*>(native_asset); + + jlong id = (jlong)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength()); + return id; +} + +static jlong +nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path) +{ + AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr); + if (mgr == NULL) { + return 0; + } + + AutoJavaStringToUTF8 str(_env, _path); + Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); + if (asset == NULL) { + return 0; + } + + jlong id = (jlong)rsaFileA3DCreateFromAsset((RsContext)con, asset); + return id; +} + +static jlong +nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName) +{ + AutoJavaStringToUTF8 fileNameUTF(_env, fileName); + jlong id = (jlong)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str()); + + return id; +} + +static jint +nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D) +{ + int32_t numEntries = 0; + rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D); + return numEntries; +} + +static void +nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries) +{ + ALOGV("______nFileA3D %u", (uint32_t) fileA3D); + RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry)); + + rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D); + + for(jint i = 0; i < numEntries; i ++) { + _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName)); + _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID); + } + + free(fileEntries); +} + +static int +nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index) +{ + ALOGV("______nFileA3D %u", (uint32_t) fileA3D); + jint id = (jint)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D); + return id; +} + +// ----------------------------------- + +static int +nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con, + jstring fileName, jfloat fontSize, jint dpi) +{ + AutoJavaStringToUTF8 fileNameUTF(_env, fileName); + jint id = (jint)rsFontCreateFromFile((RsContext)con, + fileNameUTF.c_str(), fileNameUTF.length(), + fontSize, dpi); + + return id; +} + +static int +nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, + jstring name, jfloat fontSize, jint dpi, jint native_asset) +{ + Asset* asset = reinterpret_cast<Asset*>(native_asset); + AutoJavaStringToUTF8 nameUTF(_env, name); + + jint id = (jint)rsFontCreateFromMemory((RsContext)con, + nameUTF.c_str(), nameUTF.length(), + fontSize, dpi, + asset->getBuffer(false), asset->getLength()); + return id; +} + +static int +nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path, + jfloat fontSize, jint dpi) +{ + AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr); + if (mgr == NULL) { + return 0; + } + + AutoJavaStringToUTF8 str(_env, _path); + Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER); + if (asset == NULL) { + return 0; + } + + jint id = (jint)rsFontCreateFromMemory((RsContext)con, + str.c_str(), str.length(), + fontSize, dpi, + asset->getBuffer(false), asset->getLength()); + delete asset; + return id; +} + +// ----------------------------------- + +static void +nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot) +{ + LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot); + rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot); +} + +static void +nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val) +{ + LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val); + rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val); +} + +static jint +nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot) +{ + LOG_API("nScriptGetVarI, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + int value = 0; + rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value)); + return value; +} + +static void +nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val) +{ + LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val); + rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val); +} + +static void +nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val) +{ + LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val); + rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val); +} + +static jlong +nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot) +{ + LOG_API("nScriptGetVarJ, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jlong value = 0; + rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value)); + return value; +} + +static void +nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val) +{ + LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val); + rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val); +} + +static jfloat +nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot) +{ + LOG_API("nScriptGetVarF, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jfloat value = 0; + rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value)); + return value; +} + +static void +nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val) +{ + LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val); + rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val); +} + +static jdouble +nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot) +{ + LOG_API("nScriptGetVarD, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jdouble value = 0; + rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value)); + return value; +} + +static void +nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data) +{ + LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); +} + +static void +nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data) +{ + LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); +} + +static void +nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jlong elem, jintArray dims) +{ + LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + jint dimsLen = _env->GetArrayLength(dims) * sizeof(int); + jint *dimsPtr = _env->GetIntArrayElements(dims, NULL); + rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem, + (const size_t*) dimsPtr, dimsLen); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); + _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT); +} + + +static void +nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone) +{ + LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone); + + jint length = _env->GetArrayLength(timeZone); + jbyte* timeZone_ptr; + timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0); + + rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length); + + if (timeZone_ptr) { + _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0); + } +} + +static void +nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot) +{ + LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj); + rsScriptInvoke((RsContext)con, (RsScript)obj, slot); +} + +static void +nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data) +{ + LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); +} + +static void +nScriptForEach(JNIEnv *_env, jobject _this, jlong con, + jlong script, jint slot, jlong ain, jlong aout) +{ + LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0); +} +static void +nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, + jlong script, jint slot, jlong ain, jlong aout, jbyteArray params) +{ + LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(params); + jbyte *ptr = _env->GetByteArrayElements(params, NULL); + rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0); + _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT); +} + +static void +nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, + jlong script, jint slot, jlong ain, jlong aout, + jint xstart, jint xend, + jint ystart, jint yend, jint zstart, jint zend) +{ + LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + RsScriptCall sc; + sc.xStart = xstart; + sc.xEnd = xend; + sc.yStart = ystart; + sc.yEnd = yend; + sc.zStart = zstart; + sc.zEnd = zend; + sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; + sc.arrayStart = 0; + sc.arrayEnd = 0; + rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc)); +} + +static void +nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, + jlong script, jint slot, jlong ain, jlong aout, + jbyteArray params, jint xstart, jint xend, + jint ystart, jint yend, jint zstart, jint zend) +{ + LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(params); + jbyte *ptr = _env->GetByteArrayElements(params, NULL); + RsScriptCall sc; + sc.xStart = xstart; + sc.xEnd = xend; + sc.yStart = ystart; + sc.yEnd = yend; + sc.zStart = zstart; + sc.zEnd = zend; + sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; + sc.arrayStart = 0; + sc.arrayEnd = 0; + rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc)); + _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT); +} + +// ----------------------------------- + +static jint +nScriptCCreate(JNIEnv *_env, jobject _this, jlong con, + jstring resName, jstring cacheDir, + jbyteArray scriptRef, jint length) +{ + LOG_API("nScriptCCreate, con(%p)", con); + + AutoJavaStringToUTF8 resNameUTF(_env, resName); + AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); + jint ret = 0; + jbyte* script_ptr = NULL; + jint _exception = 0; + jint remaining; + if (!scriptRef) { + _exception = 1; + //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null"); + goto exit; + } + if (length < 0) { + _exception = 1; + //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0"); + goto exit; + } + remaining = _env->GetArrayLength(scriptRef); + if (remaining < length) { + _exception = 1; + //jniThrowException(_env, "java/lang/IllegalArgumentException", + // "length > script.length - offset"); + goto exit; + } + script_ptr = (jbyte *) + _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0); + + //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length); + + ret = (jint)rsScriptCCreate((RsContext)con, + resNameUTF.c_str(), resNameUTF.length(), + cacheDirUTF.c_str(), cacheDirUTF.length(), + (const char *)script_ptr, length); + +exit: + if (script_ptr) { + _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr, + _exception ? JNI_ABORT: 0); + } + + return ret; +} + +static jlong +nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid) +{ + LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", con, id, (void *)eid); + return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid); +} + +static jlong +nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig) +{ + LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con, (void *)sid, slot, sig); + return (jint)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig); +} + +static jlong +nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot) +{ + LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", con, (void *)sid, slot); + return (jint)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot); +} + +static jlong +nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _kernels, jintArray _src, + jintArray _dstk, jintArray _dstf, jintArray _types) +{ + LOG_API("nScriptGroupCreate, con(%p)", con); + + jint kernelsLen = _env->GetArrayLength(_kernels) * sizeof(int); + jint *kernelsPtr = _env->GetIntArrayElements(_kernels, NULL); + jint srcLen = _env->GetArrayLength(_src) * sizeof(int); + jint *srcPtr = _env->GetIntArrayElements(_src, NULL); + jint dstkLen = _env->GetArrayLength(_dstk) * sizeof(int); + jint *dstkPtr = _env->GetIntArrayElements(_dstk, NULL); + jint dstfLen = _env->GetArrayLength(_dstf) * sizeof(int); + jint *dstfPtr = _env->GetIntArrayElements(_dstf, NULL); + jint typesLen = _env->GetArrayLength(_types) * sizeof(int); + jint *typesPtr = _env->GetIntArrayElements(_types, NULL); + + int id = (int)rsScriptGroupCreate((RsContext)con, + (RsScriptKernelID *)kernelsPtr, kernelsLen, + (RsScriptKernelID *)srcPtr, srcLen, + (RsScriptKernelID *)dstkPtr, dstkLen, + (RsScriptFieldID *)dstfPtr, dstfLen, + (RsType *)typesPtr, typesLen); + + _env->ReleaseIntArrayElements(_kernels, kernelsPtr, 0); + _env->ReleaseIntArrayElements(_src, srcPtr, 0); + _env->ReleaseIntArrayElements(_dstk, dstkPtr, 0); + _env->ReleaseIntArrayElements(_dstf, dstfPtr, 0); + _env->ReleaseIntArrayElements(_types, typesPtr, 0); + return id; +} + +static void +nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc) +{ + LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", con, + (void *)gid, (void *)kid, (void *)alloc); + rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc); +} + +static void +nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc) +{ + LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", con, + (void *)gid, (void *)kid, (void *)alloc); + rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc); +} + +static void +nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid) +{ + LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", con, (void *)gid); + rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid); +} + +// --------------------------------------------------------------------------- + +static jint +nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con, + jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA, + jboolean depthMask, jboolean ditherEnable, + jint srcFunc, jint destFunc, + jint depthFunc) +{ + LOG_API("nProgramStoreCreate, con(%p)", con); + return (jint)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA, + depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc, + (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc); +} + +// --------------------------------------------------------------------------- + +static void +nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a) +{ + LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a); + rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a); +} + +static void +nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a) +{ + LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); + rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a); +} + +static void +nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a) +{ + LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); + rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a); +} + +// --------------------------------------------------------------------------- + +static jlong +nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader, + jobjectArray texNames, jintArray params) +{ + AutoJavaStringToUTF8 shaderUTF(_env, shader); + jint *paramPtr = _env->GetIntArrayElements(params, NULL); + jint paramLen = _env->GetArrayLength(params); + + int texCount = _env->GetArrayLength(texNames); + AutoJavaStringArrayToUTF8 names(_env, texNames, texCount); + const char ** nameArray = names.c_str(); + size_t* sizeArray = names.c_str_len(); + + LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen); + + jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(), + nameArray, texCount, sizeArray, + (uint32_t *)paramPtr, paramLen); + + _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT); + return ret; +} + + +// --------------------------------------------------------------------------- + +static jlong +nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader, + jobjectArray texNames, jintArray params) +{ + AutoJavaStringToUTF8 shaderUTF(_env, shader); + jint *paramPtr = _env->GetIntArrayElements(params, NULL); + jint paramLen = _env->GetArrayLength(params); + + LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", con, paramLen); + + int texCount = _env->GetArrayLength(texNames); + AutoJavaStringArrayToUTF8 names(_env, texNames, texCount); + const char ** nameArray = names.c_str(); + size_t* sizeArray = names.c_str_len(); + + jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(), + nameArray, texCount, sizeArray, + (uint32_t *)paramPtr, paramLen); + + _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT); + return ret; +} + +// --------------------------------------------------------------------------- + +static jlong +nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull) +{ + LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", con, pointSprite, cull); + return (jint)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull); +} + + +// --------------------------------------------------------------------------- + +static void +nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jint script) +{ + LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script); + rsContextBindRootScript((RsContext)con, (RsScript)script); +} + +static void +nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jint pfs) +{ + LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs); + rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs); +} + +static void +nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jint pf) +{ + LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf); + rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf); +} + +static void +nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jint pf) +{ + LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf); + rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf); +} + +static void +nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jint pf) +{ + LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf); + rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf); +} + + +// --------------------------------------------------------------------------- + +static jint +nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter, + jint wrapS, jint wrapT, jint wrapR, jfloat aniso) +{ + LOG_API("nSamplerCreate, con(%p)", con); + return (jint)rsSamplerCreate((RsContext)con, + (RsSamplerValue)magFilter, + (RsSamplerValue)minFilter, + (RsSamplerValue)wrapS, + (RsSamplerValue)wrapT, + (RsSamplerValue)wrapR, + aniso); +} + +// --------------------------------------------------------------------------- + +static jlong +nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jint _loop, jfloat q) { + LOG_API("nPathCreate, con(%p)", con); + + jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic, + (RsAllocation)_vtx, + (RsAllocation)_loop, q); + return id; +} + +static jlong +nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jintArray _vtx, jintArray _idx, jintArray _prim) +{ + LOG_API("nMeshCreate, con(%p)", con); + + jint vtxLen = _env->GetArrayLength(_vtx); + jint *vtxPtr = _env->GetIntArrayElements(_vtx, NULL); + jint idxLen = _env->GetArrayLength(_idx); + jint *idxPtr = _env->GetIntArrayElements(_idx, NULL); + jint primLen = _env->GetArrayLength(_prim); + jint *primPtr = _env->GetIntArrayElements(_prim, NULL); + + int id = (int)rsMeshCreate((RsContext)con, + (RsAllocation *)vtxPtr, vtxLen, + (RsAllocation *)idxPtr, idxLen, + (uint32_t *)primPtr, primLen); + + _env->ReleaseIntArrayElements(_vtx, vtxPtr, 0); + _env->ReleaseIntArrayElements(_idx, idxPtr, 0); + _env->ReleaseIntArrayElements(_prim, primPtr, 0); + return id; +} + +static jint +nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh) +{ + LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh); + jint vtxCount = 0; + rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount); + return vtxCount; +} + +static jint +nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh) +{ + LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh); + jint idxCount = 0; + rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount); + return idxCount; +} + +static void +nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _ids, int numVtxIDs) +{ + LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh); + + RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation)); + rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs); + + for(jint i = 0; i < numVtxIDs; i ++) { + _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]); + } + + free(allocs); +} + +static void +nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jintArray _idxIds, jintArray _primitives, int numIndices) +{ + LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh); + + RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation)); + uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t)); + + rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices); + + for(jint i = 0; i < numIndices; i ++) { + _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]); + _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]); + } + + free(allocs); + free(prims); +} + +// --------------------------------------------------------------------------- + + +static const char *classPathName = "android/renderscript/RenderScript"; + +static JNINativeMethod methods[] = { +{"_nInit", "()V", (void*)_nInit }, + +{"nDeviceCreate", "()J", (void*)nDeviceCreate }, +{"nDeviceDestroy", "(J)V", (void*)nDeviceDestroy }, +{"nDeviceSetConfig", "(JII)V", (void*)nDeviceSetConfig }, +{"nContextGetUserMessage", "(J[I)I", (void*)nContextGetUserMessage }, +{"nContextGetErrorMessage", "(J)Ljava/lang/String;", (void*)nContextGetErrorMessage }, +{"nContextPeekMessage", "(J[I)I", (void*)nContextPeekMessage }, + +{"nContextInitToClient", "(J)V", (void*)nContextInitToClient }, +{"nContextDeinitToClient", "(J)V", (void*)nContextDeinitToClient }, + + +// All methods below are thread protected in java. +{"rsnContextCreate", "(JIII)J", (void*)nContextCreate }, +{"rsnContextCreateGL", "(JIIIIIIIIIIIIFI)J", (void*)nContextCreateGL }, +{"rsnContextFinish", "(J)V", (void*)nContextFinish }, +{"rsnContextSetPriority", "(JI)V", (void*)nContextSetPriority }, +{"rsnContextSetSurface", "(JIILandroid/view/Surface;)V", (void*)nContextSetSurface }, +{"rsnContextDestroy", "(J)V", (void*)nContextDestroy }, +{"rsnContextDump", "(JI)V", (void*)nContextDump }, +{"rsnContextPause", "(J)V", (void*)nContextPause }, +{"rsnContextResume", "(J)V", (void*)nContextResume }, +{"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage }, +{"rsnAssignName", "(JJ[B)V", (void*)nAssignName }, +{"rsnGetName", "(JJ)Ljava/lang/String;", (void*)nGetName }, +{"rsnObjDestroy", "(JJ)V", (void*)nObjDestroy }, + +{"rsnFileA3DCreateFromFile", "(JLjava/lang/String;)J", (void*)nFileA3DCreateFromFile }, +{"rsnFileA3DCreateFromAssetStream", "(JI)J", (void*)nFileA3DCreateFromAssetStream }, +{"rsnFileA3DCreateFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J", (void*)nFileA3DCreateFromAsset }, +{"rsnFileA3DGetNumIndexEntries", "(JJ)I", (void*)nFileA3DGetNumIndexEntries }, +{"rsnFileA3DGetIndexEntries", "(JJI[I[Ljava/lang/String;)V", (void*)nFileA3DGetIndexEntries }, +{"rsnFileA3DGetEntryByIndex", "(JJI)I", (void*)nFileA3DGetEntryByIndex }, + +{"rsnFontCreateFromFile", "(JLjava/lang/String;FI)I", (void*)nFontCreateFromFile }, +{"rsnFontCreateFromAssetStream", "(JLjava/lang/String;FII)I", (void*)nFontCreateFromAssetStream }, +{"rsnFontCreateFromAsset", "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)I", (void*)nFontCreateFromAsset }, + +{"rsnElementCreate", "(JJIZI)J", (void*)nElementCreate }, +{"rsnElementCreate2", "(J[I[Ljava/lang/String;[I)J", (void*)nElementCreate2 }, +{"rsnElementGetNativeData", "(JJ[I)V", (void*)nElementGetNativeData }, +{"rsnElementGetSubElements", "(JJ[I[Ljava/lang/String;[I)V", (void*)nElementGetSubElements }, + +{"rsnTypeCreate", "(JJIIIZZI)J", (void*)nTypeCreate }, +{"rsnTypeGetNativeData", "(JJ[I)V", (void*)nTypeGetNativeData }, + +{"rsnAllocationCreateTyped", "(JJIII)J", (void*)nAllocationCreateTyped }, +{"rsnAllocationCreateFromBitmap", "(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCreateFromBitmap }, +{"rsnAllocationCreateBitmapBackedAllocation", "(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCreateBitmapBackedAllocation }, +{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCubeCreateFromBitmap }, + +{"rsnAllocationCopyFromBitmap", "(JJLandroid/graphics/Bitmap;)V", (void*)nAllocationCopyFromBitmap }, +{"rsnAllocationCopyToBitmap", "(JJLandroid/graphics/Bitmap;)V", (void*)nAllocationCopyToBitmap }, + +{"rsnAllocationSyncAll", "(JJI)V", (void*)nAllocationSyncAll }, +{"rsnAllocationGetSurface", "(JJ)Landroid/view/Surface;", (void*)nAllocationGetSurface }, +{"rsnAllocationSetSurface", "(JJLandroid/view/Surface;)V", (void*)nAllocationSetSurface }, +{"rsnAllocationIoSend", "(JJ)V", (void*)nAllocationIoSend }, +{"rsnAllocationIoReceive", "(JJ)V", (void*)nAllocationIoReceive }, +{"rsnAllocationData1D", "(JJIIILjava/lang/Object;II)V", (void*)nAllocationData1D }, +{"rsnAllocationElementData1D", "(JJIII[BI)V", (void*)nAllocationElementData1D }, +{"rsnAllocationData2D", "(JJIIIIIILjava/lang/Object;II)V", (void*)nAllocationData2D }, +{"rsnAllocationData2D", "(JJIIIIIIJIIII)V", (void*)nAllocationData2D_alloc }, +{"rsnAllocationData3D", "(JJIIIIIIILjava/lang/Object;II)V", (void*)nAllocationData3D }, +{"rsnAllocationData3D", "(JJIIIIIIIJIIII)V", (void*)nAllocationData3D_alloc }, +{"rsnAllocationRead", "(JJLjava/lang/Object;I)V", (void*)nAllocationRead }, +{"rsnAllocationRead1D", "(JJIIILjava/lang/Object;II)V", (void*)nAllocationRead1D }, +{"rsnAllocationRead2D", "(JJIIIIIILjava/lang/Object;II)V", (void*)nAllocationRead2D }, +{"rsnAllocationGetType", "(JJ)J", (void*)nAllocationGetType}, +{"rsnAllocationResize1D", "(JJI)V", (void*)nAllocationResize1D }, +{"rsnAllocationGenerateMipmaps", "(JJ)V", (void*)nAllocationGenerateMipmaps }, + +{"rsnScriptBindAllocation", "(JJJI)V", (void*)nScriptBindAllocation }, +{"rsnScriptSetTimeZone", "(JJ[B)V", (void*)nScriptSetTimeZone }, +{"rsnScriptInvoke", "(JJI)V", (void*)nScriptInvoke }, +{"rsnScriptInvokeV", "(JJI[B)V", (void*)nScriptInvokeV }, +{"rsnScriptForEach", "(JJIJJ)V", (void*)nScriptForEach }, +{"rsnScriptForEach", "(JJIJJ[B)V", (void*)nScriptForEachV }, +{"rsnScriptForEachClipped", "(JJIJJIIIIII)V", (void*)nScriptForEachClipped }, +{"rsnScriptForEachClipped", "(JJIJJ[BIIIIII)V", (void*)nScriptForEachClippedV }, +{"rsnScriptSetVarI", "(JJII)V", (void*)nScriptSetVarI }, +{"rsnScriptGetVarI", "(JJI)I", (void*)nScriptGetVarI }, +{"rsnScriptSetVarJ", "(JJIJ)V", (void*)nScriptSetVarJ }, +{"rsnScriptGetVarJ", "(JJI)J", (void*)nScriptGetVarJ }, +{"rsnScriptSetVarF", "(JJIF)V", (void*)nScriptSetVarF }, +{"rsnScriptGetVarF", "(JJI)F", (void*)nScriptGetVarF }, +{"rsnScriptSetVarD", "(JJID)V", (void*)nScriptSetVarD }, +{"rsnScriptGetVarD", "(JJI)D", (void*)nScriptGetVarD }, +{"rsnScriptSetVarV", "(JJI[B)V", (void*)nScriptSetVarV }, +{"rsnScriptGetVarV", "(JJI[B)V", (void*)nScriptGetVarV }, +{"rsnScriptSetVarVE", "(JJI[BJ[I)V", (void*)nScriptSetVarVE }, +{"rsnScriptSetVarObj", "(JJIJ)V", (void*)nScriptSetVarObj }, + +{"rsnScriptCCreate", "(JLjava/lang/String;Ljava/lang/String;[BI)I", (void*)nScriptCCreate }, +{"rsnScriptIntrinsicCreate", "(JIJ)J", (void*)nScriptIntrinsicCreate }, +{"rsnScriptKernelIDCreate", "(JJII)J", (void*)nScriptKernelIDCreate }, +{"rsnScriptFieldIDCreate", "(JJI)J", (void*)nScriptFieldIDCreate }, +{"rsnScriptGroupCreate", "(J[I[I[I[I[I)J", (void*)nScriptGroupCreate }, +{"rsnScriptGroupSetInput", "(JJJJ)V", (void*)nScriptGroupSetInput }, +{"rsnScriptGroupSetOutput", "(JJJJ)V", (void*)nScriptGroupSetOutput }, +{"rsnScriptGroupExecute", "(JJ)V", (void*)nScriptGroupExecute }, + +{"rsnProgramStoreCreate", "(JZZZZZZIII)I", (void*)nProgramStoreCreate }, + +{"rsnProgramBindConstants", "(JJIJ)V", (void*)nProgramBindConstants }, +{"rsnProgramBindTexture", "(JJIJ)V", (void*)nProgramBindTexture }, +{"rsnProgramBindSampler", "(JJIJ)V", (void*)nProgramBindSampler }, + +{"rsnProgramFragmentCreate", "(JLjava/lang/String;[Ljava/lang/String;[I)J", (void*)nProgramFragmentCreate }, +{"rsnProgramRasterCreate", "(JZI)J", (void*)nProgramRasterCreate }, +{"rsnProgramVertexCreate", "(JLjava/lang/String;[Ljava/lang/String;[I)J", (void*)nProgramVertexCreate }, + +{"rsnContextBindRootScript", "(JI)V", (void*)nContextBindRootScript }, +{"rsnContextBindProgramStore", "(JI)V", (void*)nContextBindProgramStore }, +{"rsnContextBindProgramFragment", "(JI)V", (void*)nContextBindProgramFragment }, +{"rsnContextBindProgramVertex", "(JI)V", (void*)nContextBindProgramVertex }, +{"rsnContextBindProgramRaster", "(JI)V", (void*)nContextBindProgramRaster }, + +{"rsnSamplerCreate", "(JIIIIIF)I", (void*)nSamplerCreate }, + +{"rsnPathCreate", "(JIZJIF)J", (void*)nPathCreate }, +{"rsnMeshCreate", "(J[I[I[I)J", (void*)nMeshCreate }, + +{"rsnMeshGetVertexBufferCount", "(JJ)I", (void*)nMeshGetVertexBufferCount }, +{"rsnMeshGetIndexCount", "(JJ)I", (void*)nMeshGetIndexCount }, +{"rsnMeshGetVertices", "(JJ[II)V", (void*)nMeshGetVertices }, +{"rsnMeshGetIndices", "(JJ[I[II)V", (void*)nMeshGetIndices }, + +}; + +static int registerFuncs(JNIEnv *_env) +{ + return android::AndroidRuntime::registerNativeMethods( + _env, classPathName, methods, NELEM(methods)); +} + +// --------------------------------------------------------------------------- + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + JNIEnv* env = NULL; + jint result = -1; + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + ALOGE("ERROR: GetEnv failed\n"); + goto bail; + } + assert(env != NULL); + + if (registerFuncs(env) < 0) { + ALOGE("ERROR: MediaPlayer native registration failed\n"); + goto bail; + } + + /* success -- return valid version number */ + result = JNI_VERSION_1_4; + +bail: + return result; +} |