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