| /* |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.renderscript; |
| |
| import java.io.File; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.util.concurrent.locks.ReentrantReadWriteLock; |
| import java.util.ArrayList; |
| import java.nio.ByteBuffer; |
| |
| import android.content.Context; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.PackageManager; |
| import android.content.res.AssetManager; |
| import android.graphics.Bitmap; |
| import android.graphics.BitmapFactory; |
| import android.os.Process; |
| import android.util.Log; |
| import android.view.Surface; |
| |
| /** |
| * This class provides access to a RenderScript context, which controls RenderScript |
| * initialization, resource management, and teardown. An instance of the RenderScript |
| * class must be created before any other RS objects can be created. |
| * |
| * <div class="special reference"> |
| * <h3>Developer Guides</h3> |
| * <p>For more information about creating an application that uses RenderScript, read the |
| * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> |
| * </div> |
| * |
| * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a |
| * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration |
| * guide</a> for the proposed alternatives. |
| **/ |
| @Deprecated |
| public class RenderScript { |
| static final String LOG_TAG = "RenderScript_jni"; |
| static final boolean DEBUG = false; |
| @SuppressWarnings({"UnusedDeclaration", "deprecation"}) |
| static final boolean LOG_ENABLED = false; |
| static final int SUPPORT_LIB_API = 23; |
| static final int SUPPORT_LIB_VERSION = 2301; |
| |
| static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>(); |
| private boolean mIsProcessContext = false; |
| private boolean mEnableMultiInput = false; |
| private int mDispatchAPILevel = 0; |
| |
| private int mContextFlags = 0; |
| private int mContextSdkVersion = 0; |
| |
| private Context mApplicationContext; |
| private String mNativeLibDir; |
| |
| static private String mDenyList = ""; |
| /** |
| * Sets the denylist of Models to only use support lib runtime. |
| * Should be used before context create. |
| * |
| * @param denylist User provided denylist string. |
| * |
| * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..." |
| * e.g. : To Denylist Nexus 7(2013) and Nexus 5. |
| * mDenyList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)"; |
| */ |
| static public void setDenyList(String denyList) { |
| if (denyList != null) { |
| mDenyList = denyList; |
| } |
| } |
| /** |
| * Force using support lib runtime. |
| * Should be used before context create. |
| * |
| */ |
| static public void forceCompat() { |
| sNative = 0; |
| } |
| /* |
| * We use a class initializer to allow the native code to cache some |
| * field offsets. |
| */ |
| @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) |
| static boolean sInitialized; |
| static boolean sUseGCHooks; |
| static Object sRuntime; |
| static Method registerNativeAllocation; |
| static Method registerNativeFree; |
| |
| static Object lock = new Object(); |
| |
| // Non-threadsafe functions. |
| native boolean nLoadSO(boolean useNative, int deviceApi, String libPath); |
| native boolean nLoadIOSO(); |
| native long nDeviceCreate(); |
| native void nDeviceDestroy(long dev); |
| native void nDeviceSetConfig(long dev, int param, int value); |
| native int nContextGetUserMessage(long con, int[] data); |
| native String nContextGetErrorMessage(long con); |
| native int nContextPeekMessage(long con, int[] subID); |
| native void nContextInitToClient(long con); |
| native void nContextDeinitToClient(long con); |
| |
| static private int sNative = -1; |
| static private int sSdkVersion = -1; |
| static private boolean useIOlib = false; |
| static private boolean useNative; |
| |
| /* |
| * Context creation flag that specifies a normal context. |
| * RenderScript Support lib only support normal context. |
| */ |
| public static final int CREATE_FLAG_NONE = 0x0000; |
| |
| int getDispatchAPILevel() { |
| return mDispatchAPILevel; |
| } |
| |
| boolean isUseNative() { |
| return useNative; |
| } |
| /* |
| * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing. |
| */ |
| static native int rsnSystemGetPointerSize(); |
| static int sPointerSize; |
| static public int getPointerSize() { |
| // We provide an accessor rather than making the data item public for two reasons. |
| // 1) Prevents anyone outside this class from writing the data item. |
| // 2) Prevents anyone outside this class from reading the data item unless a class |
| // instance has been created (ensuring the data item has been initialized). |
| // DISCLAIMER: Reflection can circumvent these preventive measures. |
| synchronized(lock) { |
| if (!sInitialized) |
| throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated"); |
| } |
| return sPointerSize; |
| } |
| |
| /** |
| * Determines whether or not we should be thunking into the native |
| * RenderScript layer or actually using the compatibility library. |
| */ |
| static private boolean setupNative(int sdkVersion, Context ctx) { |
| // if targetSdkVersion is higher than the device api version, always use compat mode. |
| // Workaround for KK |
| if (android.os.Build.VERSION.SDK_INT < sdkVersion && |
| android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { |
| sNative = 0; |
| } |
| |
| if (sNative == -1) { |
| |
| // get the value of the debug.rs.forcecompat property |
| int forcecompat = 0; |
| try { |
| Class<?> sysprop = Class.forName("android.os.SystemProperties"); |
| Class[] signature = {String.class, Integer.TYPE}; |
| Method getint = sysprop.getDeclaredMethod("getInt", signature); |
| Object[] args = {"debug.rs.forcecompat", new Integer(0)}; |
| forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue(); |
| } catch (Exception e) { |
| |
| } |
| |
| if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) |
| && forcecompat == 0) { |
| sNative = 1; |
| } else { |
| sNative = 0; |
| } |
| |
| |
| if (sNative == 1) { |
| // Workarounds that may disable thunking go here |
| ApplicationInfo info; |
| try { |
| info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), |
| PackageManager.GET_META_DATA); |
| } catch (PackageManager.NameNotFoundException e) { |
| // assume no workarounds needed |
| return true; |
| } |
| long minorVersion = 0; |
| |
| // load minorID from reflection |
| try { |
| Class<?> javaRS = Class.forName("android.renderscript.RenderScript"); |
| Method getMinorID = javaRS.getDeclaredMethod("getMinorID"); |
| minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue(); |
| } catch (Exception e) { |
| // minor version remains 0 on devices with no possible WARs |
| } |
| |
| if (info.metaData != null) { |
| // asynchronous teardown: minor version 1+ |
| if (info.metaData.getBoolean("androidx.renderscript.EnableAsyncTeardown") == true) { |
| if (minorVersion == 0) { |
| sNative = 0; |
| } |
| } |
| |
| // blur issues on some drivers with 4.4 |
| if (info.metaData.getBoolean("androidx.renderscript.EnableBlurWorkaround") == true) { |
| if (android.os.Build.VERSION.SDK_INT <= 19) { |
| //android.util.Log.e("rs", "war on"); |
| sNative = 0; |
| } |
| } |
| } |
| // end of workarounds |
| } |
| } |
| |
| if (sNative == 1) { |
| // check against the denylist |
| if (mDenyList.length() > 0) { |
| String deviceInfo = '(' + |
| android.os.Build.MANUFACTURER + |
| ':' + |
| android.os.Build.PRODUCT + |
| ':' + |
| android.os.Build.MODEL + |
| ')'; |
| if (mDenyList.contains(deviceInfo)) { |
| sNative = 0; |
| return false; |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Name of the file that holds the object cache. |
| */ |
| private static final String CACHE_PATH = "com.android.renderscript.cache"; |
| static String mCachePath; |
| |
| /** |
| * Sets the directory to use as a persistent storage for the |
| * renderscript object file cache. |
| * |
| * @hide |
| * @param cacheDir A directory the current process can write to |
| */ |
| public static void setupDiskCache(File cacheDir) { |
| File f = new File(cacheDir, CACHE_PATH); |
| mCachePath = f.getAbsolutePath(); |
| f.mkdirs(); |
| } |
| |
| /** |
| * ContextType specifies the specific type of context to be created. |
| * |
| */ |
| public enum ContextType { |
| /** |
| * NORMAL context, this is the default and what shipping apps should |
| * use. |
| */ |
| NORMAL (0), |
| |
| /** |
| * DEBUG context, perform extra runtime checks to validate the |
| * kernels and APIs are being used as intended. Get and SetElementAt |
| * will be bounds checked in this mode. |
| */ |
| DEBUG (1), |
| |
| /** |
| * PROFILE context, Intended to be used once the first time an |
| * application is run on a new device. This mode allows the runtime to |
| * do additional testing and performance tuning. |
| */ |
| PROFILE (2); |
| |
| int mID; |
| ContextType(int id) { |
| mID = id; |
| } |
| } |
| |
| ContextType mContextType; |
| // Methods below are wrapped to protect the non-threadsafe |
| // lockless fifo. |
| |
| native long rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir); |
| synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) { |
| return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir); |
| } |
| native void rsnContextDestroy(long con); |
| synchronized void nContextDestroy() { |
| validate(); |
| |
| // take teardown lock |
| // teardown lock can only be taken when no objects are being destroyed |
| ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock(); |
| wlock.lock(); |
| |
| long curCon = mContext; |
| // context is considered dead as of this point |
| mContext = 0; |
| |
| wlock.unlock(); |
| rsnContextDestroy(curCon); |
| } |
| native void rsnContextSetPriority(long con, int p); |
| synchronized void nContextSetPriority(int p) { |
| validate(); |
| rsnContextSetPriority(mContext, p); |
| } |
| native void rsnContextDump(long con, int bits); |
| synchronized void nContextDump(int bits) { |
| validate(); |
| rsnContextDump(mContext, bits); |
| } |
| native void rsnContextFinish(long con); |
| synchronized void nContextFinish() { |
| validate(); |
| rsnContextFinish(mContext); |
| } |
| |
| native void rsnContextSendMessage(long con, int id, int[] data); |
| synchronized void nContextSendMessage(int id, int[] data) { |
| validate(); |
| rsnContextSendMessage(mContext, id, data); |
| } |
| |
| // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers |
| native void rsnObjDestroy(long con, long id); |
| void nObjDestroy(long id) { |
| // There is a race condition here. The calling code may be run |
| // by the gc while teardown is occuring. This protects againts |
| // deleting dead objects. |
| if (mContext != 0) { |
| rsnObjDestroy(mContext, id); |
| } |
| } |
| |
| native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize); |
| synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) { |
| validate(); |
| return rsnElementCreate(mContext, type, kind, norm, vecSize); |
| } |
| native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes); |
| synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) { |
| validate(); |
| return rsnElementCreate2(mContext, elements, names, arraySizes); |
| } |
| native void rsnElementGetNativeData(long con, long id, int[] elementData); |
| synchronized void nElementGetNativeData(long id, int[] elementData) { |
| validate(); |
| rsnElementGetNativeData(mContext, id, elementData); |
| } |
| native void rsnElementGetSubElements(long con, long id, |
| long[] IDs, String[] names, int[] arraySizes); |
| synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) { |
| validate(); |
| rsnElementGetSubElements(mContext, id, IDs, names, arraySizes); |
| } |
| |
| native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv); |
| synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) { |
| validate(); |
| return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv); |
| } |
| |
| native void rsnTypeGetNativeData(long con, long id, long[] typeData); |
| synchronized void nTypeGetNativeData(long id, long[] typeData) { |
| validate(); |
| rsnTypeGetNativeData(mContext, id, typeData); |
| } |
| |
| native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer); |
| synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) { |
| validate(); |
| return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer); |
| } |
| native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); |
| synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) { |
| validate(); |
| return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage); |
| } |
| |
| native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage); |
| synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) { |
| validate(); |
| return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage); |
| } |
| |
| |
| native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); |
| synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) { |
| validate(); |
| return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage); |
| } |
| native long rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp); |
| synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) { |
| validate(); |
| return rsnAllocationCreateBitmapRef(mContext, type, bmp); |
| } |
| native long rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage); |
| synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) { |
| validate(); |
| return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage); |
| } |
| |
| native void rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp); |
| synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) { |
| validate(); |
| rsnAllocationCopyToBitmap(mContext, alloc, bmp); |
| } |
| |
| |
| native void rsnAllocationSyncAll(long con, long alloc, int src); |
| synchronized void nAllocationSyncAll(long alloc, int src) { |
| validate(); |
| rsnAllocationSyncAll(mContext, alloc, src); |
| } |
| |
| native void rsnAllocationSetSurface(long con, long alloc, Surface sur); |
| synchronized void nAllocationSetSurface(long alloc, Surface sur) { |
| validate(); |
| rsnAllocationSetSurface(mContext, alloc, sur); |
| } |
| |
| native void rsnAllocationIoSend(long con, long alloc); |
| synchronized void nAllocationIoSend(long alloc) { |
| validate(); |
| rsnAllocationIoSend(mContext, alloc); |
| } |
| native void rsnAllocationIoReceive(long con, long alloc); |
| synchronized void nAllocationIoReceive(long alloc) { |
| validate(); |
| rsnAllocationIoReceive(mContext, alloc); |
| } |
| native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ); |
| synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) { |
| validate(); |
| return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ); |
| } |
| native long rsnAllocationGetStride(long con, long alloc); |
| synchronized long nAllocationGetStride(long alloc) { |
| validate(); |
| return rsnAllocationGetStride(mContext, alloc); |
| } |
| |
| native void rsnAllocationGenerateMipmaps(long con, long alloc); |
| synchronized void nAllocationGenerateMipmaps(long alloc) { |
| validate(); |
| rsnAllocationGenerateMipmaps(mContext, alloc); |
| } |
| native void rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp); |
| synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) { |
| validate(); |
| rsnAllocationCopyFromBitmap(mContext, alloc, bmp); |
| } |
| |
| |
| native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt, |
| int mSize, boolean usePadding); |
| synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt, |
| int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding); |
| } |
| |
| native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes); |
| synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) { |
| validate(); |
| rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes); |
| } |
| /* |
| native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes); |
| synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) { |
| validate(); |
| rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes); |
| } |
| */ |
| |
| native void rsnAllocationData2D(long con, |
| long dstAlloc, int dstXoff, int dstYoff, |
| int dstMip, int dstFace, |
| int width, int height, |
| long srcAlloc, int srcXoff, int srcYoff, |
| int srcMip, int srcFace); |
| synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff, |
| int dstMip, int dstFace, |
| int width, int height, |
| long srcAlloc, int srcXoff, int srcYoff, |
| int srcMip, int srcFace) { |
| validate(); |
| rsnAllocationData2D(mContext, |
| dstAlloc, dstXoff, dstYoff, |
| dstMip, dstFace, |
| width, height, |
| srcAlloc, srcXoff, srcYoff, |
| srcMip, srcFace); |
| } |
| |
| native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, |
| int w, int h, Object d, int sizeBytes, int dt, |
| int mSize, boolean usePadding); |
| synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, |
| int w, int h, Object d, int sizeBytes, Element.DataType dt, |
| int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding); |
| } |
| |
| native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b); |
| synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) { |
| validate(); |
| rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b); |
| } |
| |
| native void rsnAllocationData3D(long con, |
| long dstAlloc, int dstXoff, int dstYoff, int dstZoff, |
| int dstMip, |
| int width, int height, int depth, |
| long srcAlloc, int srcXoff, int srcYoff, int srcZoff, |
| int srcMip); |
| synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff, |
| int dstMip, |
| int width, int height, int depth, |
| long srcAlloc, int srcXoff, int srcYoff, int srcZoff, |
| int srcMip) { |
| validate(); |
| rsnAllocationData3D(mContext, |
| dstAlloc, dstXoff, dstYoff, dstZoff, |
| dstMip, width, height, depth, |
| srcAlloc, srcXoff, srcYoff, srcZoff, srcMip); |
| } |
| |
| |
| native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip, |
| int w, int h, int depth, Object d, int sizeBytes, int dt, |
| int mSize, boolean usePadding); |
| synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip, |
| int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt, |
| int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, |
| dt.mID, mSize, usePadding); |
| } |
| |
| native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding); |
| synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding); |
| } |
| |
| native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d, |
| int sizeBytes, int dt, int mSize, boolean usePadding); |
| synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d, |
| int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding); |
| } |
| |
| /* |
| native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff, |
| int mip, int compIdx, byte[] d, int sizeBytes); |
| synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff, |
| int mip, int compIdx, byte[] d, int sizeBytes) { |
| validate(); |
| rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes); |
| } |
| */ |
| |
| native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face, |
| int w, int h, Object d, int sizeBytes, int dt, |
| int mSize, boolean usePadding); |
| synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face, |
| int w, int h, Object d, int sizeBytes, Element.DataType dt, |
| int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding); |
| } |
| |
| /* |
| native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip, |
| int w, int h, int depth, Object d, int sizeBytes, int dt, |
| int mSize, boolean usePadding); |
| synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip, |
| int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt, |
| int mSize, boolean usePadding) { |
| validate(); |
| rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding); |
| } |
| */ |
| |
| native long rsnAllocationGetType(long con, long id); |
| synchronized long nAllocationGetType(long id) { |
| validate(); |
| return rsnAllocationGetType(mContext, id); |
| } |
| |
| native void rsnAllocationResize1D(long con, long id, int dimX); |
| synchronized void nAllocationResize1D(long id, int dimX) { |
| validate(); |
| rsnAllocationResize1D(mContext, id, dimX); |
| } |
| native void rsnAllocationResize2D(long con, long id, int dimX, int dimY); |
| synchronized void nAllocationResize2D(long id, int dimX, int dimY) { |
| validate(); |
| rsnAllocationResize2D(mContext, id, dimX, dimY); |
| } |
| |
| native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc); |
| synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc); |
| } |
| native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc); |
| synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc); |
| } |
| native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc); |
| synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptInvoke(curCon, id, slot, mUseInc); |
| } |
| native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc); |
| native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc); |
| native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, |
| int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc); |
| native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, |
| int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc); |
| synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) { |
| validate(); |
| if (params == null) { |
| rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc); |
| } else { |
| rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc); |
| } |
| } |
| |
| synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params, |
| int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) { |
| validate(); |
| if (params == null) { |
| rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc); |
| } else { |
| rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc); |
| } |
| } |
| |
| native void rsnScriptForEach(long con, long id, int slot, long[] ains, |
| long aout, byte[] params, int[] limits); |
| |
| synchronized void nScriptForEach(long id, int slot, long[] ains, long aout, |
| byte[] params, int[] limits) { |
| if (!mEnableMultiInput) { |
| Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23"); |
| throw new RSRuntimeException("Multi-input kernels are not supported before API 23)"); |
| } |
| validate(); |
| rsnScriptForEach(mContext, id, slot, ains, aout, params, limits); |
| } |
| |
| native void rsnScriptReduce(long con, long id, int slot, long[] ains, |
| long aout, int[] limits); |
| synchronized void nScriptReduce(long id, int slot, long ains[], long aout, |
| int[] limits) { |
| validate(); |
| rsnScriptReduce(mContext, id, slot, ains, aout, limits); |
| } |
| |
| native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc); |
| synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptInvokeV(curCon, id, slot, params, mUseInc); |
| } |
| native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc); |
| synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarI(curCon, id, slot, val, mUseInc); |
| } |
| native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc); |
| synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarJ(curCon, id, slot, val, mUseInc); |
| } |
| native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc); |
| synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarF(curCon, id, slot, val, mUseInc); |
| } |
| native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc); |
| synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarD(curCon, id, slot, val, mUseInc); |
| } |
| native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc); |
| synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarV(curCon, id, slot, val, mUseInc); |
| } |
| native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val, |
| long e, int[] dims, boolean mUseInc); |
| synchronized void nScriptSetVarVE(long id, int slot, byte[] val, |
| long e, int[] dims, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc); |
| } |
| native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc); |
| synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| rsnScriptSetVarObj(curCon, id, slot, val, mUseInc); |
| } |
| |
| native long rsnScriptCCreate(long con, String resName, String cacheDir, |
| byte[] script, int length); |
| synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) { |
| validate(); |
| return rsnScriptCCreate(mContext, resName, cacheDir, script, length); |
| } |
| |
| native long rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc); |
| synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) { |
| validate(); |
| if (mUseInc) { |
| if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { |
| Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21"); |
| throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)"); |
| } |
| |
| if (!mIncLoaded) { |
| try { |
| System.loadLibrary("RSSupport"); |
| } catch (UnsatisfiedLinkError e) { |
| Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e); |
| throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e); |
| } |
| if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) { |
| throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support"); |
| } |
| mIncLoaded = true; |
| } |
| if (mIncCon == 0) { |
| //Create a placeholder compat context (synchronous). |
| long device = nIncDeviceCreate(); |
| mIncCon = nIncContextCreate(device, 0, 0, 0); |
| } |
| return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc); |
| } else { |
| return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc); |
| } |
| } |
| |
| native long rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc); |
| synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc); |
| } |
| |
| native long rsnScriptInvokeIDCreate(long con, long sid, int slot); |
| synchronized long nScriptInvokeIDCreate(long sid, int slot) { |
| validate(); |
| return rsnScriptInvokeIDCreate(mContext, sid, slot); |
| } |
| |
| native long rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc); |
| synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) { |
| validate(); |
| long curCon = mContext; |
| if (mUseInc) { |
| curCon = mIncCon; |
| } |
| return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc); |
| } |
| |
| native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types); |
| synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) { |
| validate(); |
| return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types); |
| } |
| |
| native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc); |
| synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) { |
| validate(); |
| rsnScriptGroupSetInput(mContext, group, kernel, alloc); |
| } |
| |
| native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc); |
| synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) { |
| validate(); |
| rsnScriptGroupSetOutput(mContext, group, kernel, alloc); |
| } |
| |
| native void rsnScriptGroupExecute(long con, long group); |
| synchronized void nScriptGroupExecute(long group) { |
| validate(); |
| rsnScriptGroupExecute(mContext, group); |
| } |
| |
| native long rsnSamplerCreate(long con, int magFilter, int minFilter, |
| int wrapS, int wrapT, int wrapR, float aniso); |
| synchronized long nSamplerCreate(int magFilter, int minFilter, |
| int wrapS, int wrapT, int wrapR, float aniso) { |
| validate(); |
| return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso); |
| } |
| |
| // entry points for ScriptGroup2 |
| native long rsnClosureCreate(long con, long kernelID, long returnValue, |
| long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, |
| long[] depFieldIDs); |
| synchronized long nClosureCreate(long kernelID, long returnValue, |
| long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, |
| long[] depFieldIDs) { |
| validate(); |
| long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, |
| sizes, depClosures, depFieldIDs); |
| if (c == 0) { |
| throw new RSRuntimeException("Failed creating closure."); |
| } |
| return c; |
| } |
| |
| native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, |
| long[] fieldIDs, long[] values, int[] sizes); |
| synchronized long nInvokeClosureCreate(long invokeID, byte[] params, |
| long[] fieldIDs, long[] values, int[] sizes) { |
| validate(); |
| long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs, |
| values, sizes); |
| if (c == 0) { |
| throw new RSRuntimeException("Failed creating closure."); |
| } |
| return c; |
| } |
| |
| native void rsnClosureSetArg(long con, long closureID, int index, |
| long value, int size); |
| synchronized void nClosureSetArg(long closureID, int index, long value, |
| int size) { |
| validate(); |
| rsnClosureSetArg(mContext, closureID, index, value, size); |
| } |
| |
| native void rsnClosureSetGlobal(long con, long closureID, long fieldID, |
| long value, int size); |
| // Does this have to be synchronized? |
| synchronized void nClosureSetGlobal(long closureID, long fieldID, |
| long value, int size) { |
| validate(); // TODO: is this necessary? |
| rsnClosureSetGlobal(mContext, closureID, fieldID, value, size); |
| } |
| |
| native long rsnScriptGroup2Create(long con, String name, String cachePath, |
| long[] closures); |
| synchronized long nScriptGroup2Create(String name, String cachePath, |
| long[] closures) { |
| validate(); |
| return rsnScriptGroup2Create(mContext, name, cachePath, closures); |
| } |
| |
| native void rsnScriptGroup2Execute(long con, long groupID); |
| synchronized void nScriptGroup2Execute(long groupID) { |
| validate(); |
| rsnScriptGroup2Execute(mContext, groupID); |
| } |
| |
| native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| float alpha, long A, long B, float beta, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc); |
| synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| float alpha, long A, long B, float beta, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc) { |
| validate(); |
| rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc); |
| } |
| |
| native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| double alpha, long A, long B, double beta, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc); |
| synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| double alpha, long A, long B, double beta, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc) { |
| validate(); |
| rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc); |
| } |
| |
| native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc); |
| synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc) { |
| validate(); |
| rsnScriptIntrinsicBLAS_Complex(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc); |
| } |
| |
| native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc); |
| synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA, |
| int TransB, int Side, int Uplo, int Diag, int M, int N, int K, |
| double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY, |
| int KL, int KU, boolean mUseInc) { |
| validate(); |
| rsnScriptIntrinsicBLAS_Z(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc); |
| } |
| |
| native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K, |
| long A, int a_offset, long B, int b_offset, long C, int c_offset, |
| int c_mult_int, boolean mUseInc); |
| synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K, |
| long A, int a_offset, long B, int b_offset, long C, int c_offset, |
| int c_mult_int, boolean mUseInc) { |
| validate(); |
| rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc); |
| } |
| |
| // Additional Entry points For inc libRSSupport |
| |
| native boolean nIncLoadSO(int deviceApi, String libPath); |
| native long nIncDeviceCreate(); |
| native void nIncDeviceDestroy(long dev); |
| // Methods below are wrapped to protect the non-threadsafe |
| // lockless fifo. |
| native long rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType); |
| synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) { |
| return rsnIncContextCreate(dev, ver, sdkVer, contextType); |
| } |
| native void rsnIncContextDestroy(long con); |
| synchronized void nIncContextDestroy() { |
| validate(); |
| |
| // take teardown lock |
| // teardown lock can only be taken when no objects are being destroyed |
| ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock(); |
| wlock.lock(); |
| |
| long curCon = mIncCon; |
| // context is considered dead as of this point |
| mIncCon = 0; |
| |
| wlock.unlock(); |
| rsnIncContextDestroy(curCon); |
| } |
| |
| native void rsnIncContextFinish(long con); |
| synchronized void nIncContextFinish() { |
| validate(); |
| rsnIncContextFinish(mIncCon); |
| } |
| |
| native void rsnIncObjDestroy(long con, long id); |
| void nIncObjDestroy(long id) { |
| // There is a race condition here. The calling code may be run |
| // by the gc while teardown is occuring. This protects againts |
| // deleting dead objects. |
| if (mIncCon != 0) { |
| rsnIncObjDestroy(mIncCon, id); |
| } |
| } |
| native long rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize); |
| synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) { |
| validate(); |
| return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize); |
| } |
| native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv); |
| synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) { |
| validate(); |
| return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv); |
| } |
| native long rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize); |
| synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) { |
| validate(); |
| return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize); |
| } |
| |
| long mContext; |
| private boolean mDestroyed = false; |
| //Placeholder device & context for Inc Support Lib |
| long mIncCon; |
| //indicator of whether inc support lib has been loaded or not. |
| boolean mIncLoaded; |
| ReentrantReadWriteLock mRWLock; |
| @SuppressWarnings({"FieldCanBeLocal"}) |
| MessageThread mMessageThread; |
| |
| Element mElement_U8; |
| Element mElement_I8; |
| Element mElement_U16; |
| Element mElement_I16; |
| Element mElement_U32; |
| Element mElement_I32; |
| Element mElement_U64; |
| Element mElement_I64; |
| Element mElement_F32; |
| Element mElement_F64; |
| Element mElement_BOOLEAN; |
| |
| Element mElement_ELEMENT; |
| Element mElement_TYPE; |
| Element mElement_ALLOCATION; |
| Element mElement_SAMPLER; |
| Element mElement_SCRIPT; |
| |
| Element mElement_A_8; |
| Element mElement_RGB_565; |
| Element mElement_RGB_888; |
| Element mElement_RGBA_5551; |
| Element mElement_RGBA_4444; |
| Element mElement_RGBA_8888; |
| |
| Element mElement_FLOAT_2; |
| Element mElement_FLOAT_3; |
| Element mElement_FLOAT_4; |
| |
| Element mElement_DOUBLE_2; |
| Element mElement_DOUBLE_3; |
| Element mElement_DOUBLE_4; |
| |
| Element mElement_UCHAR_2; |
| Element mElement_UCHAR_3; |
| Element mElement_UCHAR_4; |
| |
| Element mElement_CHAR_2; |
| Element mElement_CHAR_3; |
| Element mElement_CHAR_4; |
| |
| Element mElement_USHORT_2; |
| Element mElement_USHORT_3; |
| Element mElement_USHORT_4; |
| |
| Element mElement_SHORT_2; |
| Element mElement_SHORT_3; |
| Element mElement_SHORT_4; |
| |
| Element mElement_UINT_2; |
| Element mElement_UINT_3; |
| Element mElement_UINT_4; |
| |
| Element mElement_INT_2; |
| Element mElement_INT_3; |
| Element mElement_INT_4; |
| |
| Element mElement_ULONG_2; |
| Element mElement_ULONG_3; |
| Element mElement_ULONG_4; |
| |
| Element mElement_LONG_2; |
| Element mElement_LONG_3; |
| Element mElement_LONG_4; |
| |
| Element mElement_MATRIX_4X4; |
| Element mElement_MATRIX_3X3; |
| Element mElement_MATRIX_2X2; |
| |
| Sampler mSampler_CLAMP_NEAREST; |
| Sampler mSampler_CLAMP_LINEAR; |
| Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR; |
| Sampler mSampler_WRAP_NEAREST; |
| Sampler mSampler_WRAP_LINEAR; |
| Sampler mSampler_WRAP_LINEAR_MIP_LINEAR; |
| Sampler mSampler_MIRRORED_REPEAT_NEAREST; |
| Sampler mSampler_MIRRORED_REPEAT_LINEAR; |
| Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR; |
| |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| // |
| |
| /** |
| * The base class from which an application should derive in order |
| * to receive RS messages from scripts. When a script calls {@code |
| * rsSendToClient}, the data fields will be filled, and the run |
| * method will be called on a separate thread. This will occur |
| * some time after {@code rsSendToClient} completes in the script, |
| * as {@code rsSendToClient} is asynchronous. Message handlers are |
| * not guaranteed to have completed when {@link |
| * androidx.renderscript.RenderScript#finish} returns. |
| * |
| */ |
| public static class RSMessageHandler implements Runnable { |
| protected int[] mData; |
| protected int mID; |
| protected int mLength; |
| public void run() { |
| } |
| } |
| /** |
| * If an application is expecting messages, it should set this |
| * field to an instance of {@link RSMessageHandler}. This |
| * instance will receive all the user messages sent from {@code |
| * sendToClient} by scripts from this context. |
| * |
| */ |
| RSMessageHandler mMessageCallback = null; |
| |
| public void setMessageHandler(RSMessageHandler msg) { |
| mMessageCallback = msg; |
| } |
| public RSMessageHandler getMessageHandler() { |
| return mMessageCallback; |
| } |
| |
| /** |
| * Place a message into the message queue to be sent back to the message |
| * handler once all previous commands have been executed. |
| * |
| * @param id |
| * @param data |
| */ |
| public void sendMessage(int id, int[] data) { |
| nContextSendMessage(id, data); |
| } |
| |
| /** |
| * The runtime error handler base class. An application should derive from this class |
| * if it wishes to install an error handler. When errors occur at runtime, |
| * the fields in this class will be filled, and the run method will be called. |
| * |
| */ |
| public static class RSErrorHandler implements Runnable { |
| protected String mErrorMessage; |
| protected int mErrorNum; |
| public void run() { |
| } |
| } |
| |
| /** |
| * Application Error handler. All runtime errors will be dispatched to the |
| * instance of RSAsyncError set here. If this field is null a |
| * {@link RSRuntimeException} will instead be thrown with details about the error. |
| * This will cause program termaination. |
| * |
| */ |
| RSErrorHandler mErrorCallback = null; |
| |
| public void setErrorHandler(RSErrorHandler msg) { |
| mErrorCallback = msg; |
| } |
| public RSErrorHandler getErrorHandler() { |
| return mErrorCallback; |
| } |
| |
| /** |
| * RenderScript worker thread priority enumeration. The default value is |
| * NORMAL. Applications wishing to do background processing should set |
| * their priority to LOW to avoid starving forground processes. |
| */ |
| public enum Priority { |
| LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)), |
| NORMAL (Process.THREAD_PRIORITY_DISPLAY); |
| |
| int mID; |
| Priority(int id) { |
| mID = id; |
| } |
| } |
| |
| void validateObject(BaseObj o) { |
| if (o != null) { |
| if (o.mRS != this) { |
| throw new RSIllegalArgumentException("Attempting to use an object across contexts."); |
| } |
| } |
| } |
| |
| void validate() { |
| if (mContext == 0) { |
| throw new RSInvalidStateException("Calling RS with no Context active."); |
| } |
| } |
| |
| /** |
| * check if IO support lib is available. |
| */ |
| boolean usingIO() { |
| return useIOlib; |
| } |
| /** |
| * Change the priority of the worker threads for this context. |
| * |
| * @param p New priority to be set. |
| */ |
| public void setPriority(Priority p) { |
| validate(); |
| nContextSetPriority(p.mID); |
| } |
| |
| static class MessageThread extends Thread { |
| RenderScript mRS; |
| boolean mRun = true; |
| int[] mAuxData = new int[2]; |
| |
| static final int RS_MESSAGE_TO_CLIENT_NONE = 0; |
| static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1; |
| static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2; |
| static final int RS_MESSAGE_TO_CLIENT_ERROR = 3; |
| |
| static final int RS_MESSAGE_TO_CLIENT_USER = 4; |
| static final int RS_ERROR_FATAL_DEBUG = 0x800; |
| static final int RS_ERROR_FATAL_UNKNOWN = 0x1000; |
| |
| MessageThread(RenderScript rs) { |
| super("RSMessageThread"); |
| mRS = rs; |
| |
| } |
| |
| public void run() { |
| // This function is a temporary solution. The final solution will |
| // used typed allocations where the message id is the type indicator. |
| int[] rbuf = new int[16]; |
| mRS.nContextInitToClient(mRS.mContext); |
| while(mRun) { |
| rbuf[0] = 0; |
| int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData); |
| int size = mAuxData[1]; |
| int subID = mAuxData[0]; |
| |
| if (msg == RS_MESSAGE_TO_CLIENT_USER) { |
| if ((size>>2) >= rbuf.length) { |
| rbuf = new int[(size + 3) >> 2]; |
| } |
| if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) != |
| RS_MESSAGE_TO_CLIENT_USER) { |
| throw new RSDriverException("Error processing message from RenderScript."); |
| } |
| |
| if(mRS.mMessageCallback != null) { |
| mRS.mMessageCallback.mData = rbuf; |
| mRS.mMessageCallback.mID = subID; |
| mRS.mMessageCallback.mLength = size; |
| mRS.mMessageCallback.run(); |
| } else { |
| throw new RSInvalidStateException("Received a message from the script with no message handler installed."); |
| } |
| continue; |
| } |
| |
| if (msg == RS_MESSAGE_TO_CLIENT_ERROR) { |
| String e = mRS.nContextGetErrorMessage(mRS.mContext); |
| |
| // Copied from java/android/renderscript/RenderScript.java |
| // Throw RSRuntimeException under the following conditions: |
| // |
| // 1) It is an unknown fatal error. |
| // 2) It is a debug fatal error, and we are not in a |
| // debug context. |
| // 3) It is a debug fatal error, and we do not have an |
| // error callback. |
| if (subID >= RS_ERROR_FATAL_UNKNOWN || |
| (subID >= RS_ERROR_FATAL_DEBUG && |
| (mRS.mContextType != ContextType.DEBUG || |
| mRS.mErrorCallback == null))) { |
| android.util.Log.e(LOG_TAG, "fatal RS error, " + e); |
| throw new RSRuntimeException("Fatal error " + subID + ", details: " + e); |
| } |
| |
| if(mRS.mErrorCallback != null) { |
| mRS.mErrorCallback.mErrorMessage = e; |
| mRS.mErrorCallback.mErrorNum = subID; |
| mRS.mErrorCallback.run(); |
| } else { |
| android.util.Log.e(LOG_TAG, "non fatal RS error, " + e); |
| // Do not throw here. In these cases, we do not have |
| // a fatal error. |
| } |
| continue; |
| } |
| |
| // 2: teardown. |
| // But we want to avoid starving other threads during |
| // teardown by yielding until the next line in the destructor |
| // can execute to set mRun = false |
| try { |
| sleep(1, 0); |
| } catch(InterruptedException e) { |
| } |
| } |
| //Log.d(LOG_TAG, "MessageThread exiting."); |
| } |
| } |
| |
| RenderScript(Context ctx) { |
| mContextType = ContextType.NORMAL; |
| if (ctx != null) { |
| mApplicationContext = ctx.getApplicationContext(); |
| // Only set mNativeLibDir for API 9+. |
| mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir; |
| } |
| mIncCon = 0; |
| mIncLoaded = false; |
| mRWLock = new ReentrantReadWriteLock(); |
| } |
| |
| /** |
| * Gets the application context associated with the RenderScript context. |
| * |
| * @return The application context. |
| */ |
| public final Context getApplicationContext() { |
| return mApplicationContext; |
| } |
| |
| /** |
| * Create a RenderScript context. |
| * |
| * @param ctx The context. |
| * @return RenderScript |
| */ |
| private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) { |
| RenderScript rs = new RenderScript(ctx); |
| |
| if (sSdkVersion == -1) { |
| sSdkVersion = sdkVersion; |
| } else if (sSdkVersion != sdkVersion) { |
| throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib"); |
| } |
| useNative = setupNative(sSdkVersion, ctx); |
| synchronized(lock) { |
| if (sInitialized == false) { |
| try { |
| Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); |
| Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); |
| sRuntime = get_runtime.invoke(null); |
| Class<?> argClass = android.os.Build.VERSION.SDK_INT >= 29 ? Long.TYPE : Integer.TYPE; |
| // The int version is (so far) always defined, but deprecated for APIs >= 29. |
| registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", argClass); |
| registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", argClass); |
| sUseGCHooks = true; |
| } catch (Exception e) { |
| Log.e(LOG_TAG, "No GC methods"); |
| sUseGCHooks = false; |
| } |
| try { |
| // For API 9 - 22, always use the absolute path of librsjni.so |
| // http://b/25226912 |
| if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && |
| rs.mNativeLibDir != null) { |
| System.load(rs.mNativeLibDir + "/librsjni.so"); |
| } else { |
| System.loadLibrary("rsjni"); |
| } |
| sInitialized = true; |
| sPointerSize = rsnSystemGetPointerSize(); |
| } catch (UnsatisfiedLinkError e) { |
| Log.e(LOG_TAG, "Error loading RS jni library: " + e); |
| throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION); |
| } |
| } |
| } |
| |
| if (useNative) { |
| android.util.Log.v(LOG_TAG, "RS native mode"); |
| } else { |
| android.util.Log.v(LOG_TAG, "RS compat mode"); |
| } |
| |
| if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { |
| useIOlib = true; |
| } |
| |
| // The target API level used to init dispatchTable. |
| int dispatchAPI = sdkVersion; |
| if (sdkVersion < android.os.Build.VERSION.SDK_INT) { |
| // If the device API is higher than target API level, init dispatch table based on device API. |
| dispatchAPI = android.os.Build.VERSION.SDK_INT; |
| } |
| |
| String rssupportPath = null; |
| // For API 9 - 22, always use the absolute path of libRSSupport.so |
| // http://b/25226912 |
| if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && |
| rs.mNativeLibDir != null) { |
| rssupportPath = rs.mNativeLibDir + "/libRSSupport.so"; |
| } |
| if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) { |
| if (useNative) { |
| android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode"); |
| useNative = false; |
| } |
| try { |
| if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && |
| rs.mNativeLibDir != null) { |
| System.load(rssupportPath); |
| } else { |
| System.loadLibrary("RSSupport"); |
| } |
| } catch (UnsatisfiedLinkError e) { |
| Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION); |
| throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION); |
| } |
| if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) { |
| Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION); |
| throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION); |
| } |
| } |
| |
| if (useIOlib) { |
| try { |
| System.loadLibrary("RSSupportIO"); |
| } catch (UnsatisfiedLinkError e) { |
| useIOlib = false; |
| } |
| if (!useIOlib || !rs.nLoadIOSO()) { |
| android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported"); |
| useIOlib = false; |
| } |
| } |
| |
| // For old APIs with dlopen bug, need to load blas lib in Java first. |
| // Only try load to blasV8 when the desired API level includes IntrinsicBLAS. |
| if (dispatchAPI >= 23) { |
| // Enable multi-input kernels only when diapatchAPI is M+. |
| rs.mEnableMultiInput = true; |
| try { |
| System.loadLibrary("blasV8"); |
| } catch (UnsatisfiedLinkError e) { |
| Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e); |
| } |
| } |
| |
| long device = rs.nDeviceCreate(); |
| rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir); |
| rs.mContextType = ct; |
| rs.mContextFlags = flags; |
| rs.mContextSdkVersion = sdkVersion; |
| rs.mDispatchAPILevel = dispatchAPI; |
| if (rs.mContext == 0) { |
| throw new RSDriverException("Failed to create RS context."); |
| } |
| rs.mMessageThread = new MessageThread(rs); |
| rs.mMessageThread.start(); |
| return rs; |
| } |
| |
| /** |
| * Create a RenderScript context. |
| * |
| * See documentation for @create for details |
| * |
| * @param ctx The context. |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx) { |
| return create(ctx, ContextType.NORMAL); |
| } |
| |
| /** |
| * calls create(ctx, ct, CREATE_FLAG_NONE) |
| * |
| * See documentation for @create for details |
| * |
| * @param ctx The context. |
| * @param ct The type of context to be created. |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx, ContextType ct) { |
| return create(ctx, ct, CREATE_FLAG_NONE); |
| } |
| |
| /** |
| * Gets or creates a RenderScript context of the specified type. |
| * |
| * The returned context will be cached for future reuse within |
| * the process. When an application is finished using |
| * RenderScript it should call releaseAllContexts() |
| * |
| * A process context is a context designed for easy creation and |
| * lifecycle management. Multiple calls to this function will |
| * return the same object provided they are called with the same |
| * options. This allows it to be used any time a RenderScript |
| * context is needed. |
| * |
| * |
| * @param ctx The context. |
| * @param ct The type of context to be created. |
| * @param flags The OR of the CREATE_FLAG_* options desired |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx, ContextType ct, int flags) { |
| int v = ctx.getApplicationInfo().targetSdkVersion; |
| return create(ctx, v, ct, flags); |
| } |
| |
| /** |
| * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE) |
| * |
| * Used by the RenderScriptThunker to maintain backward compatibility. |
| * |
| * @hide |
| * @param ctx The context. |
| * @param sdkVersion The target SDK Version. |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx, int sdkVersion) { |
| return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE); |
| } |
| |
| |
| /** |
| * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE) |
| * Create a RenderScript context. |
| * |
| * @hide |
| * @param ctx The context. |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) { |
| return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE); |
| } |
| |
| /** |
| * Gets or creates a RenderScript context of the specified type. |
| * |
| * @param ctx The context. |
| * @param ct The type of context to be created. |
| * @param sdkVersion The target SDK Version. |
| * @param flags The OR of the CREATE_FLAG_* options desired |
| * @return RenderScript |
| */ |
| public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) { |
| synchronized (mProcessContextList) { |
| for (RenderScript prs : mProcessContextList) { |
| if ((prs.mContextType == ct) && |
| (prs.mContextFlags == flags) && |
| (prs.mContextSdkVersion == sdkVersion)) { |
| |
| return prs; |
| } |
| } |
| |
| RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags); |
| prs.mIsProcessContext = true; |
| mProcessContextList.add(prs); |
| return prs; |
| } |
| } |
| |
| /** |
| * |
| * Releases all the process contexts. This is the same as |
| * calling .destroy() on each unique context retreived with |
| * create(...). If no contexts have been created this |
| * function does nothing. |
| * |
| * Typically you call this when your application is losing focus |
| * and will not be using a context for some time. |
| * |
| * This has no effect on a context created with |
| * createMultiContext() |
| */ |
| public static void releaseAllContexts() { |
| ArrayList<RenderScript> oldList; |
| synchronized (mProcessContextList) { |
| oldList = mProcessContextList; |
| mProcessContextList = new ArrayList<RenderScript>(); |
| } |
| |
| for (RenderScript prs : oldList) { |
| prs.mIsProcessContext = false; |
| prs.destroy(); |
| } |
| oldList.clear(); |
| } |
| |
| |
| |
| /** |
| * Create a RenderScript context. |
| * |
| * This is an advanced function intended for applications which |
| * need to create more than one RenderScript context to be used |
| * at the same time. |
| * |
| * If you need a single context please use create() |
| * |
| * @param ctx The context. |
| * @return RenderScript |
| */ |
| public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) { |
| return internalCreate(ctx, API_number, ct, flags); |
| } |
| |
| /** |
| * Print the currently available debugging information about the state of |
| * the RS context to the log. |
| * |
| */ |
| public void contextDump() { |
| validate(); |
| nContextDump(0); |
| } |
| |
| /** |
| * Wait for any pending asynchronous opeations (such as copies to a RS |
| * allocation or RS script executions) to complete. |
| * |
| */ |
| public void finish() { |
| nContextFinish(); |
| } |
| |
| private void helpDestroy() { |
| boolean shouldDestroy = false; |
| synchronized(this) { |
| if (!mDestroyed) { |
| shouldDestroy = true; |
| mDestroyed = true; |
| } |
| } |
| |
| if (shouldDestroy) { |
| nContextFinish(); |
| if (mIncCon != 0) { |
| nIncContextFinish(); |
| nIncContextDestroy(); |
| mIncCon = 0; |
| } |
| nContextDeinitToClient(mContext); |
| mMessageThread.mRun = false; |
| // Interrupt mMessageThread so it gets to see immediately that mRun is false |
| // and exit rightaway. |
| mMessageThread.interrupt(); |
| |
| // Wait for mMessageThread to join. Try in a loop, in case this thread gets interrupted |
| // during the wait. If interrupted, set the "interrupted" status of the current thread. |
| boolean hasJoined = false, interrupted = false; |
| while (!hasJoined) { |
| try { |
| mMessageThread.join(); |
| hasJoined = true; |
| } catch (InterruptedException e) { |
| interrupted = true; |
| } |
| } |
| if (interrupted) { |
| Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join"); |
| Thread.currentThread().interrupt(); |
| } |
| |
| nContextDestroy(); |
| } |
| } |
| |
| @Override |
| protected void finalize() throws Throwable { |
| helpDestroy(); |
| super.finalize(); |
| } |
| |
| /** |
| * Destroys this RenderScript context. Once this function is called, |
| * using this context or any objects belonging to this context is |
| * illegal. |
| * |
| * This function is a NOP if the context was created |
| * with create(). Please use releaseAllContexts() to clean up |
| * contexts created with the create function. |
| */ |
| public void destroy() { |
| if (mIsProcessContext) { |
| // users cannot destroy a process context |
| return; |
| } |
| validate(); |
| helpDestroy(); |
| } |
| |
| boolean isAlive() { |
| return mContext != 0; |
| } |
| |
| long safeID(BaseObj o) { |
| if(o != null) { |
| return o.getID(this); |
| } |
| return 0; |
| } |
| } |