1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.renderscript;
18 
19 import java.io.File;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.util.concurrent.locks.ReentrantReadWriteLock;
23 import java.util.ArrayList;
24 import java.nio.ByteBuffer;
25 
26 import android.content.Context;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.PackageManager;
29 import android.content.res.AssetManager;
30 import android.graphics.Bitmap;
31 import android.graphics.BitmapFactory;
32 import android.os.Process;
33 import android.util.Log;
34 import android.view.Surface;
35 
36 /**
37  * This class provides access to a RenderScript context, which controls RenderScript
38  * initialization, resource management, and teardown. An instance of the RenderScript
39  * class must be created before any other RS objects can be created.
40  *
41  * <div class="special reference">
42  * <h3>Developer Guides</h3>
43  * <p>For more information about creating an application that uses RenderScript, read the
44  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
45  * </div>
46  *
47  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
48  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
49  * guide</a> for the proposed alternatives.
50  **/
51 @Deprecated
52 public class RenderScript {
53     static final String LOG_TAG = "RenderScript_jni";
54     static final boolean DEBUG  = false;
55     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
56     static final boolean LOG_ENABLED = false;
57     static final int SUPPORT_LIB_API = 23;
58     static final int SUPPORT_LIB_VERSION = 2301;
59 
60     static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
61     private boolean mIsProcessContext = false;
62     private boolean mEnableMultiInput = false;
63     private int mDispatchAPILevel = 0;
64 
65     private int mContextFlags = 0;
66     private int mContextSdkVersion = 0;
67 
68     private Context mApplicationContext;
69     private String mNativeLibDir;
70 
71     static private String mDenyList = "";
72      /**
73      * Sets the denylist of Models to only use support lib runtime.
74      * Should be used before context create.
75      *
76      * @param denylist User provided denylist string.
77      *
78      * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..."
79      * e.g. : To Denylist Nexus 7(2013) and Nexus 5.
80      *        mDenyList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)";
81      */
setDenyList(String denyList)82     static public void setDenyList(String denyList) {
83         if (denyList != null) {
84             mDenyList = denyList;
85         }
86     }
87      /**
88      * Force using support lib runtime.
89      * Should be used before context create.
90      *
91      */
forceCompat()92     static public void forceCompat() {
93         sNative = 0;
94     }
95     /*
96      * We use a class initializer to allow the native code to cache some
97      * field offsets.
98      */
99     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
100     static boolean sInitialized;
101     static boolean sUseGCHooks;
102     static Object sRuntime;
103     static Method registerNativeAllocation;
104     static Method registerNativeFree;
105 
106     static Object lock = new Object();
107 
108     // Non-threadsafe functions.
nLoadSO(boolean useNative, int deviceApi, String libPath)109     native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
nLoadIOSO()110     native boolean nLoadIOSO();
nDeviceCreate()111     native long nDeviceCreate();
nDeviceDestroy(long dev)112     native void nDeviceDestroy(long dev);
nDeviceSetConfig(long dev, int param, int value)113     native void nDeviceSetConfig(long dev, int param, int value);
nContextGetUserMessage(long con, int[] data)114     native int nContextGetUserMessage(long con, int[] data);
nContextGetErrorMessage(long con)115     native String nContextGetErrorMessage(long con);
nContextPeekMessage(long con, int[] subID)116     native int  nContextPeekMessage(long con, int[] subID);
nContextInitToClient(long con)117     native void nContextInitToClient(long con);
nContextDeinitToClient(long con)118     native void nContextDeinitToClient(long con);
119 
120     static private int sNative = -1;
121     static private int sSdkVersion = -1;
122     static private boolean useIOlib = false;
123     static private boolean useNative;
124 
125     /*
126      * Context creation flag that specifies a normal context.
127      * RenderScript Support lib only support normal context.
128      */
129     public static final int CREATE_FLAG_NONE = 0x0000;
130 
getDispatchAPILevel()131     int getDispatchAPILevel() {
132         return mDispatchAPILevel;
133     }
134 
isUseNative()135     boolean isUseNative() {
136         return useNative;
137     }
138     /*
139      * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing.
140      */
rsnSystemGetPointerSize()141     static native int rsnSystemGetPointerSize();
142     static int sPointerSize;
getPointerSize()143     static public int getPointerSize() {
144         // We provide an accessor rather than making the data item public for two reasons.
145         // 1) Prevents anyone outside this class from writing the data item.
146         // 2) Prevents anyone outside this class from reading the data item unless a class
147         //    instance has been created (ensuring the data item has been initialized).
148         // DISCLAIMER: Reflection can circumvent these preventive measures.
149         synchronized(lock) {
150             if (!sInitialized)
151                 throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated");
152         }
153         return sPointerSize;
154     }
155 
156     /**
157      * Determines whether or not we should be thunking into the native
158      * RenderScript layer or actually using the compatibility library.
159      */
setupNative(int sdkVersion, Context ctx)160     static private boolean setupNative(int sdkVersion, Context ctx) {
161         // if targetSdkVersion is higher than the device api version, always use compat mode.
162         // Workaround for KK
163         if (android.os.Build.VERSION.SDK_INT < sdkVersion &&
164             android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
165             sNative = 0;
166         }
167 
168         if (sNative == -1) {
169 
170             // get the value of the debug.rs.forcecompat property
171             int forcecompat = 0;
172             try {
173                 Class<?> sysprop = Class.forName("android.os.SystemProperties");
174                 Class[] signature = {String.class, Integer.TYPE};
175                 Method getint = sysprop.getDeclaredMethod("getInt", signature);
176                 Object[] args = {"debug.rs.forcecompat", new Integer(0)};
177                 forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
178             } catch (Exception e) {
179 
180             }
181 
182             if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
183                      && forcecompat == 0) {
184                 sNative = 1;
185             } else {
186                 sNative = 0;
187             }
188 
189 
190             if (sNative == 1) {
191                 // Workarounds that may disable thunking go here
192                 ApplicationInfo info;
193                 try {
194                     info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
195                                                                       PackageManager.GET_META_DATA);
196                 } catch (PackageManager.NameNotFoundException e) {
197                     // assume no workarounds needed
198                     return true;
199                 }
200                 long minorVersion = 0;
201 
202                 // load minorID from reflection
203                 try {
204                     Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
205                     Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
206                     minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
207                 } catch (Exception e) {
208                     // minor version remains 0 on devices with no possible WARs
209                 }
210 
211                 if (info.metaData != null) {
212                     // asynchronous teardown: minor version 1+
213                     if (info.metaData.getBoolean("androidx.renderscript.EnableAsyncTeardown") == true) {
214                         if (minorVersion == 0) {
215                             sNative = 0;
216                         }
217                     }
218 
219                     // blur issues on some drivers with 4.4
220                     if (info.metaData.getBoolean("androidx.renderscript.EnableBlurWorkaround") == true) {
221                         if (android.os.Build.VERSION.SDK_INT <= 19) {
222                             //android.util.Log.e("rs", "war on");
223                             sNative = 0;
224                         }
225                     }
226                 }
227                 // end of workarounds
228             }
229         }
230 
231         if (sNative == 1) {
232             // check against the denylist
233             if (mDenyList.length() > 0) {
234                 String deviceInfo = '(' +
235                                     android.os.Build.MANUFACTURER +
236                                     ':' +
237                                     android.os.Build.PRODUCT +
238                                     ':' +
239                                     android.os.Build.MODEL +
240                                     ')';
241                 if (mDenyList.contains(deviceInfo)) {
242                     sNative = 0;
243                     return false;
244                 }
245             }
246             return true;
247         }
248         return false;
249     }
250 
251     /**
252      * Name of the file that holds the object cache.
253      */
254     private static final String CACHE_PATH = "com.android.renderscript.cache";
255     static String mCachePath;
256 
257      /**
258      * Sets the directory to use as a persistent storage for the
259      * renderscript object file cache.
260      *
261      * @hide
262      * @param cacheDir A directory the current process can write to
263      */
setupDiskCache(File cacheDir)264     public static void setupDiskCache(File cacheDir) {
265         File f = new File(cacheDir, CACHE_PATH);
266         mCachePath = f.getAbsolutePath();
267         f.mkdirs();
268     }
269 
270     /**
271      * ContextType specifies the specific type of context to be created.
272      *
273      */
274     public enum ContextType {
275         /**
276          * NORMAL context, this is the default and what shipping apps should
277          * use.
278          */
279         NORMAL (0),
280 
281         /**
282          * DEBUG context, perform extra runtime checks to validate the
283          * kernels and APIs are being used as intended.  Get and SetElementAt
284          * will be bounds checked in this mode.
285          */
286         DEBUG (1),
287 
288         /**
289          * PROFILE context, Intended to be used once the first time an
290          * application is run on a new device.  This mode allows the runtime to
291          * do additional testing and performance tuning.
292          */
293         PROFILE (2);
294 
295         int mID;
ContextType(int id)296         ContextType(int id) {
297             mID = id;
298         }
299     }
300 
301     ContextType mContextType;
302     // Methods below are wrapped to protect the non-threadsafe
303     // lockless fifo.
304 
rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir)305     native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir)306     synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
307         return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
308     }
rsnContextDestroy(long con)309     native void rsnContextDestroy(long con);
nContextDestroy()310     synchronized void nContextDestroy() {
311         validate();
312 
313         // take teardown lock
314         // teardown lock can only be taken when no objects are being destroyed
315         ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
316         wlock.lock();
317 
318         long curCon = mContext;
319         // context is considered dead as of this point
320         mContext = 0;
321 
322         wlock.unlock();
323         rsnContextDestroy(curCon);
324     }
rsnContextSetPriority(long con, int p)325     native void rsnContextSetPriority(long con, int p);
nContextSetPriority(int p)326     synchronized void nContextSetPriority(int p) {
327         validate();
328         rsnContextSetPriority(mContext, p);
329     }
rsnContextDump(long con, int bits)330     native void rsnContextDump(long con, int bits);
nContextDump(int bits)331     synchronized void nContextDump(int bits) {
332         validate();
333         rsnContextDump(mContext, bits);
334     }
rsnContextFinish(long con)335     native void rsnContextFinish(long con);
nContextFinish()336     synchronized void nContextFinish() {
337         validate();
338         rsnContextFinish(mContext);
339     }
340 
rsnContextSendMessage(long con, int id, int[] data)341     native void rsnContextSendMessage(long con, int id, int[] data);
nContextSendMessage(int id, int[] data)342     synchronized void nContextSendMessage(int id, int[] data) {
343         validate();
344         rsnContextSendMessage(mContext, id, data);
345     }
346 
347     // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
rsnObjDestroy(long con, long id)348     native void rsnObjDestroy(long con, long id);
nObjDestroy(long id)349     void nObjDestroy(long id) {
350         // There is a race condition here.  The calling code may be run
351         // by the gc while teardown is occuring.  This protects againts
352         // deleting dead objects.
353         if (mContext != 0) {
354             rsnObjDestroy(mContext, id);
355         }
356     }
357 
rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize)358     native long  rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
nElementCreate(long type, int kind, boolean norm, int vecSize)359     synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
360         validate();
361         return rsnElementCreate(mContext, type, kind, norm, vecSize);
362     }
rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes)363     native long  rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
nElementCreate2(long[] elements, String[] names, int[] arraySizes)364     synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
365         validate();
366         return rsnElementCreate2(mContext, elements, names, arraySizes);
367     }
rsnElementGetNativeData(long con, long id, int[] elementData)368     native void rsnElementGetNativeData(long con, long id, int[] elementData);
nElementGetNativeData(long id, int[] elementData)369     synchronized void nElementGetNativeData(long id, int[] elementData) {
370         validate();
371         rsnElementGetNativeData(mContext, id, elementData);
372     }
rsnElementGetSubElements(long con, long id, long[] IDs, String[] names, int[] arraySizes)373     native void rsnElementGetSubElements(long con, long id,
374                                          long[] IDs, String[] names, int[] arraySizes);
nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes)375     synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
376         validate();
377         rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
378     }
379 
rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)380     native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)381     synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
382         validate();
383         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
384     }
385 
rsnTypeGetNativeData(long con, long id, long[] typeData)386     native void rsnTypeGetNativeData(long con, long id, long[] typeData);
nTypeGetNativeData(long id, long[] typeData)387     synchronized void nTypeGetNativeData(long id, long[] typeData) {
388         validate();
389         rsnTypeGetNativeData(mContext, id, typeData);
390     }
391 
rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer)392     native long  rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
nAllocationCreateTyped(long type, int mip, int usage, long pointer)393     synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
394         validate();
395         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
396     }
rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage)397     native long  rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage)398     synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
399         validate();
400         return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
401     }
402 
rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage)403     native long  rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage)404     synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
405         validate();
406         return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
407     }
408 
409 
rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage)410     native long  rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage)411     synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
412         validate();
413         return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
414     }
rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp)415     native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
nAllocationCreateBitmapRef(long type, Bitmap bmp)416     synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
417         validate();
418         return rsnAllocationCreateBitmapRef(mContext, type, bmp);
419     }
rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage)420     native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
nAllocationCreateFromAssetStream(int mips, int assetStream, int usage)421     synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
422         validate();
423         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
424     }
425 
rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp)426     native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
nAllocationCopyToBitmap(long alloc, Bitmap bmp)427     synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
428         validate();
429         rsnAllocationCopyToBitmap(mContext, alloc, bmp);
430     }
431 
432 
rsnAllocationSyncAll(long con, long alloc, int src)433     native void rsnAllocationSyncAll(long con, long alloc, int src);
nAllocationSyncAll(long alloc, int src)434     synchronized void nAllocationSyncAll(long alloc, int src) {
435         validate();
436         rsnAllocationSyncAll(mContext, alloc, src);
437     }
438 
rsnAllocationSetSurface(long con, long alloc, Surface sur)439     native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
nAllocationSetSurface(long alloc, Surface sur)440     synchronized void nAllocationSetSurface(long alloc, Surface sur) {
441         validate();
442         rsnAllocationSetSurface(mContext, alloc, sur);
443     }
444 
rsnAllocationIoSend(long con, long alloc)445     native void rsnAllocationIoSend(long con, long alloc);
nAllocationIoSend(long alloc)446     synchronized void nAllocationIoSend(long alloc) {
447         validate();
448         rsnAllocationIoSend(mContext, alloc);
449     }
rsnAllocationIoReceive(long con, long alloc)450     native void rsnAllocationIoReceive(long con, long alloc);
nAllocationIoReceive(long alloc)451     synchronized void nAllocationIoReceive(long alloc) {
452         validate();
453         rsnAllocationIoReceive(mContext, alloc);
454     }
rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ)455     native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ);
nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ)456     synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) {
457         validate();
458         return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ);
459     }
rsnAllocationGetStride(long con, long alloc)460     native long rsnAllocationGetStride(long con, long alloc);
nAllocationGetStride(long alloc)461     synchronized long nAllocationGetStride(long alloc) {
462         validate();
463         return rsnAllocationGetStride(mContext, alloc);
464     }
465 
rsnAllocationGenerateMipmaps(long con, long alloc)466     native void rsnAllocationGenerateMipmaps(long con, long alloc);
nAllocationGenerateMipmaps(long alloc)467     synchronized void nAllocationGenerateMipmaps(long alloc) {
468         validate();
469         rsnAllocationGenerateMipmaps(mContext, alloc);
470     }
rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp)471     native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
nAllocationCopyFromBitmap(long alloc, Bitmap bmp)472     synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
473         validate();
474         rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
475     }
476 
477 
rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)478     native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
479                                     int mSize, boolean usePadding);
nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt, int mSize, boolean usePadding)480     synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
481                                         int mSize, boolean usePadding) {
482         validate();
483         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
484     }
485 
rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes)486     native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes)487     synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
488         validate();
489         rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
490     }
491     /*
492     native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
493     synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
494         validate();
495         rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
496     }
497     */
498 
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)499     native void rsnAllocationData2D(long con,
500                                     long dstAlloc, int dstXoff, int dstYoff,
501                                     int dstMip, int dstFace,
502                                     int width, int height,
503                                     long srcAlloc, int srcXoff, int srcYoff,
504                                     int srcMip, int srcFace);
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)505     synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
506                                         int dstMip, int dstFace,
507                                         int width, int height,
508                                         long srcAlloc, int srcXoff, int srcYoff,
509                                         int srcMip, int srcFace) {
510         validate();
511         rsnAllocationData2D(mContext,
512                             dstAlloc, dstXoff, dstYoff,
513                             dstMip, dstFace,
514                             width, height,
515                             srcAlloc, srcXoff, srcYoff,
516                             srcMip, srcFace);
517     }
518 
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)519     native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
520                                     int w, int h, Object d, int sizeBytes, int dt,
521                                     int mSize, boolean usePadding);
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)522     synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
523                                         int w, int h, Object d, int sizeBytes, Element.DataType dt,
524                                         int mSize, boolean usePadding) {
525         validate();
526         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
527     }
528 
rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b)529     native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b)530     synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
531         validate();
532         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
533     }
534 
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)535     native void rsnAllocationData3D(long con,
536                                     long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
537                                     int dstMip,
538                                     int width, int height, int depth,
539                                     long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
540                                     int srcMip);
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)541     synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
542                                         int dstMip,
543                                         int width, int height, int depth,
544                                         long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
545                                         int srcMip) {
546         validate();
547         rsnAllocationData3D(mContext,
548                             dstAlloc, dstXoff, dstYoff, dstZoff,
549                             dstMip, width, height, depth,
550                             srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
551     }
552 
553 
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)554     native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
555                                     int w, int h, int depth, Object d, int sizeBytes, int dt,
556                                     int mSize, boolean usePadding);
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)557     synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
558                                         int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
559                                         int mSize, boolean usePadding) {
560         validate();
561         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
562                             dt.mID, mSize, usePadding);
563     }
564 
rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding)565     native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding)566     synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
567         validate();
568         rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
569     }
570 
rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)571     native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
572                                     int sizeBytes, int dt, int mSize, boolean usePadding);
nAllocationRead1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt, int mSize, boolean usePadding)573     synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
574                                         int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
575         validate();
576         rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
577     }
578 
579     /*
580     native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
581                                          int mip, int compIdx, byte[] d, int sizeBytes);
582     synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
583                                              int mip, int compIdx, byte[] d, int sizeBytes) {
584         validate();
585         rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
586     }
587     */
588 
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)589     native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
590                                     int w, int h, Object d, int sizeBytes, int dt,
591                                     int mSize, boolean usePadding);
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)592     synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
593                                         int w, int h, Object d, int sizeBytes, Element.DataType dt,
594                                         int mSize, boolean usePadding) {
595         validate();
596         rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
597     }
598 
599     /*
600     native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
601                                     int w, int h, int depth, Object d, int sizeBytes, int dt,
602                                     int mSize, boolean usePadding);
603     synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
604                                         int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
605                                         int mSize, boolean usePadding) {
606         validate();
607         rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
608     }
609     */
610 
rsnAllocationGetType(long con, long id)611     native long  rsnAllocationGetType(long con, long id);
nAllocationGetType(long id)612     synchronized long nAllocationGetType(long id) {
613         validate();
614         return rsnAllocationGetType(mContext, id);
615     }
616 
rsnAllocationResize1D(long con, long id, int dimX)617     native void rsnAllocationResize1D(long con, long id, int dimX);
nAllocationResize1D(long id, int dimX)618     synchronized void nAllocationResize1D(long id, int dimX) {
619         validate();
620         rsnAllocationResize1D(mContext, id, dimX);
621     }
rsnAllocationResize2D(long con, long id, int dimX, int dimY)622     native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
nAllocationResize2D(long id, int dimX, int dimY)623     synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
624         validate();
625         rsnAllocationResize2D(mContext, id, dimX, dimY);
626     }
627 
rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc)628     native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc)629     synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
630         validate();
631         long curCon = mContext;
632         if (mUseInc) {
633             curCon = mIncCon;
634         }
635         rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
636     }
rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc)637     native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc)638     synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
639         validate();
640         long curCon = mContext;
641         if (mUseInc) {
642             curCon = mIncCon;
643         }
644         rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
645     }
rsnScriptInvoke(long con, long id, int slot, boolean mUseInc)646     native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
nScriptInvoke(long id, int slot, boolean mUseInc)647     synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
648         validate();
649         long curCon = mContext;
650         if (mUseInc) {
651             curCon = mIncCon;
652         }
653         rsnScriptInvoke(curCon, id, slot, mUseInc);
654     }
rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc)655     native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc)656     native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
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)657     native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
658                                         int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
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)659     native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
660                                         int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc)661     synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
662         validate();
663         if (params == null) {
664             rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
665         } else {
666             rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
667         }
668     }
669 
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)670     synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
671                                             int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
672         validate();
673         if (params == null) {
674             rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
675         } else {
676             rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
677         }
678     }
679 
rsnScriptForEach(long con, long id, int slot, long[] ains, long aout, byte[] params, int[] limits)680     native void rsnScriptForEach(long con, long id, int slot, long[] ains,
681                                  long aout, byte[] params, int[] limits);
682 
nScriptForEach(long id, int slot, long[] ains, long aout, byte[] params, int[] limits)683     synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
684                                      byte[] params, int[] limits) {
685         if (!mEnableMultiInput) {
686             Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23");
687             throw new RSRuntimeException("Multi-input kernels are not supported before API 23)");
688         }
689         validate();
690         rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
691     }
692 
rsnScriptReduce(long con, long id, int slot, long[] ains, long aout, int[] limits)693     native void rsnScriptReduce(long con, long id, int slot, long[] ains,
694                                 long aout, int[] limits);
nScriptReduce(long id, int slot, long ains[], long aout, int[] limits)695     synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
696                                     int[] limits) {
697         validate();
698         rsnScriptReduce(mContext, id, slot, ains, aout, limits);
699     }
700 
rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc)701     native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc)702     synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
703         validate();
704         long curCon = mContext;
705         if (mUseInc) {
706             curCon = mIncCon;
707         }
708         rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
709     }
rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc)710     native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
nScriptSetVarI(long id, int slot, int val, boolean mUseInc)711     synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
712         validate();
713         long curCon = mContext;
714         if (mUseInc) {
715             curCon = mIncCon;
716         }
717         rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
718     }
rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc)719     native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
nScriptSetVarJ(long id, int slot, long val, boolean mUseInc)720     synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
721         validate();
722         long curCon = mContext;
723         if (mUseInc) {
724             curCon = mIncCon;
725         }
726         rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
727     }
rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc)728     native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
nScriptSetVarF(long id, int slot, float val, boolean mUseInc)729     synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
730         validate();
731         long curCon = mContext;
732         if (mUseInc) {
733             curCon = mIncCon;
734         }
735         rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
736     }
rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc)737     native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
nScriptSetVarD(long id, int slot, double val, boolean mUseInc)738     synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
739         validate();
740         long curCon = mContext;
741         if (mUseInc) {
742             curCon = mIncCon;
743         }
744         rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
745     }
rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc)746     native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc)747     synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
748         validate();
749         long curCon = mContext;
750         if (mUseInc) {
751             curCon = mIncCon;
752         }
753         rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
754     }
rsnScriptSetVarVE(long con, long id, int slot, byte[] val, long e, int[] dims, boolean mUseInc)755     native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
756                                   long e, int[] dims, boolean mUseInc);
nScriptSetVarVE(long id, int slot, byte[] val, long e, int[] dims, boolean mUseInc)757     synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
758                                       long e, int[] dims, boolean mUseInc) {
759         validate();
760         long curCon = mContext;
761         if (mUseInc) {
762             curCon = mIncCon;
763         }
764         rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
765     }
rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc)766     native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
nScriptSetVarObj(long id, int slot, long val, boolean mUseInc)767     synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
768         validate();
769         long curCon = mContext;
770         if (mUseInc) {
771             curCon = mIncCon;
772         }
773         rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
774     }
775 
rsnScriptCCreate(long con, String resName, String cacheDir, byte[] script, int length)776     native long  rsnScriptCCreate(long con, String resName, String cacheDir,
777                                  byte[] script, int length);
nScriptCCreate(String resName, String cacheDir, byte[] script, int length)778     synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
779         validate();
780         return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
781     }
782 
rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc)783     native long  rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
nScriptIntrinsicCreate(int id, long eid, boolean mUseInc)784     synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
785         validate();
786         if (mUseInc) {
787             if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
788                 Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21");
789                 throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)");
790             }
791 
792             if (!mIncLoaded) {
793                 try {
794                     System.loadLibrary("RSSupport");
795                 } catch (UnsatisfiedLinkError e) {
796                     Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
797                     throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
798                 }
799                 if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
800                     throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
801                 }
802                 mIncLoaded = true;
803             }
804             if (mIncCon == 0) {
805                 //Create a placeholder compat context (synchronous).
806                 long device = nIncDeviceCreate();
807                 mIncCon = nIncContextCreate(device, 0, 0, 0);
808             }
809             return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
810         } else {
811             return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
812         }
813     }
814 
rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc)815     native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc)816     synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
817         validate();
818         long curCon = mContext;
819         if (mUseInc) {
820             curCon = mIncCon;
821         }
822         return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
823     }
824 
rsnScriptInvokeIDCreate(long con, long sid, int slot)825     native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
nScriptInvokeIDCreate(long sid, int slot)826     synchronized long nScriptInvokeIDCreate(long sid, int slot) {
827         validate();
828         return rsnScriptInvokeIDCreate(mContext, sid, slot);
829     }
830 
rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc)831     native long  rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
nScriptFieldIDCreate(long sid, int slot, boolean mUseInc)832     synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
833         validate();
834         long curCon = mContext;
835         if (mUseInc) {
836             curCon = mIncCon;
837         }
838         return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
839     }
840 
rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types)841     native long  rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types)842     synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
843         validate();
844         return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
845     }
846 
rsnScriptGroupSetInput(long con, long group, long kernel, long alloc)847     native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
nScriptGroupSetInput(long group, long kernel, long alloc)848     synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
849         validate();
850         rsnScriptGroupSetInput(mContext, group, kernel, alloc);
851     }
852 
rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc)853     native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
nScriptGroupSetOutput(long group, long kernel, long alloc)854     synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
855         validate();
856         rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
857     }
858 
rsnScriptGroupExecute(long con, long group)859     native void rsnScriptGroupExecute(long con, long group);
nScriptGroupExecute(long group)860     synchronized void nScriptGroupExecute(long group) {
861         validate();
862         rsnScriptGroupExecute(mContext, group);
863     }
864 
rsnSamplerCreate(long con, int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso)865     native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
866                                  int wrapS, int wrapT, int wrapR, float aniso);
nSamplerCreate(int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso)867     synchronized long nSamplerCreate(int magFilter, int minFilter,
868                                  int wrapS, int wrapT, int wrapR, float aniso) {
869         validate();
870         return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
871     }
872 
873 // entry points for ScriptGroup2
rsnClosureCreate(long con, long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs)874     native long rsnClosureCreate(long con, long kernelID, long returnValue,
875         long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
876         long[] depFieldIDs);
nClosureCreate(long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs)877     synchronized long nClosureCreate(long kernelID, long returnValue,
878         long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
879         long[] depFieldIDs) {
880       validate();
881       long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
882           sizes, depClosures, depFieldIDs);
883       if (c == 0) {
884           throw new RSRuntimeException("Failed creating closure.");
885       }
886       return c;
887     }
888 
rsnInvokeClosureCreate(long con, long invokeID, byte[] params, long[] fieldIDs, long[] values, int[] sizes)889     native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
890         long[] fieldIDs, long[] values, int[] sizes);
nInvokeClosureCreate(long invokeID, byte[] params, long[] fieldIDs, long[] values, int[] sizes)891     synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
892         long[] fieldIDs, long[] values, int[] sizes) {
893       validate();
894       long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
895           values, sizes);
896       if (c == 0) {
897           throw new RSRuntimeException("Failed creating closure.");
898       }
899       return c;
900     }
901 
rsnClosureSetArg(long con, long closureID, int index, long value, int size)902     native void rsnClosureSetArg(long con, long closureID, int index,
903       long value, int size);
nClosureSetArg(long closureID, int index, long value, int size)904     synchronized void nClosureSetArg(long closureID, int index, long value,
905         int size) {
906       validate();
907       rsnClosureSetArg(mContext, closureID, index, value, size);
908     }
909 
rsnClosureSetGlobal(long con, long closureID, long fieldID, long value, int size)910     native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
911         long value, int size);
912     // Does this have to be synchronized?
nClosureSetGlobal(long closureID, long fieldID, long value, int size)913     synchronized void nClosureSetGlobal(long closureID, long fieldID,
914         long value, int size) {
915       validate(); // TODO: is this necessary?
916       rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
917     }
918 
rsnScriptGroup2Create(long con, String name, String cachePath, long[] closures)919     native long rsnScriptGroup2Create(long con, String name, String cachePath,
920                                       long[] closures);
nScriptGroup2Create(String name, String cachePath, long[] closures)921     synchronized long nScriptGroup2Create(String name, String cachePath,
922                                           long[] closures) {
923       validate();
924       return rsnScriptGroup2Create(mContext, name, cachePath, closures);
925     }
926 
rsnScriptGroup2Execute(long con, long groupID)927     native void rsnScriptGroup2Execute(long con, long groupID);
nScriptGroup2Execute(long groupID)928     synchronized void nScriptGroup2Execute(long groupID) {
929       validate();
930       rsnScriptGroup2Execute(mContext, groupID);
931     }
932 
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)933     native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA,
934                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
935                                               float alpha, long A, long B, float beta, long C, int incX, int incY,
936                                               int KL, int KU, boolean mUseInc);
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)937     synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
938                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
939                                                   float alpha, long A, long B, float beta, long C, int incX, int incY,
940                                                   int KL, int KU, boolean mUseInc) {
941         validate();
942         rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
943     }
944 
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)945     native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA,
946                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
947                                               double alpha, long A, long B, double beta, long C, int incX, int incY,
948                                               int KL, int KU, boolean mUseInc);
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)949     synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
950                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
951                                                   double alpha, long A, long B, double beta, long C, int incX, int incY,
952                                                   int KL, int KU, boolean mUseInc) {
953         validate();
954         rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
955     }
956 
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)957     native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA,
958                                                int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
959                                                float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
960                                                int KL, int KU, boolean mUseInc);
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)961     synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
962                                                    int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
963                                                    float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
964                                                    int KL, int KU, boolean mUseInc) {
965         validate();
966         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);
967     }
968 
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)969     native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA,
970                                          int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
971                                          double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
972                                          int KL, int KU, boolean mUseInc);
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)973     synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
974                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
975                                              double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
976                                              int KL, int KU, boolean mUseInc) {
977         validate();
978         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);
979     }
980 
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)981     native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K,
982                                              long A, int a_offset, long B, int b_offset, long C, int c_offset,
983                                              int c_mult_int, boolean mUseInc);
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)984     synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
985                                              long A, int a_offset, long B, int b_offset, long C, int c_offset,
986                                              int c_mult_int, boolean mUseInc) {
987         validate();
988         rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc);
989     }
990 
991 // Additional Entry points For inc libRSSupport
992 
nIncLoadSO(int deviceApi, String libPath)993     native boolean nIncLoadSO(int deviceApi, String libPath);
nIncDeviceCreate()994     native long nIncDeviceCreate();
nIncDeviceDestroy(long dev)995     native void nIncDeviceDestroy(long dev);
996     // Methods below are wrapped to protect the non-threadsafe
997     // lockless fifo.
rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType)998     native long  rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
nIncContextCreate(long dev, int ver, int sdkVer, int contextType)999     synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
1000         return rsnIncContextCreate(dev, ver, sdkVer, contextType);
1001     }
rsnIncContextDestroy(long con)1002     native void rsnIncContextDestroy(long con);
nIncContextDestroy()1003     synchronized void nIncContextDestroy() {
1004         validate();
1005 
1006         // take teardown lock
1007         // teardown lock can only be taken when no objects are being destroyed
1008         ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
1009         wlock.lock();
1010 
1011         long curCon = mIncCon;
1012         // context is considered dead as of this point
1013         mIncCon = 0;
1014 
1015         wlock.unlock();
1016         rsnIncContextDestroy(curCon);
1017     }
1018 
rsnIncContextFinish(long con)1019     native void rsnIncContextFinish(long con);
nIncContextFinish()1020     synchronized void nIncContextFinish() {
1021         validate();
1022         rsnIncContextFinish(mIncCon);
1023     }
1024 
rsnIncObjDestroy(long con, long id)1025     native void rsnIncObjDestroy(long con, long id);
nIncObjDestroy(long id)1026     void nIncObjDestroy(long id) {
1027         // There is a race condition here.  The calling code may be run
1028         // by the gc while teardown is occuring.  This protects againts
1029         // deleting dead objects.
1030         if (mIncCon != 0) {
1031             rsnIncObjDestroy(mIncCon, id);
1032         }
1033     }
rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize)1034     native long  rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
nIncElementCreate(long type, int kind, boolean norm, int vecSize)1035     synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
1036         validate();
1037         return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
1038     }
rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)1039     native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)1040     synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
1041         validate();
1042         return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
1043     }
rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize)1044     native long  rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize);
nIncAllocationCreateTyped(long alloc, long type, int xBytesSize)1045     synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) {
1046         validate();
1047         return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize);
1048     }
1049 
1050     long     mContext;
1051     private boolean mDestroyed = false;
1052     //Placeholder device & context for Inc Support Lib
1053     long     mIncCon;
1054     //indicator of whether inc support lib has been loaded or not.
1055     boolean  mIncLoaded;
1056     ReentrantReadWriteLock mRWLock;
1057     @SuppressWarnings({"FieldCanBeLocal"})
1058     MessageThread mMessageThread;
1059 
1060     Element mElement_U8;
1061     Element mElement_I8;
1062     Element mElement_U16;
1063     Element mElement_I16;
1064     Element mElement_U32;
1065     Element mElement_I32;
1066     Element mElement_U64;
1067     Element mElement_I64;
1068     Element mElement_F32;
1069     Element mElement_F64;
1070     Element mElement_BOOLEAN;
1071 
1072     Element mElement_ELEMENT;
1073     Element mElement_TYPE;
1074     Element mElement_ALLOCATION;
1075     Element mElement_SAMPLER;
1076     Element mElement_SCRIPT;
1077 
1078     Element mElement_A_8;
1079     Element mElement_RGB_565;
1080     Element mElement_RGB_888;
1081     Element mElement_RGBA_5551;
1082     Element mElement_RGBA_4444;
1083     Element mElement_RGBA_8888;
1084 
1085     Element mElement_FLOAT_2;
1086     Element mElement_FLOAT_3;
1087     Element mElement_FLOAT_4;
1088 
1089     Element mElement_DOUBLE_2;
1090     Element mElement_DOUBLE_3;
1091     Element mElement_DOUBLE_4;
1092 
1093     Element mElement_UCHAR_2;
1094     Element mElement_UCHAR_3;
1095     Element mElement_UCHAR_4;
1096 
1097     Element mElement_CHAR_2;
1098     Element mElement_CHAR_3;
1099     Element mElement_CHAR_4;
1100 
1101     Element mElement_USHORT_2;
1102     Element mElement_USHORT_3;
1103     Element mElement_USHORT_4;
1104 
1105     Element mElement_SHORT_2;
1106     Element mElement_SHORT_3;
1107     Element mElement_SHORT_4;
1108 
1109     Element mElement_UINT_2;
1110     Element mElement_UINT_3;
1111     Element mElement_UINT_4;
1112 
1113     Element mElement_INT_2;
1114     Element mElement_INT_3;
1115     Element mElement_INT_4;
1116 
1117     Element mElement_ULONG_2;
1118     Element mElement_ULONG_3;
1119     Element mElement_ULONG_4;
1120 
1121     Element mElement_LONG_2;
1122     Element mElement_LONG_3;
1123     Element mElement_LONG_4;
1124 
1125     Element mElement_MATRIX_4X4;
1126     Element mElement_MATRIX_3X3;
1127     Element mElement_MATRIX_2X2;
1128 
1129     Sampler mSampler_CLAMP_NEAREST;
1130     Sampler mSampler_CLAMP_LINEAR;
1131     Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
1132     Sampler mSampler_WRAP_NEAREST;
1133     Sampler mSampler_WRAP_LINEAR;
1134     Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
1135     Sampler mSampler_MIRRORED_REPEAT_NEAREST;
1136     Sampler mSampler_MIRRORED_REPEAT_LINEAR;
1137     Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
1138 
1139 
1140     ///////////////////////////////////////////////////////////////////////////////////
1141     //
1142 
1143     /**
1144      * The base class from which an application should derive in order
1145      * to receive RS messages from scripts. When a script calls {@code
1146      * rsSendToClient}, the data fields will be filled, and the run
1147      * method will be called on a separate thread.  This will occur
1148      * some time after {@code rsSendToClient} completes in the script,
1149      * as {@code rsSendToClient} is asynchronous. Message handlers are
1150      * not guaranteed to have completed when {@link
1151      * androidx.renderscript.RenderScript#finish} returns.
1152      *
1153      */
1154     public static class RSMessageHandler implements Runnable {
1155         protected int[] mData;
1156         protected int mID;
1157         protected int mLength;
run()1158         public void run() {
1159         }
1160     }
1161     /**
1162      * If an application is expecting messages, it should set this
1163      * field to an instance of {@link RSMessageHandler}.  This
1164      * instance will receive all the user messages sent from {@code
1165      * sendToClient} by scripts from this context.
1166      *
1167      */
1168     RSMessageHandler mMessageCallback = null;
1169 
setMessageHandler(RSMessageHandler msg)1170     public void setMessageHandler(RSMessageHandler msg) {
1171         mMessageCallback = msg;
1172     }
getMessageHandler()1173     public RSMessageHandler getMessageHandler() {
1174         return mMessageCallback;
1175     }
1176 
1177     /**
1178      * Place a message into the message queue to be sent back to the message
1179      * handler once all previous commands have been executed.
1180      *
1181      * @param id
1182      * @param data
1183      */
sendMessage(int id, int[] data)1184     public void sendMessage(int id, int[] data) {
1185         nContextSendMessage(id, data);
1186     }
1187 
1188     /**
1189      * The runtime error handler base class.  An application should derive from this class
1190      * if it wishes to install an error handler.  When errors occur at runtime,
1191      * the fields in this class will be filled, and the run method will be called.
1192      *
1193      */
1194     public static class RSErrorHandler implements Runnable {
1195         protected String mErrorMessage;
1196         protected int mErrorNum;
run()1197         public void run() {
1198         }
1199     }
1200 
1201     /**
1202      * Application Error handler.  All runtime errors will be dispatched to the
1203      * instance of RSAsyncError set here.  If this field is null a
1204      * {@link RSRuntimeException} will instead be thrown with details about the error.
1205      * This will cause program termaination.
1206      *
1207      */
1208     RSErrorHandler mErrorCallback = null;
1209 
setErrorHandler(RSErrorHandler msg)1210     public void setErrorHandler(RSErrorHandler msg) {
1211         mErrorCallback = msg;
1212     }
getErrorHandler()1213     public RSErrorHandler getErrorHandler() {
1214         return mErrorCallback;
1215     }
1216 
1217     /**
1218      * RenderScript worker thread priority enumeration.  The default value is
1219      * NORMAL.  Applications wishing to do background processing should set
1220      * their priority to LOW to avoid starving forground processes.
1221      */
1222     public enum Priority {
1223         LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
1224         NORMAL (Process.THREAD_PRIORITY_DISPLAY);
1225 
1226         int mID;
Priority(int id)1227         Priority(int id) {
1228             mID = id;
1229         }
1230     }
1231 
validateObject(BaseObj o)1232     void validateObject(BaseObj o) {
1233         if (o != null) {
1234             if (o.mRS != this) {
1235                 throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
1236             }
1237         }
1238     }
1239 
validate()1240     void validate() {
1241         if (mContext == 0) {
1242             throw new RSInvalidStateException("Calling RS with no Context active.");
1243         }
1244     }
1245 
1246     /**
1247      * check if IO support lib is available.
1248      */
usingIO()1249     boolean usingIO() {
1250         return useIOlib;
1251     }
1252     /**
1253      * Change the priority of the worker threads for this context.
1254      *
1255      * @param p New priority to be set.
1256      */
setPriority(Priority p)1257     public void setPriority(Priority p) {
1258         validate();
1259         nContextSetPriority(p.mID);
1260     }
1261 
1262     static class MessageThread extends Thread {
1263         RenderScript mRS;
1264         boolean mRun = true;
1265         int[] mAuxData = new int[2];
1266 
1267         static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1268         static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1269         static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1270         static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1271 
1272         static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1273         static final int RS_ERROR_FATAL_DEBUG = 0x800;
1274         static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1275 
MessageThread(RenderScript rs)1276         MessageThread(RenderScript rs) {
1277             super("RSMessageThread");
1278             mRS = rs;
1279 
1280         }
1281 
run()1282         public void run() {
1283             // This function is a temporary solution.  The final solution will
1284             // used typed allocations where the message id is the type indicator.
1285             int[] rbuf = new int[16];
1286             mRS.nContextInitToClient(mRS.mContext);
1287             while(mRun) {
1288                 rbuf[0] = 0;
1289                 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1290                 int size = mAuxData[1];
1291                 int subID = mAuxData[0];
1292 
1293                 if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1294                     if ((size>>2) >= rbuf.length) {
1295                         rbuf = new int[(size + 3) >> 2];
1296                     }
1297                     if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1298                         RS_MESSAGE_TO_CLIENT_USER) {
1299                         throw new RSDriverException("Error processing message from RenderScript.");
1300                     }
1301 
1302                     if(mRS.mMessageCallback != null) {
1303                         mRS.mMessageCallback.mData = rbuf;
1304                         mRS.mMessageCallback.mID = subID;
1305                         mRS.mMessageCallback.mLength = size;
1306                         mRS.mMessageCallback.run();
1307                     } else {
1308                         throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1309                     }
1310                     continue;
1311                 }
1312 
1313                 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1314                     String e = mRS.nContextGetErrorMessage(mRS.mContext);
1315 
1316                     // Copied from java/android/renderscript/RenderScript.java
1317                     // Throw RSRuntimeException under the following conditions:
1318                     //
1319                     // 1) It is an unknown fatal error.
1320                     // 2) It is a debug fatal error, and we are not in a
1321                     //    debug context.
1322                     // 3) It is a debug fatal error, and we do not have an
1323                     //    error callback.
1324                     if (subID >= RS_ERROR_FATAL_UNKNOWN ||
1325                         (subID >= RS_ERROR_FATAL_DEBUG &&
1326                          (mRS.mContextType != ContextType.DEBUG ||
1327                           mRS.mErrorCallback == null))) {
1328                         android.util.Log.e(LOG_TAG, "fatal RS error, " + e);
1329                         throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
1330                     }
1331 
1332                     if(mRS.mErrorCallback != null) {
1333                         mRS.mErrorCallback.mErrorMessage = e;
1334                         mRS.mErrorCallback.mErrorNum = subID;
1335                         mRS.mErrorCallback.run();
1336                     } else {
1337                         android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
1338                         // Do not throw here. In these cases, we do not have
1339                         // a fatal error.
1340                     }
1341                     continue;
1342                 }
1343 
1344                 // 2: teardown.
1345                 // But we want to avoid starving other threads during
1346                 // teardown by yielding until the next line in the destructor
1347                 // can execute to set mRun = false
1348                 try {
1349                     sleep(1, 0);
1350                 } catch(InterruptedException e) {
1351                 }
1352             }
1353             //Log.d(LOG_TAG, "MessageThread exiting.");
1354         }
1355     }
1356 
RenderScript(Context ctx)1357     RenderScript(Context ctx) {
1358         mContextType = ContextType.NORMAL;
1359         if (ctx != null) {
1360             mApplicationContext = ctx.getApplicationContext();
1361             // Only set mNativeLibDir for API 9+.
1362             mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
1363         }
1364         mIncCon = 0;
1365         mIncLoaded = false;
1366         mRWLock = new ReentrantReadWriteLock();
1367     }
1368 
1369     /**
1370      * Gets the application context associated with the RenderScript context.
1371      *
1372      * @return The application context.
1373      */
getApplicationContext()1374     public final Context getApplicationContext() {
1375         return mApplicationContext;
1376     }
1377 
1378     /**
1379      * Create a RenderScript context.
1380      *
1381      * @param ctx The context.
1382      * @return RenderScript
1383      */
internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags)1384     private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
1385         RenderScript rs = new RenderScript(ctx);
1386 
1387         if (sSdkVersion == -1) {
1388             sSdkVersion = sdkVersion;
1389         } else if (sSdkVersion != sdkVersion) {
1390             throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
1391         }
1392         useNative = setupNative(sSdkVersion, ctx);
1393         synchronized(lock) {
1394             if (sInitialized == false) {
1395                 try {
1396                     Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
1397                     Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
1398                     sRuntime = get_runtime.invoke(null);
1399                     Class<?> argClass = android.os.Build.VERSION.SDK_INT >= 29 ? Long.TYPE : Integer.TYPE;
1400                     // The int version is (so far) always defined, but deprecated for APIs >= 29.
1401                     registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", argClass);
1402                     registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", argClass);
1403                     sUseGCHooks = true;
1404                 } catch (Exception e) {
1405                     Log.e(LOG_TAG, "No GC methods");
1406                     sUseGCHooks = false;
1407                 }
1408                 try {
1409                     // For API 9 - 22, always use the absolute path of librsjni.so
1410                     // http://b/25226912
1411                     if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
1412                         rs.mNativeLibDir != null) {
1413                         System.load(rs.mNativeLibDir + "/librsjni.so");
1414                     } else {
1415                         System.loadLibrary("rsjni");
1416                     }
1417                     sInitialized = true;
1418                     sPointerSize = rsnSystemGetPointerSize();
1419                 } catch (UnsatisfiedLinkError e) {
1420                     Log.e(LOG_TAG, "Error loading RS jni library: " + e);
1421                     throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
1422                 }
1423             }
1424         }
1425 
1426         if (useNative) {
1427             android.util.Log.v(LOG_TAG, "RS native mode");
1428         } else {
1429             android.util.Log.v(LOG_TAG, "RS compat mode");
1430         }
1431 
1432         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1433             useIOlib = true;
1434         }
1435 
1436         // The target API level used to init dispatchTable.
1437         int dispatchAPI = sdkVersion;
1438         if (sdkVersion < android.os.Build.VERSION.SDK_INT) {
1439             // If the device API is higher than target API level, init dispatch table based on device API.
1440             dispatchAPI = android.os.Build.VERSION.SDK_INT;
1441         }
1442 
1443         String rssupportPath = null;
1444         // For API 9 - 22, always use the absolute path of libRSSupport.so
1445         // http://b/25226912
1446         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
1447             rs.mNativeLibDir != null) {
1448             rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
1449         }
1450         if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
1451             if (useNative) {
1452                 android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
1453                 useNative = false;
1454             }
1455             try {
1456                 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
1457                     rs.mNativeLibDir != null) {
1458                     System.load(rssupportPath);
1459                 } else {
1460                     System.loadLibrary("RSSupport");
1461                 }
1462             } catch (UnsatisfiedLinkError e) {
1463                 Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
1464                 throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
1465             }
1466             if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
1467                 Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
1468                 throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
1469             }
1470         }
1471 
1472         if (useIOlib) {
1473             try {
1474                 System.loadLibrary("RSSupportIO");
1475             } catch (UnsatisfiedLinkError e) {
1476                 useIOlib = false;
1477             }
1478             if (!useIOlib || !rs.nLoadIOSO()) {
1479                 android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
1480                 useIOlib = false;
1481             }
1482         }
1483 
1484         // For old APIs with dlopen bug, need to load blas lib in Java first.
1485         // Only try load to blasV8 when the desired API level includes IntrinsicBLAS.
1486         if (dispatchAPI >= 23) {
1487             // Enable multi-input kernels only when diapatchAPI is M+.
1488             rs.mEnableMultiInput = true;
1489             try {
1490                 System.loadLibrary("blasV8");
1491             } catch (UnsatisfiedLinkError e) {
1492                 Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e);
1493             }
1494         }
1495 
1496         long device = rs.nDeviceCreate();
1497         rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
1498         rs.mContextType = ct;
1499         rs.mContextFlags = flags;
1500         rs.mContextSdkVersion = sdkVersion;
1501         rs.mDispatchAPILevel = dispatchAPI;
1502         if (rs.mContext == 0) {
1503             throw new RSDriverException("Failed to create RS context.");
1504         }
1505         rs.mMessageThread = new MessageThread(rs);
1506         rs.mMessageThread.start();
1507         return rs;
1508     }
1509 
1510     /**
1511      * Create a RenderScript context.
1512      *
1513      * See documentation for @create for details
1514      *
1515      * @param ctx The context.
1516      * @return RenderScript
1517      */
create(Context ctx)1518     public static RenderScript create(Context ctx) {
1519         return create(ctx, ContextType.NORMAL);
1520     }
1521 
1522     /**
1523      * calls create(ctx, ct, CREATE_FLAG_NONE)
1524      *
1525      * See documentation for @create for details
1526      *
1527      * @param ctx The context.
1528      * @param ct The type of context to be created.
1529      * @return RenderScript
1530      */
create(Context ctx, ContextType ct)1531     public static RenderScript create(Context ctx, ContextType ct) {
1532         return create(ctx, ct, CREATE_FLAG_NONE);
1533     }
1534 
1535     /**
1536      * Gets or creates a RenderScript context of the specified type.
1537      *
1538      * The returned context will be cached for future reuse within
1539      * the process. When an application is finished using
1540      * RenderScript it should call releaseAllContexts()
1541      *
1542      * A process context is a context designed for easy creation and
1543      * lifecycle management.  Multiple calls to this function will
1544      * return the same object provided they are called with the same
1545      * options.  This allows it to be used any time a RenderScript
1546      * context is needed.
1547      *
1548      *
1549      * @param ctx The context.
1550      * @param ct The type of context to be created.
1551      * @param flags The OR of the CREATE_FLAG_* options desired
1552      * @return RenderScript
1553      */
create(Context ctx, ContextType ct, int flags)1554     public static RenderScript create(Context ctx, ContextType ct, int flags) {
1555         int v = ctx.getApplicationInfo().targetSdkVersion;
1556         return create(ctx, v, ct, flags);
1557     }
1558 
1559     /**
1560      * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
1561      *
1562      * Used by the RenderScriptThunker to maintain backward compatibility.
1563      *
1564      * @hide
1565      * @param ctx The context.
1566      * @param sdkVersion The target SDK Version.
1567      * @return RenderScript
1568      */
create(Context ctx, int sdkVersion)1569     public static RenderScript create(Context ctx, int sdkVersion) {
1570         return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
1571     }
1572 
1573 
1574     /**
1575      * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE)
1576      * Create a RenderScript context.
1577      *
1578      * @hide
1579      * @param ctx The context.
1580      * @return RenderScript
1581      */
create(Context ctx, int sdkVersion, ContextType ct)1582     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
1583         return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE);
1584     }
1585 
1586      /**
1587      * Gets or creates a RenderScript context of the specified type.
1588      *
1589      * @param ctx The context.
1590      * @param ct The type of context to be created.
1591      * @param sdkVersion The target SDK Version.
1592      * @param flags The OR of the CREATE_FLAG_* options desired
1593      * @return RenderScript
1594      */
create(Context ctx, int sdkVersion, ContextType ct, int flags)1595     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
1596         synchronized (mProcessContextList) {
1597             for (RenderScript prs : mProcessContextList) {
1598                 if ((prs.mContextType == ct) &&
1599                     (prs.mContextFlags == flags) &&
1600                     (prs.mContextSdkVersion == sdkVersion)) {
1601 
1602                     return prs;
1603                 }
1604             }
1605 
1606             RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
1607             prs.mIsProcessContext = true;
1608             mProcessContextList.add(prs);
1609             return prs;
1610         }
1611     }
1612 
1613     /**
1614      *
1615      * Releases all the process contexts.  This is the same as
1616      * calling .destroy() on each unique context retreived with
1617      * create(...). If no contexts have been created this
1618      * function does nothing.
1619      *
1620      * Typically you call this when your application is losing focus
1621      * and will not be using a context for some time.
1622      *
1623      * This has no effect on a context created with
1624      * createMultiContext()
1625      */
releaseAllContexts()1626     public static void releaseAllContexts() {
1627         ArrayList<RenderScript> oldList;
1628         synchronized (mProcessContextList) {
1629             oldList = mProcessContextList;
1630             mProcessContextList = new ArrayList<RenderScript>();
1631         }
1632 
1633         for (RenderScript prs : oldList) {
1634             prs.mIsProcessContext = false;
1635             prs.destroy();
1636         }
1637         oldList.clear();
1638     }
1639 
1640 
1641 
1642     /**
1643      * Create a RenderScript context.
1644      *
1645      * This is an advanced function intended for applications which
1646      * need to create more than one RenderScript context to be used
1647      * at the same time.
1648      *
1649      * If you need a single context please use create()
1650      *
1651      * @param ctx The context.
1652      * @return RenderScript
1653      */
createMultiContext(Context ctx, ContextType ct, int flags, int API_number)1654     public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
1655         return internalCreate(ctx, API_number, ct, flags);
1656     }
1657 
1658     /**
1659      * Print the currently available debugging information about the state of
1660      * the RS context to the log.
1661      *
1662      */
contextDump()1663     public void contextDump() {
1664         validate();
1665         nContextDump(0);
1666     }
1667 
1668     /**
1669      * Wait for any pending asynchronous opeations (such as copies to a RS
1670      * allocation or RS script executions) to complete.
1671      *
1672      */
finish()1673     public void finish() {
1674         nContextFinish();
1675     }
1676 
helpDestroy()1677     private void helpDestroy() {
1678         boolean shouldDestroy = false;
1679         synchronized(this) {
1680             if (!mDestroyed) {
1681                 shouldDestroy = true;
1682                 mDestroyed = true;
1683             }
1684         }
1685 
1686         if (shouldDestroy) {
1687             nContextFinish();
1688             if (mIncCon != 0) {
1689                 nIncContextFinish();
1690                 nIncContextDestroy();
1691                 mIncCon = 0;
1692             }
1693             nContextDeinitToClient(mContext);
1694             mMessageThread.mRun = false;
1695             // Interrupt mMessageThread so it gets to see immediately that mRun is false
1696             // and exit rightaway.
1697             mMessageThread.interrupt();
1698 
1699             // Wait for mMessageThread to join.  Try in a loop, in case this thread gets interrupted
1700             // during the wait.  If interrupted, set the "interrupted" status of the current thread.
1701             boolean hasJoined = false, interrupted = false;
1702             while (!hasJoined) {
1703                 try {
1704                     mMessageThread.join();
1705                     hasJoined = true;
1706                 } catch (InterruptedException e) {
1707                     interrupted = true;
1708                 }
1709             }
1710             if (interrupted) {
1711                 Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
1712                 Thread.currentThread().interrupt();
1713             }
1714 
1715             nContextDestroy();
1716         }
1717     }
1718 
1719     @Override
finalize()1720     protected void finalize() throws Throwable {
1721         helpDestroy();
1722         super.finalize();
1723     }
1724 
1725     /**
1726      * Destroys this RenderScript context.  Once this function is called,
1727      * using this context or any objects belonging to this context is
1728      * illegal.
1729      *
1730      * This function is a NOP if the context was created
1731      * with create().  Please use releaseAllContexts() to clean up
1732      * contexts created with the create function.
1733      */
destroy()1734     public void destroy() {
1735         if (mIsProcessContext) {
1736             // users cannot destroy a process context
1737             return;
1738         }
1739         validate();
1740         helpDestroy();
1741     }
1742 
isAlive()1743     boolean isAlive() {
1744         return mContext != 0;
1745     }
1746 
safeID(BaseObj o)1747     long safeID(BaseObj o) {
1748         if(o != null) {
1749             return o.getID(this);
1750         }
1751         return 0;
1752     }
1753 }
1754