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